Melhores ferramentas fazem um bom trabalho - aprenda a usar o ambiente de pesquisa para analisar princípios de negociação

Autora:Lydia., Criado: 2022-12-27 16:33:51, Atualizado: 2023-09-20 09:17:27

img

Melhores ferramentas fazem um bom trabalho aprender a utilizar o ambiente de investigação para analisar os princípios de negociação

O termo hedging é um conceito muito básico no campo da negociação quantitativa e da negociação de programas. Na negociação quantitativa de moeda digital, as estratégias de hedging frequentemente usadas são: hedging spot de futuros, hedging cross-period e hedging spot, que são essencialmente transações por diferenças de preço. Talvez quando se trata do conceito, princípio e detalhes de hedging, muitos estudantes que acabam de entrar no campo da negociação quantitativa ainda não estejam muito claros. Não importa.

No painel da plataforma FMZ Quant, clique em Analisar para ir para a página da ferramenta:

img

Aqui eu carrego o arquivo de análise diretamente: Este documento de análise é uma análise do processo de abertura e fechamento de uma posição de cobertura spot de futuros durante o backtesting.quarterA troca à vista é uma transacção moeda-moeda OKX, e o par de negociação éBTC_USDTPara analisar o processo de operação do hedging spot de futuros, você pode ver o seguinte arquivo de ambiente de pesquisa específico, escrito em duas versões: uma versão em Python, uma versão em JavaScript.

Ambiente de pesquisa arquivo de linguagem Python

Análise sobre o princípio da cobertura spot de futuros.ipynb Em [1]:

from fmz import *
task = VCtx('''backtest
start: 2019-09-19 00:00:00
end: 2019-09-28 12:00:00
period: 15m
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD", "stocks":1}, {"eid":"OKX","currency":"BTC_USDT","balance":10000,"stocks":0}]
''')
# Create backtesting environment
import matplotlib.pyplot as plt
import numpy as np
# Import the plot library matplotlib and library numpy

Em [2]:

exchanges[0].SetContractType("quarter")    # The first exchange object OKX Futures (eid: Futures_OKCoin) calls the function to set the current contract as a quarterly contract
initQuarterAcc = exchanges[0].GetAccount() # The initial account information of OKX Futures Exchange is recorded in the variable initQuarterAcc
initQuarterAcc

Fora[2]: (Bilanço: 0,0, FrozenBalance: 0,0, Propriedades: 1,0, FrozenPropriedades: 0,0)

Em [3]:

initSpotAcc = exchanges[1].GetAccount()    # The initial account information of the OKX Spot Exchange is recorded in the variable initSpotAcc
initSpotAcc

Fora[3]: (Bilanço: 10000,0, FrozenBalance: 0,0, Propriedades: 0,0, FrozenPropriedades: 0,0)

Em [4]:

quarterTicker1 = exchanges[0].GetTicker()  # Get the futures exchange ticker, recorded in the variable quarterTicker1
quarterTicker1

Fora[4]: Hora: 1568851210000, High: 10441.25002, Low: 10441.25, Venda : 10441.25002, Comprar: 10441.25, Último: 10441.25001, Volume: 1772.0, OpenInterest: 0.0}

Em [5]:

spotTicker1 = exchanges[1].GetTicker()     # Get the spot exchange ticker, recorded in the variable spotTicker1
spotTicker1

Fora[5]: Tempo: 1568851210000, Alto : 10156.60000002, Baixo : 10156,6, Venda : 10156.60000002, Compra: 10156,6, Último : 10156.60000001, Volume: 7.4443, OpenInterest: 0.0}

Em [6]:

quarterTicker1.Buy - spotTicker1.Sell      # The price difference between going short on futures and going long on spot.

Fora[6]: 284,64999997999985

Em [7]:

exchanges[0].SetDirection("sell")                       # Set up a futures exchange and trade in the direction of going short
quarterId1 = exchanges[0].Sell(quarterTicker1.Buy, 10)  # Futures go short to place orders. The order quantity is 10 contracts. The returned order ID is recorded in the variable quarterId1.
exchanges[0].GetOrder(quarterId1)                       # Check the details of the order with futures order ID quarterId1.

