本篇以一个入门级策略,MACD在0轴金叉买入、MACD死叉卖出,来演示生成一个简单的历史回测数据和走势图。
有关具体的历史数据获取、MACD计算等,可以参考公众号上【Dotnet Dancer】发表的之前的文章。
以下正文:
创建一个回测测试api接口,传入大A编码和起始资金
创建一个回测结果实体类,用于存储回测交易历史数据使用
代码语言:javascript复制 /// <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轴金叉)
买入卖出模拟测试代码如下
代码语言:javascript复制 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来实现写入表格和实现回测走势图效果:
然后启动程序,执行操作。例如代码是300532,起始资金是100,000
输出表格以后,打开可以看到数据,说明历史只有三次买点,以及最高收益达到接近40%
咱们看一下第一次买点,2019年1月30日,以及卖点MACD死叉3月18号,对应K线符合要求,说明测试的买卖点策略没问题。
再换个个股试试,例如002156,刚好前几天在操作的一只。
按照该策略回测结果如下,显示最近7-12号是一个新的买入点,但是还没死叉,所以还没统计到最新数据。至于后续会怎么样,就不知道了,毕竟只是基础策略演示使用。
差不多这样,大佬们可以自己进行变种、或者开发自己的策略进行测试。【特别注意】以上仅提供回测开发案例使用,切不可盲目跟随或套用。
祝愿各位大佬量化愉快~早日实现小目标收益~
最后,继续祝大佬们好运,早日实现小目标。如果已经实现小目标,那就更上一层楼~~