암호화폐 현금 헤지 전략 (2)

저자:니나바다스, 창작: 2022-04-14 16:17:46, 업데이트: 2022-04-15 14:16:23

암호화폐 현금 헤지 전략 (2)

이전 기사에서 우리는 간단한 헤지 전략을 함께 구현했고, 그 다음 전략을 업그레이드하는 방법을 배우게 될 것입니다. 전략에는 많은 변경 사항이 없지만 변경 사항의 세부 사항에 주의가 필요합니다. 코드 내의 일부 장소의 정의는 이전 것과 비교하여 수정되었습니다. 구체적으로 이해해야합니다.

전략의 업그레이드 요구 사항

  • 스팟 교환 객체 마진 모드를 전환 변경 사항은 봇과만 관련이 있습니다. 일부 스포트 플랫폼에는 스포트 마진 인터페이스가 있으며 FMZ에도 캡슐화되어 있습니다. FMZ에 직접 캡슐화되어 스포트 마진을 지원하는 교환 객체에 대해서는 모드를 직접 전환할 수 있습니다.
  • 더 많은 스프레드 차트 표시를 추가합니다 더 많은 스프레드 차트 표시를 추가하기 위해, 우리는 단지 스프레드 곡선을 그래프A->B그리고B->A, 수평 스프레드 트리거 라인뿐만 아니라, 우리는 직접 사용할 수 있습니다chart plot library; 장점은 단순성과 사용 편리함입니다. 여기서 우리는 또한 FMZ의 기능을 사용하는 방법을 배울 수 있습니다.template library together.
  • 일방적인 헤지의 기능 이 변경은 상대적으로 크며, 특정 헤지 거래 도중 두 플랫폼 사이의 가격 스프레드를 완전히 역전시키는 것이 어렵기 때문입니다. 대부분의 경우, 한 플랫폼의 가격은 다른 플랫폼의 가격보다 지속적으로 높습니다. 이 시점에서, 우리의 자산이 완전히 헤지 된 경우 (즉, 모든 통화 기호가 낮은 가격으로 플랫폼에 있으며, 자산은 모두 높은 가격으로 플랫폼에 있습니다). 헤지는 정체되어 있으며, 더 이상 수익을 창출하기 위해 스프레드 변동성에 의존하는 것이 불가능합니다. 이 시점에서, 당신은 약간의 자산을 잃는 것만으로 통화 기호를 헤지하고 반환하는 전략을 만들어야합니다 (거의 가격으로 플랫폼으로 다시 통화 기호를 돌려주십시오). 가격 스프레드가 다시 커지면 헤지하고 수익을 창출 할 수 있습니다.
  • 헤지 스프레드 라인 같은 매개 변수를 상호적으로 수정
    전략에 인터랙티브 함수를 추가하여 실시간으로 스프레드 트리거 라인을 수정합니다.
  • 상태 표시줄 정보를 관리하고 테이블 형식으로 표시 편리한 관찰을 위해 표시해야 하는 데이터를 정리하고 관리합니다.

다음으로, 그 디자인 아이디어를 하나씩 실현해 보겠습니다.

스팟 교환 객체 마진 모드를 변경

예를 들어 Binance 스팟 봇을 들어보자. 스팟 마진 모드로 전환하려면 코드를 사용exchanges[i].IO, 매개 변수를 가져오trade_normal격리된 마진으로 전환하고 수입trade_super_margincross margin로 전환했습니다. backtest에서는 지원되지 않습니다. 보트에서만 사용할 수 있습니다.

그 시작에 준비에서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 LibraryFMZ 광장 플랫폼에서 직접 검색할 수 있습니다.

img

또는 이 링크를 직접 클릭할 수도 있습니다.https://www.fmz.com/strategy/27293템플릿의 복사 페이지로 넘어가면 됩니다.

img

버튼을 클릭하면 자신의 전략 라이브러리에 쉽게 템플릿을 복사 할 수 있습니다.

img

다음, 전략 편집 페이지에서, 당신은 템플릿 열에서 사용할 템플릿 라이브러리를 확인할 수 있습니다. 그것을 확인 한 후 전략을 저장, 그리고 전략이 이 템플릿을 사용할 것입니다. 이것은 단지 템플릿 라이브러리의 사용에 대한 간략한 설명입니다. 전략이 이미 이 템플릿을 참조했기 때문에, 작업을 반복할 필요가 없습니다. 당신이 스퀘어에 전략 코드를 복사하면, 당신은 볼 수 있습니다chart plot Library전략 편집 페이지의 템플릿 바에 참조되었습니다.

여기서 우리는 주로chart plot library음모를 꾸미기 위해서요.

img

우리는 스프레드를 계획합니다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- 네 따라서 여기서 코드를 수정해야 합니다. 먼저 매개 변수를 수정해야 합니다.

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

다음으로, 실시간 스프레드 곡선을 그리세요. 너무 많이 그리지 않으려면, 실시간 스프레드 곡선을 그래프로 그리는 코드를 균형 감지에 넣으십시오. s

        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


더 많은