Fora[7]: - Sim, senhor. Preço : 10441.25, Quantidade : 10,0 Contrato : 10.0, Preço médio: 10441,25. Tipos: 1, Offset: 0, Status: 1, Tipos de contratos : bquartal }

Em [8]:

spotAmount = 10 * 100 / quarterTicker1.Buy                 # Calculate the currency equivalent of 10 contracts as the order quantity of the spot.
spotId1 = exchanges[1].Buy(spotTicker1.Sell, spotAmount)   # Place orders on the spot exchange
exchanges[1].GetOrder(spotId1)                             # Check the order details of the spot order ID of spotId1

Fora[8]: - Sim, senhor. Preço : 10156.60000002, Montante : 0,0957, Quantidade do negócio : 0,0957, Preço médio: 10156.60000002, Tipo : 0, Offset: 0, Status: 1, Tipos de contratos: bBTC_USDT_OKX}

Podem ver-se que as ordens trimestraisId1 e spotId1 estão totalmente preenchidas, ou seja, a cobertura das posições abertas está concluída.

Em [9]:

Sleep(1000 * 60 * 60 * 24 * 7)       # Hold the position for a while and wait for the price difference to become smaller to close the position.

Após o tempo de espera, preparar para fechar a posição.quarterTicker2, spotTicker2e imprimi-los. A direção da transação do objeto de troca de futuros é definida para fechar a posição curta:exchanges[0].SetDirection("closesell")colocar uma ordem para fechar a posição. Imprimir os pormenores da ordem de encerramento da posição, indicando que a ordem de encerramento foi concluída, a posição de encerramento terminada.

Em [10]:

quarterTicker2 = exchanges[0].GetTicker()     # Get the current futures exchange ticker, recorded in the variable quarterTicker2
quarterTicker2

Fora[10]: Hora: 1569456010000, Alto : 8497.20002, Baixo : 8497,2, Venda : 8497.20002, Compra: 8497.2, Última vez: 8497.20001. Volume: 4311.0, OpenInterest: 0.0}

Em [11]:

spotTicker2 = exchanges[1].GetTicker()       # Get the current ticker of the spot exchange, recorded in the variable spotTicker2
spotTicker2

Fora[11]: - Está bem. High: 8444.70000001, Baixo: 8444.69999999, Venda : 8444.70000001, Compra: 8444.69999999, Último: 8444,7. Volume: 78.6273, OpenInterest: 0.0}

Em [12]:

quarterTicker2.Sell - spotTicker2.Buy        # The price difference between closing a short futures position and closing a long spot position.

Fora[12]: 52.5000200100003

Em [13]:

exchanges[0].SetDirection("closesell")                   # Set the current trading direction of the futures exchange to close short positions.
quarterId2 = exchanges[0].Buy(quarterTicker2.Sell, 10)   # The futures exchange places an order to close a position and records the order ID to the variable quarterId2.
exchanges[0].GetOrder(quarterId2)                        # Check futures close out order details

Fora[13]: - O que é que se passa? Preço : 8497.20002, Quantidade : 10,0 Contrato : 10.0, Preço médio: 8493,95335, Tipo : 0, Offset: 1, Status: 1, Tipos de contratos : bquartal }

Em [14]:

spotId2 = exchanges[1].Sell(spotTicker2.Buy, spotAmount) # The spot exchange places an order to close a position and records the order ID, which is recorded to the variable spotId2.
exchanges[1].GetOrder(spotId2)      # Check spot close out order details

Fora [1]: - O que é que se passa? Preço : 8444,69999999, Montante : 0,0957, Quantidade do negócio : 0,0957, Preço médio: 8444,69999999, Tipos: 1, Offset: 0, Status: 1, Tipos de contratos: bBTC_USDT_OKX}

Em [15]:

nowQuarterAcc = exchanges[0].GetAccount()   # Get the current futures exchange account information, recorded in the variable nowQuarterAcc.
nowQuarterAcc

Fora [1]: {Balanço: 0,0, FrozenBalance: 0,0, Existências: 1.021786026184, FrozenStocks: 0.0}

Em [16]:

nowSpotAcc = exchanges[1].GetAccount()      # Get the current spot exchange account information, recorded in the variable nowSpotAcc.
nowSpotAcc

