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.695
Tracking Error
0.178
Treynor Ratio
0
Total Fees
$0.00
##-------------------Class to hold variable weights---------------------------------------##        
class Weights(Object):
    MarginMultiplier = float(1.0)
    Short = float(0.805)
##-----------------Imports----------------------------------------------------------------------------------------##
import numpy as np

from clr import AddReference
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm.Framework")

from QuantConnect import Resolution, Extensions
from QuantConnect.Algorithm.Framework.Alphas import *
from QuantConnect.Algorithm.Framework.Portfolio import *
from itertools import groupby
from datetime import datetime, timedelta
from pytz import utc

from DynamicWeight import Weights

##-----------------Global variables-------------------------------------------------------------------------------##

Zero = int(0)
UTCMIN = datetime.min.replace(tzinfo=utc)

class SourceModelPortfolioConstructionModel(PortfolioConstructionModel):

##-----------------Initialize variables, lists, etc---------------------------------------------------------------##

    def __init__(self, SymbolList):
        '''Receives a list of the universe symbols.  Designed for manual universe selection'''
        
        # Static Variables
        self.CummulativeInsightCollection = InsightCollection()
        self.FlatInsightCollection = InsightCollection()
        self.RemovedSymbols = []
        self.SymbolList = SymbolList
        self.ErrorSymbols = {}
        self.Percents = {}
        
        # Long Only Variables
        self.LongInsightCollection = InsightCollection()
        self.LongNextExpiryTime = UTCMIN
        self.LongRebalancingTime = UTCMIN
        self.LongRebalancingFunc = lambda dt: dt + Extensions.ToTimeSpan(Resolution.Minute)
        self.LongSourceModel = None
        
        # Short Only Variables
        self.ShortInsightCollection = InsightCollection()
        self.ShortNextExpiryTime = UTCMIN
        self.ShortRebalancingTime = UTCMIN
        self.ShortRebalancingFunc = lambda dt: dt + Extensions.ToTimeSpan(Resolution.Hour)
        self.ShortSourceModel = None


##-----------------Creates target weights---------------------------------------------------------------------------##

    def DetermineTargetPercent(self, algorithm, insights):

        for insight in insights:
            self.CummulativeInsightCollection.Add(insight)
        
        ActiveInsights = self.CummulativeInsightCollection.GetActiveInsights(algorithm.UtcTime)
        
        LastActiveInsights = []
        for symbol, g in groupby(ActiveInsights, lambda x: x.Symbol):
            LastActiveInsights.append(sorted(g, key = lambda x: x.GeneratedTimeUtc)[-1])
        
        # Give equal weighting to each security
        count = sum(x.Direction != InsightDirection.Flat for x in LastActiveInsights)
        percent = Zero if count == Zero else (Weights.MarginMultiplier / count)
        
        for insight in LastActiveInsights:
            
            if insight.Direction == InsightDirection.Down:
                self.Percents[insight] = insight.Direction * np.minimum(percent, Weights.Short)
                
            else:
                 self.Percents[insight] = insight.Direction * percent


##-----------------Creates and returns Portfolio Targets------------------------------------------------------------##

    def CreateTargets(self, algorithm, insights):
            
        targets = []
            
        if self.LongSourceModel == None or self.ShortSourceModel == None:
            self.DetermineSourceModels(algorithm, insights)  

        self.DetermineTargetPercent(algorithm, insights)
        
        targets.extend(self.CreateShortPositions(algorithm, insights))
        targets.extend(self.CreateLongPositions(algorithm, insights))
        targets.extend(self.CreateFlatPositions(algorithm,  insights))
        
        # Create flatten target for each security that was removed from the universe
        if self.RemovedSymbols is not None:
            universeDeselectionTargets = [ PortfolioTarget(symbol, Zero) for symbol in self.RemovedSymbols ]
            targets.extend(universeDeselectionTargets)
            self.RemovedSymbols = None
        
        return targets  


