我的基金投资策略=主动基金+趋势跟踪+量化交易+机械执行

Tags
Star
理财

缘起

最近看ETF之家这个公众号的文章,觉得号主的投资思路很值得借鉴:形成一套属于自己的理财策略,制定一系列规则,用规则去指导行动,并严格遵守,而不是跟随自己的主观情绪去跟风炒作。
回想了自己过去的理财之路,确实有很多次跟风追涨的非理性操作,结果最后反被割了韭菜。 为了防止以后再度出现类似的举动,于是认真思考了自己的理财策略,写了这篇文章。也许以后自己的理财策略还会有更新,到时候再出v2.0,v3.0…
理财,本来不是一蹴而就,而是需要我们不断学习不断成长的。
我的这个基金投资策略,是选择优质LOF基金的趋势交易策略,我在聚宽量化交易平台上,根据过往的历史数据进行了回测,回测7年,年化收益率25%,最大回撤17%。

一.选基思路

精选的优质LOF为:
  • 消费类:
    • 兴全模式 163415 乔迁(从业3年,年化27%)
    • 景顺鼎益 162605 刘彦春(从业10年,年化22%)
  • 科技类:
    • 广发小盘 162703
    • 万家优选 161903 黄兴亮(从业6年,年化27%)
    • 深证100:富国天惠 161005 朱少醒(从业14年,年化22%)
选基思路就是:
  • 尽量新老搭配,各个从业年限的基金经理都有
  • 尽量覆盖行业和板块广一点,景顺偏消费,万家偏科技,一个防守一个进攻,兴全精选个股,富国精选行业,尽量分散风险
notion image
目前还不支持场外基金,后续准备支持一下场外基金,让投资标的的选择面更广一点。

二.交易原则

1.买卖规则
  • 每个LOF的20日涨幅超过5%,就买入2.5成仓
  • 每个LOF的20日涨幅低于-5%,就卖出2.5成仓
2.止损规则
  • 单笔交易的浮动盈亏率超过-20%,无条件止损

三.回测分析

收益趋势图

使用历史数据测试一个策略的可行性的时候,可以用ETF组合宝做初步测试,因为它可以可视化的设置买卖条件,不用写代码,非常方便。当初步测试的效果还不错的时候,再在聚宽平台写python代码,来做进一步的精细化测试,主要就是完善风险控制条件和交易费用处理。 这是从2014-01-01到2020-08-25的6.5年历史数据的回测分析,
notion image

风险说明图

notion image

年度收益率对比

本策略回测时的年度收益率分别为:年化30%,最大回撤19% 2014年:7.45% 【跑输沪深300】 2015年:104.99% 2016年:-4.39% 2017年:12.47% 【跑输沪深300】 2018年:-11.28% 2019年:38.77% 2020年:42.01% 对比沪深300ETF: 年化13% 最大回撤-45% 2014年:54.09% 2015年:7.09% 2016年:-9.61% 2017年:23.14% 2018年:-23.92% 2019年:38.01% 2020年:17.91% 通过回测的年度收益率可以知道,其实策略也没有每一年都能跑赢沪深300,但是,它经常能在牛市时赚得更多,在熊市时亏得更少。而沪深300,虽然15年来了一波大行情,但是守不住,最后又跌回原形了。

四.模拟盘跟踪

这是在聚宽平台上,从2020-08-27到2021-12-01的模拟盘收益曲线,期间有调整交易策略和交易标的,所以和回测分析会有一定误差。
notion image

五.实盘提示

鉴于好策略还得好执行才能落地,而聚宽的自动化交易的券商佣金比较高,而我的策略又比较简单,我这里只是用聚宽做回测,实际交易是利用华宝证券的条件单。 每个交易日的早上9点左右,检查关注的基金,20日涨幅超过5%的就买,低于-5%的就卖 具体买卖使用华宝的时间条件单,设置为9:30开盘时直接按市价买卖即可 交易时段内,不要看盘,不要看盘,不要看盘,省得忍不住想要秀一下操作,结果破坏了计划 其实在回测中,这个策略的年度调仓次数也才16次左右,我们绝大多数日期内,都只用早上一分钟的时间看一下20日涨幅就可以了,不必做任何操作,很方便上班族。

六.总结