Fora [1]: (Balanço: 9834.74705446, FrozenBalance: 0,0, Pesquisas: 0,0, FrozenStocks: 0.0}

Comparando a conta inicial com a conta corrente, é calculado o lucro e a perda da operação de cobertura.

Em [17]:

diffStocks = abs(nowQuarterAcc.Stocks - initQuarterAcc.Stocks)
diffBalance = nowSpotAcc.Balance - initSpotAcc.Balance
if nowQuarterAcc.Stocks - initQuarterAcc.Stocks > 0 :
    print("profits:", diffStocks * spotTicker2.Buy + diffBalance)
else :
    print("profits:", diffBalance - diffStocks * spotTicker2.Buy)

Fora [1]: Lucros: 18,72350977580652

Agora vamos ver por que a cobertura é rentável. Podemos ver o gráfico desenhado. O preço de futuros é uma linha azul e o preço spot é uma linha laranja. Ambos os preços estão diminuindo. O preço de futuros está diminuindo mais rápido que o preço spot.

Em [18]:

xQuarter = [1, 2]
yQuarter = [quarterTicker1.Buy, quarterTicker2.Sell]

xSpot = [1, 2]
ySpot = [spotTicker1.Sell, spotTicker2.Buy]
plt.plot(xQuarter, yQuarter, linewidth=5)
plt.plot(xSpot, ySpot, linewidth=5)
plt.show()

Fora [1]:

img

A diferença de preço varia de 284 no momento da posição de abertura de cobertura (isto é, futuros vão curto e spot vai longo) para 52 no momento da posição de fechamento (positivos futuros curtos fechados, posição longa fechada no local).

Em [19]:

xDiff = [1, 2]
yDiff = [quarterTicker1.Buy - spotTicker1.Sell, quarterTicker2.Sell - spotTicker2.Buy]
plt.plot(xDiff, yDiff, linewidth=5)
plt.show()

Fora [1]:

img

Por exemplo, a1 é o preço de futuros no momento 1, e b1 é o preço ao instante no momento 1. A2 é o preço de futuros no momento 2, e b2 é o preço ao instante no momento 2.Desde que a diferença de preço spot dos futuros no momento 1 (a1-b1) seja maior do que a diferença de preço spot dos futuros no momento 2 (a2-b2), pode ser introduzida a1 - a2>b1 - b2. Existem três situações: (a quantidade de posições futuras e de posições spot é a mesma)

  1. a1 - a2 é maior que 0, b1 - b2 é maior que 0 a1 - a2 refere-se à diferença de preço dos lucros futuros, e b1 - b2 refere-se à diferença de preço das perdas spot (porque o spot foi longo, o preço de começar a comprar é maior do que o preço de venda para fechar a posição, então o dinheiro é perdido), mas os lucros futuros são maiores do que as perdas spot. Então é lucrativo como um todo. Esta situação corresponde ao gráfico na etapa In [8].

  2. a1 - a2 é maior que 0, b1 - b2 é menor que 0 a1 - a2 é a diferença de preço dos lucros futuros, e b1 - b2 é a diferença de preço dos lucros spot (b1 - b2 é menor que 0, indicando que b2 é maior que b1, ou seja, o preço de abertura e compra da posição é baixo, e o preço de venda e fechamento é alto, por isso é rentável).

  3. a1 - a2 inferior a 0, b1 - b2 inferior a 0 a1 - a2 é a diferença de preço das perdas de futuros, e b1 - b2 é a diferença de preço dos lucros pontuais. Como a1 - a2 > b1 - b2, o valor absoluto de a1 - a2 é menor que o valor absoluto de b1 - b2, e os lucros pontuais são maiores do que as perdas de futuros. É lucrativo como um todo.

Não há caso em que a1 - a2 é menor que 0 e b1 - b2 é maior que 0, porque a1 - a2 > b1 - b2 foi definido. Da mesma forma, se a1 - a2 é igual a 0, uma vez que a1 - a2 > b1 - b2 é definido, b1 - b2 deve ser menor que 0. Portanto, desde que o método de cobertura de futuros curtos e spot longos atenda às condições a1 - b1 > a2 - b2, as operações de abertura e fechamento de posição são cobertura de lucro.

