Overall Statistics |
Total Trades 2 Average Win 0.80% Average Loss 0% Compounding Annual Return 0.398% Drawdown 0.700% Expectancy 0 Net Profit 0.797% Sharpe Ratio 0.352 Probabilistic Sharpe Ratio 13.810% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.005 Beta -0.009 Annual Standard Deviation 0.012 Annual Variance 0 Information Ratio -0.633 Tracking Error 0.131 Treynor Ratio -0.475 Total Fees $2.00 Estimated Strategy Capacity $37000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X |
class RiskModel(RiskManagementModel): '''Provides an implementation of IRiskManagementModel that limits the unrealized profit per holding to the specified percentage''' def __init__(self, maximumUnrealizedProfitPercent = 0.01): '''Initializes a new instance of the MaximumUnrealizedProfitPercentPerSecurity class Args: maximumUnrealizedProfitPercent: The maximum percentage unrealized profit allowed for any single security holding, defaults to 5% drawdown per security''' self.maximumUnrealizedProfitPercent = abs(maximumUnrealizedProfitPercent) def ManageRisk(self, algorithm, targets): '''Manages the algorithm's risk at each time step Args: algorithm: The algorithm instance targets: The current portfolio targets to be assessed for risk''' targets = [] for kvp in algorithm.Securities: security = kvp.Value if not security.Invested: continue pnl = security.Holdings.UnrealizedProfitPercent if pnl < -self.maximumUnrealizedProfitPercent: # liquidate targets.append(PortfolioTarget(security.Symbol, 0)) return targets # Your New Python File
from RiskModel import RiskModel from AlphaModel import CrossAlphaModel from ExecuteModel import ImmediateExecutionPlotModel class CalmBrownTermite(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 1) self.SetEndDate(2019,1,1) self.SetCash(10000) # self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) self.equity = "SPY" symbols = [Symbol.Create(self.equity, SecurityType.Equity, Market.USA)] resolution = Resolution.Daily self.AddUniverseSelection(ManualUniverseSelectionModel(symbols)) # self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw self.AddEquity(self.equity) fastr = int(self.GetParameter("fastr")) diff = int(self.GetParameter("diff")) self.AlphaM = CrossAlphaModel(algo = self, fastPeriod = fastr, slowPeriod = fastr+diff) self.AddAlpha(self.AlphaM) # self.AddRiskManagement(TrailingStopRiskManagementModel(0.05)) self.SetExecution(ImmediateExecutionPlotModel(self)) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.UniverseSettings.Resolution = resolution from System.Drawing import Color stockPlot = Chart('Trade Plot') stockPlot.AddSeries(Series('Price', SeriesType.Line, '$', Color.Black)) stockPlot.AddSeries(Series('Fast', SeriesType.Line, '$', Color.Green)) stockPlot.AddSeries(Series('Slow', SeriesType.Line, '$', Color.Orange)) stockPlot.AddSeries(Series('Buy', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.Triangle)) stockPlot.AddSeries(Series('Sell', SeriesType.Scatter, '$', Color.Blue, ScatterMarkerSymbol.TriangleDown)) self.AddChart(stockPlot) def OnEndOfDay(self, symbol): # if self.lastPrice is None: return self.Plot("Trade Plot", "Price", self.Securities[self.equity].Close) self.Log(self.AlphaM) if self.AlphaM.get()[0][1].IsReady: self.Plot("Trade Plot", "Fast", self.AlphaM.get()[0][0].Current.Value) self.Plot("Trade Plot", "Slow", self.AlphaM.get()[0][1].Current.Value)
class ImmediateExecutionPlotModel(ExecutionModel): '''Provides an implementation of IExecutionModel that immediately submits market orders to achieve the desired portfolio targets''' def __init__(self,algo): '''Initializes a new instance of the ImmediateExecutionModel class''' self.targetsCollection = PortfolioTargetCollection() self.algo = algo 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) action = 'Buy' if quantity > 0 else 'Sell' self.algo.Plot("Trade Plot", action, self.algo.Securities[target.Symbol].Price) self.targetsCollection.ClearFulfilled(algorithm) # Your New Python File
class CrossAlphaModel(AlphaModel): '''Alpha model that uses an EMA cross to create insights''' def __init__(self, algo, fastPeriod = 12, slowPeriod = 26, resolution = Resolution.Daily): '''Initializes a new instance of the EmaCrossAlphaModel class Args: fastPeriod: The fast EMA period slowPeriod: The slow EMA period''' self.fastPeriod = fastPeriod self.slowPeriod = slowPeriod self.resolution = resolution self.period = timedelta(days=1) self.predictionInterval = Time.Multiply(Extensions.ToTimeSpan(resolution), fastPeriod) self.symbolDataBySymbol = {} self.algo = algo resolutionString = Extensions.GetEnumString(resolution, Resolution) self.Name = '{}({},{},{})'.format(self.__class__.__name__, fastPeriod, slowPeriod, resolutionString) def get(self): indicts = [] for symbol, symbolData in self.symbolDataBySymbol.items(): indicts.append([symbolData.Fast,symbolData.Slow]) return indicts def Update(self, algorithm, data): '''Updates this alpha model with the latest data from the algorithm. This is called each time the algorithm receives data for subscribed securities Args: algorithm: The algorithm instance data: The new data available Returns: The new insights generated''' insights = [] for symbol, symbolData in self.symbolDataBySymbol.items(): if symbolData.Fast.IsReady and symbolData.Slow.IsReady: if symbolData.FastIsOverSlow: if symbolData.Slow > symbolData.Fast: # self.algo.Debug("SELL: slow = "+str(symbolData.Slow.Current.Value)+", fast = "+ str(symbolData.Fast.Current.Value)) insights.append(Insight.Price(symbolData.Symbol, self.period, InsightDirection.Down)) elif symbolData.SlowIsOverFast: if symbolData.Fast > symbolData.Slow: # self.algo.Debug("BUY: slow = "+str(symbolData.Slow.Current.Value)+", fast = "+ str(symbolData.Fast.Current.Value)) insights.append(Insight.Price(symbolData.Symbol, self.period, InsightDirection.Up)) symbolData.FastIsOverSlow = symbolData.Fast > symbolData.Slow return insights def OnSecuritiesChanged(self, algorithm, changes): '''Event fired each time the we add/remove securities from the data feed Args: algorithm: The algorithm instance that experienced the change in securities changes: The security additions and removals from the algorithm''' for added in changes.AddedSecurities: symbolData = self.symbolDataBySymbol.get(added.Symbol) if symbolData is None: # create fast/slow EMAs symbolData = SymbolData(added) symbolData.Fast = algorithm.EMA(added.Symbol, self.fastPeriod, self.resolution) symbolData.Slow = algorithm.EMA(added.Symbol, self.slowPeriod, self.resolution) self.symbolDataBySymbol[added.Symbol] = symbolData else: # a security that was already initialized was re-added, reset the indicators symbolData.Fast.Reset() symbolData.Slow.Reset() class SymbolData: '''Contains data specific to a symbol required by this model''' def __init__(self, security): self.Security = security self.Symbol = security.Symbol self.Fast = None self.Slow = None # True if the fast is above the slow, otherwise false. # This is used to prevent emitting the same signal repeatedly self.FastIsOverSlow = False @property def SlowIsOverFast(self): return not self.FastIsOverSlow # Your New Python File
class CalmBrownTermite(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 1) self.SetEndDate(2019,1,1) self.SetCash(10000) # self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) self.symbol = "SPY" self.equity = self.AddEquity(self.symbol, Resolution.Minute).Symbol fastr = 650 slowr = fastr + 650 # fastr = int(self.GetParameter("fastr")) # slowr = fastr + int(self.GetParameter("diff")) self.Fast = self.EMA(self.equity,fastr,Resolution.Minute) self.Slow = self.EMA(self.equity,slowr,Resolution.Minute) self.lastsign = None self.lastPrice = None self.previous = self.Time.min self.Tolerance = 0.00015 from System.Drawing import Color stockPlot = Chart('Trade Plot') stockPlot.AddSeries(Series('Price', SeriesType.Line, '$', Color.Green)) stockPlot.AddSeries(Series('Buy', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.Triangle)) stockPlot.AddSeries(Series('Sell', SeriesType.Scatter, '$', Color.Blue, ScatterMarkerSymbol.TriangleDown)) stockPlot.AddSeries(Series('SMA50', SeriesType.Line, '$', Color.Orange)) stockPlot.AddSeries(Series('SMA200', SeriesType.Line, '$', Color.Yellow)) self.AddChart(stockPlot) def OnData(self, data): if not data[self.equity] is None: self.lastPrice = data[self.equity].Close if not self.Slow.IsReady :return # if self.previous is None or self.previous.day==self.Time.day:return if self.lastsign is None: self.lastsign = self.Fast.Current.Value > self.Slow.Current.Value return holdings = self.Portfolio[self.equity].Quantity # BUY (CROSSOVER) if holdings <= 0 and self.Fast.Current.Value > self.Slow.Current.Value and not self.lastsign: self.Liquidate() self.SetHoldings(self.equity,1) self.Plot("Trade Plot", 'Buy', self.Securities[self.equity].Price) # SELL (CROSSOVER) elif self.Fast < self.Slow and holdings > 0 and self.lastsign: self.Liquidate() self.SetHoldings(self.equity,-1) self.Plot("Trade Plot", 'Sell', self.Securities[self.equity].Price) # SELL (STOPLOSS) if self.Portfolio[self.equity].UnrealizedProfitPercent<= -0.01 : # print(str(int(self.Portfolio.Cash))) action = 'Sell' if self.Portfolio[self.equity].IsLong else 'BUY' self.Plot("Trade Plot", action, self.Securities[self.equity].Price) self.Liquidate() # if data.Bars.ContainsKey("SPY"): # self.Plot("Trade Plot", "Price", data[self.equity].Close) # self.Plot("Trade Plot", "SMA50" ,self.Fast.Current.Value) # self.Plot("Trade Plot", "SMA200", self.Slow.Current.Value) self.previous = self.Time self.lastsign = self.Fast.Current.Value > self.Slow.Current.Value def OnEndOfDay(self, symbol): # if self.lastPrice is None: return self.Plot("Trade Plot", "Price", self.Securities[self.equity].Price) self.Plot("Trade Plot", "SMA50" ,self.Fast.Current.Value) self.Plot("Trade Plot", "SMA200", self.Slow.Current.Value)