Pesquisa sobre Binance Futures Multi-currency Hedging Strategy Parte 1

Autora:Bem-estar, Criado: 2020-05-09 11:14:50, Atualizado: 2023-11-04 19:49:01

img

Pesquisa sobre Binance Futures Multi-currency Hedging Strategy Parte 1

Clique no botão de pesquisa na página do painel e, em seguida, clique na seta para entrar. Abra o arquivo de sufixo.pynb carregado e pressione shift + enter para executar linha por linha. Há tutoriais básicos na ajuda de uso do ambiente de pesquisa.

img

Razões estratégicas

A Binance listou muitas altcoins no local. Embora as flutuações de curto prazo sejam incertas, se você olhar para a linha diária por um longo tempo, você verá que elas caíram basicamente em mais de 90%, e algumas até têm apenas frações da fração de preço mais alta. No entanto, não há um método universal de venda em curto para o local, e não há nenhuma recomendação especial exceto não tocar na altcoin. Nos últimos dois meses, a Binance Futures lançou mais de 20 contratos perpétuos, a maioria dos quais são moedas convencionais, e alguns são desconhecidos. Isso nos dá os meios para curtir essas combinações de altcoins. Usando o coeficiente de correlação entre altcoins e BTC será um método de análise eficaz, duas estratégias podem ser projetadas.

Princípios da estratégia

A primeira estratégia: vender curto a cesta selecionada de altcoins em um equivalente descentralizado, e ao mesmo tempo comprar longo a mesma quantidade de posição BTC para cobrir, a fim de reduzir riscos e volatilidade.

A segunda estratégia: curto de moedas com um preço superior ao índice de preço altcoin-bitcoin, e saudade com moedas inferiores ao índice, quanto maior o desvio, maior a posição.

# Libraries to import
import pandas as pd
import requests
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
%matplotlib inline

Escreva a moeda necessária

O contrato perpétuo da Binance atualmente lista moedas, que podem ser obtidas usando sua interface API, são um número total de 23 (excluindo BTC).

#Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
#symbols = [symbol_info['baseAsset'] for symbol_info in Info.json()['symbols']]
symbols = ['ETH', 'BCH', 'XRP', 'EOS', 'LTC', 'TRX', 'ETC', 'LINK', 'XLM', 'ADA', 'XMR', 'DASH', 'ZEC', 'XTZ', 'BNB', 'ATOM', 'ONT', 'IOTA', 'BAT', 'VET', 'NEO', 'QTUM', 'IOST']

Primeiro, vamos estudar o movimento de preços de altcoins para Bitcoin no ano passado. Eu baixei os dados antecipadamente e os postei no fórum, que podem ser citados diretamente no ambiente de pesquisa.

price_btc = pd.read_csv('https://www.fmz.com/upload/asset/1ef1af8ec28a75a2dcb.csv', index_col = 0)
price_btc.index = pd.to_datetime(price_btc.index,unit='ms') #Index date
price_btc.tail()

Resultados:

img img

5 linhas × 23 colunas

Em primeiro lugar, desenhar os preços dessas moedas para ver a tendência, os dados devem ser normalizados.

price_btc_norm = price_btc/price_btc.fillna(method='bfill').iloc[0,]
price_btc_norm.plot(figsize=(16,6),grid = True,legend=False);

img

Ao ordenar as últimas mudanças de preço, você pode encontrar várias moedas que são obviamente diferentes, a saber, LINK, XTZ, BCH, ETH. Explique que muitas vezes eles podem executar sua própria tendência e que colocá-los em curto tem um risco maior e precisa ser excluído da estratégia.

Desenhe um mapa térmico do coeficiente de correlação das moedas restantes e descubra que a tendência do ETC e do ATOM também é relativamente especial e pode ser excluída.

price_btc_norm.iloc[-1,].sort_values()[-5:]

Resultados:

ETH     0.600417
ETC     0.661616
BCH     1.141961
XTZ     2.512195
LINK    2.764495
Name: 2020-03-25 00:00:00, dtype: float64
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
plt.subplots(figsize=(12, 12)) # Set the screen size
sns.heatmap(price_btc[trade_symbols].corr(), annot=True, vmax=1, square=True, cmap="Blues");

img

