- 阅读权限
- 255
- 威望
- 0 级
- 论坛币
- 125 个
- 通用积分
- 0
- 学术水平
- 10 点
- 热心指数
- 15 点
- 信用等级
- 5 点
- 经验
- 701 点
- 帖子
- 36
- 精华
- 0
- 在线时间
- 34 小时
- 注册时间
- 2016-4-11
- 最后登录
- 2018-5-22
本科生
还不是VIP/贵宾
- 威望
- 0 级
- 论坛币
- 125 个
- 通用积分
- 0
- 学术水平
- 10 点
- 热心指数
- 15 点
- 信用等级
- 5 点
- 经验
- 701 点
- 帖子
- 36
- 精华
- 0
- 在线时间
- 34 小时
- 注册时间
- 2016-4-11
- 最后登录
- 2018-5-22
|
经管之家送您一份
应届毕业生专属福利!
求职就业群
感谢您参与论坛问题回答
经管之家送您两个论坛币!
+2 论坛币
BotVS的 CTP商品期货多品种海龟交易法源码分享 - /* 参数
- Instruments 合约列表 字符串(string)
- 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
- */
- var _bot = $.NewPositionManager();// 声明一个全局变量, 值由 $.NewPositionManager 这个导出函数 返回, 返回的是一个 对象
- var TTManager = {// 一个对象,全局对象, 生成器。
- New: function(needRestore, symbol, riskRatio, atrLen, enterPeriodA, leavePeriodA, enterPeriodB, leavePeriodB, useFilter,
- multiplierN, multiplierS, maxLots) {//构造函数
- //New函数参数:【needRestore】需要重启 ,symbol【合约编号】,riskRatio【风险比率】,atrLen【art指标长度】,enterPeriodA【入市期A】,leavePeriodA【离市期A】,
- //enterPeriodB【入市期B】,leavePeriodB【离市期B】,useFilter【使用过滤】,multiplierN【乘数N】,multiplierS【乘数S】,maxLots【单品种加仓次数】
- // subscribe
- var symbolDetail = _C(exchange.SetContractType, symbol);//根据合约编号设置合约类型,回去返回的合约信息,symbolDetail
- if (symbolDetail.VolumeMultiple == 0 || symbolDetail.MaxLimitOrderVolume == 0 || symbolDetail.MinLimitOrderVolume == 0 || symbolDetail.LongMarginRatio == 0 || symbolDetail.ShortMarginRatio == 0) {
- //合约一首 份数 == 0 或者 最大下单量 == 0 或者 最小下单量 == 0 或者 多头仓保证金率 == 0 或者 空头仓保证金率 == 0
- Log(symbolDetail);//输出 合约详细信息。
- throw "合约信息异常";//抛出 合约 异常错误,策略停止。
- } else {
- Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate);
- //显示合约一部分信息。
- }
- var obj = {//在New 函数内声明的对象,该对象在New函数最后会作为返回值返回。以下还会声明 obj对象的成员函数、成员属性。
- symbol: symbol, // 把New 函数准备构造对象 传进来的参数 symbol ,初始化给 obj 对象的成员 symbol,合约代码
- riskRatio: riskRatio,//风险比率
- atrLen: atrLen,//ATR指标长度
- enterPeriodA: enterPeriodA,// 入市 、 离市 周期
- leavePeriodA: leavePeriodA,
- enterPeriodB: enterPeriodB,
- leavePeriodB: leavePeriodB,//
- useFilter: useFilter,// 使用过滤
- multiplierN: multiplierN, // 乘数N
- multiplierS: multiplierS // 乘数S
- };
- obj.maxLots = maxLots; // 为什么不在obj 内声明、 初始化 单品种加仓次数
- obj.lastPrice = 0; //最后价格 初始化0
- obj.symbolDetail = symbolDetail; //合约的详细信息
- obj.status = { //obj对象的状态, status 也是个 对象
- symbol: symbol,//合约代码
- recordsLen: 0, //K线长度
- vm: [], //一个数组 ,用来保存 marketPosition ,openPrice , N , leavePeriod , preBreakoutFailure
- open: 0, //开仓次数
- cover: 0,//平仓次数
- st: 0, //
- marketPosition: 0, //
- lastPrice: 0, //最后价格
- holdPrice: 0, //持仓价格
- holdAmount: 0, //持仓数量
- holdProfit: 0, //持仓盈亏
- N: 0, //N值
- upLine: 0, //上线
- downLine: 0, //下线
- symbolDetail: symbolDetail, //合约的详细信息
- lastErr: "", // 最近错误
- lastErrTime: "" // 最近错误时间
- };
- obj.setLastError = function(err) {//设置 最后一次出错
- if (typeof(err) === 'undefined' || err === '') {//如果 err 参数没有传入, 火车 err 为空字符串,执行以下
- obj.status.lastErr = ""; //给 obj.status.lastErr 赋值 空字符串
- obj.status.lastErrTime = ""; // 同样也赋值 空字符串
- return; //返回
- }
- var t = new Date(); // 获取当前时间
- obj.status.lastErr = err; // 把错误信息 赋值给 obj.status.lastErr
- obj.status.lastErrTime = t.toLocaleString(); // 调用了 Date 对象的方法,toLocaleString() 方法可根据本地时间把 Date 对象转换为字符串,并返回结果。
- // 赋值给 obj.status.lasrErrTime
- };
- obj.reset = function(marketPosition, openPrice, N, leavePeriod, preBreakoutFailure) { //重启函数
- // 最后一次加仓价 , N值 , 离市周期 , 前一次失败跳出
- if (typeof(marketPosition) !== 'undefined') { //如果 marketPosition 不等于 未定义,即 在函数调用的时候 ,全部传入参数
- obj.marketPosition = marketPosition; // 把 参数传进来的 marketPosition 赋值给 obj相应的 成员
- obj.openPrice = openPrice; // 创建obj.openPrice 参数赋值给 obj对象的相应的成员 ,最后一次加仓价
- obj.preBreakoutFailure = preBreakoutFailure; // 创建了 obj 对象的成员 preBreakoutFailure ,并且有 函数参数初始化, 上次突破(布尔值)
- obj.N = N; // 创建obj.N, 给obj.N 赋值
- obj.leavePeriod = leavePeriod; // 创建了 obj对象的成员 leavePeriod 离市周期 , 函数传入参数 给其赋值
- var pos = _bot.GetPosition(obj.symbol, marketPosition > 0 ? PD_LONG : PD_SHORT); //调用商品期货交易类库 这个模板生成的 对象_bot 的成员函数
- // GetPosition ,传入 reset 自身对象obj 的成员symbol(这个对象管理的合约代码),根据marketPosition 选择 方向 PD_LONG 多仓, PD_SHORT 空仓,获取该
- //合约的 一个方向的持仓信息
- if (pos) {// 如果 返回的持仓信息 pos 不是 null ,即 有持仓信息
- obj.holdPrice = pos.Price; //给obj.holdPrice 赋值 持仓均价
- obj.holdAmount = pos.Amount; //给 obj.holdAmount 赋值 持仓数量
- Log(obj.symbol, "仓位", pos); // 在日志打印 合约代码 , 持仓信息。
- } else {//如果 pos 是null
- throw "恢复" + obj.symbol + "的持仓状态出错, 没有找到仓位信息";//抛出错误 , 恢复 symbol 这个合约的 时候 持仓状态出错,没有找到持仓信息。
- }
- Log("恢复", obj.symbol, "加仓次数", obj.marketPosition, "持仓均价:", obj.holdPrice, "持仓数量:", obj.holdAmount, "最后一次加仓价", obj.openPrice, "N值", obj.N, "离市周期:", leavePeriod, "上次突破:", obj.preBreakoutFailure ? "失败" : "成功");
- //在日志打印, 合约代码 , 加仓次数 ,持仓均价 ,持仓数量 ,最后一次加仓价
- obj.status.open = 1;//恢复开仓次数 1
- obj.status.vm = [obj.marketPosition, obj.openPrice, obj.N, obj.leavePeriod, obj.preBreakoutFailure]; //给obj.status.vm 赋值
- } else {// marketPosition === 'undefined' 即 在调用该函数时 ,没有传入任何参数。
- obj.marketPosition = 0;// 加仓次数 为0
- obj.holdPrice = 0;// 持仓均价 0
- obj.openPrice = 0; // 最后一次加仓价格 0
- obj.holdAmount = 0; // 持仓量 0
- obj.holdProfit = 0; // 持仓 盈亏 0
- obj.preBreakoutFailure = true; // test system A //上次突破是否失败, true即真
- obj.N = 0; // N值 0
- obj.leavePeriod = leavePeriodA; // 系统A 的离市周期(界面参数) 赋值给 leavePeriod
- }
- obj.holdProfit = 0; // 主要用于 if条件触发
- obj.lastErr = ""; // if 和 else 操作 都会执行该语句
- obj.lastErrTime = ""; // 同上
- };
- obj.Status = function() {// 更新obj 对象的 Status 属性
- obj.status.N = obj.N; // 用obj对象相应的属性去赋值 (status属性中相应的 成员) N值
- obj.status.marketPosition = obj.marketPosition; //加仓次数 (也是持仓方向 + - 代表方向, 数值代表 操作的次数,一个方向 直到 平仓)
- obj.status.holdPrice = obj.holdPrice;
- obj.status.holdAmount = obj.holdAmount;
- obj.status.lastPrice = obj.lastPrice;
- if (obj.lastPrice > 0 && obj.holdAmount > 0 && obj.marketPosition !== 0) {
- obj.status.holdProfit = _N((obj.lastPrice - obj.holdPrice) * obj.holdAmount * symbolDetail.VolumeMultiple, 4) * (obj.marketPosition > 0 ? 1 : -1);
- } else {
- obj.status.holdProfit = 0;
- }
- return obj.status;
- };
- obj.Poll = function() {
- var suffix = WXPush ? '@' : '';
- // switch symbol
- _C(exchange.SetContractType, obj.symbol);
- var records = exchange.GetRecords();
- if (!records) {
- obj.setLastError("获取K线失败");
- return;
- }
- obj.status.recordsLen = records.length;
- if (records.length < obj.atrLen) {
- obj.setLastError("K线长度小于 " + obj.atrLen);
- return;
- }
- var opCode = 0; // 0: IDLE, 1: LONG, 2: SHORT, 3: CoverALL
- var lastPrice = records[records.length - 1].Close;
- obj.lastPrice = lastPrice;
- if (obj.marketPosition === 0) {
- obj.status.upLine = 0;
- obj.status.downLine = 0;
- for (var i = 0; i < 2; i++) {
- if (i == 0 && obj.useFilter && !obj.preBreakoutFailure) {
- continue;
- }
- var enterPeriod = i == 0 ? obj.enterPeriodA : obj.enterPeriodB;
- if (records.length < (enterPeriod + 1)) {
- continue;
- }
- var highest = TA.Highest(records, enterPeriod, 'High');
- var lowest = TA.Lowest(records, enterPeriod, 'Low');
- obj.status.upLine = obj.status.upLine == 0 ? highest : Math.min(obj.status.upLine, highest);
- obj.status.downLine = obj.status.downLine == 0 ? lowest : Math.max(obj.status.downLine, lowest);
- if (lastPrice > highest) {
- opCode = 1;
- } else if (lastPrice < lowest) {
- opCode = 2;
- }
- obj.leavePeriod = (enterPeriod == obj.enterPeriodA) ? obj.leavePeriodA : obj.leavePeriodB;
- }
- } else {
- var spread = obj.marketPosition > 0 ? (obj.openPrice - lastPrice) : (lastPrice - obj.openPrice);
- if (spread > (obj.N * 2)) {
- opCode = 3;
- obj.preBreakoutFailure = true;
- Log(obj.symbolDetail.InstrumentName, "止损平仓", suffix);
- obj.status.st++;
- } else if (-spread > (0.5 * obj.N)) {
- opCode = obj.marketPosition > 0 ? 1 : 2;
- } else if (records.length > obj.leavePeriod) {
- if ((obj.marketPosition > 0 && lastPrice < TA.Lowest(records, obj.leavePeriod, 'Low')) ||
- (obj.marketPosition < 0 && lastPrice > TA.Highest(records, obj.leavePeriod, 'High'))) {
- obj.preBreakoutFailure = false;
- Log(obj.symbolDetail.InstrumentName, "正常平仓", suffix);
- opCode = 3;
- obj.status.cover++;
- }
- }
- }
- if (opCode == 0) {
- return;
- }
- if (opCode == 3) {
- _bot.Cover(obj.symbol);
- obj.reset();
- _G(obj.symbol, null);
- return;
- }
- // Open
- if (Math.abs(obj.marketPosition) >= obj.maxLots) {
- obj.setLastError("禁止开仓, 超过最大持仓 " + obj.maxLots);
- return;
- }
- var atrs = TA.ATR(records, atrLen);
- var N = _N(atrs[atrs.length - 1], 4);
- var account = _bot.GetAccount();
- var unit = parseInt(account.Balance * (obj.riskRatio / 100) / N / obj.symbolDetail.VolumeMultiple);
- var canOpen = parseInt(account.Balance / (opCode == 1 ? obj.symbolDetail.LongMarginRatio : obj.symbolDetail.ShortMarginRatio) / (lastPrice * 1.2) / obj.symbolDetail.VolumeMultiple);
- unit = Math.min(unit, canOpen);
- if (unit < obj.symbolDetail.MinLimitOrderVolume) {
- obj.setLastError("可开 " + unit + " 手 过小无法开仓");
- return;
- }
复制代码
扫码加我 拉你入群
请注明:姓名-公司-职位
以便审核进群资格,未注明则拒绝
|
|
|