admin管理员组文章数量:1436820
使用.NET搭建基于掘金平台的量化交易框架
合规说明:本文章仅供学习交流使用,文中涉及到的投资策略、操作方式、提及的个股等等,均是技术性演示使用,仅供技术性学习参考,不构成投资建议,请大家遵守!
前言:之前写过一部分量化开发文章,不过都是自个儿操作,或者借助QMT交易来操作。QMT量化交易只能使用Python开发,虽然可以利用C# 进行开发策略,然后通过python开发的miniqmt框架进行通信对接来间接交易,但是整体上还是感觉有点怪怪的,有种慢半拍的即视感。所以现在打算写一篇入门版本的,基于掘金平台,完全使用C# 进行开发的小例子。只做基础框架开发,供参考。
首先你需要自己注册掘金量化平台的账号。注册地址:
/
如果你是只做策略研究使用,就可以使用免费的基础版本
如果你需要通过程序化进行交易,你需要先和你的券商客户经理了解,有没有和掘金量化平台合作,有合作的话,自行申请量化交易权限以后,再找掘金平台提供指定券商的股票版本进行使用,不然是没办法盘中程序化交易的。按照目前市场标准情况,QMT门槛是2万到500W不等;量化交易权限是5W到500W不等,根据你的券商情况而定(咨询你自己的客户经理)。
接下来,我做个从头搭建一个量化框架的入门教程,供参考。先创建一个asp core webapi项目
SDK版本我本地直接使用 8
掘金平台客户端上面,找到 我的策略->新建策略,使用C# 创建一个空策略
创建完成,会生成一个策略ID,可以保存下来备用,后面做数据回测时候需要用到。
接着,还需要一个你的账户token,用于授权使用。右上角 系统设置内,找到密钥管理,这个密钥也需要用到,可以一起拿着备用。
在前面创建的项目上,可以添加一个策略文件夹,文件夹用于存储你自己的策略集合。例如第一个策略,也放这里面来。
安装掘金SDK,我使用的64位,大家可以根据自己的系统来定。
在新建的策略类里面,继承Strategy,并且补全构造函数,以及重写OnInit函数,这个步骤是必须的。然后就可以在OnInit里面进行策略的开发,可以做数据订阅、定时器等等。以下我就按照最简单的,做一个策略,每天下午14点55分执行一次判断,需要订阅数据推送,订阅的数据,需要在重写的OnTick函数里面接收,然后在尾盘55分时候执行判断是不是符合规则。如下图所示。
接下来写一个简单的小策略,例如,10日线上穿20日线买入,下穿20日线卖出
做策略回测,需要写一个对应的回测类,回测里面就需要你的策略ID和用户Token了,这样就可以根据测试结果,推送到你的掘金客户端上面展示
然后执行回测类的测试函数,在策略研究里面,就可以看到策略执行进度
客户端的绩效分析里面,可以看到一些回测具体信息,以及你的历史BS点,这样就可以轻松看出你和指数的比较,以及你的策略是不是符合你的预期收益了。
继续换一个简单策略,例如股价第一次站上20日线买入,跌破卖出
策略不一样,同一个个股来说,一般执行的回测收益也会有差异
以上只是演示量化回测的例子,并不具有投资建议属性,千万不要无脑直接拿去用。
上面测试的源码如下:
代码语言:javascript代码运行次数:0运行复制namespace WeskyQuant.Strategies
{
/// <summary>
/// 第一个策略
/// </summary>
public class MyFirstStrategy : Strategy
{
public MyFirstStrategy(string token, string strategyId, StrategyMode mode) : base(token, strategyId, mode) { }
/// <summary>
/// 重写OnInit事件,进行策略开发
/// </summary>
public override void OnInit()
{
Console.WriteLine("策略开始初始化");
Subscribe("SZSE.000001", "tick");
return;
}
DateTime currentDate; // 当前时间
/// <summary>
/// 接收掘金推送的数据
/// </summary>
/// <param name="tick"></param>
public override void OnTick(Tick tick)
{
if (tick.createdAt.Hour < 14)
{
return; // 14点之前,不操作
}
if (tick.createdAt.Hour == 14 && tick.createdAt.Minute < 55)
{
return; // 14点55分之前,不操作
}
if (currentDate == tick.createdAt.Date)
{
return; // 今天已经处理过了,防止重复处理
}
currentDate = tick.createdAt.Date;
GMDataList<Bar> historyBar = GMApi.HistoryBars(tick.symbol, "1d", tick.createdAt.AddDays(-15).ToString("yyyy-MM-dd HH:mm:ss"), tick.createdAt.ToString("yyyy-MM-dd HH:mm:ss"), Adjust.ADJUST_PREV);
if (historyBar == null)
{
Console.WriteLine("获取历史数据失败");
return;
}
var ma10 = historyBar.data.TakeLast(10).Average(x => x.close);
var ma10_ref1 = historyBar.data.TakeLast(11).SkipLast(1).Average(x => x.close);
var ma20 = historyBar.data.TakeLast(20).Average(x => x.close);
var ma20_ref1 = historyBar.data.TakeLast(21).SkipLast(1).Average(x => x.close);
var close = historyBar.data.Last().close;
var close_ref1 = historyBar.data.SkipLast(1).Last().close;
if (close > ma20 && close_ref1<=ma20_ref1)
{
GMData<Order> o = OrderValue("SZSE.300127", 100000, OrderSide.OrderSide_Buy, OrderType.OrderType_Market, PositionEffect.PositionEffect_Open, 0);
if (o.status == 0)
{
Console.WriteLine($"{tick.createdAt}:委托买入成功");
}
else
{
Console.WriteLine("委托买入失败");
}
}
else if (close < ma20 && close_ref1 >= ma20_ref1)
{
GMData<Order> o = OrderValue("SZSE.300127", 100000, OrderSide.OrderSide_Sell, OrderType.OrderType_Market, PositionEffect.PositionEffect_Close, 0);
if (o.status == 0)
{
Console.WriteLine($"{tick.createdAt}:委托卖出成功");
}
else
{
Console.WriteLine("委托卖出失败");
}
}
//if (ma10 > ma20)
//{
// if (ma10_ref1 <= ma20_ref1)
// {
// // 10日上穿20日
// GMData<Order> o = OrderValue("SZSE.300127", 100000, OrderSide.OrderSide_Buy, OrderType.OrderType_Market, PositionEffect.PositionEffect_Open, 0);
// if (o.status == 0)
// {
// Console.WriteLine($"{tick.createdAt}:委托买入成功");
// }
// else
// {
// Console.WriteLine("委托买入失败");
// }
// }
//}
//else if (ma10 < ma20)
//{
// if (ma10_ref1 >= ma20_ref1)
// {
// // 下穿
// GMData<Order> o = OrderValue("SZSE.300127", 100000, OrderSide.OrderSide_Sell, OrderType.OrderType_Market, PositionEffect.PositionEffect_Close, 0);
// if (o.status == 0)
// {
// Console.WriteLine($"{tick.createdAt}:委托卖出成功");
// }
// else
// {
// Console.WriteLine("委托卖出失败");
// }
// }
//}
}
/// <summary>
/// 第一个策略的回测函数
/// </summary>
public class MyFirstStrategyBackTest
{
public void Test()
{
//回测一年
var startTime = DateTime.Now.AddDays(-365).ToString("yyyy-MM-dd 8:20:00");
var endTime = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd 17:30:00");
MyFirstStrategy s = new MyFirstStrategy("你的token", "你的策略ID,每次新建策略,都会有一个唯一ID,你的回测数据会在策略ID对应的策略下面查看到", StrategyMode.MODE_BACKTEST);
s.SetBacktestConfig(startTime, endTime);
int nRet = s.Run();
if (nRet != 0)
{
System.Console.WriteLine("回测失败, 错误码: {0}", nRet);
}
else
{
System.Console.WriteLine("回测完成!");
}
}
}
}
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-05-02,如有侵权请联系 cloudcommunity@tencent 删除量化数据函数开发框架本文标签: 使用NET搭建基于掘金平台的量化交易框架
版权声明:本文标题:使用.NET搭建基于掘金平台的量化交易框架 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1747402096a2694180.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论