Конструкция стратегии спотового хеджирования криптовалют ((2)

Автор:Лидия., Создано: 2022-07-19 15:19:52, Обновлено: 2023-09-24 19:34:38

img

Конструкция стратегии спотового хеджирования криптовалют (2)

В предыдущей статье мы вместе реализовали простую стратегию хеджирования, а затем узнаем, как обновить эту стратегию. Изменения в стратегии не являются большими, но детали изменений требуют внимания.

Необходимость модернизации этой стратегии

  • Переключение на режим рычага оптовая биржа Это изменение относится только к реальному боту. Некоторые спотовые биржи имеют интерфейсы спотового рычага, которые также инкапсулированы на FMZ. Для обменных объектов, которые были непосредственно упакованы на FMZ и поддерживают спотовый рычаг, режим может быть переключен непосредственно.
  • Добавить отображение диаграммы распространения Добавьте дисплей диаграммы распространения, потому что это просто рисует линию распространенияA exchange -> B exchange, B exchange -> A exchange, и рисуем горизонтальную линию, которая запускает распространение.line drawing class libraryДля того, чтобы иметь дело с непосредственно, преимущество заключается в том, что это легко использовать, здесь мы также учимся, как использоватьtemplate class libraryфункция FMZ.
  • Функция одностороннего хеджирования Это изменение может быть довольно значительным, поскольку трудно полностью обратить вспять ценовую разницу между двумя биржами во время конкретных сделок хеджирования. В большинстве случаев цена на одной бирже постоянно выше, чем цена на другой бирже. В это время, если наши активы полностью хеджированы (то есть монеты все на биржах с низкими ценами, а деньги на биржах с высокими ценами). Хеджирование стагнирует, и уже невозможно полагаться на колебания спреда для получения прибыли. В это время нам нужно сделать стратегию так, чтобы вы могли потерять немного денег, чтобы хеджировать монеты обратно (позвольте монетам снова существовать на бирже с высокой ценой), и когда разница в ценах снова увеличится, мы можем продолжать хеджировать и получать прибыль.
  • Интерактивно модифицировать параметры, такие как линии хеджирования спредов Добавьте интерактивную функцию к стратегии, чтобы изменить линию разгона в реальном времени.
  • Организовать информацию строки состояния и отобразить ее в формате таблицы Упорядочить данные, которые необходимо отобразить для легкого просмотра.

Далее, давайте реализуем эти проекты один за другим.

Переключение на режим рычага оптового обмена

Возьмите Binance место реального бота в качестве примера, переключитесь на место рычагов режима, используйте кодexchanges[i].IO, введите параметрtrade_normalперейти к позиции с рычагом воздействия по позициям и вводуtrade_super_marginдля переключения на полную позицию рычага, обратное тестирование не поддерживается.

Добавьте к фазе подготовки в началеmainФункция:

    // Switch leverage mode
    for (var i = 0 ; i < exchanges.length ; i++) {   // Traverse and detect all added exchange objects
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   //If the exchange object represented by the current i-index is Binance spot, and the parameter marginType of the strategy interface is not the option of "common currency", execute the switch operation
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "Set to leveraged position-by-position")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "Set to leveraged full position")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

Стратегия здесь добавляет только код для переключения режима рычагов на Binance spot, поэтому настройка переключателя на параметрах стратегии действительна только для Binance spot.

Добавлено отображение диаграммы распространения

Это очень легко использовать уже завернутый шаблон рисунка.Line Drawing LibraryЕго можно получить, поиск прямо на площадке стратегии платформы FMZ.

img

Или нажмите на ссылку прямо:https://www.fmz.com/strategy/27293чтобы перейти на страницу копирования этого шаблона.

img

Нажмите на кнопку, чтобы скопировать библиотеку шаблона класса в свою собственную библиотеку стратегии.

img

Затем вы можете проверить библиотеку класса шаблона, которая будет использоваться в столбце шаблона на странице редактирования стратегии. Сохранить стратегию после проверки, и стратегия будет относиться к этому шаблону. Это просто краткое описание использования библиотеки класса шаблона. Эта стратегия уже ссылается на этот шаблон, поэтому нет необходимости повторять операцию. Когда вы копируете эту стратегию в поле стратегии, вы можете увидеть, чтоLine Drawing Libraryбыл упомянут в строке шаблона на странице редактирования стратегии.

В основном мы узнаем, как использовать функцииLine Drawing Libraryчтобы нарисовать диаграмму.

img

Мы планируем нарисовать распространениеA->B, распространениеB->AНам нужно нарисовать две кривые (текущий A к B, B к A), две горизонтальные линии (линия триггера), как показано на рисунке выше.

Потому что мы хотим разработать одностороннее хеджирование, триггерные линииA->BиB->AМы не можем использовать дизайн в предыдущей статье. В предыдущей статье:

      var targetDiffPrice = hedgeDiffPrice
      if (diffAsPercentage) {
          targetDiffPrice = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentage
      }

Есть только один разъем.targetDiffPrice- Да. Итак, здесь мы должны преобразовать код, преобразовать параметры сначала.

img

Затем измените код:

        var targetDiffPriceA2B = hedgeDiffPriceA2B
        var targetDiffPriceB2A = hedgeDiffPriceB2A
        if (diffAsPercentage) {
            targetDiffPriceA2B = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageA2B
            targetDiffPriceB2A = (depthA.Bids[0].Price + depthB.Asks[0].Price + depthB.Bids[0].Price + depthA.Asks[0].Price) / 4 * hedgeDiffPercentageB2A
        }

