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:
ATOM/OSMO pair
Hourly OHCLV candles
Uses simple overfitted EMA strategy (not realistic profits)
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)")