Files
strategy-lab/research/strat1/strat1_v1_SINGLE.ipynb

8.4 KiB

celkovy optimalizacni backtest na vetsim oknu 1 - 300 a možná take to udělat jako parametr zkusit CV zobrazit nejak robustnost parametru

In [ ]:
from v2realbot.tools.loadbatch import load_batch
from v2realbot.utils.utils import zoneNY
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 v2realbot.config import ACCOUNT1_PAPER_API_KEY, ACCOUNT1_PAPER_SECRET_KEY, DATA_DIR

init_notebook_mode(all_interactive=True)

vbt.settings.set_theme("dark")
vbt.settings['plotting']['layout']['width'] = 1280
vbt.settings.plotting.auto_rangebreaks = True
vbt.settings.returns.year_freq = "252 days" 
# 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

# 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

#LOAD FROM BATCH
# res, df = load_batch(batch_id="f1ac6651", #138170bc 0fb5043a  bde6d0be f1ac6651
#                      space_resolution_evenly=False,
#                      indicators_columns=["Rsi14"],
#                      main_session_only=True,
#                      verbose = False)
# if res < 0:
#     print("Error" + str(res) + str(df))
# df = df["bars"]

# basic_data = vbt.Data.from_data(vbt.symbol_dict({"BAC": df}), tz_convert=zoneNY)
# #m1_data = basic_data[['Open', 'High', 'Low', 'Close', 'Volume']]
# basic_data = basic_data.transform(lambda df: df.between_time('09:30', '16:00'))
# #basic_data.info()

#LOAD FROM PARQUET
#list all files is dir directory with parquet extension
dir = DATA_DIR + "/notebooks/"
import os
files = [f for f in os.listdir(dir) if f.endswith(".parquet")]
print('\n'.join(map(str, files)))
file_name = "ohlcv_df-SPY-2024-01-01T09:30:00-2024-05-14T16:00:00.parquet"
ohlcv_df = pd.read_parquet(dir+file_name,engine='pyarrow')
basic_data = vbt.Data.from_data(vbt.symbol_dict({"SPY": ohlcv_df}), tz_convert=zoneNY)
In [ ]:
# basic_data.stats()

basic_data.data["SPY"].info()
In [ ]:
vbt.open_api_ref(vbt.base)

vbt
In [ ]:
##na toto udelat crosssvalidationu nebo alespon na testovacim ci jinem obdobi
#take udelat long leg - tato je shortovaci

#8	-0.06	-0.2	0.0028	0.0048	4.156254

#short combination ok for train(4)/test(0.1) (window 1-90, fe 95-100)
#2,	-0.02,	-0.25,	0.0018,	0.0068

#dalsi ok hodnota shortu for train/test 4/1
#70,	8,	-0.06,	-0.2,	0.0013,	0.0053	


#kombinace bez roc_th, train/test 7/-1.5
#70	7	-0.07	0.0033	0.0063

#opet bez roc_th, train(5.77)/test 0.9 - spolus tsl_stop + tsl_th
#29	7	-0.09	0.0033	0.0068

#bez roc_th a s trailing sl train/test 8.1/-0.8 
#70	2	-0.05	0.0018	0.0068


#SPY - short
# entry_window_closes	mom_timeperiod	mom_th	sl_stop	tp_stop					
# 10	6	-0.13	0.0022	0.0057

#5	7	-0.19	0.0037	0.0042

#SPY - long
#45	4	0.27	0.0047	0.0067

# TODO:
#- vyzkouset zda nejvyhodnejsi kombinace krom train/testu funguje i na nasledujicich dnech po trainu
# -zkusit najit v short datasetu neco vyhodneho co funguji i na testu
# - dodelat kombinace pro long signaly
# - zkusit walk forward
# - vytvorit vysledkove totoznou na v2realbot
# - podivat se jak detailne funguji tsl_stop a tsl_th

#70,	4,	-0.07,	0.0048,	0.0068	


entry_window_closes, mom_timeperiod, mom_th, sl_stop, tp_stop = 8,	3,	0.07,	0.0028,	0.0033	
roc_th  = 0
momshort = vbt.indicator("talib:MOM").run(basic_data.close, timeperiod=mom_timeperiod, short_name = "slope_short")
rocp = vbt.indicator("talib:ROC").run(basic_data.close, short_name = "rocp")
#rate of change + momentum

#momshort.plot rocp.real_crossed_below(roc_th) & 
short_signal = momshort.real_crossed_below(mom_th)

long_signal = momshort.real_crossed_above(mom_th)

# print("short signal")
# print(short_signal.value_counts())

#forced_exit = pd.Series(False, index=close.index)
forced_exit = basic_data.symbol_wrapper.fill(False)
#entry_window_open = pd.Series(False, index=close.index)
entry_window_open=  basic_data.symbol_wrapper.fill(False)

# Calculate the time difference in minutes from market open for each timestamp
elapsed_min_from_open = (forced_exit.index.hour - market_open.hour) * 60 + (forced_exit.index.minute - market_open.minute)

entry_window_open[(elapsed_min_from_open >= entry_window_opens) & (elapsed_min_from_open < entry_window_closes)] = True

#print(entry_window_open.value_counts())

forced_exit[(elapsed_min_from_open >= forced_exit_start) & (elapsed_min_from_open < forced_exit_end)] = True
short_entries = (short_signal & entry_window_open)
short_exits = forced_exit

entries = (long_signal & entry_window_open)
exits = forced_exit
#long_entries.info()
#number of trues and falses in long_entries
# print(short_exits.value_counts())
# print(short_entries.value_counts())

#fig = plot_2y_close([],[momshort, rocp], close)
#short_signal.vbt.signals.plot_as_entries(close, fig=fig, add_trace_kwargs=dict(secondary_y=False))
#print(sl_stop)
#short_entries=short_entries, short_exits=short_exits,
pf = vbt.Portfolio.from_signals(close=basic_data, entries=entries, exits=exits, tsl_stop=sl_stop, tp_stop = tp_stop, fees=0.0167/100, freq="1s") #sl_stop=sl_stop, tp_stop = sl_stop,
In [ ]:
pf_B = pf.resample("30T")

pf_B.stats()
pf_B.orders.records_readable
In [ ]:
pf.plot()
In [ ]:
pf.get_drawdowns().records_readable
In [ ]:
pf.orders.records_readable
In [ ]:
pf.value.plot().show()
In [ ]: