Overall Statistics
Total Trades
37
Average Win
5.34%
Average Loss
-4.31%
Compounding Annual Return
11876.144%
Drawdown
11.400%
Expectancy
0.493
Net Profit
40.619%
Sharpe Ratio
79.354
Probabilistic Sharpe Ratio
88.616%
Loss Rate
33%
Win Rate
67%
Profit-Loss Ratio
1.24
Alpha
74.668
Beta
2.313
Annual Standard Deviation
0.942
Annual Variance
0.888
Information Ratio
83.068
Tracking Error
0.9
Treynor Ratio
32.336
Total Fees
$53.04
Estimated Strategy Capacity
$210000.00
import math
from io import StringIO
import pandas as pd

class FocusedYellowGreenGaur(QCAlgorithm):
   
    # Order ticket for our stop order, Datetime when stop order was last hit
    universeOpenPrice = {}
    universeClosePrice = {}
    boughtInPrice = {}
    peakPrices = {}
    orderTickets = {}
    stocks = []
    tradingEnabled = False
    allInvestments = []
    df = [2]*2
    startingCash = 0
    numDiversify = 0
    tickerNames = {}
    def Initialize(self):
        self.SetStartDate(2021, 1, 4)
        self.SetEndDate(2021, 1, 31)
        self.SetCash(1000)
        #universe = self.AddUniverse(self.MyCoarseFilterFunction, self.MyFineFilterFunction)
        self.SetSecurityInitializer(self.CustomSecurityInitializer)
        universe = self.AddUniverse(self.MyCoarseFilterFunction)
        self.UniverseSettings.Resolution = Resolution.Minute
        self.SetTimeZone("America/New_York")
        self.numDiversify = 1
        csv = self.Download("https://www.dropbox.com/s/owfplskyiwuc70a/companyNames.csv?dl=1")
        #sep='\t',
        self.tickerNames = pd.read_csv(StringIO(csv), header = 0, index_col = 0, squeeze = True).to_dict()
        self.Debug(self.tickerNames)
    def OnData(self, data):
        self.tradingManager(data)
        #for x in allInvestments:
        #    self.Plot("Data Chart", "Asset Price", self.Securities[x].Close)
    def CustomSecurityInitializer(self, security):
        '''Initialize the security with raw prices'''
        security.SetDataNormalizationMode(DataNormalizationMode.Adjusted)         
    def tradingManager(self, data):
        hour = self.Time.hour
        minute = self.Time.minute
        self.Log("Current Hour: " + str(hour))
        self.Log("Current Minute: " + str(minute))
        self.tradingHours()
        if (hour == 9) and (minute == 31):
            self.updateStocks(data)
            self.onMarketOpen()
        if (hour == 15) and (minute == 53):
            self.allInvestments = []
        if (hour == 15) and (minute == 59):
            self.beforeMarketClose()
            self.startingCash = self.Portfolio.Cash
            buying = self.calculateDeals(self.numDiversify)
            for toBuy in buying:
                self.buy(toBuy)
        if self.Portfolio.Invested:
            for x in self.allInvestments:
                self.Debug("Trying to sell: " + x.Value)
                self.sell(x)
        else:
            self.Debug("Successfully sold stock\n")
    def getStockName(self, ticker):
        if (ticker in self.tickerNames):
            return self.tickerNames[ticker]
        else:
            return "NULL"
    def updateStocks(self, data):
        self.stocks = []
        tempTickers = []
        tempStocks = []
        for universe in self.UniverseManager.Values:
        #for x in data:
            self.Debug("Number of Keys: " + str(len(universe.Members.Keys)))
            #if (universe is self.UniverseManager.UserDefinedUniverse):
            #   continue
            for key in universe.Members.Keys:
                if key.Value == "JMIA":
                    self.Debug(key.Value + " is in the dataset")
                self.stocks.append(key)
            self.stocks = sorted(self.stocks, key=lambda x: x.Value, reverse=False)
            #Sort alphabetically
            #self.stocks = []
            #for x in symbol:
            #    self.Log("\nI am on the ticker: " + x.Value)
            #    self.stocks.append(x)
            
    def tradingHours(self):
        minute = self.Time.minute
        hour = self.Time.hour
        day = self.Time.day
        if (hour == 9) and (minute == 31):
            self.tradingEnabled = True
            self.Debug("\nI am enabling trading")
        if (hour == 16):
            self.tradingEnabled = False
            self.Debug("\nI am disabling trading")
        return
    def onMarketOpen(self):
        self.universeOpenPrice = {}
        self.universeClosePrice = {}
        self.Debug("\nSize of stocks: " + str(len(self.stocks)))
        self.startingCash = self.Portfolio.Cash
        for owned in self.allInvestments:
            if ((not owned.Value in self.boughtInPrice)):
            #or (not owned in self.Portfolio)):
                continue
            self.orderTickets[owned] = self.StopMarketOrder(owned, ( -1) * self.Portfolio[owned].Quantity, self.boughtInPrice[owned.Value] * 0.95)
            #if ((self.Portfolio[owned].Price) > (self.boughtInPrice[owned.Value] * 1.02)):    
            #    self.Debug("Attemping to liquidate")
            #    self.Liquidate(owned)
            #else:
            #    self.Debug("Attemping to put limit sell")
            #    self.orderTickets[owned] = self.LimitOrder(owned, (-1) * self.Portfolio[owned].Quantity, self.boughtInPrice[owned.Value] * 1.02)
        self.UniverseSettings.Resolution = Resolution.Daily
        for x in self.stocks:
            #self.Log("\nI am on the ticker: " + x.Value)
            #self.Log("\nOpen Price: " + str(self.Securities[x].Price))
            self.df = self.History(self.Symbol(x), 1)
            #for row in self.df:
            #    self.Debug(str(row))
            if (len(self.df) > 0):    
                openPrices = self.df["open"]
                openPrices.unstack('symbol')
                if (len(openPrices) > 0):
                    for prices in openPrices:
                        self.universeOpenPrice[x] = prices
            else:
                self.stocks.remove(x)
        self.UniverseSettings.Resolution = Resolution.Minute
        return
    def beforeMarketClose(self):
        self.universeClosePrice = {}
        for x in self.stocks:
            self.Log("\nClose Price: " + str(self.Securities[x].Price))
            self.universeClosePrice[x] = self.Securities[x].Price
        for x in self.stocks:
            if (x.Value == "SEAC"):
                self.Debug("SEAC EMA: " + str(self.get7DayEMA(x)))
            if (x.Value == "QS"):
                self.Debug("QS Vol: " + str(self.getVolatilityScore(x)))
        return
    def MyCoarseFilterFunction(self, coarse):
        sortedByName = sorted(coarse, key=lambda x: x.Symbol.Value, reverse=False)
        filtered = []
        for x in sortedByName:
            #self.Debug("I am on the ticker: " + x.Symbol.Value)
            if (x.Symbol.Value == "JMIA"):
                self.Debug("JMIA is present before filter")
                self.Debug("JMIA Volume: " + str(x.Volume))
                self.Debug("JMIA Price: " + str(x.Price))
            if(x.Volume > 500000):
                if(x.Symbol.Value == "JMIA"):
                    self.Debug("Passed Volume test")
                if x.Price > 1:
                    if(x.Symbol.Value == "JMIA"):
                        self.Debug("Passed the price test. Adding to universe")
                    filtered.append(x.Symbol)
                #self.Debug("VoLScore: " + str(self.getVolatilityScore(x.Symbol)))
                #self.Debug("isBelow7DayEMA: " + str(self.isBelow7DayEMA(x.Symbol)))
                #self.Debug("is trending down: " + str(self.trendingDown(x.Symbol)))
        '''
        filtered = [ x.Symbol for x in sortedByName 
        if x.Volume > 500000 and
        x.Price > 10
        ]
        '''
        return filtered    
    
    def MyFineFilterFunction(self, fine):
        filtered = []
        self.Debug("I printed this before I shat myself")
        for x in fine:
            if x.Symbol.Value == "JMIA":
                self.Debug("JMIA present in fine")
            if((not ("pharma" in x.CompanyReference.LegalName))
            and (not ("Pharma" in x.CompanyReference.LegalName))
            and (not ("Medical" in x.CompanyReference.LegalName))
            and (not ("medical" in x.CompanyReference.LegalName))
            and (not ("peutics" in x.CompanyReference.LegalName))
            and (not ("Bio" in x.CompanyReference.LegalName))
            and (not ("bio" in x.CompanyReference.LegalName))):
                filtered.append(x.Symbol)
        return filtered
    def passTests(self, stock):
        return True
    def OnOrderEvent(self, orderEvent):
        if orderEvent.Status != OrderStatus.Filled:
            return
        
    def getHistory(self, ticker):
        self.Debug("On ticker: " + ticker)
        return
    
    def getAllHistory(self):
        for ticker in self.Securities.keys:
            self.getHistory(ticker)
        return
    def getPremarketScore(self, stock):
        self.df = self.History(self.Symbol(stock), 6, Resolution.Daily)
        openPrices = self.df["open"]
        closePrices = self.df["close"]
        open = []
        close = []
        openPrices.unstack('symbol')
        closePrices.unstack('symbol')
        for prices in openPrices:
            open.append(prices)
        for prices in closePrices:
            close.append(prices)
        percentChange = 0
        tempOpen = 0
        tempClose = 0
        percentChange = 0;
        numPositives = 0
        if (len(open) < 6) or (len(close) < 6):
            return 0
        for x in range(5):
            tempOpen = open[x + 1]
            tempClose = close[x]
            percentChange = abs(((tempOpen - tempClose) / tempClose) * 100)
            if (percentChange > 0):
                numPositives = numPositives + 1
        return numPositives
    def getAvgPremarketIncrease(self, stock):
        self.df = self.History(self.Symbol(stock), 6, Resolution.Daily)
        openPrices = self.df["open"]
        closePrices = self.df["close"]
        open = []
        close = []
        openPrices.unstack('symbol')
        closePrices.unstack('symbol')
        posSum = 0
        for prices in openPrices:
            open.append(prices)
        for prices in closePrices:
            close.append(prices)
        percentChange = 0
        tempOpen = 0
        tempClose = 0
        percentChange = 0;
        numPositives = 0
        if (len(open) < 6) or (len(close) < 6):
            return 0
        for x in range(5):
            tempOpen = open[x + 1]
            tempClose = close[x]
            percentChange = abs(((tempOpen - tempClose) / tempClose) * 100)
            if (percentChange > 0):
                numPositives = numPositives + 1
                posSum = posSum + percentChange
        return posSum / numPositives
    def getVolatilityScore(self, stock):
        self.df = self.History(self.Symbol(stock), 7, Resolution.Daily)
        openPrices = self.df["open"]
        closePrices = self.df["close"]
        open = []
        close = []
        openPrices.unstack('symbol')
        closePrices.unstack('symbol')
        for prices in openPrices:
            open.append(prices)
        for prices in closePrices:
            close.append(prices)
        percentChange = 0
        tempOpen = 0
        tempClose = 0
        percentSum = 0;
        if (len(open) < 7) or (len(close) < 7):
            return 0
        for x in range(7):
            tempOpen = open[x]
            tempClose = close[x]
            percentChange = abs(((tempOpen - tempClose) / tempClose) * 100)
            percentSum = percentSum + percentChange
        return percentSum
        #for col in self.df.iterrows():
            # + str(row)
            #self.Debug(str(self.df[col]['close']) + "\n")
    def trendingDown(self, stock):
        self.df = self.History(self.Symbol(stock), 6, Resolution.Daily)
        closePrices = self.df["close"]
        close = []
        closePrices.unstack('symbol')
        for prices in closePrices:
            close.append(prices)
        if (len(close) < 6):
            if(stock.Value == "SEAC"):
                self.Debug("WTF SEAC DOESNT HAVE ENOUGH PRICES?")
            return False
        sum = 0
        for i in range(6):
            #if(stock.Value == "AHT"):
                #self.Debug("Current Close Price: " + str(close[i]))
            if (((i + 1) % 2) == 0):
                sum = sum + close[5 - i]
            else:
                sum = sum - close[5 - i]
        #self.Debug("Trending Down Sum: " + str(sum))
        return (sum > 0)
    def get7DayMovingAverage(self, stock):
        self.df = self.History(self.Symbol(stock), 7, Resolution.Daily)
        closePrices = self.df["close"]
        close = []
        closePrices.unstack('symbol')
        for prices in closePrices:
            close.append(prices)
        sum = 0
        if (len(close) < 7):
            return 0
        for i in range(7):
            sum = sum + close[i]
        return (sum / 7)
        
    def EMAHelper(self, stock, close, numDays, daysLeft):
        sevenAvg = self.get7DayMovingAverage(stock)
        if (sevenAvg == 0):
            return 0
        if daysLeft == 0:
            value = (((close[numDays - 1]) - sevenAvg) * (2/(numDays + 1))) + sevenAvg
        else:
            prevEMA = self.EMAHelper(stock, close, numDays, (daysLeft - 1))
            value = ((close[numDays - daysLeft - 1] - prevEMA)) * (2/(numDays + 1)) + prevEMA
        return value
        '''
        double value;
        if (daysRemaining == 0)
        {
            double sevenAvg = get7DayMovingAverage(stock);
            value = ((stock.getClosePrice() - sevenAvg) * (2/(numDays + 1))) + sevenAvg;
        }
        else
        {
            value = ((stock.getClosePrice() - EMAHelper(getPreviousDayStock(stock), daysRemaining - 1)) * (2/(numDays + 1))) + EMAHelper(getPreviousDayStock(stock), daysRemaining - 1);
        }
        return value;
        '''
    def get7DayEMA(self, stock):
        self.df = self.History(self.Symbol(stock), 14, Resolution.Daily)
        closePrices = self.df["close"]
        close = []
        closePrices.unstack('symbol')
        for prices in closePrices:
            close.append(prices)
        sum = 0
        if (len(close) < 14):
            return 0
        for i in range(7):
            sum = sum + close[i]
        average = sum / 7
        tempEMA = average
        value = ((self.universeClosePrice[stock] - tempEMA) * (2/8)) + tempEMA
        if (stock.Value == "SEAC"):
            self.Debug("SEAC 7 DAY EMA: " + str(average))
        return average
    def isBelow7DayEMA(self, stock):
        sevenEMA = self.get7DayEMA(stock)
        currentPrice = self.universeClosePrice[stock]
        if (sevenEMA == 0):
            return True
        return (currentPrice < sevenEMA)
        '''
        double value;
        if (daysRemaining == 0)
        {
            double sevenAvg = get7DayMovingAverage(stock);
            value = ((stock.getClosePrice() - sevenAvg) * (2/(numDays + 1))) + sevenAvg;
        }
        else
        {
            value = ((stock.getClosePrice() - EMAHelper(getPreviousDayStock(stock), daysRemaining - 1)) * (2/(numDays + 1))) + EMAHelper(getPreviousDayStock(stock), daysRemaining - 1);
        }
        '''
    def calculateDeals(self, numDeals):
        alreadyBuying = []
        for i in range(numDeals):
            toAdd = self.calculateDeal(alreadyBuying)
            if toAdd != None:
                alreadyBuying.append(toAdd)
        return alreadyBuying
    def calculateDeal(self, alreadyBuying):
        #self.Debug("\nI am calculating the deals!")
        checking = "SEAC"
        boughtInstead = "AGFS"
        highestPercentChange = 0
        percentChange = 0
        volScore = 0
        bestVolScore = 0
        posScore = 0
        bestPosScore = 99
        deal = None
        skip = False
        for ticker in self.stocks:
            #self.Debug("I am on the ticker: " + ticker.Value)
            #self.Debug(ticker.Value)
            name = self.getStockName(ticker.Value)
            if (name == "NULL"):
                continue
            #self.Debug(name)
            if((("pharma" in name))
            or (("Pharma" in name))
            or (("Medical" in name))
            or (("medical" in name))
            or (("peutics" in name))
            or (("Bio" in name))
            or (("bio" in name))):
                continue
            #if (ticker.Value == "QS"):
            #    self.Debug("QS thrown out in deal method")
            if len(ticker.Value) > 4:
                continue
            if not ((ticker in self.universeOpenPrice) and (ticker in self.universeClosePrice)):
                continue
            openPrice = self.universeOpenPrice[ticker]
            closePrice = self.universeClosePrice[ticker]
            if ticker.Value == checking:
                self.Debug(checking + " is now being evaluated")
                self.Debug("Open Price: " + str(openPrice))
                self.Debug("Close Price: " + str(closePrice))
            #if ticker.Value == boughtInstead:
            #    self.Debug(boughtInstead + " is now being evaluated")
            #    self.Debug("Open Price: " + str(openPrice))
            #    self.Debug("Close Price: " + str(closePrice))
            if (len(alreadyBuying) > 0):
                for buying in alreadyBuying:
                    if buying.Value == ticker.Value:
                        skip = True
            if skip:
                continue
            if ((((self.Portfolio.Cash / self.numDiversify) * 0.9) < closePrice)):
                continue
            if ((openPrice == 0) or (closePrice == 0)):
                continue
            percentChange = ((closePrice - openPrice) / (closePrice)) * 100
            if (ticker.Value == checking):
                self.Debug(checking + " percentChange: " + str(percentChange))
            if (ticker.Value == boughtInstead):
                self.Debug(boughtInstead + " percentChange: " + str(percentChange))
            if ((percentChange < -40) or (percentChange > 0)):
                if (ticker.Value == checking):
                    self.Debug("WTF " + checking + " IS BELOW -40?")
                continue
            if (not self.isBelow7DayEMA(ticker)):
                if (ticker.Value == checking):
                    self.Debug("WTF " + checking +" is below 7 day ema!?")
                continue
            if (not self.trendingDown(ticker)):
                if (ticker.Value == checking):
                    self.Debug("Wtf " + checking + " is trending down?")
                continue
            volScore = self.getVolatilityScore(ticker)
            if (percentChange < highestPercentChange):
                if (volScore > 50):
                    continue
                if ((volScore) > bestVolScore):
                    bestVolScore = volScore
                else:
                    if (ticker.Value == checking):
                        self.Debug("Best Score: " + str(bestVolScore))
                        self.Debug("Current Score: "+ str(volScore))
                    continue
                '''
                posScore = self.getPremarketScore(ticker)
                if (posScore < bestPosScore):
                    posIncrease = self.getAvgPremarketIncrease(ticker)
                    if (posIncrease > 2):
                        bestPosScore = posScore
                        self.Debug("I am overridding best pos score")
                    else:
                        #bestVolScore = volScore
                    #self.Debug("Not the best volScore")
                    if (ticker.Value == checking):
                        self.Debug("WTF " + checking + " DOESNT HAVE THE BEST VOLSCORE?")
                        self.Debug(checking + "'s Volscore is: " + str(volScore))
                        self.Debug(deal.Value + " has a volscore of: " + str(self.getVolatilityScore(deal)))
                    continue
                '''
                if(deal != None):
                    if(deal.Value == checking):
                        self.Debug("WTF " + checking + " IS BEING OVERWRITTEN?")
                if not (((deal is None) or (ticker is None))):
                    self.Debug("Ticker " + deal.Value + " overwritten by " + ticker.Value) 
                highestPercentChange = percentChange
                deal = ticker
            else:
                if (ticker.Value == checking):
                    self.Debug("WTF " + checking + " IS NOT THE HIGHEST DECREASE?")
        if deal != None:
            self.Debug("\nCalculated Deal: " + deal.Value)
        return deal
        #for ticker in self.Securities.keys:
    def buy(self, toBuy):
        if (not toBuy in self.universeClosePrice):
            return
        price = self.universeClosePrice[toBuy]
        self.Debug("Price: " + str(price))
        purchasingPower = (self.startingCash / self.numDiversify) * 0.95
        numShares = math.floor((purchasingPower)/ price)
        self.Debug("Number of Shares: " + str(numShares))
        self.MarketOrder(toBuy, numShares)
        self.boughtInPrice[toBuy.Value] = self.Portfolio[toBuy].Price
        self.peakPrices[toBuy] = price
        self.Debug("I am buying " + toBuy.Value)
        self.allInvestments.append(toBuy)
        self.tradingEnabled = False
        return numShares
    def sell(self, toSell):
        if (not self.tradingEnabled):
            return
        if (( not toSell.Value in self.boughtInPrice )
        or ( not toSell in self.Portfolio )
        or ( not toSell in self.orderTickets )
        or (not toSell in self.peakPrices)
        or (not toSell in self.universeOpenPrice)):
            return
        self.Debug ("I have made it past the tests")
        currentPrice = self.Portfolio[toSell].Price
        boughtIn = self.boughtInPrice[toSell.Value]
        numShares = self.Portfolio[toSell].Quantity
        ticket = self.orderTickets[toSell]
        delta = ((self.peakPrices[toSell] - boughtIn) / boughtIn) * 100
        #if ((self.boughtInPrice[toSell.Value] * (0.98)) > self.universeOpenPrice[toSell]):
        #    ticket.Cancel("The Stock " + toSell.Value + " opened below purchase price")
        #    self.Liquidate(toSell)
        if (currentPrice > self.peakPrices[toSell]):
            self.peakPrices[toSell] = currentPrice
        updateSettings = UpdateOrderFields()
        self.Debug("Delta: " + str(delta))
        if ((delta > 5) and (delta < 10)):
            updateSettings.StopPrice = self.peakPrices[toSell] * 0.97
            updateSettings.Tag = "\nChanging the trailing stop"
            #ticket.Cancel("Updating StopMarketOrder")
            #self.orderTickers[toSell] = self.StopMarketOrder(toSell, ( -1) * self.Portfolio[toSell].Quantity, self.peakPrices[toSell] * 0.97)
            if (delta > 10):
                updateSettings.StopPrice = self.peakPrices[toSell] * 0.98
                updateSettings.Tag = "\nChanging the trailing stop"
                #ticket.Cancel("Updating StopMarketOrder")
                #self.orderTickers[toSell] = self.StopMarketOrder(toSell, ( -1) * self.Portfolio[toSell].Quantity, self.peakPrices[toSell] * 0.98)
        hour = self.Time.hour
        minute = self.Time.minute
        if (hour == 15) and (minute == 50):
            self.Debug("\nMarket is about to close")
            ticket.Cancel("Buying new stocks")
            self.Liquidate(toSell)
        response = ticket.Update(updateSettings)
        if (response.IsSuccess):
            self.Debug("Updated Successfully")
        return
        ''' 
    def getAllHistory():
        allQuandlData = self.History(QuandlFuture, self.Securities.Keys, timedelta(365))
        self.AssertHistoryCount("History(QuandlFuture, self.Securities.Keys, timedelta(365))", allQuandlData, 250)
        '''
    #def AssertHistoryCount(self, methodCall, tradeBarHistory, expected):
    #    count = len(tradeBarHistory.index)
    #    if count != expected:
    #        raise Exception("{} expected {}, but received {}".format(methodCall, expected, count))
            
'''class QuandlFuture(PythonQuandl):
    def __init__(self):
        # Define ValueColumnName: cannot be None, Empty or non-existant column name
        # If ValueColumnName is "Close", do not use PythonQuandl, use Quandl:
        # self.AddData[QuandlFuture](self.crude, Resolution.Daily)
        self.ValueColumnName = "Settle"
        '''