Files
strategy-lab/research/robustness/eval_robustness.ipynb
David Brazda 4bc85be3ea update
2024-10-04 12:18:09 +02:00

9.2 KiB

Robustness evaluation

Input is backtest results in the format:

  • Parameter combination (multiindex)
  • Profitability metrics (columns)

Lets explore various way to evaluate robustness.

In [5]:
#!pip install git+https://github.com/drew2323/lightweight-charts-python.git
#!pip install git+https://gitea.stratlab.dev/Stratlab/db.git
from lightweight_charts import Panel, chart, PlotSRAccessor, PlotDFAccessor
import pandas as pd
import numpy as np
import vectorbtpro as vbt
# from itables import init_notebook_mode, show
import datetime
from itertools import product
from IPython.display import display
# init_notebook_mode(all_interactive=True)

vbt.settings.set_theme("dark")
vbt.settings['plotting']['layout']['width'] = 1280
vbt.settings.plotting.auto_rangebreaks = True
# Set the option to display with pagination
pd.set_option('display.notebook_repr_html', True)
pd.set_option('display.max_rows', 10)  # Number of rows per page
In [ ]:
#fetching US-STOCKS ohlcv_1s
from lib.db import Connection
SYMBOL = "BAC"
SCHEMA = "ohlcv_1s" #time based 1s other options ohlcv_vol_200 (volume based ohlcv with resolution of 200), ohlcv_renko_20 (renko with 20 bricks size) ...
DB = "market_data"

con = Connection(db_name=DB, default_schema=SCHEMA, create_db=True)
basic_data = con.pull(symbols=[SYMBOL], schema=SCHEMA,start="2024-08-01", end="2024-08-05", tz_convert='America/New_York')

basic_data.data[SYMBOL].info()

#1month 1s data - 15s - 24MB
In [ ]:
#basic_data.ohlcv.data[SYMBOL].lw.plot()
basic_data.data[SYMBOL].lw.plot(size="s")
In [ ]:
basic_data.data[SYMBOL].vwap.lw.plot()
In [ ]:
basic_data.data[SYMBOL].vwap.lw.plot(histogram=(basic_data.data[SYMBOL].trades, "trades"))

 #xloc["2024-08-05":"2024-08-10"]
In [ ]:
# Define the market open and close times
market_open = datetime.time(9, 30)
market_close = datetime.time(16, 0)
entry_window_opens = 1
entry_window_closes = 370
forced_exit_start = 380
forced_exit_end = 390

#NUMDAYS
basic_data.wrapper.index.normalize().nunique()

Add resample function to custom columns

In [8]:
from vectorbtpro.utils.config import merge_dicts, Config, HybridConfig
from vectorbtpro import _typing as tp
from vectorbtpro.generic import nb as generic_nb

_feature_config: tp.ClassVar[Config] = HybridConfig(
    {
        "buyvolume": dict(
            resample_func=lambda self, obj, resampler: obj.vbt.resample_apply(
                resampler,
                generic_nb.sum_reduce_nb,
            )
        ),
        "sellvolume": dict(
            resample_func=lambda self, obj, resampler: obj.vbt.resample_apply(
                resampler,
                generic_nb.sum_reduce_nb,
            )
        ),
        "trades": dict(
            resample_func=lambda self, obj, resampler: obj.vbt.resample_apply(
                resampler,
                generic_nb.sum_reduce_nb,
            )
        )
    }
)

basic_data._feature_config = _feature_config
In [ ]:
s1data = basic_data[['open', 'high', 'low', 'close', 'volume','vwap','buyvolume','trades','sellvolume']]

# s5data = s1data.resample("12s")
# s5data = s5data.transform(lambda df: df.between_time('09:30', '16:00').dropna())

t1data = basic_data[['open', 'high', 'low', 'close', 'volume','vwap','buyvolume','trades','sellvolume']].resample("1T")
t1data = t1data.transform(lambda df: df.between_time('09:30', '16:00').dropna())
# t1data.data["BAC"].info()

# t30data  = basic_data[['open', 'high', 'low', 'close', 'volume','vwap','buyvolume','trades','sellvolume']].resample("30T")
# t30data = t30data.transform(lambda df: df.between_time('09:30', '16:00').dropna())
# # t30data.data["BAC"].info()

s1close = s1data.close
t1close = t1data.close

t1data.data["BAC"].close.lw.plot()
In [ ]:
from lightweight_charts import JupyterChart, chart, Panel, PlotAccessor
s5data.close.lw.plot()

# pane1 = Panel(
# ohlcv=(s5data.ohlcv.get(),))

# # Create the chart with the panel
# ch = chart([pane1], title="Chart", sync=True, session=None, size="s")
In [ ]:
s1data.data["BAC"].head()
In [7]:
#resample on specific index 
resampler = vbt.Resampler(t30data.index, s1data.index, source_freq="30T", target_freq="1s")
t30close_realigned = t30close.vbt.realign_closing(resampler)

#resample 1min to s
resampler_s = vbt.Resampler(t1data.index, s1data.index, source_freq="1T", target_freq="1s")
t1close_realigned = t1close.vbt.realign_closing(resampler_s)
In [ ]:
vbt.IF.list_indicators("*vwap")
vbt.phelp(vbt.VWAP.run)

VWAP

In [9]:
t1vwap_h = vbt.VWAP.run(t1data.high, t1data.low, t1data.close, t1data.volume, anchor="H")
t1vwap_d = vbt.VWAP.run(t1data.high, t1data.low, t1data.close, t1data.volume, anchor="D")
t1vwap_t = vbt.VWAP.run(t1data.high, t1data.low, t1data.close, t1data.volume, anchor="T")

t1vwap_h_real = t1vwap_h.vwap.vbt.realign_closing(resampler_s)
t1vwap_d_real = t1vwap_d.vwap.vbt.realign_closing(resampler_s)
t1vwap_t_real = t1vwap_t.vwap.vbt.realign_closing(resampler_s)

#t1vwap_5t.xloc["2024-01-3 09:30:00":"2024-01-03 16:00:00"].plot()
In [ ]:
#m30data.close.lw.plot()
#quick few liner
pane1 = Panel(
    histogram=[
               #(s1data.volume, "volume",None, 0.8),
               #(m30volume, "m30volume",None, 1)
               ], # [(series, name, "rgba(53, 94, 59, 0.6)", opacity)]
    right=[
          (s1data.close, "1s close"),
            (t1data.close, "1min close"),
            (t1vwap_t, "1mvwap_t"),
            (t1vwap_h, "1mvwap_h"),
            (t1vwap_d, "1mvwap_d"),
            (t1vwap_t_real, "1mvwap_t_real"),
            (t1vwap_h_real, "1mvwap_h_real"),
            (t1vwap_d_real, "1mvwap_d_real")
        #    (t1close_realigned, "1min close realigned"),
        #    (m30data.close, "30min-close"),
        #    (m30close_realigned, "30min close realigned"),
           ],
)
ch = chart([pane1], size="s" ) #xloc=slice("2024-05-1 09:30:00","2024-05-25 16:00:00"))