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

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

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),

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)


No skew for sideways data! I.e.:

daily_drift = (0.98, 1.02)


Experiment with the high_drift and low_drift parameters to adjust the volatility

# 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(
    pair_id = pair.internal_id,
    daily_drift=(0.9805, 1.02),  # bullish
    # daily_drift = (0.98, 1.0195),  # bearish
    # daily_drift = (0.98, 1.02),  # sideways

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