Таким образом, разница триггер линия изменилась от предыдущейtargetDiffPriceДо двух.targetDiffPriceA2B, targetDiffPriceB2A- Да. Следующий шаг - нарисовать эти данные на графике, используя функцию чертежной линии библиотеки чертежных линий.

        // drawing
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // The first parameter of this function is the value of the horizontal line in the Y-axis direction, and the second parameter is the display text
        $.PlotHLine(targetDiffPriceB2A, "B->A")

Когда стратегия работает, есть такая диаграмма.

img

Затем нарисуйте кривую распределения в реальном времени, чтобы избежать перетягивания линии.

        if (ts - lastKeepBalanceTS > keepBalanceCyc * 1000) {
            nowAccs = _C(updateAccs, exchanges)
            var isBalance = keepBalance(initAccs, nowAccs, [depthA, depthB])
            cancelAll()
            if (isBalance) {
                lastKeepBalanceTS = ts
                if (isTrade) {
                    var nowBalance = _.reduce(nowAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    var initBalance = _.reduce(initAccs, function(sumBalance, acc) {return sumBalance + acc.Balance}, 0)
                    LogProfit(nowBalance - initBalance, nowBalance, initBalance, nowAccs)
                    isTrade = false 
                }                
            }

            $.PlotLine("A2B", depthA.Bids[0].Price - depthB.Asks[0].Price)  // Draw real-time spread curves
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // The first parameter is the name of the curve, and the second parameter is the value of the curve at the current moment, that is, the value in the Y-axis direction at the current moment
        }

Таким образом, код чертежа составляет всего 4 строки, что позволяет стратегии иметь график, отображаемый во время выполнения.

Функция одностороннего хеджирования

Как уже упоминалось выше, триггерная линия спреда была изменена на две, контролируя триггер хеджирования наA->BиB->AТаким образом, алгоритм предыдущей цены заказа не может быть использован, и вместо этого используется метод добавления цены на рынке к рыночной цене.

        if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) {          // A -> B market conditions are met            
            var priceSell = depthA.Bids[0].Price - slidePrice
            var priceBuy = depthB.Asks[0].Price + slidePrice
            var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
            if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance * 0.8 / priceSell > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance * 0.8 / priceSell, maxHedgeAmount)
                Log("trigger A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // Tips
                hedge(exB, exA, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        } else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPriceB2A && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) {   // B -> A market conditions are met
            var priceBuy = depthA.Asks[0].Price + slidePrice
            var priceSell = depthB.Bids[0].Price - slidePrice
            var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
            if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance * 0.8 / priceBuy > minHedgeAmount) {
                amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance * 0.8 / priceBuy, maxHedgeAmount)
                Log("trigger B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  //Tips
                hedge(exA, exB, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        }

Поскольку цены покупки и продажи разделены на два данного, функция хеджированияhedgeтакже необходимо изменить.

function hedge(buyEx, sellEx, priceBuy, priceSell, amount) {
    var buyRoutine = buyEx.Go("Buy", priceBuy, amount)
    var sellRoutine = sellEx.Go("Sell", priceSell, amount)
    Sleep(500)
    buyRoutine.wait()
    sellRoutine.wait()
}

Есть также некоторые незначительные корректировки, основанные на этих изменениях, которые не будут повторяться здесь.

Интерактивно модифицировать параметры, такие как линии хеджирования спредов

Добавить взаимодействие к стратегии, так что стратегия может изменять линию запуска распространения в режиме реального времени. Дизайн взаимодействия стратегии также очень прост. Во-первых, добавить элементы управления взаимодействием в стратегию на странице редактирования стратегии.

img

Добавлено два элемента управления, один называется A2B и другой называется B2A. После ввода значения в поле ввода управления, нажмите кнопку справа от поля ввода.123в поле ввода, нажмитеA2Bкнопку, и инструкция будет отправлена в стратегию немедленно.

A2B:123

Проектируйте интерактивный код обнаружения и обработки в коде стратегии.

        // interact
        var cmd = GetCommand()   // Every time the loop is executed here, it checks whether there is an interactive command, and returns to an empty string if not.
        if (cmd) {               // An interactive command was detected, such as A2B:123
            Log("command received:", cmd)
            var arr = cmd.split(":")   // Split out the interactive control name and the value in the input box, arr[0] is A2B, arr[1] is 123
            if (arr[0] == "A2B") {     // Determine whether the triggered interactive control is A2B
                Log("Modify the parameters of A2B, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // Modify the trigger spread line
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // Modify the trigger spread line
                }
            } else if (arr[0] == "B2A") {           // Triggered control detected is B2A     
                Log("Modify the parameters of B2A, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

Организовать информацию строки состояния и отобразить ее в формате таблицы

Сделайте отображение данных строки состояния более организованным и простым для наблюдения.

        var tbl = {
            "type" : "table", 
            "title" : "data", 
            "cols" : ["exchange", "coin", "freeze coin", "denominated currency", "freeze denominated currency", "trigger spread", "current spread"], 
            "rows" : [], 
        }
        tbl.rows.push(["A:" + exA.GetName(), nowAccs[0].Stocks, nowAccs[0].FrozenStocks, nowAccs[0].Balance, nowAccs[0].FrozenBalance, "A->B:" + targetDiffPriceA2B, "A->B:" + (depthA.Bids[0].Price - depthB.Asks[0].Price)])
        tbl.rows.push(["B:" + exB.GetName(), nowAccs[1].Stocks, nowAccs[1].FrozenStocks, nowAccs[1].Balance, nowAccs[1].FrozenBalance, "B->A:" + targetDiffPriceB2A, "B->A:" + (depthB.Bids[0].Price - depthA.Asks[0].Price)])

        LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")

img

Обратное тестирование

Backtesting - это только стратегия тестирования, функция предварительного обнаружения, и многие ошибки могут быть протестированы на стадии backtesting на самом деле.

img

Источник стратегии:https://www.fmz.com/strategy/302834


Связанные

Больше