Type/to search
8
Follow
1364
Followers
Desenho de estratégia de hedge spot de moeda digital (2)
Original
Created 2021-07-30 16:36:48  Updated 2023-09-20 10:36:43
 5
 2731

img

Desenho de estratégia de hedge spot de moeda digital (2)

No artigo anterior, implementamos uma estratégia de hedge simples. A seguir, aprenderemos como atualizar essa estratégia.
As mudanças de estratégia não serão grandes, mas os detalhes das mudanças exigem atenção. As definições de algumas partes do código mudaram e precisam ser entendidas.

A necessidade de atualizar esta estratégia

  • Altere o modo de alavancagem do objeto de troca à vista
    Essa mudança está relacionada apenas à negociação real. Algumas bolsas spot têm interfaces de alavancagem spot, que também são encapsuladas no FMZ. Para objetos de câmbio que foram encapsulados diretamente no FMZ e suportam alavancagem spot, você pode alternar o modo diretamente.
  • Adicionada exibição de gráfico de spread
    Adicionar exibição de gráfico de dispersão, porque apenas desenharA交易所->B交易所B交易所->A交易所Desenhe a linha horizontal que aciona a propagação. Nós usamos diretamente画线类库A vantagem é que é simples e fácil de usar. Aqui também aprenderemos como usar o FMZ模版类库Função.
  • Função de cobertura unidirecional
    Essa mudança é bastante significativa porque é difícil reverter completamente a diferença de preço entre as duas bolsas em transações de hedge específicas. Na maioria das vezes, o preço em uma bolsa é consistentemente mais alto que o preço em outra bolsa. Neste momento, se todos os nossos ativos estiverem protegidos (ou seja, as moedas estiverem todas nas bolsas com preços baixos, e o dinheiro estiver todo nas bolsas com preços altos). O hedge parou e não é mais possível depender de flutuações de preços para obter lucros. Neste momento, a estratégia precisa ser tal que você possa perder um pouco de dinheiro para proteger as moedas de volta (deixar as moedas existirem novamente em uma bolsa com um preço alto), e então você pode continuar a proteger e obter lucros quando o preço a diferença se torna maior novamente.
  • Modifique interativamente parâmetros como linhas de spread de hedge
    Adicione funções interativas à estratégia e você poderá modificar a linha de gatilho do spread em tempo real.
  • Organize as informações da barra de status e exiba-as em forma de tabela
    Organize os dados a serem exibidos para facilitar a observação.

Em seguida, vamos implementar esses designs um por um.

Altere o modo de alavancagem do objeto de troca à vista

Tomando como exemplo a negociação spot da Binance, mude para o modo de alavancagem spot usando o códigoexchanges[i].IO, passe parâmetrostrade_normalMude para posição alavancada por posição e passetrade_super_marginMude para a posição de alavancagem total, o backtesting não é suportado. Isso só é usado em negociações reais.

existirmainAdicione a seguinte fase de preparação ao início da função:

// 切换杠杆模式 for (var i = 0 ; i < exchanges.length ; i++) { // 遍历检测所有添加的交易所对象 if (exchanges[i].GetName() == "Binance" && marginType != 0) { // 如果当前i索引代表的交易所对象是币安现货,并且策略界面参数marginType选择的不是「普通币币」选项,执行切换 if (marginType == 1) { Log(exchanges[i].GetName(), "设置为杠杆逐仓") exchanges[i].IO("trade_normal") } else if (marginType == 2) { Log(exchanges[i].GetName(), "设置为杠杆全仓") exchanges[i].IO("trade_super_margin") } } }

A estratégia aqui apenas adiciona o código para alternar o modo de alavancagem moeda a moeda para o Binance spot, portanto, a troca definida nos parâmetros da estratégia é válida apenas para o Binance spot.

Adicionada exibição de gráfico de spread

É muito simples usar os modelos de desenho incluídos. O modelo que usamos é chamado画线类库. Você pode pesquisar e obtê-lo diretamente na plataforma de estratégia FMZ.

img

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

img

Clique no botão para copiar esta biblioteca de modelos para sua própria biblioteca de estratégias.

img

Em seguida, na página de edição de políticas, você pode verificar a biblioteca de modelos necessária na coluna de modelos. Depois de marcar a caixa e salvar a política, esta política fará referência a este modelo. Aqui, explicamos brevemente o uso da biblioteca de modelos. Esta estratégia já referenciou este modelo, então não há necessidade de repetir a operação. Depois de copiar esta estratégia no Strategy Square, você poderá vê-la na coluna de modelo da página de edição de estratégia.画线类库Já citado.

Aprendemos principalmente como usar画线类库função para desenhar o gráfico.

img

Estamos planejandoA->BA diferença de preço,B->AA diferença de preço e a linha de gatilho da diferença de preço são desenhadas. Você precisa desenhar duas curvas (a diferença de preço atual de A para B e de B para A) e duas linhas horizontais (linhas de diferença de preço de gatilho), conforme mostrado na figura acima.

Porque precisamos projetar uma cobertura unilateral,A->BeB->AA linha de gatilho é diferente. O design do artigo anterior não pode mais ser usado.
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 }

Existe apenas um gatilho de propagaçãotargetDiffPrice
Então aqui precisamos modificar o código, primeiro modificar os parâmetros.

img

