H-Barrio

May 28, 20213 min

Operando con Criptomonedas y Euros usando Quantconnect y su motor Lean

De manera oficial Quantconnect no permite operar con criptomonedas usando cuentas de brókeres que no estén denominadas en dólares US (al menos todavía). El proceso que el motor utiliza para descubrir los precios relativos de los pares de monedas necesitan los dolares US (USD de toda la vida) como punto de inicio, así que si nuestra cuenta de broker está denominada en Euros (y en nada mas que Euros) el motor de operaciones en vivo no podrá resolver las posiciones del libro de cuentas (el cashbook).

Aun así es posible lanzar algoritmos de automáticos utilizando, como ejemplo, Coinbase y usando un par de trucos simples. Este ejemplo ejecuta una estrategia muy simple de "Moving Average Convergence-Divergence" utilizando el part Ethereum - Euro (ETHEUR):

import decimal as d
 
import numpy as np
 

 
class CryptoTechnical(QCAlgorithm):
 

 
def Initialize(self):
 

 
self.Debug('Initializing...')
 
self.SetStartDate(2020, 1, 1) # Set Start Date
 
self.SetEndDate(2020, 9, 1) # Set End Date
 
self.fiat = 'EUR'
 
self.crypto = 'ETH'
 
# Set Strategy Cash (USD)
 
self.SetCash(1)
 
# Set Strategy Cash (EUR)
 
self.SetCash(self.fiat, 6000, 1.1)
 
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
 
self.pair = self.crypto + self.fiat
 
self.symbol = self.AddCrypto(self.pair, Resolution.Minute, Market.GDAX).Symbol
 

 
#Symbol Data Dictionary:
 
self.symbol_data = {}
 

 
# Indicator Parameters
 
self.ind_params = (26, 12, 9)
 
#Create symbol data object for symbol
 
self.InitizalizeSymbolData(self.symbol, self.ind_params)
 
self.Debug('Initialized.')
 

 
def OnData(self, data):
 
for key, symbol_data in self.symbol_data.items():
 
symbol_data.ComputeStatus()
 
if self.Time.minute % 15 == 0 and self.LiveMode:
 
inspection = symbol_data.indicator.Signal.Current.Value
 
self.Debug('Indicator: '+str(inspection))
 
decision = 'Buy' if symbol_data.is_buy else 'Sell'
 
self.Debug('Decision:'+str(decision))
 

 
fiat_amount = self.Portfolio.CashBook[self.fiat].Amount
 
crypto_amount = self.Portfolio.CashBook[self.crypto].Amount
 

 
if symbol_data.is_buy == True and self.Portfolio.CashBook[self.fiat].Amount > 100 :
 
Price = data[key].Close
 
quantity = round((self.Portfolio.CashBook[self.fiat].Amount*0.99)/Price, 3)
 
if quantity > 0:
 
self.MarketOrder(key, quantity)
 

 
if symbol_data.is_sell == True and self.Portfolio.CashBook[self.crypto].Amount > 0.01 :
 
Price = data[key].Close
 
quantity = round(self.Portfolio.CashBook[self.crypto].Amount*0.99, 3)
 
self.MarketOrder(key, -quantity)
 

 

 
def InitizalizeSymbolData(self, symbol, parameters):
 
needed_period = max(parameters)+1
 
if symbol not in self.symbol_data:
 
self.symbol_data[symbol] = SymbolData(self, symbol, parameters)
 
history = self.History(symbol, needed_period, Resolution.Hour)
 
if not history.empty:
 
self.symbol_data[symbol].WarmUpIndicators(history)
 

 
class SymbolData(object):
 
def __init__(self, algorithm, symbol, parameters):
 
self.symbol = symbol
 
self.indicator = algorithm.MACD(symbol, *parameters, MovingAverageType.Simple, Resolution.Hour)
 
self.is_buy = False
 
self.is_sell = False
 

 
def WarmUpIndicators(self, history):
 
for index, row in history.loc[str(self.symbol)].iterrows():
 
self.indicator.Update(index, row["close"])
 

 
def ComputeStatus(self):
 
if self.indicator.Signal.Current.Value > self.indicator.Current.Value:
 
self.is_buy = True
 
self.is_sell = False
 
else:
 
self.is_sell = True
 
self.is_buy = False
 

Los números marcados en negrita indican las cantidades mínimas tanto de moneda fiduciaria (Euros) y criptomonedas (ETH) a mantener en todo momento. El algoritmo no hará operaciones con todas las monedas disponibles en un único momento ya que puede resultar en órdenes demasiado grandes que no podrán ser completadas. También hay que tener en cuenta el lote mínimo de cada broker, en este caso, y para Coinbase, aquí, que además es parte de los acuerdos legales a los que nos comprometemos al usar su servicio. Antes de lanzar el algoritmo, hay que asegurarse de que la cuenta contiene tanto Euros como Ethereum, si es necesario habrá que proceder a la compra de manera manual del mínimo lote posible de Ethereum para que el algoritmo pueda resolver el cambio de EUR a USD a través de ETHUSD.

Esta es la prueba retroactiva de esta estrategia MACD con ETHEUR, atención a las comisiones, las operaciones con criptomonedas tienen comisiones relativamente altas dependiendo de la capitalización de tu cuenta:

Por favor recuerde que las publicaciones en Ostirion.net no son consejos financieros. Ostirion.net no mantiene posiciones en ninguno de los instrumentos financieros que se mencionan en esta publicación en el momento de la publicación. Si necesita más información, apoyo con la gestión de activos financieros, desarrollo de estrategias de trading automatizados o despliegue táctico de estrategias existentes no dude en contactar con nosotros aquí.

    430
    0