想想做AI量化的初心,与当初学计算机的逻辑相似。
极少数,不需要依赖所谓大团队可以完成的事情。当然现在计算机个人能完成一个大作品的机会很少了,都是资本在主导。
量化还有。因为投资不是严格意义上的科学,这一点让做的人很痛苦,因为你有时候会发现它毫无规律,而恰恰是这一点,让普通人让有机会参与其中。否则规律早就被挖掘了。
昨天的文章:年化24.9%:基于动量、波动率、乖离率的多因子合成策略的指数轮动。(代码+数据下载)
今天继续优化,希望通过择时来改善最大回撤,尝试了几种方式,效果有限。
比如,当“20日动量小于0时”,则卖出,由于我们后续还有排序规则,所以,相当于我们是对选择的标的做了一层过滤,就是20日动量为负时不持仓。
收益变少了(长期年化18.2%),回撤并没有明显改善。
————这里我的分析逻辑如下:我们的综合分,已经考虑到动量因素,中短期动量,波动率,乖离率,若是我们再使用动量来过滤,那么可能把评分高的滤掉,被评分低的取而代之,因为并没有起来改善性能的效果。
这也是我为什么一直考虑轮动、机器排序模型的原因。量化择时太难,预测市场太难。你要问,不预测量化做什么呢?——按概率选择“相对更好”的。就是我们并不知道市场下一步怎么走,但我们会知道,A比B相对更好,长期这样选择,结果一定不会差。
from engine.datafeed.dataloader import Hdf5Dataloader from engine.env import Env from engine.algo import * from engine.config import DATA_H5 from engine.config import etfs_indexes loader = Hdf5Dataloader(etfs_indexes.values(), start_date="20100101") fields = ['roc(close,20)', 'std(volume,20)','bias(close,20)', 'roc(close,5)', 'std(volume,5)','bias(close,5)', 'rank(roc_20)+rank(bias_20)+rank(roc_5)+rank(bias_5)-rank(std_20)-rank(std_5)'] names = ['roc_20', 'std_20','bias_20', 'roc_5', 'std_5','bias_5', 'rank'] df = loader.load(fields=fields, names=names) e = Env(df=df, benchmarks=['000300.SH', '399006.SZ']) e.set_algos([ RunDays(days=10), RunWeekly(), SelectAll(), SelectBySignal(buy_rules=[], sell_rules=['ind(roc_20)<-0']), SelectTopK(drop_top_n=1, K=2, order_by='rank', b_ascending=False), #PickTime() WeightEqually() ]) e.backtest_loop() e.show_results() # e.save_results()
接下来,我们考虑一下大盘择时:
比如创业板的RSRS因子,年化20.7%,最大回撤26%。有明显的超额收益,而且有效控制了回撤,在2015年牛熊转换其间保住了大部分收益。
from engine.datafeed.dataloader import Hdf5Dataloader symbols = ['399006.SZ'] loader = Hdf5Dataloader(symbols, start_date="20120101") df = loader.load(fields=['slope_pair(high,low,18)', 'zscore(rsrs_18,600)'], names=['rsrs_18', 'zscore']) from engine.env import Env from engine.algo.algos import * from engine.algo.algo_weights import * bench_loader = Hdf5Dataloader(['399006.SZ'], start_date='20120101') e = Env(df, name='创业板RSRS择时', benchmarks=bench_loader.load()) e.set_algos([ #RunMonthly(), SelectBySignal(buy_rules=['ind(zscore)>0.7'], sell_rules=['ind(zscore)<-0.7']), WeightEqually() ]) e.backtest_loop() e.show_results(plot=True) # e.save_results()
指数多因子改进后:年化27.7%,夏普大于1。
from engine.datafeed.dataloader import Hdf5Dataloader from engine.env import Env from engine.algo import * from engine.config import DATA_H5 from engine.config import etfs_indexes loader = Hdf5Dataloader(etfs_indexes.values(), start_date="20100101") fields = ['roc(close,20)', 'std(volume,20)', 'bias(close,20)', 'roc(close,5)', 'std(volume,5)', 'bias(close,5)', 'rank(roc_20)+rank(bias_20)+rank(roc_5)+rank(bias_5)-rank(std_20)-rank(std_5)'] names = ['roc_20', 'std_20', 'bias_20', 'roc_5', 'std_5', 'bias_5', 'rank'] df = loader.load(fields=fields, names=names) bench_loader = Hdf5Dataloader(['399006.SZ', '000300.SH']) e = Env(df=df, benchmarks=bench_loader.load(fields=['slope_pair(high,low,18)', 'zscore(rsrs_18,600)<-0.7'], names=['rsrs_18', 'zscore'])) e.set_algos([ # RunDays(days=10), RunWeekly(), # SelectAll(), # SelectBySignal(buy_rules=[], sell_rules=['ind(roc_20)<-0']), SelectTopK(drop_top_n=1, K=1, order_by='rank', b_ascending=False), PickTime(benchmark='399006.SZ', signal='zscore'), PickTime(benchmark='000300.SH', signal='zscore'), WeightEqually() ]) e.backtest_loop() e.show_results() # e.save_results()
再做一些优化,考虑上实盘。
今天代码的重点,在昨天基础上,加上了大盘择时,当大盘的RSRS指数为-0.7时,清空仓位。风险、收益均得到了不小的提升。
代码已经发布。知识星球与开源项目:万物之中,希望至美
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/104068
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!