Help !
-
Hi!
I'm trying to use the optimizer on this strategy that I found in the official documentation, can anyone help me?
## modified startegy import xarray as xr import numpy as np import qnt.backtester as qnbt import qnt.data as qndata import qnt.ta as qnta import qnt.data as qndata import qnt.ta as qnta import qnt.output as qnout import qnt.stats as qns import qnt.log as qnlog import qnt.optimizer as qnop import qnt.backtester as qnbt import xarray as xr def load_data(period): futures= qndata.futures.load_data(tail=period, assets=["F_DX"]).isel(asset=0) crypto= qndata.cryptofutures.load_data(tail=period) return {"futures": futures, "crypto": crypto}, futures.time.values def window(data, max_date: np.datetime64, lookback_period: int): min_date= max_date - np.timedelta64(lookback_period, "D") return { "futures": data["futures"].sel(time=slice(min_date, max_date)), "crypto": data["crypto"].sel(time=slice(min_date, max_date)), } data = qndata.cryptofutures.load_data(min_date='2014-01-01') futures= qndata.futures.load_data(tail=365, assets=["F_DX"]).isel(asset=0) crypto= qndata.cryptofutures.load_data(tail=365) data = {"futures": futures, "crypto": crypto}, futures.time.values def strategy(data,param1=20,param2=20): close_futures= data["futures"].sel(field="close") close_crypto= data["crypto"].sel(field="close") sma20 = qnta.sma(close_futures, param1)#.isel(time=-1) sma20_crypto = qnta.sma(close_crypto, param2)#.isel(time=-1) return xr.where(sma20 < sma20_crypto, 1, -1) result = qnop.optimize_strategy( data, strategy, qnop.full_range_args_generator( param1=range(5, 1500, 5), # min, max, step param2=range(5, 1000, 5) # min, max, step ), workers=1 # you can set more workers on your PC ) qnop.build_plot(result) print("---") print("Best iteration:") display(result['best_iteration'])
-
Hello. Try this
import xarray as xr import numpy as np import qnt.backtester as qnbt import qnt.data as qndata import qnt.ta as qnta import qnt.data as qndata import qnt.ta as qnta import qnt.output as qnout import qnt.stats as qns import qnt.log as qnlog import qnt.optimizer as qnop import qnt.backtester as qnbt import xarray as xr def align_data_by_time(data, data_for_align): data_for_outer = xr.align(data.time, data_for_align, join='outer')[1] ff = data_for_outer.ffill(dim='time') r = ff.sel(time=data.time) return r min_date = '2014-01-01' cryptofutures = qndata.cryptofutures.load_data(min_date=min_date) futures = align_data_by_time( data=cryptofutures, data_for_align=qndata.futures.load_data(min_date=min_date, assets=["F_DX"])) data = {"futures": futures, "cryptofutures": cryptofutures} def strategy(data, param1=20, param2=20): close_futures = data["futures"].sel(field="close").drop('asset') close_crypto = data["cryptofutures"].sel(field="close") sma20 = qnta.sma(close_futures, param1) sma20_crypto = qnta.sma(close_crypto, param2) a = xr.where(sma20 < sma20_crypto, 1, -1) return a def stats_function(data, output): start_date = qns.get_default_is_start_date_for_type('cryptofutures') stat = qns.calc_stat(data['cryptofutures'], output.sel(time=slice(start_date, None))) return stat.isel(time=-1).to_pandas().to_dict() result = qnop.optimize_strategy( data, strategy, qnop.full_range_args_generator( param1=range(5, 150, 15), # min, max, step param2=range(5, 100, 15) # min, max, step ), workers=1, # you can set more workers on your PC stats_function=stats_function, ) qnop.build_plot(result) print("---") print("Best iteration:") print(result['best_iteration'])
-
After a lot of time I get this:
then I run the backtest with the parameters I've found....and I get a totally different result!
How's that?
first block to find params:
import xarray as xr import numpy as np import qnt.backtester as qnbt import qnt.data as qndata import qnt.ta as qnta import qnt.data as qndata import qnt.ta as qnta import qnt.output as qnout import qnt.stats as qns import qnt.log as qnlog import qnt.optimizer as qnop import qnt.backtester as qnbt import xarray as xr def align_data_by_time(data, data_for_align): data_for_outer = xr.align(data.time, data_for_align, join='outer')[1] ff = data_for_outer.ffill(dim='time') r = ff.sel(time=data.time) return r min_date = '2014-01-01' cryptofutures = qndata.cryptofutures.load_data(min_date=min_date) futures = align_data_by_time( data=cryptofutures, data_for_align=qndata.futures.load_data(min_date=min_date, assets=["F_DX"])) data = {"futures": futures, "cryptofutures": cryptofutures} def strategy(data, param1=20, param2=20): #5 param1 , 385 param 2 best fit close_futures = data["futures"].sel(field="close").drop('asset') close_crypto = data["cryptofutures"].sel(field="close") sma20 = qnta.sma(close_futures, param1) sma20_crypto = qnta.sma(close_crypto, param2) a = xr.where(sma20 < sma20_crypto, 1, -1) return a def stats_function(data, output): start_date = qns.get_default_is_start_date_for_type('cryptofutures') stat = qns.calc_stat(data['cryptofutures'], output.sel(time=slice(start_date, None))) return stat.isel(time=-1).to_pandas().to_dict() result = qnop.optimize_strategy( data, strategy, qnop.full_range_args_generator( param1=range(5, 1500, 10), # min, max, step param2=range(5, 1500, 10) # min, max, step ), workers=1, # you can set more workers on your PC stats_function=stats_function, ) qnop.build_plot(result) print("---") print("Best iteration:") print(result['best_iteration'])
then this cell:
import xarray as xr import numpy as np import qnt.backtester as qnbt import qnt.data as qndata import qnt.ta as qnta def load_data(period): futures= qndata.futures.load_data(tail=period, assets=["F_DX"]).isel(asset=0) crypto= qndata.cryptofutures.load_data(tail=period) return {"futures": futures, "crypto": crypto}, futures.time.values def window(data, max_date: np.datetime64, lookback_period: int): min_date= max_date - np.timedelta64(lookback_period, "D") return { "futures": data["futures"].sel(time=slice(min_date, max_date)), "crypto": data["crypto"].sel(time=slice(min_date, max_date)), } def strategy(data): close_futures= data["futures"].sel(field="close") close_crypto= data["crypto"].sel(field="close") sma20 = qnta.sma(close_futures, 400).isel(time=-1) sma20_crypto = qnta.sma(close_crypto, 400).isel(time=-1) return xr.where(sma20 < sma20_crypto, 1, -1) qnbt.backtest( competition_type= "cryptofutures", load_data= load_data, lookback_period= 365, start_date= "2014-01-01", strategy= strategy, window= window )
And I get a negative Sharpe!!! I tried with param1 5 and param2 385, too. Same bad results!
The optimizer says that for these values I should get Sharpe >1 !!! -
@magenta-grimer There are 2 things you might want to change:
1: the lookback_period is 365 but you want a 400-day SMA. This will only produce NaNs, so the boolean array sma20 < sma20_crypto will be False everywhere resulting in -1 weights. 2*365 as lookback does the trick for these settings.
2: Bitcoin is trading 24/7, futures aren't. Better use crypto.time.values instead of futures.time.values for the output of load_data.
There might be something else that I didn't catch but the resulting sharpe is at least close to what would be expected (1.109 with 5 and 385)