4
Подписаться
1271
Подписчики

Разработка стратегии хеджирования спотовых цифровых валют (2)

Создано: 2021-07-30 16:36:48, Обновлено: 2023-09-20 10:36:43
comments   5
hits   2475

Разработка стратегии хеджирования спотовых цифровых валют (2)

Разработка стратегии хеджирования спотовых цифровых валют (2)

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

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

  • Переключение режима кредитного плеча объекта спотовой биржи Это изменение касается только реальной торговли. Некоторые спотовые биржи имеют интерфейсы спотового кредитного плеча, которые также инкапсулированы в FMZ. Для объектов обмена, которые были напрямую инкапсулированы в FMZ и поддерживают спотовое кредитное плечо, вы можете напрямую переключать режим.
  • Добавлено отображение спред-диаграммы Добавить отображение спред-диаграммы, так как рисовать можно толькоA交易所->B交易所B交易所->A交易所Нарисуйте горизонтальную линию, которая запускает спред. Мы напрямую используем画线类库Преимущество в том, что он прост и удобен в использовании. Здесь мы также научимся использовать FMZ模版类库Функция.
  • Функция одностороннего хеджирования Это изменение весьма существенно, поскольку полностью устранить разницу в ценах между двумя биржами в конкретных хеджинговых сделках сложно. Большую часть времени цена на одной бирже стабильно выше, чем цена на другой бирже. На данный момент, если все наши активы захеджированы (то есть все монеты находятся на биржах с низкими ценами, а все деньги — на биржах с высокими ценами). Хеджирование зашло в тупик, и больше невозможно полагаться на колебания цен для получения прибыли. В это время стратегия должна быть такой, чтобы вы могли потерять немного денег, чтобы захеджировать монеты (позволить монетам снова существовать на бирже с высокой ценой), а затем продолжить хеджировать прибыль, когда разница в ценах снова станет больше.
  • Интерактивно изменяйте параметры, такие как линии спреда хеджирования Добавьте в стратегию интерактивные функции, и вы сможете изменять линию срабатывания спреда в режиме реального времени.
  • Организуйте информацию в строке состояния и отобразите ее в виде таблицы. Организуйте отображение данных для удобства наблюдения.

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

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

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

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

    // 切换杠杆模式
    for (var i = 0 ; i < exchanges.length ; i++) {   // 遍历检测所有添加的交易所对象
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   // 如果当前i索引代表的交易所对象是币安现货,并且策略界面参数marginType选择的不是「普通币币」选项,执行切换
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "设置为杠杆逐仓")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "设置为杠杆全仓")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

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

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

Использовать готовые шаблоны чертежей очень просто. Шаблон, который мы используем, называется画线类库. Вы можете найти и получить его непосредственно на стратегическом квадрате платформы FMZ.

Разработка стратегии хеджирования спотовых цифровых валют (2)

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

Разработка стратегии хеджирования спотовых цифровых валют (2)

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

Разработка стратегии хеджирования спотовых цифровых валют (2)

Затем на странице редактирования политики вы можете проверить нужную вам библиотеку шаблонов в столбце шаблонов. После установки флажка и сохранения политики эта политика будет ссылаться на этот шаблон. Здесь мы просто кратко объясним использование библиотеки шаблонов. Эта стратегия уже ссылается на этот шаблон, поэтому нет необходимости повторять операцию. После копирования этой стратегии в Strategy Square вы увидите ее в столбце шаблона на странице редактирования стратегии.画线类库Уже цитировалось.

В основном мы учимся использовать画线类库функция для рисования графика.

Разработка стратегии хеджирования спотовых цифровых валют (2)

Мы планируем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。 Итак, здесь нам нужно изменить код, для начала изменив параметры.

Разработка стратегии хеджирования спотовых цифровых валют (2)

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

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

        // 画图
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // 该函数第一个参数是水平线在Y轴方向上的值,第二个参数是显示文本
        $.PlotHLine(targetDiffPriceB2A, "B->A")

Когда стратегия запущена, появится такая диаграмма.

Разработка стратегии хеджирования спотовых цифровых валют (2)

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

        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)  // 画实时差价曲线
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // 第一个参数是曲线名称,第二个参数是曲线当前时刻的值,即当前时刻Y轴方向上的值
        }

Таким образом, используя всего 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 盘口条件满足            
            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("触发A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // 提示信息
                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 盘口条件满足
            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("触发B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  // 提示信息
                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()
}

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

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

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

Разработка стратегии хеджирования спотовых цифровых валют (2)

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

A2B:123

Разработать код обнаружения и обработки взаимодействия в коде стратегии.

        // 交互
        var cmd = GetCommand()   // 每次循环执行到这里时,都检测有没有交互指令过来,没有则返回空字符串
        if (cmd) {               // 检测到有交互指令,例如:A2B:123
            Log("接收到命令:", cmd)
            var arr = cmd.split(":")   // 拆分出交互控件名称和输入框中的值,arr[0]就是A2B,arr[1]就是123
            if (arr[0] == "A2B") {     // 判断触发的交互控件是不是A2B
                Log("修改A2B的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // 修改触发差价线
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // 修改触发差价线
                }
            } else if (arr[0] == "B2A") {           // 检测到触发的控件是B2A     
                Log("修改B2A的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

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

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

        var tbl = {
            "type" : "table", 
            "title" : "数据", 
            "cols" : ["交易所", "币", "冻结币", "计价币", "冻结计价币", "触发差价", "当前差价"], 
            "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) + "`")

Разработка стратегии хеджирования спотовых цифровых валют (2)

Бэктестинг

Backtesting — это всего лишь проверка стратегии и предварительное обнаружение функций. Многие ошибки можно проверить на этапе backtesting. Нет необходимости уделять слишком много внимания результатам бэктеста. Окончательную стратегию все равно нужно протестировать в реальной среде.

Разработка стратегии хеджирования спотовых цифровых валют (2)

Разработка стратегии хеджирования спотовых цифровых валют (2)

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