期货CTP接口与程序化(量化交易)的对接(3)——序列变量的载体

Thea ·
更新时间:2024-09-21
· 500 次阅读

上一讲:期货CTP接口与程序化(量化交易)的对接(2)

序列变量的载体

上一讲举了一个简单的例子,现在继续用这个例子来讲解。
它使用的策略是:长阳达到X且在均线之上买进,长阴达到X且在均线之下买进。代码是:

public class Signal //信号结构体 { //定义信号数据,自己写 public Signal(string 下单方式) { //根据买开还是买平还是卖开还是卖平什么的,信号数据怎么变,自己写 } } public class Strg //策略管理器 { static List K线序列 = new List(); static List 均线序列 = new List(); //K线序列,有行情模块给它增加元素,这里不用管 //但均线序列需要在这里增加 static void 更新均线(int N) //这个函数是简化了的,它是假设每根K线只更新一次均线的算法 { //若要每个tick都更新均线,代码就比较多了,这里先不说 if (N <= 0) return; int K线根数 = K线序列.Count; if (K线根数 < N) return; if (K线根数 == N) { double sum = 0; for (int i = 0; i N) { double 上一根K线的均线值 = 均线序列.Last(); double 当前K线的均线值 = 上一根K线的均线值 + (K线序列.Last() - K线序列[K线根数 - 1 - N]) / (double)N; 均线序列.Add(当前K线的均线值); } } public static List 傻瓜策略(double X, int N, double 最高价, double 最低价, double 开盘价) { List signals = new List(); 更新均线(N); if (均线序列.Count <= 0) return signals; double 均线 = 均线序列.Last(); if (均线 = 开盘价 + X && 最高价 >= 均线) { signals.Add(new Signal("买平")); signals.Add(new Signal("买开")); } else if (最低价 <= 开盘价 - X && 最低价 <= 均线) { signals.Add(new Signal("卖平")); signals.Add(new Signal("卖开")); } return signals; } }

这里面用到了一个叫做“均线序列”的序列变量。上一讲讲过,使用序列变量是为了提高计算效率,序列变量的算法,是用上一根K线的数据推导当前K线的数据,而不需要把N根K线拿来统统算一遍。在程序化实际工作中,这是不得不采用的,否则你的实盘根本跑不动。计算速度加快了,代码却更多了,让程序员更烧脑了。
现在又一个新问题会让程序员更头疼。序列变量的转移。
如果所有的变量都留在上面的框里,都老老实实地待在这儿,那就简单了。但是,你的序列变量很有可能要跑到别的模块里去搞事情,比如均线这个变量,它至少要到画图模块里去指挥画线。
在实际工作中,序列变量还有很多:

所有的指标
所有的标记、线条、方框等
行情方向(可能需要分成大趋势、中趋势、小趋势)
行情峰谷的位置和价格
持仓信息
各种开仓的位置和成本
条件单
……

这些都要跑到不同的模块里去显示,或者指导交易,或者起别的作用,而且,它们是一起跑的,每当执行一次策略函数,这些变量都变了,就都要输出,它们是组团转移的。
更麻烦的是,当不同的合约使用同一策略时,每个合约都有这样的一套变量,这个合约的均线与那个合约的均线是不一样的,这样一来,你就更不能把均线记录在一个地方了。像上述代码那样,在与策略函数同级的位置定义均线序列,不好使了,试想,一个合约的均线记录在这儿,另一个合约的均线也记录在这儿,甚至同一个合约的不同周期的均线也记录在这儿,哪里还分得清。
所以需要这个东西:序列变量的载体。它主要有两个作用:
1.当序列变量需要组团转移时,这个载体给它们打包,简化操作。
2.每个交易方案(合约、周期、策略参数的每个组合),都有自己独特的载体,这样,甲方案的均线就不会与乙方案的均线混淆。
这个载体,是C#的一个结构体,举例如下:

public class StrgData //序列变量载体,每个交易方案都要有这样的一个东西来记录其特有的序列变量 { public List 均线序列 = new List(); public List signals = new List(); //还有很多其他序列变量 //这里不写出来了 }

策略的代码变成了:

public class StrgData //序列变量载体,每个交易方案都要有这样的一个东西来记录其特有的序列变量 { public List 均线序列 = new List(); public List signals = new List(); //还有很多其他序列变量 //这里不写出来了 } public class Signal //信号结构体 { //定义信号数据,自己写 public Signal(string 下单方式) { //根据买开还是买平还是卖开还是卖平什么的,信号数据怎么变,自己写 } } public class Strg //策略管理器 { public static List K线序列 = new List(); public static Dictionary strgDatas = new Dictionary(); //各交易方案的序列变量载体,键为交易方案名称,值为序列变量载体 //假如说有一个交易方案叫做“把傻瓜策略用在聚丙烯上”,那么它的序列变量载体就是strgDatas["把傻瓜策略用在聚丙烯上"] static void 更新均线(int N, ref StrgData strgData) //这个函数是简化了的,它是假设每根K线只更新一次均线的算法 { //若要每个tick都更新均线,代码就比较多了,这里先不说 if (N <= 0) return; int K线根数 = K线序列.Count; if (K线根数 < N) return; if (K线根数 == N) { double sum = 0; for (int i = 0; i N) { double 上一根K线的均线值 = strgData.均线序列.Last(); double 当前K线的均线值 = 上一根K线的均线值 + (K线序列.Last() - K线序列[K线根数 - 1 - N]) / (double)N; strgData.均线序列.Add(当前K线的均线值); } } public static void 傻瓜策略(double X, int N, ref StrgData strgData, double 最高价, double 最低价, double 开盘价) { 更新均线(N, ref strgData); if (strgData.均线序列.Count <= 0) return; double 均线 = strgData.均线序列.Last(); if (均线 = 开盘价 + X && 最高价 >= 均线) { strgData.signals.Add(new Signal("买平")); strgData.signals.Add(new Signal("买开")); } else if (最低价 <= 开盘价 - X && 最低价 <= 均线) { strgData.signals.Add(new Signal("卖平")); strgData.signals.Add(new Signal("卖开")); } } }
作者:grayhat2005



ctp 量化交易 程序 载体 变量

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章
Jenny 2021-05-16
709