리소스 로딩... 로딩...

암호화폐 선물에 대한 마틴게일 전략 설계

저자:FMZ~리디아, 창작: 2022-08-04 15:41:45, 업데이트: 2023-09-21 21:10:49

img

암호화폐 선물에 대한 마틴게일 전략 설계

최근에는 FMZ 공식 그룹에서 많은 마틴게일 전략이 논의되고 있으며, 플랫폼에서 암호화폐 계약의 마틴게일 전략은 많지 않습니다. 따라서, 저는 이 기회를 이용해 암호화폐 선물에 대한 간단한 마틴게일 전략을 설계했습니다. 왜 마틴게일 전략이라고 불리는가? 마틴 전략의 잠재적 위험은 실제로 작지 않기 때문에 마틴 전략에 따라 정확하게 설계되지 않았기 때문입니다. 그러나, 이 유형의 전략은 여전히 많은 위험을 가지고 있으며, 마틴 유형의 전략의 매개 변수 설정은 위험과 밀접하게 관련이 있으며, 위험을 무시해서는 안됩니다.

이 문서에서는 주로 마르틴형 전략의 설계에 대해 설명하고 학습합니다. 전략 아이디어가 매우 명확하기 때문에 FMZ의 사용자로서 전략 설계를 더 고려합니다.

전체 자본을 얻는다

전체 자본은 종종 암호화폐 선물 전략을 설계할 때 사용됩니다. 이것은 수익을 계산해야하기 때문입니다. 특히 부동 수익을 계산해야 할 때입니다. 포지션은 마진으로 점유되어 있기 때문에 미뤄진 주문도 점유됩니다. 이 시점에서 API 인터페이스는exchange.GetAccount()FMZ 플랫폼의 사용 가능한 자산과 대기 주문 동결 자산을 얻기 위해 호출됩니다. 사실, 대부분의 암호화폐 선물 거래소는 총 자본의 데이터를 제공하지만이 속성은 FMZ에 균일하게 포장되지 않습니다.

그래서 우리는 서로 다른 교환에 따라 이 데이터를 얻기 위해 함수를 설계합니다.

// OKEX V5 obtain 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("failed to obtain the total equity of the account!")
            return null
        }
    }
    return totalEquity
}

// Binance futures
function getTotalEquity_Binance() {
    var totalEquity = null 
    var ret = exchange.GetAccount()
    if (ret) {
        try {
            totalEquity = parseFloat(ret.Info.totalWalletBalance)
        } catch(e) {
            Log("failed to obtain the total equity of the account!")
            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 "This exchange is not supported"
    }
}

몇 가지 보조 기능을 설계

주요 함수와 주요 논리를 설계하기 전에, 우리는 몇 가지 준비를하고 몇 가지 보조 기능을 설계해야합니다.

  • 모든 현재 대기 주문을 취소합니다.

    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 andcoverShort. 그래서 우리는 이러한 작업에 대응하는 네 가지 주문 기능을 설계했습니다. 주문만을 고려하면 방향, 주문 가격 및 주문 양이 몇 가지 필요한 요소가 있습니다. 그래서 우리는 이렇게 하는 함수를 디자인했습니다.trade작업 처리 할 때distance, price, amount정해져 있습니다. openLong, openShort, coverLong 및 coverShort에 대한 함수 호출은trade기능, 즉, 설정된 거리와 가격, 그리고 양에 기초한 선물 거래소에 주문을 하는 것입니다.

주요 기능

전략 아이디어는 매우 간단합니다. 현재 가격을 기준으로 취하고 특정 거리에 판매 (단거리) 및 구매 (장거리) 명령을 올리고 아래로합니다. 거래가 완료되면 나머지 모든 주문이 취소되고 그 다음 포지션 가격에 따라 특정 거리에 새로운 클로징 오더가 배치되며 업데이트 된 현재 가격에 인크리시 오더가 배치되지만 추가 포지션에 대한 오더 볼륨은 두 배로 증가하지 않습니다.

  • 초기 작업 대기 중인 주문 때문에, 우리는 주문 ID를 기록하기 위해 두 개의 글로벌 변수가 필요합니다.

    var buyOrderId = null
    var sellOrderId = null
    

    그런 다음 전략 인터페이스 매개 변수는 OKEX_V5 시뮬레이션 봇 옵션을 사용하도록 설계되어 있으므로 코드에 약간의 처리 작업이 필요합니다.

    var exName = exchange.GetName()    
    // Switch 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 precision", pricePrecision, amountPrecision)
    

    설계에 의해 간단한 데이터 복구

    if (totalEq == -1 && !IsVirtual()) {
        var recoverTotalEq = _G("totalEq")
        if (!recoverTotalEq) {
            var currTotalEq = getTotalEquity()
            if (currTotalEq) {
                totalEq = currTotalEq
                _G("totalEq", currTotalEq)
            } else {
                throw "failed to obtain 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, mainly using the latest transaction price
          var pos = _C(exchange.GetPosition)       // Read current position data
          if (pos.length > 1) {                    // Judging the position data, because of the logic of this strategy, it is unlikely that long and short positions will appear at the same time, so if there are long and short positions at the same time, an error will be thrown
              Log(pos)
              throw "Simultaneous long and short positions"                  // Throw an error to stop the strategy
          }
          //Depends on status
          if (pos.length == 0) {                    // Make different operations according to the position status, when there is no position, pos.length == 0 
              // If you have not held a position, count the profit once
              if (!IsVirtual()) {
                  var currTotalEq = getTotalEquity()
                  if (currTotalEq) {
                      LogProfit(currTotalEq - totalEq, "current total equity:", currTotalEq)
                  }
              }
    
              buyOrderId = openLong(ticker.Last - targetProfit, amount)       // Open a buy order for a long position
              sellOrderId = openShort(ticker.Last + targetProfit, amount)     // Open a short sell order
          } else if (pos[0].Type == PD_LONG) {   // For long positions, the position and quantity of pending orders are different
              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) {   // For short positions, the position and quantity of pending orders 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 one side of the pending order fails, cancel all pending orders and start over
              cancelAll()
              buyOrderId = null 
              sellOrderId = null
              continue
          } 
    
          while (1) {  // The pending order is completed, start monitoring 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) {    // Detected that both buy and sell orders have been filled
                  cancelAll()
                  break
              } else if (!isFindBuyId) {   // Detected buy order closing
                  Log("buy order closing")
                  cancelAll()
                  break
              } else if (!isFindSellId) {  // Detected sell order closing
                  Log("sell order closing")
                  cancelAll()
                  break
              }
              LogStatus(_D())
              Sleep(3000)
          }
          Sleep(500)
      }
    

모든 논리와 설계가 설명되어 있습니다.

백테스팅

전략이 5월 19일 시장에서 통과하도록 하자.

img

img

마르틴게일 전략은 여전히 어떤 위험을 안고 있다는 것을 알 수 있습니다.

실제 로봇은 OKEX V5 시뮬레이션 로봇으로 실행될 수 있습니다.

전략 주소:https://www.fmz.com/strategy/294957

전략은 주로 학습을 위해 사용되며 실제 돈은 조심스럽게 사용해야 합니다~!


관련

더 많은