| Overall Statistics |
|
Total Trades 249 Average Win 0% Average Loss 0% Compounding Annual Return -26.394% Drawdown 11.400% Expectancy 0 Net Profit -7.821% Sharpe Ratio -3.017 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.207 Beta 0.003 Annual Standard Deviation 0.069 Annual Variance 0.005 Information Ratio -1.509 Tracking Error 0.186 Treynor Ratio -81.558 Total Fees $75.26 |
# Imports
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Jupyter")
AddReference("QuantConnect.Indicators")
from System import *
from QuantConnect import *
from QuantConnect.Data.Custom import *
from QuantConnect.Data.Market import QuoteBar
from QuantConnect.Jupyter import *
from QuantConnect.Indicators import *
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
import pandas as pd
# Create an instance
qb = QuantBook()
import numpy as np
from decimal import Decimal
class BasicTemplateAlgorithm(QCAlgorithm):
# Things to compare: Max order size of N. Have crypto assets to cover a little more than that N amount.
# No max order size specified, have crypto assets in equal amounts to USD
# Try both of these with scheduled events to ensure the accounts have necessary amounts to stabilize
def Initialize(self):
self._limitTicket = None
self._stopMarketTicket = None
self._stopLimitTicket = None
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
self.SetCash(1000)
#self.SetCash("BTC", 0.02)
#self.SetCash("ETH", 0.6)
self.SetStartDate(2018,11,17)
self.SetEndDate(2019,2,21)
self.BTCUSD = self.AddCrypto("BTCUSD", Resolution.Minute).Symbol
self.ETHBTC = self.AddCrypto("ETHBTC", Resolution.Minute).Symbol
self.ETHUSD = self.AddCrypto("ETHUSD", Resolution.Minute).Symbol
self.maxTrade = 100
def OnData(self, data):
# Get Open prices
if (data.QuoteBars.ContainsKey("BTCUSD") and data.QuoteBars.ContainsKey("ETHBTC") and data.QuoteBars.ContainsKey("ETHUSD")):
btcusdOpen = data["BTCUSD"].Open
ethbtcOpen = data["ETHBTC"].Open
ethusdOpen = data["ETHUSD"].Open
#self.Plot("BTCUSD", btcusdOpen)
# Get asksizes (DOUBLE CHECK: I think bid sizes are needed since we sell on ETHUSD)
# These could throw errors if data not available
cryptoQuoteBars = data.QuoteBars
btcusdAskSize = cryptoQuoteBars["BTCUSD"].LastAskSize
ethbtcAskSize = cryptoQuoteBars["ETHBTC"].LastAskSize
ethusdBidSize = cryptoQuoteBars["ETHUSD"].LastBidSize
#Convert each ask size to equivalent USDamount
USDbtcAskSize = btcusdAskSize*btcusdOpen
USDethbtcAskSize = ethbtcAskSize*ethusdOpen
USDethBidSize = ethusdBidSize*ethusdOpen
# Make List of USD equivalent ask and bid prices
askBidSizesD1 = [USDbtcAskSize,USDethbtcAskSize,USDethBidSize]
# Look for minimum value in List
minSizeD1 = min(askBidSizesD1)
# USD holdings
# Calculate the order size to execute to prevent slippage
# If the minimum ask/bid size is smaller than the amount of USD we have, use it
# If the minimum ask/Bid size is = or greater than the amount of USD held, use the amount held
usdTotalD1 = self.Portfolio.CashBook["USD"].Amount
# if(minSizeD1 < self.Portfolio.CashBook["USD"].Amount):
# usdTradeAmt = 0.8*minSizeD1
# else:
# usdTradeAmt = 0.8*self.Portfolio.CashBook["USD"].Amount
if(minSizeD1 < self.maxTrade):
usdTradeAmt = minSizeD1
else:
usdTradeAmt = self.maxTrade
#TriArb Logic
#convert USD to BTC -> use USD to buy BTC
usdTObtc = usdTradeAmt/btcusdOpen
#convert BTC to ETH - > use BTC to buy ETH
btcTOeth = usdTObtc/ethbtcOpen
#convert ETH to USD - > use ETH to sell for USD
ethTOusd = btcTOeth*ethusdOpen
if(usdTotalD1 > usdTradeAmt and usdTradeAmt == self.maxTrade):
if (((ethTOusd-usdTradeAmt)/usdTradeAmt)*100) > 0.9:
# self.Debug("Percent profit: {}".format(str((((ethTOusd-usdTotalD1)/usdTotalD1)*100)-0.9)))
# self.Debug("BTCUSD ask Size in USD: {}$".format(USDbtcAskSize))
# self.Debug("ETHBTC ask Size in USD: {}$".format(USDethbtcAskSize))
# self.Debug("ETHUSD bid Size in USD: {}$".format(USDethBidSize))
self.MarketOrder(self.BTCUSD, usdTObtc, True)
self.MarketOrder(self.ETHBTC, btcTOeth, True)
self.MarketOrder(self.ETHUSD, -btcTOeth, True)