Overall Statistics |
Total Trades 43 Average Win 1.75% Average Loss -0.98% Compounding Annual Return 2.600% Drawdown 7.600% Expectancy 0.250 Net Profit 2.608% Sharpe Ratio 0.287 Probabilistic Sharpe Ratio 21.322% Loss Rate 55% Win Rate 45% Profit-Loss Ratio 1.78 Alpha 0.025 Beta -0.003 Annual Standard Deviation 0.086 Annual Variance 0.007 Information Ratio -0.554 Tracking Error 0.313 Treynor Ratio -7.296 Total Fees $0.00 |
from datetime import timedelta class MovingAverageCrossAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 1, 1) # Set Start Date self.SetEndDate(2020, 12, 31) # Set End Date self.SetCash(100000) # Set Strategy Cash self.Data = {} for ticker in ["EURUSD","NZDUSD","USDJPY"]: symbol = self.AddForex(ticker , Resolution.Hour).Symbol self.Data[symbol] = SymbolData( self.SMA(symbol, 50, Resolution.Hour), self.SMA(symbol, 200, Resolution.Hour)) self.SetWarmUp(203, Resolution.Hour) self.quant = 100000 def OnData(self, data): if self.IsWarmingUp: return for symbol, symbolData in self.Data.items(): fastPastValue = symbolData.fastSMAWindow[1].Value # Previous fast SMA value slowPastValue = symbolData.slowSMAWindow[1].Value # Previous slow SMA value fast = symbolData.fast.Current.Value slow = symbolData.slow.Current.Value if not self.Portfolio[symbol].Invested: price = data[symbol].Close if fast > slow and fastPastValue < slow: self.MarketOrder(symbol, self.quant) self.StopMarketOrder(symbol, -self.quant, (price * 0.99)) self.LimitOrder(symbol, -self.quant, (price * 1.02)) def OnOrderEvent(self, orderEvent): order = self.Transactions.GetOrderById(orderEvent.OrderId) if order.Status == OrderStatus.Filled: if order.Type == OrderType.Limit or order.Type == OrderType.Limit: self.Transactions.CancelOpenOrders(order.Symbol) class SymbolData: def __init__(self, fast, slow): self.fast = fast self.slow = slow self.fastSMAWindow = RollingWindow[IndicatorDataPoint](2) #setting the Rolling Window for the fast SMA indicator, takes two values self.fast.Updated += self.FastSmaUpdated #Updating those two values self.slowSMAWindow = RollingWindow[IndicatorDataPoint](3) #setting the Rolling Window for the slow SMA indicator, takes two values self.slow.Updated += self.SlowSmaUpdated #Updating those two values def FastSmaUpdated(self, sender, updated): '''Event holder to update the fast SMA Rolling Window values''' if self.fast.IsReady: self.fastSMAWindow.Add(updated) def SlowSmaUpdated(self, sender, updated): '''Event holder to update the slow SMA Rolling Window values''' if self.slow.IsReady: self.slowSMAWindow.Add(updated)