Por exemplo, o modelo seguinte é um dos casos:

Em [20]:

a1 = 10
b1 = 5
a2 = 11
b2 = 9

# a1 - b1 > a2 - b2 launches: a1 - a2 > b1 - b2

xA = [1, 2]
yA = [a1, a2]

xB = [1, 2]
yB = [b1, b2]
plt.plot(xA, yA, linewidth=5)
plt.plot(xB, yB, linewidth=5)
plt.show()

Fora [1]:

img

Ambiente de pesquisa Arquivo de linguagem JavaScript

O ambiente de pesquisa suporta não só Python, mas também JavaScript Eu também dou um exemplo de ambiente de pesquisa JavaScript:

Análise do princípio da cobertura spot de futuros (JavaScript).ipynb Em [1]:

// Import the required package, click "Save settings" on the FMZ's "Strategy editing page" to get the string configuration and convert it to an object.
var fmz = require("fmz")                           // Import the talib, TA, and plot libraries automatically after import
var task = fmz.VCtx({
start: '2019-09-19 00:00:00',
end: '2019-09-28 12:00:00',
period: '15m',
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD","stocks":1},{"eid":"OKX","currency":"BTC_USDT","balance":10000,"stocks":0}]
})

Em [2]:

exchanges[0].SetContractType("quarter")  // The first exchange object OKX Futures (eid: Futures_OKCoin) calls the function to set the current contract as a quarterly contract.
var initQuarterAcc = exchanges[0].GetAccount()  // The initial account information of OKX Futures Exchange is recorded in the variable initQuarterAcc.
initQuarterAcc

Fora[2]: { Saldo: 0, FrozenBalance: 0, Stocks: 1, FrozenStocks: 0 }

Em [3]:

var initSpotAcc = exchanges[1].GetAccount()     // The initial account information of the OKX Spot Exchange is recorded in the variable initSpotAcc.
initSpotAcc

Fora[3]: { Saldo: 10 000, FrozenBalance: 0, Stocks: 0, FrozenStocks: 0 }

Em [4]:

var quarterTicker1 = exchanges[0].GetTicker()   // Get the futures exchange ticker, recorded in the variable quarterTicker1.
quarterTicker1

Fora[4]: Hora: 1568851210000, Alto: 10441.25002, Baixo: 10441,25. Venda: 10441.25002, Compra: 10441.25, Último: 10441.25001, Volume: 1772, Interesse aberto: 0 }

Em [5]:

var spotTicker1 = exchanges[1].GetTicker()     // Get the spot exchange ticker, recorded in the variable spotTicker1.
spotTicker1

Fora[5]: Hora: 1568851210000, Alto: 10156.60000002, Baixo: 10156,6. Vender: 10156.60000002, Compra: 10156,6, Último: 10156.60000001, Volume: 7.4443, Interesse aberto: 0 }

Em [6]:

quarterTicker1.Buy - spotTicker1.Sell         // The price difference between going short on futures and going long on spot.

Fora[6]: 284,64999997999985 Em [7]:

exchanges[0].SetDirection("sell")             // Set up a futures exchange and trade in the direction of going short
var quarterId1 = exchanges[0].Sell(quarterTicker1.Buy, 10)  // Go short futures to place orders. The order quantity is 10 contracts. The returned order ID is recorded in the variable quarterId1.
exchanges[0].GetOrder(quarterId1)                           // Check the details of the order with futures order ID quarterId1.

Fora[7]: {Id: 1, Preço: 10441.25, Montante: 10 O valor do negócio: 10, Preço médio: 10441,25. Tipo: 1, Deslocamento: 0, Situação: Tipo de contrato: trimestre }

Em [8]:

var spotAmount = 10 * 100 / quarterTicker1.Buy                  // Calculate the currency equivalent of 10 contracts as the order quantity of the spot.
var spotId1 = exchanges[1].Buy(spotTicker1.Sell, spotAmount)    // Place orders on the spot exchange.
exchanges[1].GetOrder(spotId1)                                  // Check the order details of the spot order ID of spotId1.

Fora[8]: {Id: 1, Preço: 10156.60000002, Montante: 0,0957, O valor do acordo é de 0,0957. Preço médio: 10156.60000002, Tipo: 0, Deslocamento: 0, Situação: Tipo de contrato: BTC_USDT_OKX }

