Overall Statistics
Total Trades
10
Average Win
0%
Average Loss
0%
Compounding Annual Return
35.047%
Drawdown
10.700%
Expectancy
0
Net Profit
32.732%
Sharpe Ratio
1.575
Probabilistic Sharpe Ratio
65.495%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.327
Beta
-0.122
Annual Standard Deviation
0.193
Annual Variance
0.037
Information Ratio
0.283
Tracking Error
0.398
Treynor Ratio
-2.498
Total Fees
$10.33
from QuantConnect.Data.UniverseSelection import * 
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
from clr import AddReference
AddReference("QuantConnect.Algorithm.Framework")
from QuantConnect.Algorithm.Framework.Execution import ExecutionModel

class DynamicNadionCircuit(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020, 1, 1)  # Set Start Date
        # self.SetEndDate(2014, 1, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        self.averages = { }
        self.SetWarmUp(timedelta(days=100))
        self.positions = {}
        
        self.UniverseSettings.Resolution = Resolution.Daily
        self.SetUniverseSelection(MyUniverseSelectionModel(self))
        self.SetAlpha(MaAlpha(self))
        self.SetPortfolioConstruction(MyPortfolioConstructionModel(self)) 
        # self.SetExecution(ImmediateExecutionModel())
        # self.SetRiskManagement(NullRiskManagementModel())

    def OnOrderEvent(self, OrderEvent):

        if OrderEvent.FillQuantity == 0:
            return

        fetched = self.Transactions.GetOrderById(OrderEvent.OrderId)

        self.Debug("{} was filled. Symbol: {}. Quantity: {}. Direction: {}"
                   .format(str(fetched.Type),
                           str(OrderEvent.Symbol),
                           str(OrderEvent.FillQuantity),
                           str(OrderEvent.Direction)))
                           
class PortfolioData():
    def __init__(self, symbol, targetPrice, shares):
        self.symbol = symbol
        self.target = targetPrice
        self.shared = shares

class MyPortfolioConstructionModel(PortfolioConstructionModel):
    
    def __init__(self, parent):
        self.parent = parent

    # Create list of PortfolioTarget objects from Insights
    def CreateTargets(self, algorithm, insights):
        targets = []
        
        for insight in insights:
            #TODO We might add INVESTED!
            if not algorithm.Securities[insight.Symbol].Invested:
                targets.append(PortfolioTarget.Percent(algorithm, insight.Symbol, 0.1))
            # targets.append(PortfolioTarget(insight.Symbol, 10))
          
        return targets

        
class MaAlpha(AlphaModel):
    def __init__(self, parent):
        self.securities = [] #list to store securities to consider
        self.parent = parent
      
    def OnSecuritiesChanged(self, algorithm, changes):
        
        for security in changes.AddedSecurities:
            if not security.Invested:
                #buy security when the price is below the 100EMA
                if self.parent.averages[security.Symbol].ma.Current.Value > security.Price:
                    self.parent.Log("Active position, Symbol: " + str(security.Symbol) + ", EMA: " + str(self.parent.averages[security.Symbol].ma.Current.Value) + ", Price: " + str(security.Price))
                    self.securities.append(security)
                    
        
    def Update(self, algorithm, data):
        
        longInsights = []
        for securities in self.securities:
            longInsights.append(Insight.Price(securities.Symbol, timedelta(60), InsightDirection.Up))
        insightsGroup = Insight.Group(longInsights)
        
        return insightsGroup

class MyUniverseSelectionModel(FundamentalUniverseSelectionModel):

    def __init__(self, parent):
        super().__init__(True, None, None)
        self.parent = parent

    def SelectCoarse(self, algorithm, coarse):
        filtered = [x for x in coarse if x.HasFundamentalData and x.Price > 0]
        sortedByDollarVolume = sorted(filtered, key=lambda x: x.DollarVolume, reverse=True)[:100]
        
        for security in sortedByDollarVolume:  
            symbol = security.Symbol
            
            if symbol not in self.parent.averages:
                # Get history prices
                history = self.parent.History(symbol, 200, Resolution.Daily)
                
                # Adjust SelectionData to pass in the history result
                self.parent.averages[symbol] = SelectionData(history)
            
            #update SelectionData with the newest prices
            self.parent.averages[symbol].update(self.parent.Time, security.AdjustedPrice)
        
        
        return [x.Symbol for x in sortedByDollarVolume]

    def SelectFine(self, algorithm, fine):
        
        selected = []
        
        filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology]
        self.technology = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:10]
        # filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices]
        # self.financialServices = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5]
        # filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive]
        # self.consumerDefensive = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5]
        
        for security in self.technology:
            symbol = security.Symbol

            #Pass the stocks to the AlphaModel
            if  self.parent.averages[symbol].is_ready():
                selected.append(symbol)
                
        return selected
        
             
class SelectionData():
    def __init__(self, history):
        self.ma = ExponentialMovingAverage(200)
        
        #setup this class with the history data
        for bar in history.itertuples():
            self.update(bar.Index[1], bar.close)
    
    def is_ready(self):
        return self.ma.IsReady
    
    def update(self, time, price):
        self.ma.Update(time, price)