A última moeda remanescente caiu em uma média de 66% ao ano, obviamente há amplo espaço para curto. Sintetizando a tendência dessas moedas no índice de preço altcoin, descobriu-se que basicamente caiu todo o caminho, foi mais estável no segundo semestre do ano passado e começou a cair todo o caminho este ano.

Deve-se notar que o índice de altcoin atual está no ponto mais baixo do ano passado. Talvez não seja uma oportunidade curta, mas sim uma oportunidade longa de compra. você tem que decidir por si mesmo.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # You can set the remaining currencies, which you want to subtract.
1-price_btc_norm[trade_symbols].iloc[-1,].mean()

Resultados:

0.6714306758250285
price_btc_norm[trade_symbols].mean(axis=1).plot(figsize=(16,6),grid = True,legend=False);

img

Dados de Sustentabilidade da Binance

Da mesma forma, os dados sobre a Sustentabilidade da Binance foram coletados, você também pode citá-los diretamente em seu caderno, os dados são a linha K do mercado de 1h de 28 de janeiro a 31 de março de 2020, porque a maioria dos contratos perpétuos da Binance foram lançados apenas dois meses, então os dados são suficientes para backtest.

price_usdt = pd.read_csv('https://www.fmz.com/upload/asset/20227de6c1d10cb9dd1.csv ', index_col = 0)
price_usdt.index = pd.to_datetime(price_usdt.index)
price_usdt.tail()

Resultados:

img img

Em primeiro lugar, olhe para a tendência geral com dados normalizados. Na queda de março, em relação ao preço no início de fevereiro, o preço foi geralmente cortado, mostrando que o risco de contrato perpétuo também é muito alto. Esta onda de declínio também é um grande desafio para a estratégia.

price_usdt_norm = price_usdt/price_usdt.fillna(method='bfill').iloc[0,]
price_usdt_norm.plot(figsize=(16,6),grid = True,legend=False);

img

Desenhe o preço do índice da moeda que queremos vender contra o Bitcoin, o princípio estratégico é curto esta curva, e o retorno é basicamente o inverso desta curva.

price_usdt_btc = price_usdt.divide(price_usdt['BTC'],axis=0)
price_usdt_btc_norm = price_usdt_btc/price_usdt_btc.fillna(method='bfill').iloc[0,]
price_usdt_btc_norm[trade_symbols].mean(axis=1).plot(figsize=(16,6),grid = True);
#price_usdt_btc_norm.mean(axis=1).plot(figsize=(16,6),grid = True,legend=False);

img

Motor de ensaio posterior

Como o backtest local FMZ não tem dados para todas as moedas e não suporta backtest multi-moeda, é necessário reimplementar um motor de backtest. Então eu escrevi um novo motor de backtest, é relativamente simples, mas basicamente suficiente. Levando em conta a taxa de transação, mas basicamente ignorou a taxa de capital, não considerou a situação de manutenção do capital de margem. O total de capital, margem ocupada e alavancagem foram registrados. Uma vez que esta estratégia tem o atributo de que a posição longa é igual a posição curta, então o impacto das taxas de capital não é significativo.

O backtest não leva em conta a situação de deslizamento de preço, você pode aumentar a simulação de taxa de transação por conta própria, considerando a baixa taxa de transação do criador do Binance, mesmo a diferença de diferença de preço no mercado de moeda impopular é muito pequena, você pode usar o método de comissão iceberg no mercado real ao fazer um pedido, o impacto não deve ser significativo.

Quando você cria um objeto de troca, você precisa especificar a moeda a ser negociada. Comprar é longo e vender é curto. Devido à limitação do contrato perpétuo, ao abrir a posição, as posições longas e curtas são automaticamente fechadas juntas. Quando vender a posição curta e o número de moedas são negativos. Os parâmetros são os seguintes:

  • trade_symbols: lista de moedas a negociar
  • alavancagem: alavancagem, margem de incidência,
  • Comissão: taxa de transacção, por defeito 0,00005
  • inicial_saldo: activo inicial, avaliação em USDT
  • log: imprimir registos de transacções
