break;
}
}
var obj = TTManager.New(hasPosition, symbol, keepBalance, RiskRatio, ATRLength, EnterPeriodA, LeavePeriodA, EnterPeriodB, LeavePeriodB, UseEnterFilter, IncSpace, StopLossRatio, MaxLots);
// 根据界面参数 使用 构造函数 New 构造 一个品种的海龟交易策略控制对象
tts.push(obj); // 把该对象压入 tts 数组, 最终根据合约列表 ,生成了若干个品种的 控制对象储存在tts数组
}
var preTotalHold = -1;
var lastStatus = '';
while (true) { // 主要循环
if (GetCommand() === "暂停/继续") { // API GetCommand 函数 获取 程序界面上的 命令。此处 如果 点击了界面上的“暂停/继续”按钮
Log("暂停交易中...");
while (GetCommand() !== "暂停/继续") { // 进入等待循环 ,直到再次点击 “暂停/继续” 按钮 退出 等待循环
Sleep(1000);
}
Log("继续交易中...");
}
while (!exchange.IO("status")) { // 一旦断开服务器的连接,则尝试重连 并等待。
Sleep(3000);
LogStatus("正在等待与交易服务器连接, " + new Date() + "\n" + lastStatus); // 输出上一次的 状态栏 内容,并 更新时间。
}
var tblStatus = { // 用于显示在状态栏表格上的 持仓信息 对象
type: "table",
title: "持仓信息",
cols: ["合约名称", "持仓方向", "持仓均价", "持仓数量", "持仓盈亏", "加仓次数", "开仓次数", "止损次数", "成功次数", "当前价格", "N"],
rows: []
};
var tblMarket = { // 用于显示在状态栏表格上的 市场信息 对象
type: "table",
title: "运行状态",
cols: ["合约名称", "合约乘数", "保证金率", "交易时间", "柱线长度", "上线", "下线", "止损价", "离市价", "异常描述", "发生时间"],
rows: []
};
var totalHold = 0;
var vmStatus = {};
var ts = new Date().getTime(); // 当前时间戳
var holdSymbol = 0; // 持有的合约量
for (var i = 0; i < tts.length; i++) { // 遍历tts数组
tts[i].Poll(); // 调用每个 合约的海龟管理对象的 Poll 函数
var d = tts[i].Status(); // 更新每个 海龟管理对象的 状态 属性 status 并返回。
if (d.holdAmount > 0) { // 如果当前索引的对象 有 持仓
vmStatus[d.symbol] = d.vm; // 给空对象 vmStatus 添加合约名称 为属性名 的属性,并给其赋值 持仓信息vm
holdSymbol++; // 给持有的合约品种数量 累计
}
tblStatus.rows.push([d.symbolDetail.InstrumentName, d.holdAmount == 0 ? '--' : (d.marketPosition > 0 ? '多' : '空'), d.holdPrice, d.holdAmount, d.holdProfit, Math.abs(d.marketPosition), d.open, d.st, d.cover, d.lastPrice, d.N]);
// 压入当前 索引 的 海龟管理对象 的信息 到状态分页表格
tblMarket.rows.push([d.symbolDetail.InstrumentName, d.symbolDetail.VolumeMultiple, _N(d.symbolDetail.LongMarginRatio, 4) + '/' + _N(d.symbolDetail.ShortMarginRatio, 4), (d.isTrading ? '是#0000ff' : '否#ff0000'), d.recordsLen, d.upLine, d.downLine, d.stopPrice, d.leavePrice, d.lastErr, d.lastErrTime]);
// 压入当前 索引 的 海龟管理对象 的信息 到行情分页表格
totalHold += Math.abs(d.holdAmount); // 值为回调函数 的参数ret 的属性 更新,可以参见 回调函数的 传入实参。processTask 函数中的 ret
// 累计 总持仓手数
}
var now = new Date(); // 获取最新时间
var elapsed = now.getTime() - ts; // 计算主要耗时代码 , 迭代 执行 Poll 函数的 开始与结束的 时间差。
var tblAssets = _bot.GetAccount(true); // 获取账户详细信息并返回一个表格对象。(因为参数传递的是true, 参见 模板的 GetAccount 函数的 getTable 参数)
var nowAccount = _bot.Account(); // 获取账户信息
if (tblAssets.rows.length > 10) { // 如果获取的 表格的 行数 大于10
// replace AccountId
tblAssets.rows[0] = ["InitAccount", "初始资产", initAccount]; // 设置 索引 0 的行数 为 初始资金信息。
} else {
tblAssets.rows.unshift(["NowAccount", "当前可用", nowAccount], ["InitAccount", "初始资产", initAccount]); // 往 rows 数组 中开始的位置插入2个元素
}
lastStatus = '`' + JSON.stringify([tblStatus, tblMarket, tblAssets]) + '`\n轮询耗时: ' + elapsed + ' 毫秒, 当前时间: ' + now.toLocaleString() + ', 星期' + ['日', '一', '二', '三', '四', '五', '六'][now.getDay()] + ", 持有品种个数: " + holdSymbol;
// 组合 各种 用于显示在界面的信息。
if (totalHold > 0) { // 在有持仓时才 显示 手动恢复字符串(vmStatus JSON序列化)
lastStatus += "\n手动恢复字符串: " + JSON.stringify(vmStatus);
}
LogStatus(lastStatus); // 调用API 显示在 状态栏
if (preTotalHold > 0 && totalHold == 0) { // 当全部持仓 平掉 没有持仓时
LogProfit(nowAccount.Balance - initAccount.Balance - initMargin); // 输出 盈利, 显示到收益曲线(此种情况 出现概率较低,很难有同时全部都未持仓的状态,所以收益都是 动态的,可以看 账户详细信息分析当前状况)
}
preTotalHold = totalHold; // 每次都更新 确保 输出收益只显示一次。
Sleep(LoopInterval * 1000); // 轮询等待。避免API 访问过于频繁
}
}
菜鸟程序员注释,如有错误,欢迎斧正,感谢支持! ^。^