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)