| Overall Statistics |
|
Total Trades 227 Average Win 18.92% Average Loss -7.47% Compounding Annual Return 318.262% Drawdown 56.500% Expectancy 1.219 Net Profit 223775.100% Sharpe Ratio 3.46 Probabilistic Sharpe Ratio 98.567% Loss Rate 37% Win Rate 63% Profit-Loss Ratio 2.53 Alpha 2.423 Beta -0.087 Annual Standard Deviation 0.697 Annual Variance 0.486 Information Ratio 3.193 Tracking Error 0.717 Treynor Ratio -27.856 Total Fees $134619.42 Estimated Strategy Capacity $11000.00 Lowest Capacity Asset ETHUSD E3 |
class DualMomentum(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2016, 1, 1) # Set Start Date
#self.SetEndDate(2021, 2, 1) # Set Start Date
self.InitCash = 100000
self.SetCash(self.InitCash) # Set Strategy Cash
self.equities = ["BTCUSD", "ETHUSD"]
self.equityCombinedMomentum = {}
self.bonds = ["UBT"]
self.bondCombinedMomentum = {}
self.InitCash = 100000
self.MKT = self.AddCrypto("BTCUSD", Resolution.Daily, Market.Bitfinex).Symbol
self.bitcoin = []
for equity in self.equities:
self.AddCrypto(equity, Resolution.Hour, Market.Bitfinex)
self.Securities[equity].SetDataNormalizationMode(DataNormalizationMode.TotalReturn)
self.equityCombinedMomentum[equity] = CombinedMomentum(self, equity)
for bond in self.bonds:
self.AddEquity(bond, Resolution.Hour)
self.Securities[bond].SetDataNormalizationMode(DataNormalizationMode.TotalReturn)
self.bondCombinedMomentum[bond] = CombinedMomentum(self, bond)
self.leverage = 1
self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.At(15, 0), self.rebalance)
def shiftAssets(self, target, type):
if not (self.Portfolio[target].Invested):
for symbol in self.Portfolio.Keys:
self.Liquidate(symbol)
if not self.Portfolio.Invested:
if type == 0:
self.MarketOnCloseOrder(target, self.CalculateOrderQuantity(target, 1 * self.leverage))
else:
self.MarketOnCloseOrder(target, self.CalculateOrderQuantity(target, 1 * self.leverage))
def rebalance(self):
topEquities = sorted(self.equityCombinedMomentum.items(), key=lambda x: x[1].getValue(), reverse=True)
topBonds = sorted(self.bondCombinedMomentum.items(), key=lambda x: x[1].getValue(), reverse=True)
if (topEquities[0][1].getValue() > 0):
self.shiftAssets(topEquities[0][0], 0)
else:
self.shiftAssets(topBonds[0][0], 1)
# Plot Benchmark
hist = self.History(self.MKT, 2, Resolution.Daily)['close'].unstack(level= 0).dropna()
self.bitcoin.append(hist[self.MKT].iloc[-1])
bitcoin_perf = self.bitcoin[-1] / self.bitcoin[0] * self.InitCash
self.Plot('Strategy Equity', 'BTCUSD', bitcoin_perf)
def OnData(self, data):
pass
class CombinedMomentum():
def __init__(self, algo, symbol):
self.fst = algo.MOMP(symbol, 15, Resolution.Daily)
#self.med = algo.MOMP(symbol, 15, Resolution.Daily)
#self.slw = algo.MOMP(symbol, 20, Resolution.Daily)
#self.lng = algo.MOMP(symbol, 40, Resolution.Daily)
def getValue(self):
value = (self.fst.Current.Value)
return value