Como pode ver, as ordens quarterId1 e spotId1 estão totalmente preenchidas, ou seja, a cobertura das posições de abertura está concluída.

Em [9]:

Sleep(1000 * 60 * 60 * 24 * 7)            // Hold the position for a while and wait for the price difference to become smaller to close the position.

Após o tempo de espera, preparar para fechar a posição.quarterTicker2, spotTicker2e imprimi-los. A direção da transação do objeto de troca de futuros é definida para fechar a posição curta:exchanges[0].SetDirection("closesell")colocar uma ordem para fechar a posição. Imprimir os pormenores da ordem de encerramento da posição, indicando que a ordem de encerramento foi concluída, a posição de encerramento terminada.

Em [10]:

var quarterTicker2 = exchanges[0].GetTicker()    // Get the current futures exchange ticker, recorded in the variable quarterTicker2.
quarterTicker2

Fora[10]: Hora: 1569456010000, Alto: 8497.20002, Baixo: 8497.2, Venda: 8497.20002, Compra: 8497.2, Último: 8497.20001, Volume: 4311, Interesse aberto: 0 }

Em [11]:

var spotTicker2 = exchanges[1].GetTicker()       // Get the current ticker of the spot exchange, recorded in the variable spotTicker2.
spotTicker2

Fora[11]: (Hora: 1569456114600) Alto: 8444.70000001, Baixo: 8444.69999999, Venda: 8444.70000001, Compra: 8444.69999999, Último: 8444,7, Volume: 78.6273, Interesse aberto: 0 }

Em [12]:

quarterTicker2.Sell - spotTicker2.Buy            // The price difference between closing short position of futures and closing long position of spot.

Fora[12]: 52.5000200100003

Em [13]:

exchanges[0].SetDirection("closesell")           // Set the current trading direction of the futures exchange to close short positions.
var quarterId2 = exchanges[0].Buy(quarterTicker2.Sell, 10)       // The futures exchange places an order to close the position, and records the order ID to the variable quarterId2.
exchanges[0].GetOrder(quarterId2)                                // Check futures closing position order details.

Fora[13]: - O que é? Preço: 8497.20002, Montante: 10 O valor do negócio: 10, Preço médio: 8493,95335, Tipo: 0, Deslocamento: 1, Situação: Tipo de contrato: trimestre }

Em [14]:

var spotId2 = exchanges[1].Sell(spotTicker2.Buy, spotAmount)     // The spot exchange places an order to close the position, and records the order ID to the variable spotId2.
exchanges[1].GetOrder(spotId2)                                   // Check spot closing position order details.

Fora [1]: - O que é? Preço: 8444,69999999, Montante: 0,0957, O valor da transacção é de 0,0957. Preço médio: 8444,69999999, Tipo: 1, Deslocamento: 0, Situação: 1, Tipo de contrato: BTC_USDT_OKX }

Em [15]:

var nowQuarterAcc = exchanges[0].GetAccount()     // Get the current futures exchange account information, recorded in the variable nowQuarterAcc.
nowQuarterAcc                                     

