C#/.NET量化开发实现财富自由【6】回归测试——寻找属于你的财富策略的必经之路...

本篇以一个入门级策略,MACD在0轴金叉买入、MACD死叉卖出,来演示生成一个简单的历史回测数据和走势图。

有关具体的历史数据获取、MACD计算等,可以参考公众号上【Dotnet Dancer】发表的之前的文章。

公众号快捷关注二维码:

839ba7d430745ec02934da3e66b2dc1e.jpeg

以下正文:

创建一个回测测试api接口,传入大A编码和起始资金

0eb3346f1cbcb4eb9a032670acff9777.png

创建一个回测结果实体类,用于存储回测交易历史数据使用

/// <summary>
 /// 回测结果
 /// </summary>
 public class BackTestInfo
 {
     /// <summary>
     /// 日期
     /// </summary>
    public DateTime DateTime { get; set; }


     /// <summary>
     /// 整体收益率
     /// </summary>
     public double RateOfReturn {  get; set; }


     /// <summary>
     /// 持股数量
     /// </summary>
     public double Count { get; set; }


     /// <summary>
     /// 买入/卖出价格
     /// </summary>
     public double Price {  get; set; }


     /// <summary>
     /// 记录上次买入价格,用于卖出计算收益
     /// </summary>
     public double OldPrice { get; set; }


     /// <summary>
     /// 实时资金
     /// </summary>
     public double Money {  get; set; }


     /// <summary>
     /// 起始资金
     /// </summary>
     public double SourceMoney { get; set; }


     /// <summary>
     /// 买入/卖出   true 买入
     /// </summary>
     public bool IsBuy {  get; set; }


     public BackTestInfo() { }
     public BackTestInfo(BackTestInfo info) {
         Count = info.Count;
         OldPrice = info.Price;
         Money = info.Money;
         SourceMoney = info.SourceMoney;
         IsBuy = info.IsBuy;
     }
 }

根据以前的文章,计算出每一天都DIF和MACD,并赋值。然后计算在0轴金叉的个股(一般情况下,前一天DIF小于0,当天DIF大于0,并且当天MACD>0,前一天MACD<0,则为0轴金叉)

买入卖出模拟测试代码如下

if (testHistory[i - 1].MACD < 0 && testHistory[i].MACD >= 0 && testHistory[i - 1].DIF<0 && testHistory[i].DIF>=0) // 例如0轴金叉
  {
      // 买入
      if (backTestInfos.Any())
      {
          var newBackInfo = new BackTestInfo(backTestInfos.Last());
          newBackInfo.DateTime = testHistory[i].Date;
          newBackInfo.Price = testHistory[i].Close.Value;
          if (newBackInfo.IsBuy)
          {
              // 已经是持仓,跳过
              continue;
          }
          else
          {
              newBackInfo.IsBuy = true;
          }
          // 计算能买多少股,去掉小数点部分
          int buyCount = (int)((newBackInfo.Money / newBackInfo.Price));


          // 梭哈买入
          newBackInfo.Count = buyCount;
          // 扣除佣金,例如万分之一
          newBackInfo.Money = newBackInfo.Money - (buyCount * newBackInfo.Price * 0.0001);


          // 实时收益率
          newBackInfo.RateOfReturn = (newBackInfo.Money - newBackInfo.SourceMoney) / newBackInfo.SourceMoney * 100;




          backTestInfos.Add(newBackInfo);
      }
      else
      {
          // 第一个数据
          var newBackInfo = new BackTestInfo();
          newBackInfo.DateTime = testHistory[i].Date;
          newBackInfo.Price = testHistory[i].Close.Value;
          newBackInfo.IsBuy = true;


          newBackInfo.Money = money;
          newBackInfo.SourceMoney = money;
          // 计算能买多少股,去掉小数点部分
          int buyCount = (int)((newBackInfo.Money / newBackInfo.Price));


          // 梭哈买入
          newBackInfo.Count = buyCount;
          // 扣除佣金,例如万分之一
          newBackInfo.Money = newBackInfo.Money - (buyCount * newBackInfo.Price * 0.0001);


          // 实时收益率
          newBackInfo.RateOfReturn = (newBackInfo.Money - newBackInfo.SourceMoney) / newBackInfo.SourceMoney * 100;


          backTestInfos.Add(newBackInfo);


      }
  }
  else if (testHistory[i].MACD <= 0 || testHistory[i].DIF<0) // DIF或MACD死叉卖出
  {
      // 卖出
      if (backTestInfos.Any())
      {
          var newBackInfo = new BackTestInfo(backTestInfos.Last());
          newBackInfo.DateTime = testHistory[i].Date;
          newBackInfo.Price = testHistory[i].Close.Value;
          if (!newBackInfo.IsBuy)
          {
              // 没有持仓,跳过
              continue;
          }
          else
          {
              newBackInfo.IsBuy = false;
          }


          // 计算清仓卖出资金收益,数量*(卖出价 - 买入价)
          double saleMoney = newBackInfo.Count * newBackInfo.Price;
          double buyMoney = newBackInfo.Count * newBackInfo.OldPrice;


          newBackInfo.Money = newBackInfo.Money + (saleMoney - buyMoney - (saleMoney * 0.0001) -(saleMoney * 0.001)); // ETF不计算印花税,股票卖出计算印花税例如千分之一。计算收益后总资金量


          // 实时收益率
          newBackInfo.RateOfReturn = (newBackInfo.Money - newBackInfo.SourceMoney) / newBackInfo.SourceMoney * 100;


          backTestInfos.Add(newBackInfo);
      }
      else
      {
          // 第一个数据,没买入,就没有卖出,跳过
          continue;
      }
  }

把回测结果写入到表格,写入方式随意。我此处使用EPPlus来实现写入表格和实现回测走势图效果:

a14f54f0614703e3d1f8d9db2cb5908e.png

然后启动程序,执行操作。例如代码是300532,起始资金是100,000

566e774b302b604b90261bc14b413b9b.png

输出表格以后,打开可以看到数据,说明历史只有三次买点,以及最高收益达到接近40%

cbb9ab1af6661bd763b71650bc2d4122.png

咱们看一下第一次买点,2019年1月30日,以及卖点MACD死叉3月18号,对应K线符合要求,说明测试的买卖点策略没问题。

f84458b5741a6a05753171eccf9d2c4d.png

再换个个股试试,例如002156,刚好前几天在操作的一只。

298033a06b2f10d86ddd06aedcc16c4e.png

按照该策略回测结果如下,显示最近7-12号是一个新的买入点,但是还没死叉,所以还没统计到最新数据。至于后续会怎么样,就不知道了,毕竟只是基础策略演示使用。

114bc88f46bdef059d242afca3311e60.png

差不多这样,大佬们可以自己进行变种、或者开发自己的策略进行测试。【特别注意】以上仅提供回测开发案例使用,切不可盲目跟随或套用。

祝愿各位大佬量化愉快~早日实现小目标收益~

6ec41aa8f691a67d17ed511261d6ae7b.png

如果对.NET开发量化技巧有想法或者爱好,乐意分享自己的感悟和策略,也可以扫码进群:进群二维码7-28之前有效。

80f547011249e80fea9daaced5d52a8d.png

如果以上内容觉得有用或者有帮助,建议就不要转发了,可以默默关注。最近Quant打的比较严格,技术文章有被Ban的风险,所以且看且珍惜~~

最后,继续祝大佬们好运,早日实现小目标。如果已经实现小目标,那就更上一层楼~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值