| Overall Statistics |
|
Total Trades 218 Average Win 2.05% Average Loss -0.61% Compounding Annual Return 21.548% Drawdown 9.700% Expectancy 0.320 Net Profit 21.548% Sharpe Ratio 1.193 Probabilistic Sharpe Ratio 54.503% Loss Rate 70% Win Rate 30% Profit-Loss Ratio 3.36 Alpha 0.184 Beta -0.018 Annual Standard Deviation 0.154 Annual Variance 0.024 Information Ratio 0.782 Tracking Error 0.209 Treynor Ratio -10.023 Total Fees $0.00 |
class DynamicVerticalCoreWave(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 1, 1) # Set Start Date
self.SetEndDate(2015, 12, 31)
self.SetCash(10000) # Set Strategy Cash
self.market = "fxcm"
self.defaultQuantity = 25000
self.periodFast = 5
self.periodSlow = 9
self.symbol = self.AddForex("EURUSD", Resolution.Hour, self.market).Symbol
self.emaFast = self.EMA(self.symbol, self.periodFast, Resolution.Hour)
self.emaSlow = self.EMA(self.symbol, self.periodSlow, Resolution.Hour)
self.emaFastHistory = RollingWindow[float](self.periodFast + 1)
self.emaSlowHistory = RollingWindow[float](self.periodSlow + 1)
def OnData(self, data):
self.emaFastHistory.Add(self.emaFast.Current.Value)
self.emaSlowHistory.Add(self.emaSlow.Current.Value)
if not self.emaSlow.IsReady:
return
if not data.ContainsKey(self.symbol) or data[self.symbol] is None:
return
if self.Portfolio[self.symbol].IsLong:
if self.Falling(self.emaSlowHistory, self.periodSlow):
self.MarketOrder(self.symbol, -self.defaultQuantity)
elif self.Portfolio[self.symbol].IsShort:
if self.Rising(self.emaSlowHistory, self.periodSlow):
self.MarketOrder(self.symbol, self.defaultQuantity)
else:
if self.CrossAbove(self.emaFastHistory, self.emaSlowHistory) and not self.Falling(self.emaSlowHistory, self.periodSlow):
self.MarketOrder(self.symbol, self.defaultQuantity)
if self.CrossBelow(self.emaFastHistory, self.emaSlowHistory) and not self.Rising(self.emaSlowHistory, self.periodSlow):
self.MarketOrder(self.symbol, -self.defaultQuantity)
def CrossAbove(self, window1, window2, tolerance=0):
return window1[0] > window2[0] * (1 + tolerance) and window1[1] < window2[1] * (1 - tolerance)
def CrossBelow(self, window1, window2, tolerance = 0):
return window1[0] < window2[0] * (1 - tolerance) and window1[1] > window2[1] * (1 + tolerance)
def Rising(self, window, lookback = 1, tolerance = 0):
return window[0] > window[lookback] * (1 + tolerance)
def Falling(self, window, lookback = 1, tolerance = 0):
return window[0] < window[lookback] * (1 - tolerance)