| Overall Statistics |
|
Total Trades 69 Average Win 0% Average Loss -0.78% Compounding Annual Return 68.639% Drawdown 23.500% Expectancy -1 Net Profit 76.545% Sharpe Ratio 1.241 Probabilistic Sharpe Ratio 30.599% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha 1.296 Beta 0.004 Annual Standard Deviation 1.043 Annual Variance 1.089 Information Ratio 1.28 Tracking Error 1.089 Treynor Ratio 343.66 Total Fees $23320.57 Estimated Strategy Capacity $15000.00 Lowest Capacity Asset BTCUSD XJ |
#region imports
from AlgorithmImports import *
#endregion
# EMA Cross over strategy 9-13-21-55
# -------------------------------------------------------------------
CRYPTO = "BTCUSD"; EMA_C1 = 9; EMA_C2 = 13; EMA_F = 21; EMA_S = 55;
# -------------------------------------------------------------------
class MovingAverageCrossAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 1, 1)
self.SetEndDate(2022, 2, 1)
self.SetCash("USDT", 100000)
self.SetBrokerageModel(BrokerageName.FTXUS, AccountType.Margin)
res = Resolution.Minute
self.crypto = self.AddCrypto(CRYPTO, res, Market.GDAX).Symbol
consolidator = TradeBarConsolidator(timedelta(minutes = 45))
self.Consolidate(self.crypto, timedelta(minutes = 45), self.BarHandler)
self.ema_c1 = self.EMA(self.crypto, EMA_C1, res)
self.ema_c2 = self.EMA(self.crypto, EMA_C2, res)
self.ema_f = self.EMA(self.crypto, EMA_F, res)
self.ema_s = self.EMA(self.crypto, EMA_S, res)
self.RegisterIndicator(self.crypto, self.ema_c1, consolidator)
self.RegisterIndicator(self.crypto, self.ema_c2, consolidator)
self.RegisterIndicator(self.crypto, self.ema_f,consolidator)
self.RegisterIndicator(self.crypto, self.ema_s,consolidator)
self.SetWarmUp(5*EMA_S, res)
self.sell_Ticket = False
self.buy_Ticket = False
self.position_close_long = False
self.position_close_short = False
def OnData(self, data):
if self.IsWarmingUp:
return
if not self.ema_s.IsReady:
return
ema_c1 = self.ema_c1.Current.Value
ema_c2 = self.ema_c2.Current.Value
ema_f = self.ema_f.Current.Value
ema_s = self.ema_s.Current.Value
# open initial long when ema ribbon crosses to the upside
if not self.Portfolio[self.crypto].IsLong:
if not self.sell_Ticket:
if not self.position_close_long:
if self.ema_c1 > self.ema_c2 > self.ema_f > self.ema_s:
self.SetHoldings(self.crypto, 0.95)
self.sell_Ticket = True
# close long when the two fastest emas cross, create a boolan to keep track
if self.Portfolio[self.crypto].IsLong:
if self.sell_Ticket:
if ema_c1 < ema_c2:
self.Liquidate(self.crypto)
self.position_close_long = True
# reopen position if it was closed and it was a fake out
if not self.Portfolio[self.crypto].IsLong:
if self.sell_Ticket and self.position_close_long:
if ema_f < ema_c2 < ema_c1:
self.SetHoldings(self.crypto, 0.95)
self.position_close_long = False
# reset all boolans when ribbon flips
if not self.Portfolio[self.crypto].IsLong:
if self.position_close_long:
if ema_f < ema_s:
self.position_close_long = False
self.sell_ticket = False
## open initial short when ema ribbon crosses to the upside
if not self.Portfolio[self.crypto].IsShort:
if not self.buy_Ticket:
if not self.position_close_short:
if ema_c1 < ema_c2 < ema_f < ema_s:
self.SetHoldings(self.crypto, -0.95)
self.buy_Ticket = True
## close short when the two fastest emas cross, create a boolan to keep track
if self.Portfolio[self.crypto].IsShort:
if self.buy_Ticket:
if ema_c2 > ema_c1:
self.Liquidate(self.crypto)
self.position_close_short = True
## reopen short position if it was closed and it was a fake out
if not self.Portfolio[self.crypto].IsShort:
if self.buy_Ticket and self.position_close_short:
if self.ema_f > self.ema_c2 > self.ema_c1 :
self.SetHoldings(self.crypto, -0.95)
self.position_close_short = False
## reset all boolans when ribbon flips
if not self.Portfolio[self.crypto].IsShort:
if self.buy_Ticket and self.position_close_short:
if ema_s < ema_f:
self.position_close_short = False
self.buy_ticket = False
def BarHandler(self, consolidated):
if self.IsWarmingUp or not self.ema_f.IsReady:
return
self.Plot(self.crypto, "Close", self.Securities[self.crypto].Close)
self.Plot(self.crypto, "ema_c1", self.ema_c1.Current.Value)
self.Plot(self.crypto, "ema_c2", self.ema_c1.Current.Value)
self.Plot(self.crypto, "ema_s", self.ema_c1.Current.Value)
self.Plot(self.crypto, "ema_f", self.ema_c1.Current.Value)