Projeto de estratégia de cobertura spot de criptomoedas (2)

Autora:Lydia., Criado: 2022-07-19 15:19:52, Atualizado: 2023-09-24 19:34:38

img

Projeto de estratégia de cobertura spot de criptomoedas (2)

No artigo anterior, implementamos uma estratégia de hedge simples juntos, e então vamos aprender como atualizar essa estratégia. As mudanças de estratégia não são grandes, mas os detalhes das mudanças precisam de atenção.

A necessidade de melhorar esta estratégia

  • Mudança do modo de alavancagem do objeto de câmbio spot Esta mudança está relacionada apenas com o bot real. Algumas casas de câmbio spot têm interfaces de alavancagem spot, que também são encapsuladas no FMZ. Para objetos de câmbio que foram diretamente empacotados no FMZ e suportam alavancagem spot, o modo pode ser trocado diretamente.
  • Adicionar exibição de gráfico de spread Adicione a exibição do gráfico de spread, porque é apenas desenhar a linha de spread deA exchange -> B exchange, B exchange -> A exchange, e desenhar a linha horizontal que desencadeia a propagação.line drawing class libraryA vantagem é que é fácil de usar, aqui também aprendemos como usar otemplate class libraryFunção da FMZ.
  • Função de cobertura unilateral Essa mudança pode ser bastante significativa, porque é difícil reverter completamente a diferença de preço entre as duas bolsas durante transações específicas de hedging. Na maioria das vezes, o preço em uma bolsa é consistentemente maior do que o preço em outra bolsa. Neste momento, se nossos ativos estiverem totalmente hedgeados (ou seja, as moedas estão todas em bolsas com preços baixos e o dinheiro está em bolsas com preços altos). A hedge está estagnada e não é mais possível confiar na flutuação do spread para obter lucro. Neste momento, precisamos fazer a estratégia para que você possa perder um pouco de dinheiro para hedgear as moedas de volta (deixe as moedas existir na bolsa com preço alto novamente), e quando a diferença de preço se torna maior novamente, podemos continuar a hedgear e ganhar lucro.
  • Modificar de forma interativa parâmetros como linhas de cobertura de spread Adicionar função interativa à estratégia para modificar a linha de disparo da propagação em tempo real.
  • Organizar informações da barra de estado e exibi-las em formato de tabela Organizar os dados que precisam ser exibidos para fácil visualização.

Em seguida, vamos implementar estes projetos um por um.

Mudança de modo de alavancagem do objeto de troca spot

Pegue Binance spot real bot como um exemplo, mudar para o local alavancado modo, usar o códigoexchanges[i].IO, introduzir o parâmetrotrade_normalpara mudar para posição de alavancagem por posição e entrada,trade_super_marginpara mudar para alavancagem posição total, backtesting não é suportado.

Adicionar à fase de preparação no início domainFunção:

    // Switch leverage mode
    for (var i = 0 ; i < exchanges.length ; i++) {   // Traverse and detect all added exchange objects
        if (exchanges[i].GetName() == "Binance" && marginType != 0) {   //If the exchange object represented by the current i-index is Binance spot, and the parameter marginType of the strategy interface is not the option of "common currency", execute the switch operation
            if (marginType == 1) {
                Log(exchanges[i].GetName(), "Set to leveraged position-by-position")
                exchanges[i].IO("trade_normal")
            } else if (marginType == 2) {
                Log(exchanges[i].GetName(), "Set to leveraged full position")
                exchanges[i].IO("trade_super_margin")
            }
        }
    }

A estratégia aqui só adiciona o código para mudar o modo de alavancagem moeda para moeda do Binance spot, então a configuração do interruptor nos parâmetros da estratégia é válida apenas para o Binance spot.

Adicionou a exibição do gráfico de spread

É muito fácil de usar o modelo de desenho já embrulhado.Line Drawing LibraryPode ser obtido pesquisando diretamente no quadrado de estratégia da plataforma FMZ.

img

Ou clique diretamente no link:https://www.fmz.com/strategy/27293para saltar para a página de cópia para este modelo.

img

Clique no botão para copiar esta biblioteca de classe modelo para sua própria biblioteca de estratégia.

img

Em seguida, você pode verificar a biblioteca de classes de modelo a ser usada na coluna de modelo na página de edição de estratégia. Salve a estratégia depois de verificá-la, e a estratégia irá se referir a este modelo. Esta é apenas uma breve descrição do uso da biblioteca de classes de modelo. Esta estratégia já fez referência a este modelo, por isso não há necessidade de repetir a operação. Quando você copia esta estratégia no quadrado de estratégia, você pode ver queLine Drawing Libraryfoi referenciado na barra de modelo na página de edição da estratégia.

Aprenderemos principalmente como utilizar as funções doLine Drawing Librarypara desenhar um gráfico.

img

