Overall Statistics
Total Trades
621
Average Win
0.57%
Average Loss
-0.73%
Compounding Annual Return
43.899%
Drawdown
21.200%
Expectancy
0.575
Net Profit
168.097%
Sharpe Ratio
1.429
Loss Rate
12%
Win Rate
88%
Profit-Loss Ratio
0.78
Alpha
0.265
Beta
4.43
Annual Standard Deviation
0.239
Annual Variance
0.057
Information Ratio
1.357
Tracking Error
0.239
Treynor Ratio
0.077
Total Fees
$967.76
import numpy as np
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Indicators")
AddReference("QuantConnect.Common")
import math as mt
from System import *
from QuantConnect import *
from QuantConnect.Data import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
from System.Collections.Generic import List
import decimal as d
from datetime import timedelta
### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>

def make_div_by_05(s, buy=False):
        s *= 20.00
        s =  mt.floor(s) if buy else mt.ceil(s)
        s /= 20.00
        return s               
class theMAs(object):
    def __init__(self,symbol):
        self.dv = 0 
        price = 0 
        self.symbol = symbol
        self.Short = SimpleMovingAverage(3)
        self.Long = SimpleMovingAverage(42)
        self.percent_diff = 0 
    def update(self,time,value):
        if self.Short.Update(time,value) and self.Long.Update(time,value):
            short = self.Short.Current.Value
            Long = self.Long.Current.Value