虽然上面都是好基金,但是如果只是一味地死守不动,不知道止损和止盈的话,其实风险也很大的,毕竟它们的历史最大回撤也都是差不多50%左右的。我回测了一下,如果最开始每个基金买入2.5成仓位,买入后一直持有不动,年化收益率差不多是24%,但是它的最大回撤太大了,高达42%,我想很难有人能在如此高的回撤时,依然坚持持有的,太考验人性了。
好标的也需要有好的买卖点,才能稳定盈利。我的策略呢,就是加入了择时,通过择时机制来决定买卖点,以及止盈止损,以及仓位管理。这个策略的收益率曲线会平滑一点,适合随时加入新资金,毕竟每个月的工资闲着也是闲着,还不如进来买基金。而如果不考虑择时,有空闲资金了就进场,说不定就恰好买在最高点了。
我的基本择时思路就是:根据20日涨幅判断,大涨之前,20日涨幅必然会突破5%,大跌之前,20日涨幅也必然会突破-5%。
不求买在最低点,卖在最高点,只要我们在相对低点买入,相对高点卖出,就足以盈利,这也是趋势交易的精髓。
当然了,这些突破里面必然会有假突破,会导致亏损,但是亏损时少亏点,盈利时多赚点,总体而已,就依然是盈利的,本策略的胜率大概是0.46,盈利交易的平均收益率为4.88%,亏损交易的平均收益率为-1.20%,年度交易频次大约是16次。
其实做趋势交易有点像钓鱼,一定要有耐心,也许我们会有很多次的无效拉杆,但是只要我们能守住,最终总能钓到鱼的。
从15年开始接触基金,最开始只知道看支付宝上推荐的基金买,追涨杀跌,但往往慢人一步,最后一算下来,其实没赚到什么钱,手续费倒是交了不少。
后来了解到基金定投,开始定投沪深300+中证500,但是定投时间久了以后,发现基金定投虽然简单,但其实挺坑的,本质还是属于左侧交易策略,一种变相的抄底而已,而且它的止盈策略不好定,卖点不好把握,如果用了几年的时间,最后只赚10%就离场,我觉得不太划算。而如果真的来一个长期的下降趋势,估计这个定投的过程会比较煎熬,而且长期的资金利用率并不高,稳健理财可以基金定投,但如果想年化收益率高一点,实现财富相对自由,还是趋势交易更有机会一点。
关于趋势交易,看过一些书,《趋势交易:股市稳定盈利之道》给自己很大的启发,感觉比较符合自己的调性,现在基本都是做趋势交易了。后来接触到聚宽平台,以前只能凭自己的感觉制定一些买卖规则,现在可以利用聚宽的数据验证下自己的规则,虽然实际交易上可能没啥差别,但是经过了回测考验的策略,自己心里总是觉得有点谱,不像以前那样没底。
总而言之,我的投资体系就是:主动基金+趋势跟踪+量化交易+机械执行

七.相关工具

  1. 【乌龟量化】股票、指数、行业和基金的基本面数据_乌龟量化
  1. 华宝智投 – 集股票开户、行情资讯、自动交易于一身的智能炒股软件
  1. 同花顺财经__让投资变得更简单
  1. ETF之家 - 指数基金投资者关心的话题都在这里 - ETF基金|基金定投|净值排名|入门指南

八.策略源码

# 导入函数库  
from jqdata import *  
import copy  
def initialize(context):  
    # 设定沪深300作为基准  
    set_benchmark('000300.XSHG')  
    # 开启动态复权模式(真实价格)  
    set_option('use_real_price', True)  
    # 输出内容到日志 log.info()  
    log.info('初始函数开始运行且全局只运行一次')  
    # 过滤掉order系列API产生的比error级别低的log  
    log.set_level('order', 'error')  
    # 设置手续费是:买入时佣金万分之一,卖出时佣金万分之一,无印花税, 每笔交易佣金最低扣0块钱  
    set_order_cost(OrderCost( open_commission=0.0002, close_commission=0.0002,close_tax=0, min_commission=0), type='fund')  
    # 设置滑点  
    set_slippage(FixedSlippage(0.01))  
    # 开盘时运行  
    run_daily(market_open, time='open')  
def market_open(context):  
    check_LOF(context)  
    check_stop(context)  
def check_LOF(context):  
    # 兴全模式 163415  
    # 景顺鼎益 162605  
    # 广发小盘 162703  
    # 万家优选 161903  
    g.funds=['163415.XSHE','162605.XSHE','162703.XSHE','161903.XSHE']   
    target_value=context.portfolio.total_value/len(g.funds)  
    for fund in g.funds:  
        rate20=get_rate20(fund)  
        # 若20日涨幅高于5%, 则买入  
        if rate20 >= 0.05 and fund not in context.portfolio.positions:  
            # 买入LOF基金    
            order_target_value(fund, target_value)  
        # 若20日涨幅低于-5%, 则卖出  
        elif rate20 <= -0.05 and fund in context.portfolio.positions:  
            order_target_value(fund, 0)  
def check_stop(context):  
    for position in list(context.portfolio.positions.values()):  
        fund=position.security  
        value=round(position.value,0)  
        price=position.price  
        avg_cost=position.avg_cost  
        rate=round(price/avg_cost-1,2)  
        rate20=get_rate20(position.security)  
        if rate <=-0.20:  
           # 卖出基金  
            order_target_value(position.security, 0)  
            log.info("触发止损信号: 标的={0},标的价值={1},20日涨幅={2},浮动盈亏={3} ".format(position.security,round(position.value,0),rate20,rate))  
def get_rate20(fund):  
    close_data = get_bars(fund, count=21, unit='1d', fields=['date','close'])  
    close_before_

© fishyer 2022