Planejamos desenhar a propagação deA->B, a disseminação deB->APrecisamos desenhar duas curvas (currente A para B, B para A spread), duas linhas horizontais (trigger spread line), como mostrado na figura acima.

Porque queremos projetar cobertura unilateral, as linhas de gatilho deA->BeB->ANão podemos usar o desenho do artigo anterior. No artigo anterior:

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

Só há um disparo.targetDiffPrice- Não. Então aqui temos que transformar o código, transformar os parâmetros primeiro.

img

Então, modifique o código:

        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
        }

Desta forma, a diferença linha gatilho mudou a partir do anteriortargetDiffPriceA dois.targetDiffPriceA2B, targetDiffPriceB2A- Não. O próximo passo é desenhar esses dados no gráfico usando a função de linha de desenho da biblioteca de desenho de linha.

        // drawing
        $.PlotHLine(targetDiffPriceA2B, "A->B")  // The first parameter of this 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")

Quando a estratégia está em execução, há um gráfico como este.

img

Em seguida, desenhe a curva de spread em tempo real, para evitar exagerar a linha. Coloque o código que desenha a curva dos dados de spread em tempo real na verificação de saldo.

        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)  // Draw real-time spread curves
            $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price)  // The first parameter is the name of the curve, and the second parameter is the value of the curve at the current moment, that is, the value in the Y-axis direction at the current moment
        }

Desta forma, o código de desenho é de apenas 4 linhas, permitindo que a estratégia tenha um gráfico exibido no tempo de execução.

Função de cobertura unilateral

Como mencionado acima, a linha de desencadeamento do spread foi modificada em duas, controlando o desencadeador de cobertura deA->BeB->AAssim, não se pode utilizar o algoritmo anterior do preço da encomenda e, em vez disso, utiliza-se o método de adição do preço de saída ao preço de mercado.

        if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) {          // A -> B market conditions are met            
            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("trigger A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks)  // Tips
                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 conditions are met
            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("trigger B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks)  //Tips
                hedge(exA, exB, priceBuy, priceSell, amount)
                cancelAll()
                lastKeepBalanceTS = 0
                isTrade = true 
            }            
        }

Uma vez que os preços de compra e venda são separados em dois dados, a função de coberturahedgeO que é que se passa?

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

Há também alguns ajustes menores baseados nestas alterações, que não serão repetidos aqui.

Modificar de forma interativa parâmetros como as linhas de cobertura de spread

Adicionar interação à estratégia, para que a estratégia possa modificar a linha de gatilho de propagação em tempo real. Primeiro, adicione controles de interação à estratégia na página de edição de estratégia.

img

Adicionou dois controles, um chamado A2B e outro chamado B2A. Depois de inserir um valor na caixa de entrada de controle, clique no botão à direita da caixa de entrada. Uma instrução será enviada para a estratégia imediatamente, por exemplo: inserir o valor123na caixa de entrada, clique noA2BO botão, e uma instrução será enviada para a estratégia imediatamente.

A2B:123

Projetar código de detecção e processamento interativo no código de estratégia.

        // interact
        var cmd = GetCommand()   // Every time the loop is executed here, it checks whether there is an interactive command, and returns to an empty string if not.
        if (cmd) {               // An interactive command was detected, such as A2B:123
            Log("command received:", cmd)
            var arr = cmd.split(":")   // Split out the interactive control name and the value in the input box, arr[0] is A2B, arr[1] is 123
            if (arr[0] == "A2B") {     // Determine whether the triggered interactive control is A2B
                Log("Modify the parameters of A2B, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageB2A = parseFloat(arr[1])     // Modify the trigger spread line
                } else {
                    hedgeDiffPriceA2B = parseFloat(arr[1])          // Modify the trigger spread line
                }
            } else if (arr[0] == "B2A") {           // Triggered control detected is B2A     
                Log("Modify the parameters of B2A, ", diffAsPercentage ? "The parameter is the difference percentage" : "The parameter is the difference:", arr[1])
                if (diffAsPercentage) {
                    hedgeDiffPercentageA2B = parseFloat(arr[1])
                } else {
                    hedgeDiffPriceB2A = parseFloat(arr[1])
                }
            }
        }

Organizar informações da barra de status e exibi-las em formato de tabela

Torne a exibição dos dados da barra de status mais organizada e fácil de observar.

        var tbl = {
            "type" : "table", 
            "title" : "data", 
            "cols" : ["exchange", "coin", "freeze coin", "denominated currency", "freeze denominated currency", "trigger spread", "current spread"], 
            "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

Testes de retrocesso

O backtesting é apenas uma estratégia de teste, uma função de detecção preliminar, e muitos bugs podem ser testados na fase de backtesting na verdade.

img

Código fonte da estratégia:https://www.fmz.com/strategy/302834


Relacionados

Mais.