只支持两个交易所, 可自定义差价的类型, 支持2.77托管者的自定义图表功能
var __lastDiff = 0; var __AType = ["Last", "Buy", "Sell"][AType]; var __BType = ["Last", "Buy", "Sell"][BType]; var cfg = { tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, title : { text : '差价分析图'}, rangeSelector: { buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}], selected: 0, inputEnabled: false }, xAxis: { type: 'datetime'}, yAxis : { plotLines : [{ value : 0.0, color : 'black', dashStyle : 'shortdash', width : 3, }, { value : NormalDiff, color : 'green', dashStyle : 'shortdash', width : 1, }, { value : HighDiff, color : 'red', dashStyle : 'shortdash', width : 1, },{ value : -NormalDiff, color : 'green', dashStyle : 'shortdash', width : 1, }, { value : -HighDiff, color : 'red', dashStyle : 'shortdash', width : 1, }] }, series : [{ name : '价差', data : [], tooltip: { valueDecimals: 2 } }] }; function _N(v, precision) { if (typeof(precision) != 'number') { precision = 4; } var d = parseFloat(v.toFixed(Math.max(10, precision+5))); s = d.toString().split("."); if (s.length < 2 || s[1].length <= precision) { return d; } var b = Math.pow(10, precision); return Math.floor(d*b)/b; } function GetTicker(e) { if (typeof(e) == 'undefined') { e = exchange; } var ticker; while (!(ticker = e.GetTicker())) { Sleep(Interval); } return ticker; } function onTick() { var tickerA = GetTicker(exchanges[0]); var tickerB = GetTicker(exchanges[1]); var diff = _N(tickerA[__AType] - tickerB[__BType]); LogStatus(exchanges[0].GetName(), _N(tickerA[__AType]), exchanges[1].GetName(), _N(tickerB[__BType]), "差价:", diff); if (__lastDiff != 0) { if (Math.abs(Math.abs(diff) - Math.abs(__lastDiff)) > 200) { return; } } if (diff != __lastDiff) { // add添加数据到series, 参数格式为[series序号, 数据]; cfg.yAxis.plotLines[0].value=diff; cfg.subtitle={text:'当前价差:' + diff}; __chart.update(cfg); __chart.add([0, [new Date().getTime(), diff]]); __lastDiff = diff; } } function main() { if (parseFloat(Version()) < 2.77) { throw "只支持2.77或以上版本"; } if (exchanges.length != 2) { throw "只支持两个交易所对冲"; } // 传给Chart函数的必须是一个与上下文无关的结构体(附合HighStocks规则, 详情参数HighStocks使用方法) __chart = Chart(cfg); // reset 清空所有图表之前的信息 // __chart.reset(); if (EnableCR) { for (var i = 0; i < exchanges.length; i++) { var rate = exchanges[i].GetRate(); if (exchanges[i].GetBaseCurrency() != 'CNY') { exchanges[i].SetRate(USDCNY); Log("更改", exchanges[i].GetName(), "汇率", rate, "为", USDCNY); } var eName = exchanges[i].GetName(); if (eName == "Futures_BitVC") { exchanges[i].SetContractType("week"); } } } Log(exchanges[0].GetName()+"."+__AType, "-", exchanges[1].GetName()+"."+__BType, '差价做为收益显示到图表'); TickInterval = Math.max(TickInterval, 50); Interval = Math.max(Interval, 50); while (true) { onTick(); Sleep(TickInterval); if (GetCommand() === '重置数据') { LogReset(); LogProfitReset(); __chart.reset(); Log("数据重置成功"); } } }template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6