class BasicTemplateAlgorithm(QCAlgorithm):
    def __init__(self):
        self.Age = {}
    def Initialize(self):
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
        self.SetWarmUp(200)
        self.firstbuy = 1
        self.days = 0
        self.Tobuy = 0
        self.filtered_stocks = []
        self.averages = {}
        self.MaxCandidates=50
        self.MaxBuyOrdersAtOnce=20
        self.MyLeastPrice=0.40
        self.MyMostPrice=1.40
        self.MyFireSalePrice=self.MyLeastPrice
        self.MyFireSaleAge=3
        self.SetStartDate(2016,1,07)  #Set Start Date
        self.SetEndDate(2017,12,07)    #Set End Date
        self.SetCash(2500)           #Set Strategy Cash
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddEquity("SPY", Resolution.Daily)
        self.AddUniverse(self.CoarseSelectionFunction,self.FineSelectionFunction)
        self.Schedule.On(self.DateRules.EveryDay(),self.TimeRules.Every(timedelta(minutes=10)),Action(self.rebalance))
        self.Schedule.On(self.DateRules.EveryDay(),self.TimeRules.At(9,37),Action(self.before_trading_start))
    def CoarseSelectionFunction(self, coarse):
        
        stocks_To_buy = filter(lambda x: x.Price >=self.MyLeastPrice,coarse)
        stocks_To_buy = filter(lambda x: x.Price <=self.MyMostPrice,stocks_To_buy)
        stocks_To_buy = filter(lambda x: x.HasFundamentalData,stocks_To_buy)
        
        #for stock in stocks_To_buy[:10]:
            #self.Log("The market of the stock is {}".format(stock.StandardName))
            
        #Symbols with more than 5 letters are usually not common stocks and otc's have 5 letters
        
        #Check here for more info https://www.investopedia.com/ask/answers/06/nasdaqfifthletter.asp(could take off)
        
        return [x.Symbol for x in stocks_To_buy[:60] if len(str(x.Symbol.Value)) < 5 and x.Symbol.Value != 'SPY' ]
        
    def FineSelectionFunction(self, fine):
        #Making sure not mlp
        stocks_To_buy = filter(lambda x: 'lp' not in str(x.CompanyReference.ShortName).lower(),fine)
        #Making sure not adr
        stocks_To_buy = filter(lambda x: int(x.SecurityReference.IsDepositaryReceipt) ==0,stocks_To_buy)
        #Making sure is primary adr
        stocks_To_buy = filter(lambda x: x.SecurityReference.IsPrimaryShare,stocks_To_buy)
        #Making sure not otc
        stocks_To_buy = filter(lambda x: str(x.SecurityReference.ExchangeId) != "OTC",stocks_To_buy)
        #get moving averages and dollar volume
        for stock in stocks_To_buy:
            self.AddEquity(str(stock.Symbol.Value))
            hist = self.History([stock.Symbol.Value],20,Resolution.Daily)
            if 'volume' in hist:
                dv = (hist['volume'].mean()*hist['close'].mean())/len(hist)
                #self.dvolume[stock.Symbol.Value] = dvolume(stock.Symbol.Value,dv)  
                #self.Log(("Volume for stock {} is {}".format(self.dvolume[stock.Symbol.Value].symbol,self.dvolume[stock.Symbol.Value].dvolAvg)))
            
                if stock.Symbol not in self.averages:
                    self.averages[stock.Symbol] = theMAs(stock.Symbol)
                avg = self.averages[stock.Symbol]
                avg.dv=dv
                avg.price = self.Securities[stock.Symbol.Value].Price
                avg.update(stock.EndTime,self.Securities[stock.Symbol.Value].Price)
                if float(str(avg.Long)) >0 :
                    avg.percent_diff = (float(str(avg.Short)) - float(str(avg.Long))) / float(str(avg.Long))
                    #self.Log("The long ma for {} is {}".format(stock.Symbol.Value,avg.dv))
        values = self.averages.values()
        
        values.sort(key=lambda x: x.dv)
        
        minmum_range = int(round(len(values) * 0.06))
        maximum_range = int(round(len(values) * 0.40))
        if minmum_range < 1:
            minmum_range =0
        if maximum_range < 1:
            maximum_range = 1
        values = values[minmum_range:maximum_range]
        values.sort(key=lambda x: x.percent_diff)
        values = values[:10]
        #self.Log(str(values[0].dv))
        #for stock in values:
            #self.Log("{0} {1}".format(str(stock.symbol),str(stock.percent_diff)))
        #self.Log("--------")
        #for stock in stocks_To_buy:
            #self.Log("here is the stock{}".format(str(stock.SecurityReference.ExchangeId)))
            
        return [ x.symbol for x in values]
        
    def before_trading_start(self):
        day = str(self.UtcTime).split("-")[-1]
        day = day.split(" ")[0]
        #self.Log(str(day))
        MyLeastPrice=0.40
        MyMostPrice=1.40
        for stock in self.Portfolio.Values:
            if stock.Invested:
                if str(stock.Symbol) not in self.Age:
                    self.Age[str(stock.Symbol)] = 0
                else:
                    self.Age[str(stock.Symbol)]+=1
                #self.Log(str(self.Age[stock.Symbol]))
        """for stock.Symbol in self.Age:
            if stock.Symbol not in self.Portfolio.Values:
                self.Age.pop(stock.Symbol)
                
            #self.Log(str(self.Age[stock.Symbol]))
        lowestprice = MyLeastPrice
        if len(self.Portfolio.Transactions) > 0:
            for stock in self.Portfolio.Transactions:
                self.Log(str(stock))
                if stock.Invested:
                #theid = self.Transactions.LastOrderId(str(stock.Symbol))
                #self.Log(str(self.Transactions.GetOrderById(theid)))
                    curr_price = float(self.Securities[stock.Symbol].Price)
                if curr_price < lowestprice:
                    lowestprice = curr_price
        else:
            self.Log(str(self.Portfolio.Transactions))"""
                   
            
            
    def OnSecuritiesChanged(self, changes):
        time = str(self.Time).split(' ')[1]
        hour = time.split(':')[0]
        m = time.split(':')[1]
        self.filtered_stocks = [stock for stock in changes.AddedSecurities]
        #self.Log("amount of stocks in universe {}".format(len(self.filtered_stocks)))

    def rebalance(self):
        
        cash = float(self.Portfolio.Cash)
        self.Tobuy = float(len(self.filtered_stocks))
        if self.Tobuy > 0:
            weight = float(1/self.Tobuy)
        self.days+=1
        BuyFactor=0.96
        SellFactor=1.05
        for stock in self.Portfolio.Values:
            if stock.Invested:
                if len(self.Transactions.GetOpenOrders(stock.Symbol)) == 0:
                    curr_price = float(self.Securities[stock.Symbol].Price)
                    cost_basis = float(self.Portfolio[stock.Symbol].AveragePrice)
                    shares_held = self.Portfolio[stock.Symbol].Quantity
                    sell_price = make_div_by_05(curr_price*SellFactor,buy = False)
                    if (sell_price)== 0 and shares_held > 0:
                        pass
                    if stock.Symbol in self.Age:
                        if(self.Age[str(stock.Symbol)] % 3 == 0) and self.Age[str(stock.Symbol)] >= self.MyFireSaleAge \
                        and self.MyLeastPrice > curr_price or cost_basis >curr_price:
                            stop_price = float(make_div_by_05(0.96*curr_price,buy=False))
                            self.LimitOrder(stock.Symbol,-shares_held,stop_price)
                    else:
                        self.LimitOrder(stock.Symbol,-shares_held,sell_price)
        if len(self.filtered_stocks) > 0 and cash > 0:
            self.Log(str(cash))
            for stock in self.filtered_stocks:
                shares_held = self.Portfolio[stock.Symbol].Quantity
                oo = len(self.Transactions.GetOpenOrders(stock.Symbol))
                if shares_held == 0 and oo == 0:
                    hist = self.History([stock.Symbol],20,Resolution.Daily)
                    if 'close' in hist.columns:
                        avg_price = float(hist['close'].mean())
                        curr_price = float(self.Securities[stock.Symbol].Price)
                        if curr_price == None or curr_price == 0:
                            pass
                        else:
                            if curr_price > (1.2* avg_price):
                                buy_price = curr_price*0.99
                            else:
                                buy_price=float(make_div_by_05(BuyFactor*curr_price, buy=True))
                                #self.Log("The cash{} The weight{} the curr_price{} the buy_price{}".format(cash,weight,curr_price,buy_price))
                            StockShares = int(cash*0.25/buy_price)    
                            self.LimitOrder(stock.Symbol,StockShares,buy_price)
                            self.filtered_stocks.pop(self.filtered_stocks.index(stock))
                            self.Notify.Sms("5105011500", "Stock Watched:\n" + str(stock.Symbol) + "\n Resistance: $" + str(buy_price) + "\nFuego Financial")
                            self.Notify.Sms("7073190735", "Stock Watched:\n" + str(stock.Symbol) + "\n Resistance: $" + str(buy_price) + "\nFuego Financial")
                            self.Notify.Sms("5105989476", "Stock Watched:\n" + str(stock.Symbol) + "\n Resistance: $" + str(buy_price) + "\nFuego Financial")