796 Futures counter-hand doubling algorithm, open first or more, can also specify a failure to continue in the previous direction, if it fails, then increase the position according to the specified multiplier, the strategy is risky, only used for learning.
var FirstTradeType = [ORDER_TYPE_BUY, ORDER_TYPE_SELL][OpType]; var OrgAccount = null; var Counter = {s : 0, f: 0}; var LastProfit = 0; var AllProfit = 0; var _Failed = 0; function StripOrders(e, orderId) { var order = null; if (typeof(orderId) == 'undefined') { orderId = null; } while (true) { var dropped = 0; var orders = _C(e.GetOrders); for (var i = 0; i < orders.length; i++) { if (orders[i].Id == orderId) { order = orders[i]; } else { var extra = ""; if (orders[i].DealAmount > 0) { extra = "成交: " + orders[i].DealAmount; } else { extra = "未成交"; } e.SetDirection(orders[i].Type == ORDER_TYPE_BUY ? "buy" : "sell"); e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); dropped++; } } if (dropped == 0) { break; } Sleep(300); } return order; } var preMsg = ""; function GetAccount(e, waitFrozen) { if (typeof(waitFrozen) == 'undefined') { waitFrozen = false; } var account = null; var alreadyAlert = false; while (true) { account = _C(e.GetAccount); if (!waitFrozen || account.FrozenStocks < MinStock) { break; } if (!alreadyAlert) { alreadyAlert = true; Log("发现账户有冻结的钱或币", account); } Sleep(Interval); } msg = "成功: " + Counter.s + " 次, 失败: " + Counter.f + " 次, 当前账户 币: " + account.Stocks; if (account.FrozenStocks > 0) { msg += " 冻结的币: " + account.FrozenStocks; } if (msg != preMsg) { preMsg = msg; LogStatus(msg, "#ff0000"); } return account; } function GetPosition(e, orderType) { var positions = _C(e.GetPosition); if (typeof(orderType) == 'undefined') { return positions; } for (var i = 0; i < positions.length; i++) { if (positions[i].Type == orderType) { return positions[i]; } } return null; } function GetTicker(e) { while (true) { var ticker = _C(e.GetTicker); if (ticker.Buy > 0 && ticker.Sell > 0 && ticker.Sell > ticker.Buy) { return ticker; } Sleep(100); } } // mode = 0 : direct buy, 1 : buy as buy1 function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxSpace, retryDelay) { var initPosition = GetPosition(e, tradeType); var nowPosition = initPosition; var orderId = null; var prePrice = 0; var dealAmount = 0; var diffMoney = 0; var isFirst = true; var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; var isBuy = tradeType == ORDER_TYPE_BUY; while (true) { var account = _C(e.GetAccount); var ticker = GetTicker(e); var tradePrice = 0; if (isBuy) { tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); } else { tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); } if (orderId == null) { if (isFirst) { isFirst = false; } else { nowPosition = GetPosition(e, tradeType); } dealAmount = _N((nowPosition ? nowPosition.Amount : 0) - (initPosition ? initPosition.Amount : 0), 6); var doAmount = Math.min(tradeAmount - dealAmount, account.Stocks * MarginLevel, 4); if (doAmount < MinStock) { break; } prePrice = tradePrice; e.SetDirection(tradeType == ORDER_TYPE_BUY ? "buy" : "sell"); orderId = tradeFunc(tradePrice, doAmount); } else { if (mode == 0 || Math.abs(tradePrice - prePrice) > maxSpace) { orderId = null; } var order = StripOrders(exchange, orderId); if (order == null) { orderId = null; } } Sleep(retryDelay); } if (dealAmount <= 0) { return null; } return nowPosition; } function coverFutures(e, orderType) { var coverAmount = 0; while (true) { var positions = _C(e.GetPosition); var ticker = GetTicker(e); var found = 0; for (var i = 0; i < positions.length; i++) { if (positions[i].Type == orderType) { if (coverAmount == 0) { coverAmount = positions[i].Amount; } if (positions[i].Type == ORDER_TYPE_BUY) { e.SetDirection("closebuy"); e.Sell(ticker.Buy, positions[i].Amount); } else { e.SetDirection("closesell"); e.Buy(ticker.Sell, positions[i].Amount); } found++; } } if (found == 0) { break; } Sleep(2000); StripOrders(e); } return coverAmount; } function loop(pos) { var tradeType = null; if (typeof(pos) == 'undefined' || !pos) { tradeType = FirstTradeType; pos = Trade(exchange, tradeType, OpAmount, OpMode, SlidePrice, MaxSpace, Interval); if (!pos) { throw "出师不利, 开仓失败"; } else { Log(tradeType == ORDER_TYPE_BUY ? "开多仓完成" : "开空仓完成", "均价:", pos.Price, "数量:", pos.Amount); } } else { tradeType = pos.Type; } var holdPrice = pos.Price; var holdAmount = pos.Amount; var openFunc = tradeType == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; var coverFunc = tradeType == ORDER_TYPE_BUY ? exchange.Sell : exchange.Buy; var reversePrice = 0; var coverPrice = 0; var canOpen = true; if (tradeType == ORDER_TYPE_BUY) { reversePrice = _N(holdPrice * (1 - StopLoss), 4); coverPrice = _N(holdPrice * (1 + StopProfit), 4); } else { reversePrice = _N(holdPrice * (1 + StopLoss), 4); coverPrice = _N(holdPrice * (1 - StopProfit), 4); } var coverId = null; var msg = "持仓价: " + holdPrice + " 止损价: " + reversePrice; for (var i = 0; i < 10; i++) { if (coverId) { break; } if (tradeType == ORDER_TYPE_BUY) { exchange.SetDirection("closebuy"); coverId = exchange.Sell(coverPrice, holdAmount, msg); } else { exchange.SetDirection("closesell"); coverId = exchange.Buy(coverPrice, holdAmount, msg); } Sleep(Interval); } if (!coverId) { StripOrders(exchange); throw "下单失败"; } while (true) { Sleep(Interval); var ticker = GetTicker(exchange); if ((tradeType == ORDER_TYPE_BUY && ticker.Last < reversePrice) || (tradeType == ORDER_TYPE_SELL && ticker.Last > reversePrice)) { StripOrders(exchange); var coverAmount = coverFutures(exchange, tradeType); if (_Failed >= MaxLoss) { Counter.f++; Log("超过最大失败次数", MaxLoss); break; } var reverseAmount = _N(coverAmount * ReverseRate, 4); var account = GetAccount(exchange, true); if (_N(account.Stocks * MarginLevel, 4) < reverseAmount) { Log("没有币反手开仓, 需要开仓: ", reverseAmount, "个, 只有", account.Stocks, "个币"); Counter.f++; break; } var reverseType = tradeType; if (ReverseMode == 0) { reverseType = tradeType == ORDER_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY; } var pos = Trade(exchange, reverseType, reverseAmount, OpMode, SlidePrice, MaxSpace, Interval); if (pos) { Log(reverseType == ORDER_TYPE_BUY ? "多仓" : "空仓", "加倍开仓完成"); } return pos; } else { var orders = _C(exchange.GetOrders); if (orders.length == 0) { Counter.s++; var account = GetAccount(exchange, true); LogProfit(account.Stocks, account); break; } } } return null; } function onexit() { StripOrders(exchange); Log("Exit"); } function main() { if (exchange.GetName().indexOf("Futures") == -1) { throw "只支持期货, 现货暂不支持"; } EnableLogLocal(SaveLocal); if (exchange.GetRate() != 1) { Log("已禁用汇率转换"); exchange.SetRate(1); } StopProfit /= 100; StopLoss /= 100; var eName = exchange.GetName(); if (eName == "Futures_CTP") { throw "暂只支持数字货币期货" } exchange.SetContractType(Symbol); exchange.SetMarginLevel(MarginLevel); Interval *= 1000; SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF"); StripOrders(exchange); OrgAccount = GetAccount(exchange, true); LogStatus("启动成功"); var pos = null; var positions = GetPosition(exchange); if (positions.length == 1) { pos = positions[0]; Log("发现一个仓位, 已经自动恢复进度"); } else if (positions.length > 1) { throw "发现持仓超过1个"; } while (true) { pos = loop(pos); if (!pos) { _Failed = 0; } else { _Failed++; } Sleep(Interval); } }
qq813380629I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can't go back, I can go back, I can go back, I can go back, I can go back.
qq813380629I can't track it back, and it's weird.
qq813380629I can't track it back, and it's weird.