##-----------------Captures the source models' hash codes-----------------------------------------------------------##

    def DetermineSourceModels(self, algorithm, insights):
        
        for insight in insights:
            
            if insight.Symbol == self.SymbolList[0] and insight.Direction == InsightDirection.Up and self.LongSourceModel == None and insight.SourceModel != self.ShortSourceModel:
                self.LongSourceModel = insight.SourceModel
                algorithm.Debug("Long Source Model: {0}".format(self.LongSourceModel))
                
            elif insight.Symbol == self.SymbolList[0] and insight.Direction == InsightDirection.Down and insight.Period == timedelta(days=3) and self.ShortSourceModel == None:
                self.ShortSourceModel = insight.SourceModel
                algorithm.Debug("Short Source Model: {0}".format(self.ShortSourceModel))
                
                
                
##-----------------Generates Long  targets separately------------------------------------------------------------##

    def CreateLongPositions(self, algorithm, insights):
        
        LongTargets = []
        
        if (algorithm.UtcTime <= self.LongNextExpiryTime and algorithm.UtcTime <= self.LongRebalancingTime and len(insights) == Zero and self.RemovedSymbols is None):
            return LongTargets
            
        for insight in insights:
            if insight.SourceModel == self.LongSourceModel:
                self.LongInsightCollection.Add(insight) 
        
        # Get insight that haven't expired of each symbol that is still in the universe
        ActiveInsights = self.LongInsightCollection.GetActiveInsights(algorithm.UtcTime)

        # Get the last generated active insight
        LastActiveInsights = []
        for symbol, g in groupby(ActiveInsights, lambda x: x.Symbol):
            LastActiveInsights.append(sorted(g, key = lambda x: x.GeneratedTimeUtc)[-1])
        
        self.ErrorSymbols = {}
        for insight in LastActiveInsights:
            symbol = insight.Symbol
            target = PortfolioTarget.Percent(algorithm, symbol, self.Percents[insight])
            if not target is None:
                LongTargets.append(target)
            else:
                self.ErrorSymbols[symbol] = symbol

        # Get expired insights and create flatten targets for each symbol
        ExpiredInsights = self.LongInsightCollection.RemoveExpiredInsights(algorithm.UtcTime)
        
        for insight in ExpiredInsights:
            self.Percents.pop(insight)

        ExpiredTargets = []
        for symbol, f in groupby(ExpiredInsights, lambda x: x.Symbol):
            if not self.LongInsightCollection.HasActiveInsights(symbol, algorithm.UtcTime) and not symbol in self.ErrorSymbols:
                ExpiredTargets.append(PortfolioTarget(symbol, Zero))
                continue

        LongTargets.extend(ExpiredTargets)

        self.LongNextExpiryTime = self.LongInsightCollection.GetNextExpiryTime()
        
        if self.LongNextExpiryTime is None:
            self.LongNextExpiryTime = UTCMIN

        self.LongRebalancingTime = self.LongRebalancingFunc(algorithm.UtcTime)  
            
        return LongTargets
        
        
        
##-----------------Generates Short  targets separately-----------------------------------------------------------##

    def CreateShortPositions(self, algorithm, insights):
        
        ShortTargets = []
        
        if (algorithm.UtcTime <= self.ShortNextExpiryTime and algorithm.UtcTime <= self.ShortRebalancingTime and len(insights) == Zero and self.RemovedSymbols is None):
            return ShortTargets
        
        for insight in insights:
            if insight.SourceModel == self.ShortSourceModel:
                self.ShortInsightCollection.Add(insight) 
        
        # Get insight that haven't expired of each symbol that is still in the universe
        ActiveInsights = self.ShortInsightCollection.GetActiveInsights(algorithm.UtcTime)

        # Get the last generated active insight
        LastActiveInsights = []
        for symbol, g in groupby(ActiveInsights, lambda x: x.Symbol):
            LastActiveInsights.append(sorted(g, key = lambda x: x.GeneratedTimeUtc)[-1])

        self.ErrorSymbols = {}
        for insight in LastActiveInsights:
            symbol = insight.Symbol
            target = PortfolioTarget.Percent(algorithm, symbol, self.Percents[insight])
            if not target is None:
                ShortTargets.append(target)
            else:
                self.ErrorSymbols[symbol] = symbol

        # Get expired insights and create flatten targets for each symbol
        ExpiredInsights = self.ShortInsightCollection.RemoveExpiredInsights(algorithm.UtcTime)

        for insight in ExpiredInsights:
            self.Percents.pop(insight)
            
        ExpiredTargets = []
        for symbol, f in groupby(ExpiredInsights, lambda x: x.Symbol):
            if not self.ShortInsightCollection.HasActiveInsights(symbol, algorithm.UtcTime) and not symbol in self.ErrorSymbols:
                ExpiredTargets.append(PortfolioTarget(symbol, Zero))
                continue

        ShortTargets.extend(ExpiredTargets)

        self.ShortNextExpiryTime = self.ShortInsightCollection.GetNextExpiryTime()
        
        if self.ShortNextExpiryTime is None:
            self.ShortNextExpiryTime = UTCMIN

        self.ShortRebalancingTime = self.ShortRebalancingFunc(algorithm.UtcTime)
        
        return ShortTargets
        
        

