В процессе загрузки ресурсов... загрузка...

Дизайн стратегии хеджирования цифровых валют на месте ((1)

Автор:Изобретатели количественного измерения - мечты, Создано: 2021-07-19 17:38:24, Обновлено: 2023-09-20 10:35:16

img

Дизайн стратегии хеджирования цифровых валют на месте ((1)

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

Разработка функций, параметров интерфейсов в соответствии с требованиями стратегии

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

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

На основе этих соображений стратегии должны быть разработаны несколько параметров:

  • Ограничения:hedgeDiffPrice, когда разница превышает это значение, запускается операция хеджирования.
  • Минимальный риск:minHedgeAmountМинимальная сумма, которую можно хеджировать.
  • Максимальная хеджировка:maxHedgeAmount, максимальный размер хеджировки в одном экземпляре ((число монет) ).
  • А точность цены:pricePrecisionA, точность цены, размещенной на бирже A ((дешевые цифры)).
  • A: точность:amountPrecisionA, A - точность единиц (плохие цифры) на бирже.
  • Цена B:pricePrecisionB, точность цены, размещенной на бирже B ((небольшие цифры)).
  • В-третьих, точность измерения:amountPrecisionBВ этом случае, если вы хотите, чтобы вы были в курсе, вы должны быть готовы к тому, что вы будете делать.
  • А обменный курс:rateA, первая добавленная обменная точка конвертируется, по умолчанию 1 не конвертируется.
  • Курс на бирже:rateBВторой добавленный объект обмена конвертируется, по умолчанию 1 не конвертируется.

Хеджирующая стратегия требует, чтобы количество монет в двух счетах всегда оставалось неизменным (т. е. не держать никаких позиций в направлении, сохраняя нейтральность), поэтому требуется, чтобы в стратегии была балансовая логика, которая всегда обнаруживает баланс. При обнаружении баланса не нужно получать данные о активах двух бирж. Нам нужно написать функцию для использования.

  • обновлениеAccs
    function updateAccs(arrEx) {
        var ret = []
        for (var i = 0 ; i < arrEx.length ; i++) {
            var acc = arrEx[i].GetAccount()
            if (!acc) {
                return null
            }
            ret.push(acc)
        }
        return ret 
    }
    

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

  • Отменить все
    function cancelAll() {
        _.each(exchanges, function(ex) {
            while (true) {
                var orders = _C(ex.GetOrders)
                if (orders.length == 0) {
                    break
                }
                for (var i = 0 ; i < orders.length ; i++) {
                    ex.CancelOrder(orders[i].Id, orders[i])
                    Sleep(500)
                }
            }
        })
    }
    

При сбалансированном количестве монет нам нужно найти цены, которые суммируются до определенного количества монет в некотором объеме данных, поэтому нам нужна такая функция для обработки.

  • GetDepthPrice
    function getDepthPrice(depth, side, amount) {
        var arr = depth[side]
        var sum = 0
        var price = null
        for (var i = 0 ; i < arr.length ; i++) {
            var ele = arr[i]
            sum += ele.Amount
            if (sum >= amount) {
                price = ele.Price
                break
            }
        }
        return price
    }
    

И тогда нам нужно написать дизайн операций с конкретным хеджированием, который должен быть спроектирован в виде параллельных операций:

  • хребет
    function hedge(buyEx, sellEx, price, amount) {
        var buyRoutine = buyEx.Go("Buy", price, amount)
        var sellRoutine = sellEx.Go("Sell", price, amount)
        Sleep(500)
        buyRoutine.wait()
        sellRoutine.wait()
    }
    

Наконец, мы закончим дизайн балансовой функции, которая немного сложнее.

  • Сохранить баланс
    function keepBalance(initAccs, nowAccs, depths) {
        var initSumStocks = 0
        var nowSumStocks = 0 
        _.each(initAccs, function(acc) {
            initSumStocks += acc.Stocks + acc.FrozenStocks
        })
        _.each(nowAccs, function(acc) {
            nowSumStocks += acc.Stocks + acc.FrozenStocks
        })
      
        var diff = nowSumStocks - initSumStocks
        // 计算币差
        if (Math.abs(diff) > minHedgeAmount && initAccs.length == nowAccs.length && nowAccs.length == depths.length) {
            var index = -1
            var available = []
            var side = diff > 0 ? "Bids" : "Asks"
            for (var i = 0 ; i < nowAccs.length ; i++) {
                var price = getDepthPrice(depths[i], side, Math.abs(diff))
                if (side == "Bids" && nowAccs[i].Stocks > Math.abs(diff)) {
                    available.push(i)
                } else if (price && nowAccs[i].Balance / price > Math.abs(diff)) {
                    available.push(i)
                }
            }
            for (var i = 0 ; i < available.length ; i++) {
                if (index == -1) {
                    index = available[i]
                } else {
                    var priceIndex = getDepthPrice(depths[index], side, Math.abs(diff))
                    var priceI = getDepthPrice(depths[available[i]], side, Math.abs(diff))
                    if (side == "Bids" && priceIndex && priceI && priceI > priceIndex) {
                        index = available[i]
                    } else if (priceIndex && priceI && priceI < priceIndex) {
                        index = available[i]
                    }
                }
            }
            if (index == -1) {
                Log("无法平衡")            
            } else {
                // 平衡下单
                var price = getDepthPrice(depths[index], side, Math.abs(diff))
                if (price) {
                    var tradeFunc = side == "Bids" ? exchanges[index].Sell : exchanges[index].Buy
                    tradeFunc(price, Math.abs(diff))
                } else {
                    Log("价格无效", price)
                }
            }        
            return false
        } else if (!(initAccs.length == nowAccs.length && nowAccs.length == depths.length)) {
            Log("错误:", "initAccs.length:", initAccs.length, "nowAccs.length:", nowAccs.length, "depths.length:", depths.length)
            return true 
        } else {
            return true 
        }
    }
    

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

Дизайн стратегических основных функций

В FMZ, стратегия начинается с:mainФункция начинает выполняться на.mainВ начале функции мы должны сделать некоторые инициализационные действия.

  • Имя объекта биржи Поскольку многие действия в стратегии используются к объектам биржи, например, получить рынок, разместить заказ и т. д. Поэтому использование длинного имени каждый раз может быть проблематичным, небольшой трюк - использовать простое имя вместо него, например:

    var exA = exchanges[0]
    var exB = exchanges[1]
    

    Это позволяет вам легко писать код позже.

  • Дизайн, связанный с валютными курсами и точностью

      // 精度,汇率设置
      if (rateA != 1) {
          // 设置汇率A
          exA.SetRate(rateA)
          Log("交易所A设置汇率:", rateA, "#FF0000")
      }
      if (rateB != 1) {
          // 设置汇率B
          exB.SetRate(rateB)
          Log("交易所B设置汇率:", rateB, "#FF0000")
      }
      exA.SetPrecision(pricePrecisionA, amountPrecisionA)
      exB.SetPrecision(pricePrecisionB, amountPrecisionB)
    

    Если параметры валютного курсаrateArateBУстановлено на 1 ((по умолчанию это 1), т.е.rateA != 1илиrateB != 1Если вы не хотите, чтобы ваши деньги были переведены в другие валюты, вы можете перейти на другие валюты, если вы хотите, чтобы ваши деньги были переведены в другие валюты.

  • Перезагрузить все данные

    img

    Иногда при запуске политики требуется удалить все журналы, данные с пробелов. Можно разработать параметры интерфейса политики.isReset, а затем частично реконструировать код, инициированный в политике, например:

      if (isReset) {   // 当isReset为真时重置数据
          _G(null)
          LogReset(1)
          LogProfitReset()
          LogVacuum()
          Log("重置所有数据", "#FF0000")
      }
    
  • Восстановить первоначальные данные учетной записи, обновить данные текущей учетной записи Для определения баланса стратегия требует постоянного учета первоначального состояния активов счета в сравнении с текущим.nowAccsЭта переменная используется для записи текущих данных с помощью функции, которую мы только что разработали.updateAccsДоступ к данным счетов текущих бирж.initAccsИспользуется для записи первоначального состояния счета (данные о количестве валют на биржах A и B, о количестве купюр и т.д.);initAccsПервое использование_G()Функция восстановления ((_G) Функция постоянно записывает данные и может восстанавливать записанные данные, см. API-документы:СсылкиЕсли запрос не выполняется, назначайте и используйте текущую информацию об аккаунте_GФункциональная запись.

    Например, следующие коды:

      var nowAccs = _C(updateAccs, exchanges)
      var initAccs = _G("initAccs")
      if (!initAccs) {
          initAccs = nowAccs
          _G("initAccs", initAccs)
      }
    

Транзакционная логика, главный цикл в основной функции

Код в основном цикле - это процесс, который выполняется каждым раундом логики стратегии, и непрерывное повторное выполнение составляет основной цикл стратегии. Давайте посмотрим, какой процесс выполняется каждым разом программой в основном цикле.

  • Получить данные о рынке и оценить их эффективность

          var ts = new Date().getTime()
          var depthARoutine = exA.Go("GetDepth")
          var depthBRoutine = exB.Go("GetDepth")
          var depthA = depthARoutine.wait()
          var depthB = depthBRoutine.wait()
          if (!depthA || !depthB || depthA.Asks.length == 0 || depthA.Bids.length == 0 || depthB.Asks.length == 0 || depthB.Bids.length == 0) {
              Sleep(500)
              continue 
          }
    

    Здесь вы можете увидеть параллельные функции, использующие платформу FMZ.exchange.GoЯ создал вызовGetDepth()Одновременные объекты интерфейсовdepthARoutinedepthBRoutine│ При создании этих двух параллельных объектов, призывGetDepth()Также произошел интерфейс, когда два запроса на получение глубоких данных были отправлены на биржу в прошлом. Затем позвоните.depthARoutinedepthBRoutineОбъектыwait()Как получить глубокие данные?
    После получения глубинных данных необходимо проверить глубинные данные, чтобы оценить их эффективность.continueСмысл в том, чтобы переделать цикл главы.

  • Использование价差值Параметры?差价比例Параметры?

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

    В параметрах мы сделали такой дизайн. Параметры FMZ могут быть основаны на параметрах.ПоказатьИлиСпрятатьсяТак что мы можем сделать параметр, чтобы решить, что использовать.价格差Или差价比例

    img

    Добавление параметра к параметрам интерфейса стратегииdiffAsPercentage❖ Два других параметра, которые могут быть показаны или скрыты на основе этого параметра, настроены так:hedgeDiffPrice@!diffAsPercentageКогдаdiffAsPercentageВ качестве фальшивого параметра.hedgeDiffPercentage@diffAsPercentageКогдаdiffAsPercentageПоказать этот параметр верно. После того, как мы сделали этот дизайн, мы отобрали:diffAsPercentageПараметры, которые используются в качестве условий для запуска хеджирования в зависимости от разницы цен.diffAsPercentageПараметры являются условиями, которые запускают хеджирование на основе разницы в ценах.

  • Определение условий возникновения хеджирования

          if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPrice && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) {          // A -> B 盘口条件满足            
              var price = (depthA.Bids[0].Price + depthB.Asks[0].Price) / 2
              var amount = Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount)
              if (nowAccs[0].Stocks > minHedgeAmount && nowAccs[1].Balance / price > minHedgeAmount) {
                  amount = Math.min(amount, nowAccs[0].Stocks, nowAccs[1].Balance / price, maxHedgeAmount)
                  Log("触发A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, price, amount, nowAccs[1].Balance / price, nowAccs[0].Stocks)  // 提示信息
                  hedge(exB, exA, price, amount)
                  cancelAll()
                  lastKeepBalanceTS = 0
                  isTrade = true 
              }            
          } else if (depthB.Bids[0].Price - depthA.Asks[0].Price > targetDiffPrice && Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount) >= minHedgeAmount) {   // B -> A 盘口条件满足
              var price = (depthB.Bids[0].Price + depthA.Asks[0].Price) / 2
              var amount = Math.min(depthB.Bids[0].Amount, depthA.Asks[0].Amount)
              if (nowAccs[1].Stocks > minHedgeAmount && nowAccs[0].Balance / price > minHedgeAmount) {
                  amount = Math.min(amount, nowAccs[1].Stocks, nowAccs[0].Balance / price, maxHedgeAmount)
                  Log("触发B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, price, amount, nowAccs[0].Balance / price, nowAccs[1].Stocks)  // 提示信息
                  hedge(exA, exB, price, amount)
                  cancelAll()
                  lastKeepBalanceTS = 0
                  isTrade = true 
              }            
          }
    

    В этом случае, если вы хотите, чтобы ваш бизнес был более эффективным, вы должны использовать эти инструменты. 1, в первую очередь удовлетворяется разница хеджирования, и хеджируется только тогда, когда разница счета удовлетворяет параметру дифференциации; 2, для того чтобы минимальный риск, установленный в параметрах, соответствовал минимальному размеру, который может быть ограничен различными биржами, следует выбрать наименьший из них. 3, Активы на биржах, продающих операции, достаточно, чтобы продать, а активы на биржах, покупающих операции, достаточно, чтобы купить. Когда эти условия выполнены, выполнение хеджирующей функции производится для хеджирования. Перед основной функцией мы объявляем переменную заранее.isTradeДля обозначения того, произошел ли хеджирование, здесь, если хеджирование вызвано, эта переменная задается какtrueИ перезагрузить глобальные переменные.lastKeepBalanceTSДля 0 ((lastKeepBalanceTS используется для маркировки времени последней операции балансирования, установка на 0 сразу же запускает операцию балансирования), а затем отключить все привязанные списки.

  • Балансировка

          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 
                  }                
              }            
          }
    

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

  • Информация о статусе

          LogStatus(_D(), "A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, " B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, " targetDiffPrice:", targetDiffPrice, "\n", 
              "当前A,Stocks:", nowAccs[0].Stocks, "FrozenStocks:", nowAccs[0].FrozenStocks, "Balance:", nowAccs[0].Balance, "FrozenBalance", nowAccs[0].FrozenBalance, "\n", 
              "当前B,Stocks:", nowAccs[1].Stocks, "FrozenStocks:", nowAccs[1].FrozenStocks, "Balance:", nowAccs[1].Balance, "FrozenBalance", nowAccs[1].FrozenBalance, "\n", 
              "初始A,Stocks:", initAccs[0].Stocks, "FrozenStocks:", initAccs[0].FrozenStocks, "Balance:", initAccs[0].Balance, "FrozenBalance", initAccs[0].FrozenBalance, "\n", 
              "初始B,Stocks:", initAccs[1].Stocks, "FrozenStocks:", initAccs[1].FrozenStocks, "Balance:", initAccs[1].Balance, "FrozenBalance", initAccs[1].FrozenBalance)
    

    Схема состояния не является особо сложной, она показывает текущее время, показывает разницу между биржами А и Б и между биржами Б и А. Она показывает разницу между целями хеджирования. Она показывает данные активов счетов A и B.

Обработка транзакционных пар в разных валютах

В параметрах мы разработали параметры для преобразования валютных курсов.mainМы также разработали часть первоначальных операций функции, которая называется конвертация курсов.SetRateФункция конвертации валютных курсов должна быть выполнена сначала. В результате, мы получаем больше информации о том, что мы делаем, чем делаем.

  • Все данные рынка, данные заказов, данные о хранении.
  • В этом случае, если вы не можете получить деньги, вы можете использовать свои деньги в качестве счета. Например, текущая торговая параBTC_USDTВ целом,USDTВ частности, в банковских счетах используются валюты, которые могут быть использованы в качестве средств.USDTЕсли я хочу конвертировать их в CNY, я могу установить это в кодеexchange.SetRate(6.8)Вы должныexchangeВсе данные, полученные функциями под объектом этой биржи, обмениваются в CNY. В обмен на то, почему мы даем монетыSetRateФункция вводаКурс текущей валюты к целевой валюте

Полная стратегия:Стратегии хеджирования наличности в различных валютах


Связанные

Больше

Скорпионы-разногласные_ украинский фехтовальщикОтлично.