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

Автор:Нинабадасс., Создано: 2022-04-14 16:17:46, Обновлено: 2022-04-15 14:16:23

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

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

Требования к модернизации стратегии

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

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

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

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

В ходе подготовки к началуmainФункция, добавить:

    // switch the margin mode 
    for (var i = 0 ; i < exchanges.length ; i++) {   // traverse and detect all exchange objects added
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   // if the exchange object represented by the current index i is Binance Spot, and the parameter marginType on the strategy interface is not selected as the "common spot" option, execute the switch
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "set to isolated margin")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "set to cross margin")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

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

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

Использование в капсулированном графических шаблонов очень просто.chart plot LibraryВы можете искать его непосредственно на площади ФМЗ.

img

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

img

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

img

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

Здесь мы в основном узнаем, как использовать функцииchart plot libraryчтобы составить план.

img

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

Потому что мы хотим спроектировать односторонний жидкий хребет, триггерные линии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- Да. Далее вы можете использовать функцию графического графического графика библиотеки графических графиков, чтобы нарисовать данные на графике.

        // plot
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // the first parameter of the 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)  // plot real-time spread curves
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // the first parameter is the curve name, and the second parameter is the curve value 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 condition satisfied             
            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("triggerA->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // prompt message
                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 condition satisfied 
            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("triggerB->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  // prompt message
                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

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

        // interaction 
        var cmd = GetCommand()   // every time when the loop is operated here, it will detect whether an interactive command is sent; if no, return null string 
        if (cmd) {               // interactive command detected, such as A2B:123
            Log("received command:", cmd)
            var arr = cmd.split(":")   // split out the interactive control name and the value in the input box; arr[0] means A2B, and arr[1] means 123
            if (arr[0] == "A2B") {     // judge whether the triggered interactive control is A2B
                Log("modify parameterA2B,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // modify the spread trigger line 
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // modify the spread trigger line 
                }
            } else if (arr[0] == "B2A") {           // detected the triggered control is B2A 
                Log("modify parameterB2A,", diffAsPercentage ? "parameter of spread ratio:" : "parameter of spread:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

Управлять информацией строки состояния и отображать ее в формате таблицы

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

        var tbl = {
            "type" : "table", 
            "title" : "data", 
            "cols" : ["platform", "Currency", "frozenCurrrency", "quoteCurrency", "frozenQuoteCurrency", "triggerSpread", "currentSpread"], 
            "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

Обратный тест

Бактэст - это только тест стратегии, как предварительная функция обнаружения. Многие ошибки могут быть проверены на этапе бактесте. Не нужно слишком беспокоиться о результатах бактесте. В конечном итоге стратегия все еще должна быть протестирована в реальной среде с реальными ботами.

img

img

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


Больше