Overall Statistics
Total Trades
726
Average Win
0.03%
Average Loss
-0.03%
Compounding Annual Return
-0.925%
Drawdown
3.000%
Expectancy
-0.084
Net Profit
-0.127%
Sharpe Ratio
0.054
Probabilistic Sharpe Ratio
35.154%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.84
Alpha
0.023
Beta
-0.046
Annual Standard Deviation
0.081
Annual Variance
0.007
Information Ratio
-2.488
Tracking Error
0.158
Treynor Ratio
-0.095
Total Fees
$750.91
import clr
clr.AddReference("System")
clr.AddReference("QuantConnect.Algorithm")
clr.AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import SGD
from sklearn.preprocessing import MinMaxScaler
from datetime import timedelta

class MOMAlphaModel(AlphaModel):
    # se puede hacer una knn aca adentro
    def __init__(self):
        self.mom = {}
        
        self.model = Sequential()
        self.model.add(Dense(10))
        self.model.add(Activation('relu'))
        self.model.add(Dense(1))
        
        
    def OnSecuritiesChanged(self, algorithm, changes):
        self.TrainNN(changes.AddedSecurities, algorithm)
        
        for security in changes.AddedSecurities:
            symbol = security.Symbol
            new_feature = np.array([algorithm.History(security.Symbol,15, Resolution.Daily)["open"]])
            algorithm.Debug(f"{new_feature}")
            algorithm.Debug(f" its shape is {new_feature.shape}")
            try:
                self.mom[symbol] = self.model.predict(new_feature, batch_size=1)
                algorithm.Debug(f"Prediction for {symbol} is {self.mom[symbol]}")
            except Exception as e:
                algorithm.Debug(f"{e}")
                pass
    
    def TrainNN(self, data, algorithm):
        Xs = []
        Ys = []
        
        if len(data) == 0:
            return None
        
        for sec in data:
            #price = [last 10 weeks prices]
            if len(algorithm.History(sec.Symbol,16, Resolution.Daily)['open']) >= 16:
                #Ys.append(algorithm.History(sec.Symbol,16, Resolution.Daily)["open"][0] / algorithm.History(sec.Symbol,16, Resolution.Daily)["open"][1] - 1)
                Xs.append(algorithm.History(sec.Symbol,15, Resolution.Daily)["open"])
        
        if len(Xs) >= 1:
            for X in Xs:
                Ys.append(X[0] / X[1] - 1)
            Xs = np.array(Xs) #shape: (number of secs , 15 )
            Ys = np.array(Ys) #shape: (number of secs, )
            
            sgd = SGD(lr = 0.05) # learning rate = 0.01

            self.model.compile(loss='mse', optimizer=sgd)

            cost = self.model.fit(x=Xs, y=Ys, batch_size=None, epochs=10)
        

    def Update(self, algorithm, data):
        
        ups = []
        downs = []
        
        for i in self.mom:
            if self.mom[i] > 0.01:
                ups.append(Insight.Price(i, timedelta(days = 1), InsightDirection.Up))
            elif self.mom[i] < -0.01:
                downs.append(Insight.Price(i, timedelta(days = 1), InsightDirection.Down))
            else:
                pass
        
        algorithm.Debug(f"Produced {len(ups)+len(downs)} insights")
        return Insight.Group(ups + downs)
        
 
class FrameworkAlgorithm(QCAlgorithm):
    
    def Initialize(self):
        self.SetStartDate(2014, 10, 1)   
        self.SetEndDate(2014, 12, 1)    
        self.SetCash(100000)           
        
        #symbols = [Symbol.Create("SPY", SecurityType.Equity, Market.USA),  Symbol.Create("BND", SecurityType.Equity, Market.USA)]
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(self.MyCoarseFilterFunction, self.MyFineFundamentalFunction)
        
        self.SetAlpha(MOMAlphaModel())
        
        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
        self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.02))
        
        #1. Set the Execution Model to an Immediate Execution Model
        self.SetExecution(ImmediateExecutionModel())
        #self.Debug(f"I hold these secs: {[sec.Symbol for sec in self.Securities]}")
        
    def MyCoarseFilterFunction(self, coarse):
        sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
        filtered = [ x.Symbol for x in sortedByDollarVolume if x.HasFundamentalData ]
        return filtered[:80]

    def MyFineFundamentalFunction(self, fine):
        sortedByPeRatio = sorted(fine, key=lambda x: x.ValuationRatios.PERatio, reverse=False)
        return [ x.Symbol for x in sortedByPeRatio[:20] ]
        #how do insights work