Tags: synthetic-data, ema, trend-analysis

Osmosis synthetic data backtesting example#

This is an example notebook how to backtest trading strategies on Osmosis Cosmos DEX. It is based on work done in HackAtom Seoul 2022 hackathon.

Some highlights of this notebook:

Set up#

Set up strategy paramets that will decide its behavior

[1]:
import datetime
import logging

import pandas as pd

from tradingstrategy.chain import ChainId
from tradingstrategy.timebucket import TimeBucket
from tradeexecutor.strategy.cycle import CycleDuration
from tradeexecutor.strategy.strategy_module import TradeRouting, ReserveCurrency

# Rebalance every 8h
trading_strategy_cycle = CycleDuration.cycle_8h

# How much of the cash to put on a single trade
position_size = 0.90

candle_time_bucket = TimeBucket.h1

chain_id = ChainId.osmosis

#
# Strategy thinking specific parameter
#

# 14 days
slow_ema_candle_count = 14*24

# 5 days
fast_ema_candle_count = 5*24

# How many candles to extract from the dataset once
batch_size = slow_ema_candle_count * 2

# Range of backtesting and synthetic data generation.
# Because we are using synthetic data actual dates do not really matter -
# only the duration

# Osmosis launched
# generate a few months of data before strategy start

start_at_data = datetime.datetime(2021, 12, 25)
start_at_strategy = datetime.datetime(2022, 4, 25)

# When our data and strategy ends
end_at = datetime.datetime(2022, 7, 25)

Create our fake exchange and pair#

This will be needed to generate the candles with the same pair_id, and also later, when we generate our synthetic universe

[2]:
import random
from tradeexecutor.testing.synthetic_pair_data import generate_pair
from tradeexecutor.testing.synthetic_ethereum_data import generate_random_ethereum_address
from tradeexecutor.testing.synthetic_exchange_data import generate_exchange

pair_id = 1

exchange = generate_exchange(
        exchange_id=random.randint(1, 1000),
        chain_id=chain_id,
        address=generate_random_ethereum_address(),
    )

pair = generate_pair(exchange, symbol0="ATOM", symbol1="OSMO", internal_id=pair_id)

Create our candles#

Bullish data#

For the purposes of this notebook, we have created bullish data, this was achieved by slightly skewing the daily_drift argument to the right of 1. Notice how it is 2% above 1 but 1.95% below 1.

Bearish data#

Try skewing to the left for bearish data. I.e:

daily_drift = (0.98, 1.0195)

Ranging#

No skew for sideways data! I.e.:

daily_drift = (0.98, 1.02)

Volatility#

Experiment with the high_drift and low_drift parameters to adjust the volatility

[3]:
# Create our candles
from tradeexecutor.testing.synthetic_price_data import generate_ohlcv_candles
from tradingstrategy.charting.candle_chart import visualise_ohlcv
import pandas as pd

candles = generate_ohlcv_candles(
    start=start_at_data,
    end=end_at,
    bucket=candle_time_bucket,
    pair_id = pair.internal_id,
    exchange_id=exchange.exchange_id,
    daily_drift=(0.9805, 1.02),  # bullish
    # daily_drift = (0.98, 1.0195),  # bearish
    # daily_drift = (0.98, 1.02),  # sideways
    high_drift=1.01,
    low_drift=0.99,
)

visualise_ohlcv(candles, chart_name="Bullish synthetic data for ATOM/OSMO", y_axis_name="Price (USD)")