Em seguida, 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 linha de gatilho da diferença de preço muda em relação à anteriortargetDiffPriceUm, tornou-se doistargetDiffPriceA2BtargetDiffPriceB2A
Em seguida, você pode usar a função de desenho de linha da biblioteca de desenho de linha para desenhar esses dados no gráfico.

// 画图 $.PlotHLine(targetDiffPriceA2B, "A->B") // 该函数第一个参数是水平线在Y轴方向上的值,第二个参数是显示文本 $.PlotHLine(targetDiffPriceB2A, "B->A")

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

img

Em seguida, desenhe a curva de spread em tempo real para evitar excesso de desenho. Coloque o código para desenhar curvas de dados de diferença de preços 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) // 画实时差价曲线 $.PlotLine("B2A", depthB.Bids[0].Price - depthA.Asks[0].Price) // 第一个参数是曲线名称,第二个参数是曲线当前时刻的值,即当前时刻Y轴方向上的值 }

Dessa forma, com apenas 4 linhas de código de desenho, a estratégia pode exibir um gráfico quando estiver em execução.

Função de cobertura unidirecional

Conforme mencionado acima, a linha de gatilho da diferença de preço foi transformada em duas, controlandoA->BO gatilho da cerca vivaB->AA proteção é acionada. Dessa forma, o algoritmo de preço da ordem anterior não pode ser usado, e o método do preço de mercado mais deslizamento é usado em seu lugar.

if (depthA.Bids[0].Price - depthB.Asks[0].Price > targetDiffPriceA2B && Math.min(depthA.Bids[0].Amount, depthB.Asks[0].Amount) >= minHedgeAmount) { // A -> B 盘口条件满足 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("触发A->B:", depthA.Bids[0].Price - depthB.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[1].Balance * 0.8 / priceSell, nowAccs[0].Stocks) // 提示信息 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 盘口条件满足 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("触发B->A:", depthB.Bids[0].Price - depthA.Asks[0].Price, priceBuy, priceSell, amount, nowAccs[0].Balance * 0.8 / priceBuy, nowAccs[1].Stocks) // 提示信息 hedge(exA, exB, priceBuy, priceSell, amount) cancelAll() lastKeepBalanceTS = 0 isTrade = true } }

Como os preços de compra e venda são separados em dois dados, a função de hedgehedgeEle também precisa ser modificado.

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 pequenos ajustes baseados nessas mudanças, que não vou abordar aqui. Você pode olhar o código para detalhes.

Modifique interativamente parâmetros como linhas de spread de hedge

Adicione interatividade à estratégia para que ela possa modificar a linha de gatilho do spread em tempo real. Este é um requisito de design para uma estratégia semiautomática, que também é implementada aqui como uma demonstração de ensino.
O design de interação da estratégia também é muito simples. Primeiro, adicione controles interativos à estratégia na página de edição de estratégia.

img

Dois controles são adicionados, um chamado A2B e o outro chamado B2A. Depois de inserir um valor na caixa de entrada de controle, clique no botão no lado direito da caixa de entrada. Uma instrução será enviada imediatamente para a estratégia, por exemplo: insira um valor na caixa de entrada123, cliqueA2BEste botão enviará imediatamente instruções para a estratégia.

A2B:123

Projete código de detecção e processamento de interação no código de estratégia.

// 交互 var cmd = GetCommand() // 每次循环执行到这里时,都检测有没有交互指令过来,没有则返回空字符串 if (cmd) { // 检测到有交互指令,例如:A2B:123 Log("接收到命令:", cmd) var arr = cmd.split(":") // 拆分出交互控件名称和输入框中的值,arr[0]就是A2B,arr[1]就是123 if (arr[0] == "A2B") { // 判断触发的交互控件是不是A2B Log("修改A2B的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1]) if (diffAsPercentage) { hedgeDiffPercentageB2A = parseFloat(arr[1]) // 修改触发差价线 } else { hedgeDiffPriceA2B = parseFloat(arr[1]) // 修改触发差价线 } } else if (arr[0] == "B2A") { // 检测到触发的控件是B2A Log("修改B2A的参数,", diffAsPercentage ? "参数为差价百分比" : "参数为差价:", arr[1]) if (diffAsPercentage) { hedgeDiffPercentageA2B = parseFloat(arr[1]) } else { hedgeDiffPriceB2A = parseFloat(arr[1]) } } }

Organize as informações da barra de status e exiba-as em forma de tabela

Torne os dados da barra de status mais organizados e fáceis de observar.

var tbl = { "type" : "table", "title" : "数据", "cols" : ["交易所", "币", "冻结币", "计价币", "冻结计价币", "触发差价", "当前差价"], "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 retrospectivos

Backtesting é apenas um teste de estratégia e uma detecção preliminar de funções. Muitos bugs podem realmente ser testados durante o estágio de backtesting. Não há necessidade de prestar muita atenção aos resultados do backtest. A estratégia final ainda precisa ser testada em um ambiente real.

img

img

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

Related Recommendations
Comment
All comments (5)

    这个交易策略加入 合约功能 就好了 就是把永续合约 交割合约 都加进去

    4 years ago

    好的,有机会出个教程。

    4 years ago

    梦大,回测提示 main:127:9 - TypeError: Cannot read property 'SetPrecision' of undefined
    【不同计价币的现货对冲策略 Ver1.1】

    5 years ago

    要添加两个交易所对象。

    5 years ago

    明白了,谢谢梦大。

    5 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)