##-----------------Generates Flat targets separately----------------------------------------------------------------##    

    def CreateFlatPositions(self, algorithm, insights):
        
        FlatTargets = []
        
        self.ErrorSymbols = {}
        for insight in insights:
            if insight.Direction == InsightDirection.Flat:
                symbol = insight.Symbol
                target = PortfolioTarget.Percent(algorithm, symbol, Zero)
                if not target is None:
                    FlatTargets.append(target)
                else:
                    self.ErrorSymbols[symbol] = symbol    
                
        return FlatTargets   



##-----------------Handles changes to the universe------------------------------------------------------------------##

    def OnSecuritiesChanged(self, algorithm, changes):
    
        # Get removed symbol and invalidate them in the insight collections
        self.RemovedSymbols = [x.Symbol for x in changes.RemovedSecurities]
        
        self.LongInsightCollection.Clear(self.RemovedSymbols)
        self.ShortInsightCollection.Clear(self.RemovedSymbols)
        self.FlatInsightCollection.Clear(self.RemovedSymbols)
##-------------------Imports-------------------------------------------------------------------##

import numpy as np
import pandas as pd
import re
from datetime import *

from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")
AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect import Resolution, Extensions
from QuantConnect.Algorithm.Framework.Execution import *
from QuantConnect.Data.UniverseSelection import *
from QuantConnect.Data.Custom.CBOE import *
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
from QuantConnect.Algorithm.Framework.Selection import *

##-------------------Alpha Files and Objects--------------------------------------------------##

from DynamicWeight import Weights

#from LongAlpha import Long
#from ShortAlpha import Short


##-------------------Portfolio Construction Files---------------------------------------------##

from SourceModelPortfolioConstruction import SourceModelPortfolioConstructionModel


##-------------------Risk Management Files----------------------------------------------------##

#from RiskManagement import ManageRisk


##-------------------Global variables---------------------------------------------------------##

resolution = Resolution.Minute


class Project(QCAlgorithm):

##-------------------Initialize variables, lists, asset subscriptions, etc--------------------##

    def Initialize(self):
        # Set Start Date so that backtest has 5+ years of data
        self.SetStartDate(2014, 1, 1)

        # Set Cash
        self.SetCash(1000000)
        
        #Variables
        self.Zero = int(0)

        # Selected Securitites
        self.Assets = [
                self.AddEquity("SPY", Resolution = resolution),
                self.AddEquity("SPXL", Resolution = resolution),
                self.AddEquity("SPXS", Resolution = resolution)]

        ManualSymbols = []
        SymbolList = []
        
        for x in self.Assets:
            ManualSymbols.append(Symbol.Create(x.Symbol, SecurityType.Equity, Market.USA))
            SymbolList.append(x.Symbol)

##-------------------Construct Alpha Model----------------------------------------------------##

        #Universe Selection
        self.AddUniverseSelection(ManualUniverseSelectionModel(ManualSymbols))
        
        #Alpha Models
    #    self.AddAlpha(LongAlpha())
    #    self.AddAlpha(ShortAlpha())
        
        #Portfolio Construction
        self.SetPortfolioConstruction(SourceModelPortfolioConstructionModel(SymbolList))
        
        #Risk Management
    #    self.SetRiskManagement(ManageRisk())
        
        #Brokerage Model
        self.SetBrokerageModel(AlphaStreamsBrokerageModel())