Fora [1]: { Saldo: 0, FrigoríficoBalance: 0, Reservas: 1.021786026184, FrozenStocks:

Em [16]:

var nowSpotAcc = exchanges[1].GetAccount()        // Get the current spot exchange account information, recorded in the variable nowSpotAcc.
nowSpotAcc

Fora [1]: Saldo: 9834.74705446, FrigoríficoBalance: 0, Reservas: 0, FrozenStocks: Comparando a conta inicial com a conta corrente, é calculado o lucro e a perda da operação de cobertura.

Em [17]:

var diffStocks = Math.abs(nowQuarterAcc.Stocks - initQuarterAcc.Stocks)
var diffBalance = nowSpotAcc.Balance - initSpotAcc.Balance
if (nowQuarterAcc.Stocks - initQuarterAcc.Stocks > 0) {
    console.log("profits:", diffStocks * spotTicker2.Buy + diffBalance)
} else {
    console.log("profits:", diffBalance - diffStocks * spotTicker2.Buy)
}

Fora [1]: Lucros: 18,72350977580652

Agora vamos ver por que a cobertura é rentável. Podemos ver o gráfico desenhado. O preço de futuros é uma linha azul e o preço spot é uma linha laranja. Ambos os preços estão diminuindo. O preço de futuros está diminuindo mais rápido que o preço spot.

Em [18]:

var objQuarter = {
    "index" : [1, 2],                                          // The index is 1, that is, the first time, the opening time, and 2 is the closing time.
    "arrPrice" : [quarterTicker1.Buy, quarterTicker2.Sell],
}
var objSpot = {
    "index" : [1, 2],
    "arrPrice" : [spotTicker1.Sell, spotTicker2.Buy],
}
plot([{name: 'quarter', x: objQuarter.index, y: objQuarter.arrPrice}, {name: 'spot', x: objSpot.index, y: objSpot.arrPrice}])

Fora [1]: A diferença de preço varia de 284 no momento da cobertura de posições de abertura (ou seja, os futuros ficaram curtos e o local ficou longo) para 52 no momento do fechamento (fechamento de posição curta de futuros e fechamento de posição longa de local).

Em [19]:

var arrDiffPrice = [quarterTicker1.Buy - spotTicker1.Sell, quarterTicker2.Sell - spotTicker2.Buy]
plot(arrDiffPrice)

Fora [1]:Por exemplo, a1 é o preço de futuros no momento 1, e b1 é o preço ao instante no momento 1. A2 é o preço de futuros no momento 2, e b2 é o preço ao instante no momento 2.Desde que a diferença de preço spot dos futuros no momento 1 (a1-b1) seja maior do que a diferença de preço spot dos futuros no momento 2 (a2-b2), pode ser introduzida a1 - a2>b1 - b2. Existem três situações: (a quantidade de posições futuras e de posições spot é a mesma)

  1. a1 - a2 é maior que 0, b1 - b2 é maior que 0 a1 - a2 refere-se à diferença de preço dos lucros futuros, e b1 - b2 refere-se à diferença de preço das perdas spot (porque o spot foi longo, o preço de começar a comprar é maior do que o preço de venda para fechar a posição, então o dinheiro é perdido), mas os lucros futuros são maiores do que as perdas spot. Então é lucrativo como um todo. Esta situação corresponde ao gráfico na etapa In [8].

  2. a1 - a2 é maior que 0, b1 - b2 é menor que 0 a1 - a2 é a diferença de preço dos lucros futuros, e b1 - b2 é a diferença de preço dos lucros spot (b1 - b2 é menor que 0, indicando que b2 é maior que b1, ou seja, o preço de abertura e compra da posição é baixo, e o preço de venda e fechamento é alto, por isso é rentável).

  3. a1 - a2 inferior a 0, b1 - b2 inferior a 0 a1 - a2 é a diferença de preço das perdas de futuros, e b1 - b2 é a diferença de preço dos lucros pontuais. Como a1 - a2 > b1 - b2, o valor absoluto de a1 - a2 é menor que o valor absoluto de b1 - b2, e os lucros pontuais são maiores do que as perdas de futuros. É lucrativo como um todo.

Não há caso em que a1 - a2 é menor que 0 e b1 - b2 é maior que 0, porque a1 - a2 > b1 - b2 foi definido. Da mesma forma, se a1 - a2 é igual a 0, uma vez que a1 - a2 > b1 - b2 é definido, b1 - b2 deve ser menor que 0. Portanto, desde que o método de cobertura de futuros curtos e spot longos atenda às condições a1 - b1 > a2 - b2, as operações de abertura e fechamento de posição são cobertura de lucro.

Por exemplo, o modelo seguinte é um dos casos:

Em [20]:

var a1 = 10
var b1 = 5
var a2 = 11
var b2 = 9

// a1 - b1 > a2 - b2 launches: a1 - a2 > b1 - b2

var objA = {
    "index" : [1, 2],
    "arrPrice" : [a1, a2],
}
var objB = {
    "index" : [1, 2],
    "arrPrice" : [b1, b2],
}
plot([{name : "a", x : objA.index, y : objA.arrPrice}, {name : "b", x : objB.index, y : objB.arrPrice}])

Fora [1]:

Experimentem, rapazes!


Relacionados

Mais.