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

Фьючерсы на криптовалюты по стратегии Мартингейла

Автор:Нинабадасс., Создано: 2022-04-12 17:50:07, Обновлено: 2022-04-12 18:06:07

Фьючерсы на криптовалюты по стратегии Мартингейла

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

В этой статье мы в основном объясняем и учимся на дизайне стратегий типа Мартингейла. Сама идея стратегии уже очень ясна, поэтому мы, как пользователи FMZ, можем рассмотреть больше о дизайне стратегии.

Получить полный капитал

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

Поэтому мы отдельно разрабатываем функции для получения данных по разным платформам:

// OKEX V5 obtains the total equity 
function getTotalEquity_OKEX_V5() {
    var totalEquity = null 
    var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
    if (ret) {
        try {
            totalEquity = parseFloat(ret.data[0].details[0].eq)
        } catch(e) {
            Log("Fail to obtain the total equity of the account!")
            return null
        }
    }
    return totalEquity
}

// Binance Ftures 
function getTotalEquity_Binance() {
    var totalEquity = null 
    var ret = exchange.GetAccount()
    if (ret) {
        try {
            totalEquity = parseFloat(ret.Info.totalWalletBalance)
        } catch(e) {
            Log("Fail to obtain the total equity!")
            return null
        }
    }
    return totalEquity
}

ВtotalEquityЗатем мы записываем функцию как ввод вызова, и вызываем соответствующую функцию согласно названию платформы.

function getTotalEquity() {
    var exName = exchange.GetName()
    if (exName == "Futures_OKCoin") {
        return getTotalEquity_OKEX_V5()
    } else if (exName == "Futures_Binance") {
        return getTotalEquity_Binance()
    } else {
        throw "Do not support the platform"
    }
}

Разработка нескольких вспомогательных функций

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

  • Отменить все текущие заказы

    function cancelAll() {
        while (1) {
            var orders = _C(exchange.GetOrders)
            if (orders.length == 0) {
                break
            }
            for (var i = 0 ; i < orders.length ; i++) {
                exchange.CancelOrder(orders[i].Id, orders[i])
                Sleep(500)
            }
            Sleep(500)
        }
    }
    

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

  • Операция размещения фьючерсных ордеров

    function trade(distance, price, amount) {
        var tradeFunc = null 
        if (distance == "buy") {
            tradeFunc = exchange.Buy
        } else if (distance == "sell") {
            tradeFunc = exchange.Sell
        } else if (distance == "closebuy") {
            tradeFunc = exchange.Sell
        } else {
            tradeFunc = exchange.Buy
        }
        exchange.SetDirection(distance)
        return tradeFunc(price, amount)
    }
    
    function openLong(price, amount) {
        return trade("buy", price, amount)
    }
    
    function openShort(price, amount) {
        return trade("sell", price, amount)
    }
    
    function coverLong(price, amount) {
        return trade("closebuy", price, amount)
    }
    
    function coverShort(price, amount) {
        return trade("closesell", price, amount)
    }
    

    Для торговли фьючерсами существует четыре направления: открытая длинная позиция (openLong), открытая короткая позиция (openShort), закрытая длинная позиция (coverLong) и закрытая короткая позиция (coverShort). Поэтому мы разработали четыре функции ордера, чтобы соответствовать этим операциям. Если вы рассматриваете только размещение ордеров, то есть несколько необходимых факторов: направление, цена ордера и сумма ордера.

    Мы также разработали функцию под названием:tradeдля обработки операции, когдаdirection (distance), order price (price)иorder amount (amount)Указываются.

    Призывы к функциям открытых длинных позиций (openLong), открытых коротких позиций (openShort), закрытых длинных позиций (coverLong) и закрытых коротких позиций (coverShort) в конечном итоге завершаютсяtradeфункция, то есть, в соответствии с указанным направлением, ценой и суммой, размещать заказы в фьючерсных платформах.

Основная функция

