这个策略属于期货的做市策略 会对盘口价格造成影响 所以不适合大资金. 策略为研究市场行为而写, 实盘请用小资金测试.
var DO_IDLE = 0; var DO_LONG = 1; var DO_SHORT = 2; var _MarginLevel = [5, 10, 20][MLevel]; var _ContractType = ["week", "month", "quarter"][ContractType]; var _CurrentDirection = [DO_LONG, DO_SHORT, DO_IDLE][OpType !=2 ? OpType : WaitType]; var _isAuto = OpType == 2; var _IsBitVC = false; var _Is796 = false; var _IsOKCoin = false; var _MinAmount = 0; var _Fee = 0.0003; function _N(v, precision) { if (typeof(precision) != 'number') { precision = _IsOKCoin ? 3 : 2; } 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 GetOrders() { var orders = null; while (!(orders = exchange.GetOrders())) { Sleep(Interval); } return orders; } function CancelPendingOrders(orderType) { while (true) { var orders = GetOrders(); var count = 0; if (typeof(orderType) != 'undefined') { for (var i = 0; i < orders.length; i++) { if (orders[i].Type == orderType) { count++; } } } else { count = orders.length; } if (count == 0) { return; } for (var j = 0; j < orders.length; j++) { if (typeof(orderType) == 'undefined' || (orderType == orders[j].Type)) { exchange.CancelOrder(orders[j].Id, orders[j]); if (j < (orders.length-1)) { Sleep(Interval); } } } } } function GetPosition(orderType) { var positions; while (!(positions = exchange.GetPosition())) { Sleep(Interval); } for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType == _ContractType && positions[i].Type == orderType) { return positions[i]; } } return null; } function GetAccount() { var account; while (!(account = exchange.GetAccount())) { Sleep(Interval); } return account; } function GetLimit() { var ticker; while (!(ticker = exchange.GetTicker())) { Sleep(Interval); } if (IsVirtual()) { return {high: ticker.Sell + 100, low: ticker.Buy - 100}; } var js = exchange.GetRawJSON(); try { var obj = JSON.parse(js); return {high: parseFloat(obj.limit_highest_price), low: parseFloat(obj.limit_lowest_price)}; } catch (e) { Log(e); } return null; } function GetDepth() { var depth; while (true) { depth = exchange.GetDepth(); if (depth && depth.Asks.length > 0 && depth.Bids.length > 0 && depth.Asks[0].Price > depth.Bids[0].Price) { break; } Sleep(Interval); } return depth; } var LastOpenPrice = 0; var LastCoverPrice = 0; var LastHoldPrice = 0; var LastRecord = null; var LastEMATime = 0; function GetDirection() { if (OpType != 2) { return _CurrentDirection; } var n = new Date().getTime(); if ((n - LastEMATime) < (EMAInterval * 1000)) { return _CurrentDirection; } LastEMATime = n; var records = exchange.GetRecords(); if (!records || records.length < (EMA_Slow + 3)) { return _CurrentDirection; } var newLast = records[records.length-1]; if ((!LastRecord) || (LastRecord.Time == newLast.Time && LastRecord.Close == newLast.Close)) { if (!LastRecord) { LastRecord = newLast; } return _CurrentDirection; } LastRecord = newLast; var emaFast = TA.EMA(records, EMA_Fast); var emaSlow = TA.EMA(records, EMA_Slow); return emaFast[emaFast.length-1] >= emaSlow[emaSlow.length-1] ? DO_LONG : DO_SHORT; } function GetPrice() { var buyPrice = 0; var buyAmount = 0; var sellPrice = 0; var sellAmount = 0; var depth = GetDepth(); for (var i = 0; i < depth.Asks.length; i++) { sellAmount += depth.Asks[i].Amount; if (sellAmount >= DepthSell) { sellPrice = depth.Asks[i].Price; break; } } for (var i = 0; i < depth.Bids.length; i++) { buyAmount += depth.Bids[i].Amount; if (buyAmount >= DepthBuy) { buyPrice = depth.Bids[i].Price; break; } } var diff = MinDiff - (sellPrice - buyPrice); if (diff >= 0) { buyPrice = buyPrice - (diff/2); sellPrice = sellPrice + (diff/2); } else { buyPrice += SlidePrice; sellPrice -= SlidePrice; } return {buy : buyPrice, sell: sellPrice}; } function updateProfit() { var account = GetAccount(); if (_IsBitVC) { try { var obj = JSON.parse(exchange.GetRawJSON()); LogProfit(obj.dynamicRights, 'Stocks:', account.Stocks, 'FrozenStocks:', account.FrozenStocks); } catch(e) { Log(e); } } else { LogProfit(account.Stocks + account.FrozenStocks); } } var _prePositions = 0; function onTick() { var price = GetPrice(); if (_IsBitVC) { var limit = GetLimit(); if (limit) { price.sell = Math.max(Math.min(price.sell, limit.high), limit.low); price.buy = Math.min(Math.max(price.buy, limit.low), limit.high); } } var openFunc = _CurrentDirection == DO_LONG ? exchange.Buy : exchange.Sell; var openDirection = _CurrentDirection == DO_LONG ? "buy" : "sell"; var openTradeType = _CurrentDirection == DO_LONG ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; var coverFunc = _CurrentDirection == DO_LONG ? exchange.Sell : exchange.Buy; var coverDirection = _CurrentDirection == DO_LONG ? "closebuy" : "closesell"; var coverTradeType = _CurrentDirection == DO_LONG ? ORDER_TYPE_SELL : ORDER_TYPE_SELL; var openPrice = _N(_CurrentDirection == DO_LONG ? price.buy : price.sell); var coverPrice = _N(_CurrentDirection == DO_LONG ? price.sell : price.buy); var op = 0; var isFighting = false; var marketCoverPrice = coverPrice; if (LastHoldPrice > 0 && LastCoverPrice > 0) { if (_CurrentDirection == DO_LONG) { isFighting = (LastHoldPrice - coverPrice) <= StopLoss; if (isFighting) { coverPrice = _N((LastHoldPrice * (1+_Fee)) + StopProfit); } else { isFighting = true; } } else { isFighting = (coverPrice - LastHoldPrice) <= StopLoss; if (isFighting) { coverPrice = _N((LastHoldPrice * (1-_Fee)) - StopProfit); } } } if (LastHoldPrice > 0) { LogStatus(_CurrentDirection == DO_LONG ? "多仓" : "空仓", isFighting ? "僵持中.." : "止损中..", "持仓均价: ", _N(LastHoldPrice), "盘口平仓价:", marketCoverPrice, isFighting ? "#0000ff" : "#ff0000"); } else { LogStatus(_CurrentDirection == DO_LONG ? "做多" : "做空", "开仓价: ", openPrice, "平仓价:", marketCoverPrice, "抢盘中... #428bca"); } if (openPrice != LastOpenPrice) { op = 1; } if (coverPrice != LastCoverPrice) { op = op == 0 ? 2 : 3; } if (op == 3) { CancelPendingOrders(); } else if (op != 0) { CancelPendingOrders(op == 1 ? openTradeType : coverTradeType); } else { return; } var position = 0; var hold = GetPosition(openTradeType); if (hold) { position = hold.Amount; LastHoldPrice = hold.Price; } else { LastHoldPrice = 0; } var coverAmount = _N(Math.min(position, _IsBitVC ? (LotCover * 100) : LotCover)); if (!_Is796) { coverAmount = parseInt(coverAmount); } if (_IsBitVC) { coverAmount = parseInt(parseInt(coverAmount / 100) * 100); } if ((op == 2 || op == 3) && (coverAmount >= _MinAmount)) { exchange.SetDirection(coverDirection); if (coverFunc(coverPrice, coverAmount, "上次平仓价格", LastCoverPrice) > 0) { LastCoverPrice = coverPrice; } } if (position == 0 && _prePositions != 0) { updateProfit(); _prePositions = 0; } var d = GetDirection(); if (_prePositions == 0) { _prePositions = position; } if (_isAuto) { if (d != _CurrentDirection) { if (position == 0 && GetOrders().length == 0) { Log(d == DO_LONG ? "开始做多" : "开始做空"); _CurrentDirection = d; } return; } } var account = GetAccount(); var canUsedStocks = account.Stocks; if (KeepStocksRate > 0) { canUsedStocks = _N(Math.max(account.Stocks - _N((position * (_IsOKCoin ? 10 : 1) / _MarginLevel / (_Is796 ? 1 : openPrice)) * KeepStocksRate), 0) / KeepStocksRate); } var openAmount = 0; if (_IsBitVC) { openAmount = parseInt(parseInt(Math.min(((canUsedStocks * _MarginLevel * (openPrice*0.9)) / 100), Lot)) * 100); } else if (_IsOKCoin) { openAmount = parseInt(Math.min(((canUsedStocks * _MarginLevel * (openPrice*0.9)) / 10), Lot)); } else { openAmount = _N(Math.min(canUsedStocks * _MarginLevel, Lot)); } if ((op == 1 || op == 3) && (openAmount >= _MinAmount)) { exchange.SetDirection(openDirection); if (openFunc(openPrice, openAmount, "上次建仓价格", LastOpenPrice) > 0) { LastOpenPrice = openPrice; } } } function onexit() { CancelPendingOrders(); Log("Exit"); } function main() { var eName = exchange.GetName(); if (eName.indexOf("Futures") == -1) { throw "该策略为期货专用策略"; } if (_IsOKCoin && _MarginLevel == 5) { throw "OKCoin期货只支持10倍或20倍杠杆"; } if (DisableLog) { EnableLog(false); } _IsBitVC = eName.indexOf("BitVC") != -1; _Is796 = eName.indexOf("796") != -1; _IsOKCoin = eName.indexOf("OKCoin") != -1; if (_IsBitVC) { _MinAmount = 100; } else if (_IsOKCoin) { _MinAmount = 1; } else { _MinAmount = exchange.GetMinStock(); } exchange.SetRate(1); Log(exchange.GetName(), GetAccount()); CancelPendingOrders(); LoopInterval = Math.max(LoopInterval, 1); EMAInterval = Math.max(EMAInterval, 1); if (_IsBitVC || _IsOKCoin) { Lot = parseInt(Math.max(1, Lot)); LotCover = parseInt(Math.max(1, LotCover)); if (Lot < 1 || LotCover < 1) { throw "手数最少为1, BitVC一手相当于100元人民币, OKCoin相当于10美金."; } } KeepStocksRate = parseInt(KeepStocksRate); Log("预留", KeepStocksRate, "倍的保证金"); if (_IsOKCoin && ContractType == 0) { _ContractType = "this_week"; } if (!_IsOKCoin && ContractType == 1) { throw "只有OKCoin期货支持月全约"; } if (_Is796 && ContractType != 0) { throw "796只支持周合约类型"; } exchange.SetContractType(_ContractType); exchange.SetMarginLevel(_MarginLevel); if (OpType == 2) { Log("开始收集K线信息, 请耐心等待."); } while (true) { if (_CurrentDirection == DO_IDLE) { _CurrentDirection = GetDirection(); } else { onTick(); } Sleep(LoopInterval * 1000); } }template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6