CTP商品期货多品种海龟交易策略 (注释版)
- 只支持操作CTP商品期货
- 支持自动或手动恢复进度
- 可同时操作多个不同品种
- 增加时间段区分与各种网络错误问题的应对处理
- 移仓功能目前正在加入中
请下载最新托管者并比较版本号是否最新
$ ./robot -v
BotVS docker 3.0 compiled at 2016-07-05T09:56:18+0800
代码逐行翻译了一边,适合量化程序化初学者。
听说看注释前, 熟悉一下海龟交易法,效果会更好哦!
/*
参数:
Instruments 合约列表 字符串(string) MA701,CF701,zn1701,SR701,pp1701,l1701,hc1610,ni1701,i1701,v1701,rb1610,jm1701,ag1612,al1701,jd1701,cs1701,p1701
LoopInterval 轮询周期(秒) 数字型(number) 3
RiskRatio % Risk Per N ( 0 - 100) 数字型(number) 1
ATRLength ATR计算周期 数字型(number) 20
EnterPeriodA 系统一入市周期 数字型(number) 20
LeavePeriodA 系统一离市周期 数字型(number) 10
EnterPeriodB 系统二入市周期 数字型(number) 55
LeavePeriodB 系统二离市周期 数字型(number) 20
UseEnterFilter 使用入市过滤 布尔型(true/false) true
IncSpace 加仓间隔(N的倍数) 数字型(number) 0.5
StopLossRatio 止损系数(N的倍数) 数字型(number) 2
MaxLots 单品种加仓次数 数字型(number) 4
RMode 进度恢复模式 下拉框(selected) 自动|手动
VMStatus@RMode==1 手动恢复字符串 字符串(string) {}
WXPush 推送交易信息 布尔型(true/false) true
MaxTaskRetry 开仓最多重试次数 数字型(number) 5
KeepRatio 预留保证金比例 数字型(number) 10
*/
var _bot = $.NewPositionManager(); // 调用CTP商品期货交易类库 的导出函数 生成一个用于单个品种交易的对象
var TTManager = { // 海龟策略 控制器
New: function(needRestore, symbol, keepBalance, riskRatio, atrLen, enterPeriodA, leavePeriodA, enterPeriodB, leavePeriodB, useFilter,
multiplierN, multiplierS, maxLots) {
// 该控制器对象 TTManager 的属性 New 赋值一个 匿名函数(构造海龟的函数,即:构造函数),用于创建 海龟任务,参数分别是:
// needRestore: 是否需要恢复,symbol:合约代码,keepBalance:必要的预留的资金,riskRatio:风险系数, atrLen:ATR指标(参数)周期。enterPeriodA:入市周期A
// leavePeriodA:离市周期A , enterPeriodB:入市周期B, leavePeriodB:离市周期B,useFilter:使用过滤,multiplierN:加仓系数,multiplierS:止损系数,maxLots:最大加仓次数
// subscribe
var symbolDetail = _C(exchange.SetContractType, symbol);
// 声明一个局部变量 symbolDetail 用于接受API SetContractType 函数的返回值(值为symbol的合约的详细信息,symbol 是 "MA709",返回的就是甲醇709合约的详细信息),
// 调用API SetContractType 订阅并切换合约为 symbol 变量值的合约。 _C() 函数的作用是 对 SetContractType 合约容错处理,即如果 SetContractType返回null 会循环重试。
if (symbolDetail.VolumeMultiple == 0 || symbolDetail.MaxLimitOrderVolume == 0 || symbolDetail.MinLimitOrderVolume == 0 || symbolDetail.LongMarginRatio == 0 || symbolDetail.ShortMarginRatio == 0) {
// 如果 返回的合约信息对象symbolDetail 中 VolumeMultiple、MaxLimitOrderVolume 等数据异常,则调用 throw 抛出错误,终止程序。
Log(symbolDetail);
throw "合约信息异常";
} else { // 检索的数据没有异常则,输出部分合约信息。
Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate);
}
var ACT_IDLE = 0; // 定义一些宏 (标记)
var ACT_LONG = 1;
var ACT_SHORT = 2;
var ACT_COVER = 3; // 动作宏
var ERR_SUCCESS = 0; // 错误宏
var ERR_SET_SYMBOL = 1;
var ERR_GET_ORDERS = 2;
var ERR_GET_POS = 3;
var ERR_TRADE = 4;
var ERR_GET_DEPTH = 5;
var ERR_NOT_TRADING = 6;
var errMsg = ["成功", "切换合约失败", "获取订单失败", "获取持仓失败", "交易下单失败", "获取深度失败", "不在交易时间"]; // 错误宏的值 对应该数组的索引,对应索引的值就是翻译
var obj = { // 声明一个对象,构造完成后返回。单个的海龟策略控制对象。
symbol: symbol, // 合约代码 构造函数执行时的参数传入
keepBalance: keepBalance, // 预留的资金 构造函数执行时的参数传入
riskRatio: riskRatio, // 风险系数 构造函数执行时的参数传入
atrLen: atrLen, // ATR 长度 构造函数执行时的参数传入
enterPeriodA: enterPeriodA, // 入市周期A 构造函数执行时的参数传入
leavePeriodA: leavePeriodA, // 离市周期A 构造函数执行时的参数传入
enterPeriodB: enterPeriodB, // 入市周期B 构造函数执行时的参数传入
leavePeriodB: leavePeriodB, // 离市周期B 构造函数执行时的参数传入
useFilter: useFilter, // 使用入市过滤条件 构造函数执行时的参数传入
multiplierN: multiplierN, // 加仓系数 基于N 构造函数执行时的参数传入
multiplierS: multiplierS // 止损系数 基于N 构造函数执行时的参数传入
};
obj.task = { // 给 obj对象添加一个 task 属性(值也是一个对象),用来保存 海龟的任务状态数据。
action: ACT_IDLE, // 执行动作
amount: 0, // 操作量
dealAmount: 0, // 已经处理的操作量
avgPrice: 0, // 成交均价
preCost: 0, // 前一次交易成交的额度
preAmount: 0, // 前一次成交的量
init: false, // 是否初始化
retry: 0, // 重试次数
desc: "空闲", // 描述信息
onFinish: null // 处理完成时的 回调函数,即可以自行设定一个 回调函数在完成当前 action 记录的任务后执行的代码。
}
obj.maxLots = maxLots; // 赋值 最大加仓次数 构造函数执行时的参数传入
obj.lastPrice = 0; // 最近成交价,用于计算 持仓盈亏。
obj.symbolDetail = symbolDetail; // 储存 合约的详细信息 到obj 对象的 symbolDetail 属性
obj.status = { // 状态数据
symbol: symbol, // 合约代码
recordsLen: 0, // K线长度
vm: [], // 持仓状态 , 用来储存 每个品种的 ,手动恢复字符串。
open: 0, // 开仓次数
cover: 0, // 平仓次数
st: 0, // 止损平仓次数
marketPosition: 0, // 加仓次数
lastPrice: 0, // 最近成交价价格
holdPrice: 0, // 持仓均价
holdAmount: 0, // 持仓数量
holdProfit: 0, // 浮动持仓盈亏
N: 0, // N值 , 即ATR
upLine: 0, // 上线
downLine: 0, // 下线
symbolDetail: symbolDetail, // 合约详细信息
lastErr: "", // 上次错误
lastErrTime: "", // 上次错误时间信息
stopPrice: '', // 止损价格
leavePrice: '', //
isTrading: false // 是否在交易时间
};
obj.setLastError = function(err) {
// 给obj对象添加方法,设置 最近一次的错误信息
if (typeof(err) === 'undefined' || err === '') { // 如果参数未传入,或者 错误信息为 空字符串
obj.status.lastErr = ""; // 清空 obj 对象的 status 属性的 对象的lastErr属性
obj.status.lastErrTime = ""; // 清空
return; // 返回
}
var t = new Date(); // 获取新时间
obj.status.lastErr = err; // 设置错误信息
obj.status.lastErrTime = t.toLocaleString(); // toLocaleString() 根据本地时间格式,把 Date 对象转换为字符串。
};
obj.reset = function(marketPosition, openPrice, N, leavePeriod, preBreakoutFailure) {
// 给obj对象添加方法,恢复仓位。
// 参数,marketPosition:加仓次数,openPrice:最后一次加仓价, N:N值, leavePeriod:离市周期,preBreakoutFailure:是否上次突破失败
if (typeof(marketPosition) !== 'undefined') { // 如果 第一个参数不是未定义 ,传入参数
obj.marketPosition = marketPosition; // 给obj 添加属性 marketPosition : 加仓次数 正数为多仓,负数为空仓
obj.openPrice = openPrice; // 最后一次加仓价
obj.preBreakoutFailure = preBreakoutFailure; // 是否上次突破失败
obj.N = N; // N值
obj.leavePeriod = leavePeriod; // 离市周期
var pos = _bot.GetPosition(obj.symbol, marketPosition > 0 ? PD_LONG : PD_SHORT); // 调用 模板类库生成的 交易控制对象的成员函数GetPosition 获取 持仓信息
if (pos) {