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)