Если у вас есть какие-либо вопросы, пожалуйста, оставьте комментарии.
// 参数 /* var MinAmount = 1 var SlidePrice = 5 var Interval = 500 */ function GetPosition(e, contractType, direction) { e.SetContractType(contractType) var positions = _C(e.GetPosition); for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType == contractType && positions[i].Type == direction) { return positions[i] } } return null } function Open(e, contractType, direction, opAmount) { var initPosition = GetPosition(e, contractType, direction); var isFirst = true; var initAmount = initPosition ? initPosition.Amount : 0; var nowPosition = initPosition; var directBreak = false var preNeedOpen = 0 var timeoutCount = 0 while (true) { var ticker = _C(e.GetTicker) var needOpen = opAmount; if (isFirst) { isFirst = false; } else { nowPosition = GetPosition(e, contractType, direction); if (nowPosition) { needOpen = opAmount - (nowPosition.Amount - initAmount); } // 检测directBreak 并且持仓未变的情况 if (preNeedOpen == needOpen && directBreak) { Log("疑似仓位数据延迟,等待30秒", "#FF0000") Sleep(30000) nowPosition = GetPosition(e, contractType, direction); if (nowPosition) { needOpen = opAmount - (nowPosition.Amount - initAmount); } /* timeoutCount++ if (timeoutCount > 10) { Log("连续10次疑似仓位延迟,下单失败!", "#FF0000") break } */ } else { timeoutCount = 0 } } if (needOpen < MinAmount) { break; } var amount = needOpen; preNeedOpen = needOpen e.SetDirection(direction == PD_LONG ? "buy" : "sell"); var orderId; if (direction == PD_LONG) { orderId = e.Buy(ticker.Sell + SlidePrice, amount, "开多仓", contractType, ticker); } else { orderId = e.Sell(ticker.Buy - SlidePrice, amount, "开空仓", contractType, ticker); } directBreak = false var n = 0 while (true) { Sleep(Interval); var orders = _C(e.GetOrders); if (orders.length == 0) { if (n == 0) { directBreak = true } break; } for (var j = 0; j < orders.length; j++) { e.CancelOrder(orders[j].Id); if (j < (orders.length - 1)) { Sleep(Interval); } } n++ } } var ret = { price: 0, amount: 0, position: nowPosition }; if (!nowPosition) { return ret; } if (!initPosition) { ret.price = nowPosition.Price; ret.amount = nowPosition.Amount; } else { ret.amount = nowPosition.Amount - initPosition.Amount; ret.price = _N(((nowPosition.Price * nowPosition.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount); } return ret; } function Cover(e, contractType, opAmount, direction) { var initPosition = null; var position = null; var isFirst = true; while (true) { while (true) { Sleep(Interval); var orders = _C(e.GetOrders); if (orders.length == 0) { break; } for (var j = 0; j < orders.length; j++) { e.CancelOrder(orders[j].Id); if (j < (orders.length - 1)) { Sleep(Interval); } } } position = GetPosition(e, contractType, direction) if (!position) { break } if (isFirst == true) { initPosition = position; opAmount = Math.min(opAmount, initPosition.Amount) isFirst = false; } var amount = opAmount - (initPosition.Amount - position.Amount) if (amount <= 0) { break } var ticker = _C(e.GetTicker) if (position.Type == PD_LONG) { e.SetDirection("closebuy"); e.Sell(ticker.Buy - SlidePrice, amount, "平多仓", contractType, ticker); } else if (position.Type == PD_SHORT) { e.SetDirection("closesell"); e.Buy(ticker.Sell + SlidePrice, amount, "平空仓", contractType, ticker); } Sleep(Interval) } return position } $.OpenLong = function(e, contractType, amount) { if (typeof(e) == "string") { amount = contractType contractType = e e = exchange } return Open(e, contractType, PD_LONG, amount); } $.OpenShort = function(e, contractType, amount) { if (typeof(e) == "string") { amount = contractType contractType = e e = exchange } return Open(e, contractType, PD_SHORT, amount); }; $.CoverLong = function(e, contractType, amount) { if (typeof(e) == "string") { amount = contractType contractType = e e = exchange } return Cover(e, contractType, amount, PD_LONG); }; $.CoverShort = function(e, contractType, amount) { if (typeof(e) == "string") { amount = contractType contractType = e e = exchange } return Cover(e, contractType, amount, PD_SHORT); }; function main() { Log(exchange.GetPosition()) var info = $.OpenLong(exchange, "quarter", 100) Log(info, "#FF0000") Log(exchange.GetPosition()) info = $.CoverLong(exchange, "quarter", 30) Log(exchange.GetPosition()) Log(info, "#FF0000") info = $.CoverLong(exchange, "quarter", 80) Log(exchange.GetPosition()) Log(info, "#FF0000") }
Костяные ножиА теперь, пожалуйста, объясните, как использовать ссылки в основной функции. Например, если вы открываете контракт BTC_USDT за квартал по цене 30000, как это должно быть написано? Живые дают объяснения в основной функции. var info = $.OpenLong ((exchange, "quarter", 100) Это много позиций для открытия квартальных контрактов, верно?
Высокий всасывание низкий бросокSlidePrice лучше всего будет относиться к цене.
Изобретатели количественного измерения - мечты$.OpenLong ((exchange, "quarter", 100) В то же время, если вы хотите, чтобы ваши клиенты были готовы к тому, что вы можете получить больше денег, вы должны быть готовы к тому, что вы получите больше.
Изобретатели количественного измерения - мечтыЧасто рекомендуется писать отдельные механизмы торговли, для которых требуется некоторое количество времени для обнаружения остатков сделок. Часто рекомендуется напрямую настроить логику торговли.
Высокий всасывание низкий бросокЯ использую этот OpenLong DOT ((4 ножи), дайте мне 9 ножи для выписки ((4 + 5).
Изобретатели количественного измерения - мечтыНе, это скидка, это немного больше, чем при еде.