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
-11.991
Tracking Error
0.012
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
import numpy as np  # needed for NaN handling
import math  # ceil and floor are useful for rounding
from datetime import timedelta
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Common")
import statistics
from System import *
from QuantConnect import *


import talib

class MyAlgorithm(QCAlgorithm):
    
    def Initialize(self):
        
        self.symbols = None
        
        # over simplistic tracking of position age
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
        
        #self.SetSlippageModel(VolumeShareSlippageModel())
        # SMA 
        self.SetStartDate(2019,1,1)  #Set Start Date
        self.SetEndDate(2020,6,28)    #Set End Date
        self.SetCash(1000)
        #self.SetWarmUp(50, Resolution.Minute)
        
        self.SetBenchmark("SPY")
        self.UniverseSettings.Resolution = Resolution.Minute
        self.UniverseSettings.Leverage = 1
        
        self.AddSecurity("SPY", Resolution.Minute).Symbol
        self.Max_Candidates = 100
        self.Max_BuyOrdersAtOnce = 20
        self.MyLeastPrice = 1.50
        self.MyMostPrice = 5.00
        self.MyFireSalePrice = self.MyLeastPrice
        self.MyFireSaleAge = 6
        
        #self.time = { };
        self.averages = { };
        #self.changes = None
        #self.index = 0
        
        self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x))) # esto es para resolution menor de day
        
        #self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
        self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction))
        
        #BEFORE TRADING START en initialize
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", -10), Action(self.before_trading_start))
        
        
        # Rebalance
        EveryThisManyMinutes = 10
        TradingDayHours = 6.5
        TradingDayMinutes = int(TradingDayHours * 60)
        #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(timedelta(minutes=EveryThisManyMinutes)), Action(self.my_rebalance))
        
        for minutz in range(1, TradingDayMinutes, EveryThisManyMinutes):
            self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", minutz), Action(self.my_rebalance))
        
        # Prevent excessive Logging of canceled orders at market close.
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose("SPY", 1), Action(self.cancel_open_orders))
        
        
        
        
    def OnSecuritiesChanged(self, changes):
        self.Debug("checking")
        self.changes = changes
        
        
    def CoarseSelectionFunction(self, coarse):
       
        sorted(coarse, key = lambda x: x.DollarVolume, reverse = True)
           
        # We are going to use a dictionary to refer the object that will keep the moving averages
        #self.Debug('coarse ' +str(coarse))
        for cf in coarse:
            if cf.HasFundamentalData:
                if cf.Symbol not in self.averages:
                    self.averages[cf.Symbol] = SymbolData(cf.Symbol)
                    
                # Updates the SymbolData object with current EOD price
                avg = self.averages[cf.Symbol]
                avg.update(cf.EndTime, cf.AdjustedPrice)

        # Filter the values of the dict: we only want up-trending securities
        #values = list(filter(lambda x: x.is_downtrend, self.averages.values()))
        #values.sort(key = lambda x: x.scale , reverse = False)
        values = sorted(self.averages.values(), key = lambda x: x.scale, reverse = True)[:self.Max_Candidates]
        self.values = list(values)
        #for x in self.values:
        #    self.Debug('values ' + str(x.symbol) + ' price ' + str(x.price) + ' scale ' + str(x.scale))
            
        self.g = [x for x in self.values if (float(x.price) >= self.MyLeastPrice) and (float(x.price) <= self.MyMostPrice)]
        
        return  [ x.symbol for x in self.g[:self.Max_Candidates] ]
        
        

    def FineSelectionFunction(self, fine):
        
        self.filtered = [x for x in fine if (x.SecurityReference.SecurityType == 'ST00000001') 
        and (x.SecurityReference.IsDepositaryReceipt == False)
        and not (x.CompanyReference.IsLimitedPartnership)
        and (x.SecurityReference.IsPrimaryShare)
        and (x.SecurityReference.ExchangeId != 'OTC')]
        #and x.CompanyReference.StandardName == ".*L[. ]?P.?$"]
        # Not when-issued equities.
        
        
        LowVar = 0.06 * len(self.filtered)
        
        HighVar = 0.4 * len(self.filtered)
        
        
        self.filtered_h = [x.Symbol for x in self.filtered[:int(HighVar)]]
        self.filtered_l = [x.Symbol for x in self.filtered[-int(LowVar):]]
        
        
        self.symbols = self.filtered_h + self.filtered_l
        
        
        return self.symbols


    def before_trading_start(self):
        #update prices of my active securities and do some checks about the time they have been in my portfolio
        
         pass    
    
    def cancel_open_orders(self):
        pass

    def my_rebalance(self):
        #do my buy and sells checking minute bars prices by comparing it to period daily prices mean
        data = self.CurrentSlice
        for symbol, symbol_data in self.averages.items():
            if not (data.ContainsKey(symbol) and data[symbol] is not None):
                continue
            current_price = data[symbol].Price
            mean = symbol_data.fast.Current.Value   # daily mean
            self.Quit(f"{symbol}; Current price: {current_price}; Mean: {mean}")
            
            self.Quit()

    
    def OnData(self, data):
        
        pass
    
class SymbolData(object):
    def __init__(self, symbol):
        self.symbol = symbol
        
        #SMA (daily resolution)

        self.fast = SimpleMovingAverage(3)
        self.slow = SimpleMovingAverage(45)
        self.price = 0
        self.is_downtrend = False
        self.scale = 0 
        

    def update(self, time, value):
        self.price = value
        if self.fast.Update(time, value) and self.slow.Update(time, value):
            fast = self.fast.Current.Value
            slow = self.slow.Current.Value
            self.is_downtrend = fast < slow
            self.scale = (fast-slow)/slow
        
        if self.is_downtrend:
            self.scale = (fast - slow) / slow