立方体参数优化
构建参数搜索空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # Define hyper-parameter space # 49 fast x 49 slow x 19 signal fast_windows, slow_windows, signal_windows = vbt.utils.params.create_param_combs( (product, (combinations, np.arange(2, 51, 1), 2), np.arange(2, 21, 1)))
pd.DataFrame({"fast_windows":fast_windows, "slow_windows":slow_windows, "signal_windows":signal_windows}) Out[6]: fast_windows slow_windows signal_windows 0 2 3 2 1 2 3 3 2 2 3 4 3 2 3 5 4 2 3 6 ... ... ... ... 22339 49 50 16 22340 49 50 17 22341 49 50 18 22342 49 50 19 22343 49 50 20
|
计算指标和信号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| # Run MACD indicator macd_ind = vbt.MACD.run( price, fast_window=fast_windows, slow_window=slow_windows, signal_window=signal_windows )
# Long when MACD is above zero AND signal entries = macd_ind.macd_above(0) & macd_ind.macd_above(macd_ind.signal)
# Short when MACD is below zero OR signal exits = macd_ind.macd_below(0) | macd_ind.macd_below(macd_ind.signal)
exits Out[16]: macd_fast_window 2 ... 49 macd_slow_window 3 ... 50 macd_signal_window 2 3 ... 19 20 split_idx 0 1 2 0 ... 2 0 1 2 0 False False False False ... False False False False 1 False False False False ... False False False False 2 False False False False ... False False False False 3 True True True True ... False False False False 4 True False True True ... False False False False 5 True False True True ... False False False False 6 True True False True ... False False False False 7 False False False False ... False False False False 8 False True True False ... False False False False 9 True False True True ... False False False False
|
可见这里的信号为持续性信号,不同与常规的crossxx信号
组合收益评估
1 2 3
| # Build portfolio pf = vbt.Portfolio.from_signals( price.vbt.tile(len(fast_windows)), entries, exits, fees=0.001, freq='1D')
|
原始的1列price,经过range_split后变为3列,但是依然和entries列数不同,所以需要tile对齐列数据。
1 2 3 4 5 6
| price.shape Out[26]: (16, 3) len(fast_windows) Out[27]: 22344 entries.shape Out[28]: (16, 67032)
|
tile函数效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Out[21]:price.head() split_idx 0 1 2 0 0.374540 0.304242 0.065052 1 0.950714 0.524756 0.948886 2 0.731994 0.431945 0.965632 3 0.598658 0.291229 0.808397 4 0.156019 0.611853 0.304614
price.vbt.tile(2) Out[22]: split_idx 0 1 2 0 1 2 0 0.374540 0.304242 0.065052 0.374540 0.304242 0.065052 1 0.950714 0.524756 0.948886 0.950714 0.524756 0.948886 2 0.731994 0.431945 0.965632 0.731994 0.431945 0.965632 3 0.598658 0.291229 0.808397 0.598658 0.291229 0.808397 4 0.156019 0.611853 0.304614 0.156019 0.611853 0.304614 5 0.155995 0.139494 0.097672 0.155995 0.139494 0.097672
|
可视化
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # Draw all window combinations as a 3D volume fig = pf.total_return().vbt.volume( x_level='macd_fast_window', y_level='macd_slow_window', z_level='macd_signal_window', slider_level='split_idx', trace_kwargs=dict( colorbar=dict( title='Total return', tickformat='%' ) ) ) fig.show()
|
会导致电脑卡顿,效果上也没觉得多么直观。