Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.287 Tracking Error 0.347 Treynor Ratio 0 Total Fees $0.00 |
import datetime class MorningBreakOut(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 1, 1) # Set Start Date self.SetCash(100000) # Set Strategy Cash self.SetTimeZone("Europe/Berlin") self.SetBrokerageModel(BrokerageName.OandaBrokerage) # self.SetBenchmark("SPY") symbols = [] symbols.append(Symbol.Create("DE30EUR", SecurityType.Cfd, Market.Oanda)) #3. Set a universe using self.SetUniverseSelection(), and pass in a ManualUniverseSelectionModel() self.SetUniverseSelection(ManualUniverseSelectionModel(symbols)) #2. Set the resolution of the universe assets to daily resolution self.UniverseSettings.Resolution = Resolution.Minute # holds {"symbol": symbolData} instance for each symbol self.symbolDataBySymbol = {} # Call the MOMAlphaModel Class self.SetAlpha( OMRAlphaModel(self.symbolDataBySymbol) ) self.SetPortfolioConstruction( AllInOrSplitEqually() ) self.SetRiskManagement( OpenPositionRiskManagement(self.symbolDataBySymbol) ) self.SetExecution( ImmediateExecutionModel(self.symbolDataBySymbol) ) def OnDataConsolidated(self, sender, quoteBar): self.Log("OnDataConsolidated called on " + str(self.Time)) self.Log(str(quoteBar)) def OnSecuritiesChanged(self, changes): '''We should use this event to setup any state required for our alpha calculations. The method provides the algorithm object, and a list of securities changes. For example, we could generate indicators for each symbol in this method and save the symbols and indicators to a dictionary. ''' # Initialize SymbolData for each symbol for added in changes.AddedSecurities: self.Debug("securities change") symbolData = self.symbolDataBySymbol.get(added.Symbol) if symbolData is None: symbolData = SymbolData(added) symbolData.RegisterConsolidator(self, minutes=60) self.symbolDataBySymbol[added.Symbol] = symbolData class SymbolData: '''Contains data specific to a symbol required by this model''' def __init__(self, security): self.Security = security self.Symbol = security.Symbol self._openingBar = None self.oneR = None def OnDataConsolidated(self, quoteBar): if quoteBar.Time.hour == 9: self.openingBar = quoteBar self.oneR = abs(self.openingBar.High - self.openingBar.Low) self.Debug(f"EndTime: {quoteBar.EndTime}, High: {quoteBar.High}, Low: {quoteBar.Low}, oneR: {abs(quoteBar.High-quoteBar.Low)}") def RegisterConsolidator(self, algorithm, minutes=60): openRangeCons = algorithm.Consolidate(self.Symbol, timedelta(minutes), self.OnDataConsolidated) algorithm.SubscriptionManager.AddConsolidator(self.Symbol, openRangeCons) @property def openingBar(self): return self._openingBar @openingBar.setter def openingBar(self, value): self._openingBar = value class OMRAlphaModel(AlphaModel): def __init__(self, symbolDataBySymbol): self.symbolDataBySymbol = symbolDataBySymbol def Update(self, algorithm, data): insights = [] for symbol, symbolData in self.symbolDataBySymbol.items(): if symbolData.openingBar is None: continue algorithm.Debug("no openingBar") direction = InsightDirection.Flat if not algorithm.Portfolio[symbol].Invested: # Entry if data[symbol].Close >= symbolData.openingBar.High: direction = InsightDirection.Up if data[symbol].Close <= symbolData.openingBar.Low: direction = InsightDirection.Down insights.append(Insight(symbolData.Symbol, timedelta(1), InsightType.Price, direction, "Entry")) # Take Profit if algorithm.Portfolio[symbol].Invested: if data[symbol].Close >= symbolData.openingBar.High + symbolData.oneR: InsightDirection.Down if data[symbol].Close <= symbolData.openingBar.Low - symbolData.oneR: InsightDirection.Up insights.append(Insight(symbolData.Symbol, timedelta(1), InsightType.Price, direction, "TakeProfit")) return insights class AllInOrSplitEqually(PortfolioConstructionModel): def __init__(self): pass def DetermineTargetPercent(self, activeInsights): '''Will determine the target percent for each insight Args: activeInsights: The active insights to generate a target for''' result = {} # give equal weighting to each security count = sum(x.Direction != InsightDirection.Flat for x in activeInsights) percent = 0 if count == 0 else 1.0 / count for insight in activeInsights: result[insight] = insight.Direction * percent return result class OpenPositionRiskManagement(RiskManagementModel): def __init__(self, symbolDataBySymbol): self.symbolDataBySymbol = symbolDataBySymbol self.trailingStop = None def ManageRisk(self, algorithm, targets): targets = [] for symbol in self.symbolDataBySymbol: # Time Exit if necessary if algorithm.Time.time() >= datetime.time(21,15): targets.append(PortfolioTarget(symbol, 0)) continue # Trailing StopLoss if algorithm.Portfolio[symbol].Quantity > 0: self.trailingStop = round(self.symbolDataBySymbol[symbol].openingBar.High - self.oneR / 2, 1) if algorithm.Securities[symbol].Close <= self.trailingStop: targets.append(PortfolioTarget(symbol, 0)) if algorithm.Portfolio[symbol].Quantity < 0: self.trailingStop = round(self.symbolDataBySymbol[symbol].openingBar.Low + self.oneR / 2, 1) if algorithm.Securities[symbol].Close >= self.trailingStop: targets.append(PortfolioTarget(symbol, 0)) return targets class ImmediateExecutionModel(ExecutionModel): '''Provides an implementation of IExecutionModel that immediately submits market orders to achieve the desired portfolio targets''' def __init__(self, symbolDataBySymbol): '''Initializes a new instance of the ImmediateExecutionModel class''' self.targetsCollection = PortfolioTargetCollection() self.symbolDataBySymbol = symbolDataBySymbol def Execute(self, algorithm, targets): '''Immediately submits orders for the specified portfolio targets. Args: algorithm: The algorithm instance targets: The portfolio targets to be ordered''' # for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call self.targetsCollection.AddRange(targets) if self.targetsCollection.Count > 0: for target in self.targetsCollection.OrderByMarginImpact(algorithm): # calculate remaining quantity to be ordered quantity = OrderSizing.GetUnorderedQuantity(algorithm, target) if quantity != 0: algorithm.MarketOrder(target.Symbol, quantity) self.symbolDataBySymbol.openingBar = None self.targetsCollection.ClearFulfilled(algorithm)