class Exchange:
    
    def __init__(self, trade_symbols, leverage=20, commission=0.00005,  initial_balance=10000, log=False):
        self.initial_balance = initial_balance # Initial asset
        self.commission = commission
        self.leverage = leverage
        self.trade_symbols = trade_symbols
        self.date = ''
        self.log = log
        self.df = pd.DataFrame(columns=['margin','total','leverage','realised_profit','unrealised_profit'])
        self.account = {'USDT':{'realised_profit':0, 'margin':0, 'unrealised_profit':0, 'total':initial_balance, 'leverage':0}}
        for symbol in trade_symbols:
            self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0, 'margin':0, 'unrealised_profit':0}
            
    def Trade(self, symbol, direction, price, amount, msg=''):
        if self.date and self.log:
            print('%-20s%-5s%-5s%-10.8s%-8.6s %s'%(str(self.date), symbol, 'buy' if direction == 1 else 'sell', price, amount, msg))
            
        cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
        open_amount = amount - cover_amount
        
        self.account['USDT']['realised_profit'] -= price*amount*self.commission # Minus transaction fee
        
        if cover_amount > 0: # close position first
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  # profit
            self.account['USDT']['margin'] -= cover_amount*self.account[symbol]['hold_price']/self.leverage # Free the margin
            
            self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
            self.account[symbol]['amount'] -= -direction*cover_amount
            self.account[symbol]['margin'] -=  cover_amount*self.account[symbol]['hold_price']/self.leverage
            self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
            
        if open_amount > 0:
            total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
            total_amount = direction*self.account[symbol]['amount']+open_amount
            
            self.account['USDT']['margin'] +=  open_amount*price/self.leverage            
            self.account[symbol]['hold_price'] = total_cost/total_amount
            self.account[symbol]['amount'] += direction*open_amount
            self.account[symbol]['margin'] +=  open_amount*price/self.leverage
            
        self.account[symbol]['unrealised_profit'] = (price - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
        self.account[symbol]['price'] = price
        self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*price
        
        return True
    
    def Buy(self, symbol, price, amount, msg=''):
        self.Trade(symbol, 1, price, amount, msg)
        
    def Sell(self, symbol, price, amount, msg=''):
        self.Trade(symbol, -1, price, amount, msg)
        
    def Update(self, date, close_price): # Update assets
        self.date = date
        self.close = close_price
        self.account['USDT']['unrealised_profit'] = 0
        for symbol in self.trade_symbols:
            if np.isnan(close_price[symbol]):
                continue
            self.account[symbol]['unrealised_profit'] = (close_price[symbol] - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
            self.account[symbol]['price'] = close_price[symbol]
            self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*close_price[symbol]
            self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit']
            if self.date.hour in [0,8,16]:
                pass
                self.account['USDT']['realised_profit'] += -self.account[symbol]['amount']*close_price[symbol]*0.01/100
        
        self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6)
        self.account['USDT']['leverage'] = round(self.account['USDT']['margin']/self.account['USDT']['total'],4)*self.leverage
        self.df.loc[self.date] = [self.account['USDT']['margin'],self.account['USDT']['total'],self.account['USDT']['leverage'],self.account['USDT']['realised_profit'],self.account['USDT']['unrealised_profit']]
# First test the backtest engine
e = Exchange(['BTC','XRP'],initial_balance=10000,commission=0,log=True)

e.Buy('BTC',100, 5)
e.Sell('XRP',10, 50)

e.Sell('BTC',105,e.account['BTC']['amount'])
e.Buy('XRP',9,-e.account['XRP']['amount'])

round(e.account['USDT']['realised_profit'],4)
75.0

O primeiro código de estratégia

Estratégia lógica:

  • Verifique o preço da moeda, se não for nan, você pode negociar
  • Verifique o valor do contrato altcoin. Se for menor que o valor alvo trade_value, a diferença correspondente será vendida a descoberto, e se for maior, o valor correspondente será comprado para fechar a posição.
  • Adicione o valor curto de todas as altcoins e ajuste a posição do BTC para se proteger contra ele.

A posição short trade_value determina o tamanho da posição.

# Need to hedge with BTC
trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # Remaining currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 2000
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        if e.account[symbol]['value'] - trade_value  < -20 :
            e.Sell(symbol, price, round((trade_value-e.account[symbol]['value'])/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if e.account[symbol]['value'] - trade_value > 20 :
            e.Buy(symbol, price, round((e.account[symbol]['value']-trade_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        empty_value += e.account[symbol]['value']
    price = row[1]['BTC']
    if e.account['BTC']['value'] - empty_value < -20:
        e.Buy('BTC', price, round((empty_value-e.account['BTC']['value'])/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if e.account['BTC']['value'] - empty_value > 20:
        e.Sell('BTC', price, round((e.account['BTC']['value']-empty_value)/price,6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_1 = e

O lucro final de cada moeda é o seguinte:

pd.DataFrame(stragey_1.account).T.apply(lambda x:round(x,3))

img

Os dois gráficos abaixo são a curva de património líquido e a alavancagem utilizada.

O amarelo na curva de patrimônio líquido é o efeito da alavancagem de 1x em curto o índice altcoin. Pode-se ver que a estratégia basicamente amplifica a flutuação do índice, o que está de acordo com as expectativas. O retorno final de dois meses é de 60%, o retracement máximo é de 20%, e a alavancagem máxima é de cerca de 8 vezes. Na maioria das vezes, é menos de 6 vezes. Ainda é seguro. O mais importante, a cobertura completa fez com que a estratégia perca pouco na queda de 12 de março.

Quando o preço da moeda de venda a descoberto sobe e o valor do contrato aumenta, a posição é reduzida, por outro lado, quando se obtém lucro, a posição é aumentada.

Mas os riscos também foram mencionados anteriormente, altcoins são muito propensos a executar sua própria tendência, e pode subir muito a partir do fundo. Isso depende de como você usá-lo. Se você é otimista sobre o altcoin e acha que ele atingiu o fundo, você pode operar na direção e comprar longo este índice. Ou se você é otimista sobre certas moedas, você pode hedge com eles.

(stragey_1.df['total']/stragey_1.initial_balance).plot(figsize=(18,6),grid = True); # Net worth curve
#(2-price_usdt_btc_norm[trade_symbols].mean(axis=1)).plot(figsize=(18,6),grid = True);

img

# Strategy leverage
stragey_1.df['leverage'].plot(figsize=(18,6),grid = True);

img

Além disso, uma vez que o preço da altcoin contra o USDT também caiu, o plano extremo não é hedged, vendendo diretamente curto, mas a flutuação é muito grande e o retração é alta

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH', 'ETC','ATOM','BNB','EOS','LTC'])) # Remaining currencies
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 2000
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        if e.account[symbol]['value'] - trade_value  < -20 :
            e.Sell(symbol, price, round((trade_value-e.account[symbol]['value'])/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if e.account[symbol]['value'] - trade_value > 20 :
            pass
            #e.Buy(symbol, price, round((e.account[symbol]['value']-trade_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        empty_value += e.account[symbol]['value']
stragey_1b = e
(stragey_1b.df['total']/stragey_1.initial_balance).plot(figsize=(18,6),grid = True); # Net worth curve
(2-price_usdt_btc_norm[trade_symbols].mean(axis=1)).plot(figsize=(18,6),grid = True);

img

O segundo código de estratégia

Estratégia lógica:

  • Verifique se há um preço ou se há um preço para negociar
  • Verificar o desvio do preço da moeda do índice
  • Ir longo e curto com base no julgamento de desvio, e julgar a posição de acordo com o tamanho do desvio
  • Calcular posições não cobertas e cobrir com BTC

Trade_value também controla o tamanho das posições abertas.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,0)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 50:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -50:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    price = row[1]['BTC']
    aim_value = -empty_value
    now_value = e.account['BTC']['value']*np.sign(e.account['BTC']['amount'])
    if aim_value - now_value > 50:
        e.Buy('BTC', price, round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if aim_value - now_value < -50:
        e.Sell('BTC', price, -round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_2 = e

O retorno da segunda estratégia é muito melhor do que a primeira estratégia. Nos últimos dois meses, ele tem um retorno de 100%, mas ainda tem uma retração de 20%. Na semana passada, devido às pequenas flutuações do mercado, o retorno não é óbvio. A alavancagem geral não é grande. Essa estratégia vale a pena tentar. Dependendo do grau de desvio, mais de 7800 posições USDT foram abertas no máximo.

Observe que se uma moeda executar uma tendência independente, por exemplo, ela aumentou várias vezes em relação ao índice, ela acumulará um grande número de posições curtas na moeda, e o mesmo declínio acentuado também fará com que a estratégia de compra seja longa, o que pode limitar a posição máxima de abertura.

(stragey_2.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);

img

# Summary results by currency
pd.DataFrame(e.account).T.apply(lambda x:round(x,3))

img

e.df['leverage'].plot(figsize=(18,6),grid = True);

img

Se o resultado de não cobrir é o seguinte, a diferença não é realmente muito porque posições longas e curtas são basicamente equilibradas.

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) # Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2b = e
(stragey_2b.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);
#(stragey_2.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True); # Can be stacked together

img

Se você se referir à regressão do preço do USDT, o efeito será muito pior

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH']))+['BTC'] #Remaining currencies
price_usdt_norm_mean = price_usdt_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols,initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols+['BTC']:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_norm.loc[row[0],symbol] - price_usdt_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
stragey_2c = e
(stragey_2c.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);
(stragey_2b.df['total']/stragey_2.initial_balance).plot(figsize=(18,6),grid = True);

img

Se você limitar o valor de posição máxima, o desempenho será pior

trade_symbols = list(set(symbols)-set(['LINK','XTZ','BCH', 'ETH'])) #Remaining currencies
price_usdt_btc_norm_mean = price_usdt_btc_norm[trade_symbols].mean(axis=1)
e = Exchange(trade_symbols+['BTC'],initial_balance=10000,commission=0.0005,log=False)
trade_value = 300
for row in price_usdt.iloc[:].iterrows():
    e.Update(row[0], row[1])
    empty_value = 0
    for symbol in trade_symbols:
        price = row[1][symbol]
        if np.isnan(price):
            continue
        diff = price_usdt_btc_norm.loc[row[0],symbol] - price_usdt_btc_norm_mean[row[0]]
        aim_value = -trade_value*round(diff/0.01,1)
        now_value = e.account[symbol]['value']*np.sign(e.account[symbol]['amount'])
        empty_value += now_value
        if aim_value - now_value > 20 and abs(aim_value)<3000:
            e.Buy(symbol, price, round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
        if aim_value - now_value < -20 and abs(aim_value)<3000:
            e.Sell(symbol, price, -round((aim_value - now_value)/price, 6),round(e.account[symbol]['realised_profit']+e.account[symbol]['unrealised_profit'],2))
    price = row[1]['BTC']
    aim_value = -empty_value
    now_value = e.account['BTC']['value']*np.sign(e.account['BTC']['amount'])
    if aim_value - now_value > 20:
        e.Buy('BTC', price, round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
    if aim_value - now_value < -20:
        e.Sell('BTC', price, -round((aim_value - now_value)/price, 6),round(e.account['BTC']['realised_profit']+e.account['BTC']['unrealised_profit'],2))
stragey_2d = e
(stragey_2d.df['total']/stragey_2.initial_balance).plot(figsize=(17,6),grid = True);

img

Resumo e risco

A primeira estratégia aproveita o fato de que o valor geral das altcoins não é tão bom quanto o bitcoin. Se você comprar bitcoins longos, você pode querer manter essa estratégia por um longo tempo. Devido à equivalência de posições longas e curtas, você basicamente não tem medo da taxa de financiamento de 8h. No longo prazo, a taxa de ganho é relativamente alta. Mas também me preocupo que a altcoin esteja atualmente no fundo, e possa ficar fora de uma tendência ascendente e causar uma perda desta estratégia.

A segunda estratégia usa a característica de regressão de preço do altcoin, que sobe mais do que o índice e tem uma alta probabilidade de cair. No entanto, pode acumular muitas posições em uma única moeda. Se uma determinada moeda realmente não cair, causará uma grande perda.

Devido aos diferentes tempos de início da estratégia e aos parâmetros específicos, o impacto das pessoas que utilizam esta estratégia durante um longo período não deverá ser grande.

Em suma, não existe uma estratégia perfeita, apenas uma atitude correta para com a estratégia, que depende, em última instância, da compreensão dos riscos e do julgamento do futuro pelo utilizador.


Relacionados

Mais.