Идея стратегии очень проста; возьмите текущую цену в качестве базовой линии, и с определенного расстояния выше и ниже базовой линии, чтобы разместить ордера на продажу (короткий) и ордера на покупку (длинный). Если заказы одной стороны выполняются, отмените все оставшиеся заказы, а затем новые закрытые заказы будут размещены на определенном расстоянии в соответствии с ценой позиции, и заказы на покупку будут размещены по обновленной текущей цене, но заказы на покупку не удвоят сумму заказа.

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

    var buyOrderId = null
    var sellOrderId = null
    

    Затем, возможность использования моделируемого бота OKEX_V5 разработана в параметрах интерфейса стратегии, поэтому некоторая обработка должна быть выполнена в коде:

    var exName = exchange.GetName()    
    // switch to OKEX V5 simulated bot 
    if (isSimulate && exName == "Futures_OKCoin") {
        exchange.IO("simulate", true)
    }
    

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

    if (isReset) {
        _G(null)
        LogReset(1)
        LogProfitReset()
        LogVacuum()
        Log("Reset all data", "#FF0000")
    }
    

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

    exchange.SetContractType("swap")
    

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

    exchange.SetPrecision(pricePrecision, amountPrecision)
    Log("set percision", pricePrecision, amountPrecision)
    

    Простая функция восстановления данных в конструкции

    if (totalEq == -1 && !IsVirtual()) {
        var recoverTotalEq = _G("totalEq")
        if (!recoverTotalEq) {
            var currTotalEq = getTotalEquity()
            if (currTotalEq) {
                totalEq = currTotalEq
                _G("totalEq", currTotalEq)
            } else {
                throw "Fail to obtain the initial equity"
            }
        } else {
            totalEq = recoverTotalEq
        }
    }
    

    Если вы хотите указать начальный общий капитал счета при запуске стратегии, вы можете установить параметрtotalEq. Если этот параметр установлен на -1, стратегия будет читать сохраненные данные об общем капитале. Если нет сохраненных данных об общем капитале, то в настоящее время прочитанный общий капитал используется в качестве начального общего капитала в стратегии. Позже, если общий капитал увеличивается, это означает, что он заработал прибыль; если общий капитал снижается, это означает, что есть убыток. Если читаются данные об общем капитале, используйте данные для продолжения работы.

  • Основная логика После того, как начальная работа была сделана, мы наконец пришли к основной логической части стратегии.

      while (1) {                                  // the main logic of the strategy is designed as an infinite loop
          var ticker = _C(exchange.GetTicker)      // read the current market information first, in which we mainly use the latest trading price
          var pos = _C(exchange.GetPosition)       // read the current position data 
          if (pos.length > 1) {                    // judge the position data; due to the strategy logic, it is unlikely to have long and short positions at the same time, so if there are long and short positions at the same time, an error will be thrown
              Log(pos)
              throw "concurrently with long and short positions"                  // raise an error, and stop the strategy 
          }
          // according to the status 
          if (pos.length == 0) {                    // according to the position status, make different operations; if pos.length == 0, it means currently no position
              // when there is no position yet, calculate the equity 
              if (!IsVirtual()) {
                  var currTotalEq = getTotalEquity()
                  if (currTotalEq) {
                      LogProfit(currTotalEq - totalEq, "Current total equity:", currTotalEq)
                  }
              }
    
              buyOrderId = openLong(ticker.Last - targetProfit, amount)       // pend buy order of open long position 
              sellOrderId = openShort(ticker.Last + targetProfit, amount)     // pend sell order of open short position
          } else if (pos[0].Type == PD_LONG) {   // there are long positions; pending position and amount are 
              var n = 1
              var price = ticker.Last
              buyOrderId = openLong(price - targetProfit * n, amount)
              sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount)
          } else if (pos[0].Type == PD_SHORT) {   // there are short positions; pending position and amount are different 
              var n = 1
              var price = ticker.Last
              buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
              sellOrderId = openShort(price + targetProfit * n, amount)
          }
    
          if (!sellOrderId || !buyOrderId) {   // if opending orders of one side fails, cancel all pending orders and try again 
              cancelAll()
              buyOrderId = null 
              sellOrderId = null
              continue
          } 
    
          while (1) {  // finish pending the order, and start to monitor the order
              var isFindBuyId = false 
              var isFindSellId = false
              var orders = _C(exchange.GetOrders)
              for (var i = 0 ; i < orders.length ; i++) {
                  if (buyOrderId == orders[i].Id) {
                      isFindBuyId = true 
                  }
                  if (sellOrderId == orders[i].Id) {
                      isFindSellId = true 
                  }               
              }
              if (!isFindSellId && !isFindBuyId) {    // both buy order and sell order are detected to be executed 
                  cancelAll()
                  break
              } else if (!isFindBuyId) {   // a buy order execution is detected 
                  Log("buy order executed")
                  cancelAll()
                  break
              } else if (!isFindSellId) {  // a sell order execution is detected 
                  Log("sell order executed")
                  cancelAll()
                  break
              }
              LogStatus(_D())
              Sleep(3000)
          }
          Sleep(500)
      }
    

Тогда вся логика и дизайн полностью объяснены.

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

Пусть стратегия пройдет через рыночные котировки 19 мая 2021 года.

img

img

Как мы видим, стратегия, похожая на стратегию Мартингейла, по-прежнему имеет определенные риски.

Тест бота может использовать OKEX V5 симулируемый бот для запуска

img

Адрес стратегии:https://www.fmz.com/strategy/294957

Стратегия используется в основном для изучения, поэтому не используйте стратегию в реальном боте!


Больше