Pesquisa avançada de plataformas
O FMZ possui um notebook jupyter incorporado para ajudar os usuários a se familiarizarem com a API da plataforma e conduzir pesquisas de estratégia, e suporta os ambientes de aprendizagem de Python3 C++11/17 e Javascript. Notebook+Python é uma ferramenta muito poderosa, que é quase indispensável para análise de dados e pesquisa de estratégia. Embora o backtest que vem com a plataforma FMZ seja muito útil, ele não é adequado para estratégias com volumes de dados complexos e grandes.
O ambiente de pesquisa dentro do FMZ pode ser usado, mas a rede é inconveniente. Recomenda-se instalar no seu próprio dispositivo o anaconda3, com notebook e bibliotecas relacionadas com o uso comum para cálculos matemáticos; ele pode compartilhar o ambiente da rede local e ter melhor desempenho. Também é recomendável usar o Google colab. Embora haja algumas limitações de armazenamento, é gratuito e poderoso, adequado para a pesquisa relacionada ao estudo de robôs.
Há muitos tutoriais on-line para habilidades específicas de uso de notebook e Python. Você pode encontrar muitas informações pesquisando palavras-chave, como quantificação de Python e tutorial de notebook jupyter. Você precisa aprender e dominar uma série de conceitos básicos, como rastreador, processamento de dados, backtest, design de estratégia e plot.
As plataformas geralmente fornecem APIs para obter K-lines com dados de histórico, e alguns também fornecem dados de execução de comércio por comércio.
Em seguida, vamos demonstrar como obter e armazenar os dados da linha K de contratos perpétuos no Binance.
Primeiro, encontre a documentação do Binance Perpetual Swap:https://binance-docs.github.io/apidocs/futures/cn/#c59e471e81. Você pode ver os parâmetros necessários e os formatos de dados retornados. Normalmente, o número de K-lines adquiridas pela API é limitado, e o Binance tem um máximo de 1000, por isso precisa ser adquirido por iteração de loop. A situação em outras plataformas é semelhante à do Binance.
Os períodos suportados pelo Binance: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M.
Em [24]:
solicitações de importação # solicitações de rede para a biblioteca comum
a partir da data-hora data de importação, data-hora
Tempo de importação
importar pandas como pd
Em [160]:
def GetKlines ((símbolo=
O armazenamento e leitura de dados pode usar as funções dentro da biblioteca panda.
Além do preço mais alto, o preço mais baixo, o preço de abertura, o preço de fechamento e o volume executado, os dados da linha K devolvidos pela Binance também incluem o valor total das negociações, o valor da iniciativa de compra, o valor da execução, etc. Estas são informações valiosas que podem ser usadas para construir estratégias.
Em [86]:
Df.to_csv ((
- Não.
Em [88]:
df.index = pd.to_datetime ((df.time,unit=
O artigo anterior também deu o mecanismo de backtest Python, mas aqui está uma versão otimizada. Contratos perpétuos com margem USDT (ou outra moeda de cotação com margem) são muito semelhantes aos contratos spot. A diferença é que os contratos perpétuos podem ser alavancados e manter quantidade negativa (equivalente a fazer curto), e podem compartilhar um mecanismo de backtest. Contratos de entrega cripto-marginados são especiais, pois são liquidados em moeda e exigem backtest específico.
Aqui é dado um exemplo simples, que pode implementar spot multi-símbolo ou backtesting perpétuo multi-símbolo. Muitos detalhes são ignorados: como alavancagem de futuros, ocupação de margem, taxa de financiamento, mecanismo de liquidação, criação de mercado e transações de tomadores de ordens, bem como manutenção de ordens, mas geralmente não afeta os resultados normais do backtest. E o preço e a quantidade da correspondência e a atualização da conta precisam ser importados externamente. Os leitores podem melhorá-lo nesta base.
Introdução à classe de intercâmbio:
conta:USDT indica a moeda de base, que não é necessária; realized_profit: os lucros e perdas já realizados; unrealised_profit: os lucros e perdas ainda não realizados; total: o património total; taxa: a taxa de manipulação.
trade_symbols: matriz de pares de negociação; você também pode passar em um par de negociação; a moeda de cotação padrão é USDT, mas você também pode usar outros símbolos de moeda de cotação para backtest.
Taxa: a taxa de entrega; para simplificar, não se faz distinção entre quem faz e quem recebe.
inicial_saldo: os activos iniciais; o montante inicial dos pares de negociação por defeito é 0.
Função de compra: comprar, o que corresponde a fazer compras e fechar contratos perpétuos, sem um mecanismo de correspondência.
Função de venda: vender.
Função de atualização: atualizar as informações da conta, que devem ser inseridas no dicionário de preços de todos os pares de negociação. Em [98]: classe Intercâmbio:
def Iniciar(self, trade_symbols, fee=0.0004, initial_balance=10000):
self.initial_balance = inicial_balance #balance inicial
auto.fee = taxa
self.trade_symbols = trade_symbols
O montante total do saldo inicial é calculado em função da taxa de câmbio.
para símbolo em trade_symbols:
Self.account[simbolo] = {
def Comércio (próprio, símbolo, direcção, preço, montante):
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.fee #take out the fee
self.account['USDT']['fee'] += price*amount*self.fee
self.account[symbol]['fee'] += price*amount*self.fee
if cover_amount > 0: #close first
self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount #profit
self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
self.account[symbol]['amount'] -= -direction*cover_amount
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[symbol]['hold_price'] = total_cost/total_amount
self.account[symbol]['amount'] += direction*open_amount
def Comprar ((self, símbolo, preço, montante):self.Trade(símbolo 1, preço, montante)
def Vender ((self, símbolo, preço, montante):self.Trade(símbolo -1, preço, montante)
def Atualização ((self, close_price): #actualizar os ativos
conta própria[
Em primeiro lugar, vamos fazer um backtest de uma estratégia de rede perpétua clássica. Esta estratégia é muito popular na nossa plataforma recentemente. Em comparação com a rede spot, não precisa manter moeda e pode adicionar alavancagem, o que é muito mais conveniente do que a rede spot. No entanto, como não pode ser diretamente testado, não é propício para selecionar símbolos de moeda. Aqui usamos o mecanismo de backtest agora para testá-lo.
No topo do
Quanto mais curto o período da linha K, mais precisos são os resultados correspondentes do backtest e maior a quantidade de dados necessários.
Em [241]:
símbolo =
e = Exchange (([símbolo], taxa=0.0002, inicial_saldo=10000)
init_price = df.loc[0,
if kline.low < buy_price: #the lowest price of K-line is less than the current maker price; the buy order is executed
e.Buy(symbol,buy_price,value/buy_price)
if kline.high > sell_price:
e.Sell(symbol,sell_price,value/sell_price)
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount'], e.account['USDT']['total']-e.initial_balance])
res = pd.DataFrame ((data=res_list, colunas=[
Este tipo de estratégia também é relativamente popular, mas a plataforma FMZ não é muito boa no backtesting de estratégias de múltiplos símbolos, basta usar este mecanismo de backtest para experimentar.
Primeiro, obtenha os preços de fechamento dos quatro símbolos no ano passado. Pode-se ver que o ETH tem o maior aumento, e os outros três têm aumentos semelhantes. Se você manter esses quatro símbolos em média, o valor líquido final é de 4,5.
Em [290]:
símbolos = [
A estratégia da tartaruga é uma estratégia de tendência clássica, que inclui uma lógica completa de stop-loss para adicionar posições.https://zhuanlan.zhihu.com/p/27987938Vamos implementar uma versão simples aqui para backtest.
O período da estratégia de tartaruga tem uma grande influência na estratégia, e não é aconselhável escolher um período que seja muito curto. Aqui, escolhemos 6h. O período do canal de Donchian é selecionado como 5, e a relação de posição é selecionada como 0,003 de acordo com o backtest. Quando o preço atravessa a upBand do canal para abrir 1 unidade de posição longa, e o preço continua a aumentar em volatilidade de 0,3 após a abertura das posições, continue a adicionar 1 unidade, e o preço cai abaixo de 2,5 Volatilidade do último preço aberto para parar a perda. O princípio da ordem curta é o mesmo. Devido ao grande mercado de alta do ETH, a estratégia de tartaruga capturou a tendência principal e finalmente alcançou 27 vezes os lucros, com uma alavancagem máxima de 4 vezes durante o período.
Os parâmetros da estratégia da tartaruga estão estreitamente relacionados com o período e devem ser selecionados através de backtest.
Pode-se ver a partir do gráfico final do valor líquido que a estratégia de tartaruga é uma estratégia de longo prazo, durante a qual pode não haver lucro por 3 a 4 meses, e perdas de parada repetidas, mas uma vez que há uma grande cotação de mercado de um lado, a estratégia de tartaruga pode aproveitar a tendência para acumular uma grande posição, mantê-la até o final da tendência, ganhar muitos lucros. No final do aumento, a estratégia vai acumular muitas posições. Neste momento, a volatilidade será relativamente grande, e muitas vezes grandes lucros serão retirados. Usar a estratégia de tartaruga requer que você aceite suas deficiências e sua paciência.
Em [424]:
símbolo =
if kline.high > kline.up and e.account[symbol]['amount'] == 0: #first time to open long position
e.Buy(symbol,kline.up,unit) #notice the trading price here
last_price = kline.up
if e.account[symbol]['amount'] > 0 and kline.high > last_price + open_times*kline.N: #long position, buy in
e.Buy(symbol,last_price + open_times*kline.N,unit)
last_price = last_price + open_times*kline.N
if e.account[symbol]['amount'] > 0 and kline.low < last_price - stop_times*kline.N: #long position, stop loss
e.Sell(symbol,last_price - stop_times*kline.N,e.account[symbol]['amount'])
if kline.low < kline.down and e.account[symbol]['amount'] == 0: #open short
e.Sell(symbol,kline.down,unit)
last_price = kline.down
if e.account[symbol]['amount'] < 0 and kline.low < last_price - open_times*kline.N: #short position, buy in
e.Sell(symbol,last_price - open_times*kline.N,unit)
last_price = last_price - open_times*kline.N
if e.account[symbol]['amount'] < 0 and kline.high > last_price + stop_times*kline.N: #short position, stop loss
e.Buy(symbol,last_price + stop_times*kline.N,-e.account[symbol]['amount'])
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount']*kline.close, e.account['USDT']['total']])
res = pd.DataFrame ((data=res_list, colunas=[
Se você é proficiente no uso da plataforma de pesquisa do notebook jupyter, pode facilmente realizar operações, como aquisição de dados, análise de dados, backtest de estratégia, exibição de gráficos, etc., o que é o caminho inevitável para a negociação quantitativa.
Use o Python para realizar análise de dados:https://wizardforcel.gitbooks.io/pyda-2e/content/
Tutorial Quantitativo Python:https://wizardforcel.gitbooks.io/python-quant-uqer/content/
Em [ ]: