| Overall Statistics |
|
Total Trades 122 Average Win 14.50% Average Loss -9.51% Compounding Annual Return 37537.353% Drawdown 51.600% Expectancy 0.697 Net Profit 2054.680% Sharpe Ratio 339.673 Probabilistic Sharpe Ratio 99.249% Loss Rate 33% Win Rate 67% Profit-Loss Ratio 1.53 Alpha 632.743 Beta 1.463 Annual Standard Deviation 1.864 Annual Variance 3.474 Information Ratio 340.939 Tracking Error 1.856 Treynor Ratio 432.914 Total Fees $450.12 Estimated Strategy Capacity $770000.00 Lowest Capacity Asset ALEC X1USNADYJ71H |
import math
from io import StringIO
import pandas as pd
class QuandlFINRAData(PythonQuandl):
def __init__(self):
## Rename the Quandl object column to the data we want, which is the 'ShortVolume' column
## of the CSV that our API call returns
self.ValueColumnName = 'ShortVolume'
class FocusedYellowGreenGaur(QCAlgorithm):
# Order ticket for our stop order, Datetime when stop order was last hit
universeOpenPrice = {}
universeClosePrice = {}
peakPrices = {}
orderTickets = {}
stocks = []
tradingEnabled = False
allInvestments = []
df = [2]*2
startingCash = 0
numDiversify = 0
tickerNames = {}
boughtInPrice = {}
universeLowestPrice = {}
universeHighestPrice = {}
yesterdayShortInterest = {}
historicalShortInterest = {}
gettingShort = False
yesterdayDeals = []
currentDeals = []
blacklist = []
active = True
RSILimit = None
prevDay = -1
beginningMonthEquity = 0
tradeCount = 0
sellingEnabled = True
def Initialize(self):
self.SetStartDate(2021, 1, 1)
self.SetEndDate(2021, 7, 8)
self.SetCash(2000)
self.SetSecurityInitializer(self.CustomSecurityInitializer)
#string = 'FINRA/FNSQ_' + 'A' #+ ticker.Value
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")
#csv2 = self.Download("https://www.dropbox.com/s/9r7669u38kkrdi1/tickers.csv?dl=1"),
#self.AddData(QuandlFINRAData, 'FINRA/FNSQ_A', Resolution.Daily).Symbol
#self.Debug(self.allTickers)
self.RSILimit = self.GetParameter("RSILimit")
self.RSILimit = 100 if self.RSILimit is None else int(self.RSILimit)
def OnData(self, data):
hour = self.Time.hour
minute = self.Time.minute
self.tradingManager(data)
def CustomSecurityInitializer(self, security):
'''Initialize the security with raw prices'''
security.SetDataNormalizationMode(DataNormalizationMode.Adjusted)
def monthManager(self):
currentDay = self.Time.month
self.Debug("Current Month: " + str(currentDay))
if (self.prevDay != currentDay):
#newMonth
self.tradeCount = 0
self.beginningMonthEquity = self.Portfolio.TotalPortfolioValue
self.active = True
if (self.Portfolio.Invested):
self.tradeCount = self.tradeCount + 1
if (self.tradeCount == 5):
currentEquity = self.Portfolio.TotalPortfolioValue
self.Debug("Current Equity: " + str(currentEquity))
self.Debug("Beginning of Month Equity: " + str(self.beginningMonthEquity))
self.tradeCount = 6
if (currentEquity < self.beginningMonthEquity):
self.active = False
self.prevDay = currentDay
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.Debug("Short Interest: " + str(data['FINRA/FNSQ_A'].Value))
self.updateLowestPrice()
self.updateHighestPrice()
self.onMarketOpen()
self.sellingEnabled = True
if (hour == 15) and (minute == 53):
self.allInvestments = []
if (hour == 15) and (minute == 54):
if not self.active:
return
#if (self.IsWarmingUp):
# return
# self.Quit("I am warming up")
self.beforeMarketClose()
self.startingCash = self.Portfolio.Cash
if self.Portfolio.Invested:
return
buying = self.calculateDeals(self.numDiversify)
self.yesterdayDeals = buying
#Enable this to use what is calculated today
self.currentDeals = buying
for toBuy in self.currentDeals:
self.buy(toBuy)
self.currentDeals = self.yesterdayDeals
#if (hour == 15) and (minute == 58):
# self.monthManager()
#if (hour == 9) and (minute == 31):
# self.Debug("THe Hour is 9")
# self.Debug("The minute is: " + str(minute))
#if (hour == 16):
# self.getShortVolumeTwo()
#for short in self.yesterdayShortInterest:
# self.Debug("Short Interest: " + str(short))
#if (hour == 15) and (minute == 50):
if self.Portfolio.Invested and self.sellingEnabled:
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 updateLowestPrice(self):
for stock in self.stocks:
self.df = self.History(self.Symbol(stock), 50, Resolution.Daily)
if not 'low' in self.df:
continue
closePrices = self.df["low"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
if (len(close) < 50):
continue
lowest = 9999999
for x in close:
if (x < lowest):
lowest = x
self.universeLowestPrice[stock] = lowest
self.Debug("Length of lowestPrice = " + str(len(self.universeLowestPrice)))
def updateHighestPrice(self):
for stock in self.stocks:
self.df = self.History(self.Symbol(stock), 20, Resolution.Daily)
if not 'high' in self.df:
continue
closePrices = self.df["high"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
if (len(close) < 20):
return 0
lowest = 0
for x in close:
if (x > lowest):
lowest = x
self.universeHighestPrice[stock] = lowest
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:
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
#if (self.boughtInPrice[owned.Value] > self.Portfolio[owned].Price):
# self.Liquidate(owned)
#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):
if (not 'open' in self.df):
continue
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
return
def MyCoarseFilterFunction(self, coarse):
sortedByName = sorted(coarse, key=lambda x: x.Volume, reverse=True)
filtered = []
temp = None
for x in sortedByName:
if (x.Volume < 500000):
break
if (x.Price > 800):
continue
if (x.Price < 5):
continue
filtered.append(x.Symbol)
filtered = filtered[:50]
filtered = sorted(filtered, key=lambda x: x.Value, reverse=False)
if (temp != None):
if (not temp in filtered):
filtered.append(temp)
#filtered.append(temp)
#for ticker in filtered:
#self.UniverseSettings.Resolution = Resolution.Daily
#self.AddData(QuandlFINRAData, 'FINRA/FNSQ_A', Resolution.Daily).Symbol
#for ticker in filtered:
#self.gettingShort = True
#string = 'FINRA/FNSQ_' + ticker.Value
#self.AddData(QuandlFINRAData, string, Resolution.Daily).Symbol
self.UniverseSettings.Resolution = Resolution.Minute
return filtered
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), 15, 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) < 15) or (len(close) < 15):
return 0
for x in range(15):
tempOpen = open[x]
tempClose = close[x]
percentChange = abs(((tempOpen - tempClose) / tempClose) * 100)
if (percentChange > 0):
numPositives = numPositives + 1
return numPositives
def getRSIRelation(self, stock, numDays, upperLimit):
if (stock == None):
return 0
if (self.Symbol(stock) == None):
return 0
const = 50
self.df = self.History(self.Symbol(stock), const, 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)
if (len(open) < const) or (len(close) < const):
return 0
if not stock in self.universeOpenPrice:
return 0
if not stock in self.universeClosePrice:
return 0
RSI = 99999
winCount = 0
loseCount = 0
for j in range(numDays, const):
posSum = 0
negSum = 0
for i in range((j - numDays), j):
percentChange = ((close[i] - open[i])/ open[i]) * 100
if (percentChange > 0):
posSum = percentChange + posSum
else:
negSum = abs(percentChange) + negSum
posAvg = (posSum) / (numDays)
negAvg = (negSum) / (numDays)
if (negAvg == 0):
continue
ratio = (posAvg / negAvg)
RSI = (100 - (100 / (1 + ratio)))
if not ((j + 1) == const):
if (RSI < upperLimit):
if (open[j + 1] < close[j + 1]):
winCount = winCount + 1
else:
loseCount = loseCount + 1
if (loseCount + winCount) == 0:
return 0
return ((winCount) / (loseCount + winCount)) * 100
def getHighRSI(self, stock, numDays):
self.df = self.History(self.Symbol(stock), (numDays), Resolution.Daily)
openPrices = self.df["high"]
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)
if (len(open) < (numDays)) or (len(close) < (numDays)):
return 0
if not stock in self.universeOpenPrice:
return 0
if not stock in self.universeClosePrice:
return 0
posSum = 0
negSum = 0
for i in range(1, numDays):
percentChange = ((open[i] - close[i - 1])/ open[i]) * 100
if (percentChange > 0):
posSum = percentChange + posSum
else:
negSum = abs(percentChange) + negSum
currDayHigh = self.getCurrentDayHigh(stock)
currPerChange = ((currDayHigh - self.universeClosePrice[stock]) / self.universeClosePrice[stock]) * 100
if (currPerChange > 0):
posSum = currPerChange + posSum
else:
negSum = abs(currPerChange) + negSum
posAvg = (posSum) / (numDays + 1)
negAvg = (negSum) / (numDays + 1)
if (negAvg == 0):
return 0
ratio = (posAvg / negAvg)
RSI = (100 - (100 / (1 + ratio)))
#self.Debug("RSI: " + str(RSI))
return RSI
def getRSI(self, stock, numDays):
self.df = self.History(self.Symbol(stock), (numDays - 1), Resolution.Daily)
if not "open" in self.df:
return 0
if not 'close' in self.df:
return 0
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)
if (len(open) < (numDays - 1)) or (len(close) < (numDays - 1)):
return 0
if not stock in self.universeOpenPrice:
return 0
if not stock in self.universeClosePrice:
return 0
posSum = 0
negSum = 0
for i in range(numDays - 1):
percentChange = ((close[i] - open[i])/ open[i]) * 100
if (percentChange > 0):
posSum = percentChange + posSum
else:
negSum = abs(percentChange) + negSum
currPerChange = ((self.universeClosePrice[stock] - self.universeOpenPrice[stock]) / self.universeOpenPrice[stock]) * 100
if (currPerChange > 0):
posSum = currPerChange + posSum
else:
negSum = abs(currPerChange) + negSum
posAvg = (posSum) / (numDays + 1)
negAvg = (negSum) / (numDays + 1)
if (negAvg == 0):
return 0
ratio = (posAvg / negAvg)
RSI = (100 - (100 / (1 + ratio)))
#self.Debug("RSI: " + str(RSI))
return RSI
def getBearScore(self, stock):
self.df = self.History(self.Symbol(stock), 100, 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)
if (len(open) < 100) or (len(close) < 100):
return 0
if not stock in self.universeOpenPrice:
return 0
if not stock in self.universeClosePrice:
return 0
if (self.universeOpenPrice[stock] < self.universeClosePrice[stock]):
return 0
keepGoing = True
numBears = 0
otherNumBears = 0
i = 0
while keepGoing:
if (close[99 - i] < open[99 - i]):
numBears = numBears + 1
else:
keepGoing = False
i = i + 1
#Check if this happened recently
for j in range(100):
if (close[99 - i] < open[99 - i]):
otherNumBears = otherNumBears + 1
else:
otherNumBears = 0
if (otherNumBears > numBears):
return 0
return numBears
def getStockState(self, stock):
self.df = self.History(self.Symbol(stock), 25, Resolution.Daily)
if not "open" in self.df:
return "no"
if not "close" in self.df:
return "no"
openPrices = self.df["open"]
closePrices = self.df["close"]
open = []
close = []
openPrices.unstack('symbol')
closePrices.unstack('symbol')
belowAvgCount = 0
aboveAvgCount = 0
if (len(openPrices) < 25):
return False
if (len(closePrices) < 25):
return False
for prices in openPrices:
open.append(prices)
for prices in closePrices:
close.append(prices)
for i in range(5):
sum = 0
for j in range(20):
sum = sum + close[j + (4 - i)]
average = (sum / 20)
if ((average < close[24 - i]) or (average < open[24 - i])):
belowAvgCount = belowAvgCount + 1
else:
aboveAvgCount = aboveAvgCount + 1
score = (belowAvgCount - aboveAvgCount)
score = abs(score)
if (score == 1):
return "neutral"
score = (aboveAvgCount - belowAvgCount)
if (score == 5):
return "perfectBullish"
elif (score > 1):
return "bullish"
elif (score == -5):
return "perfectBearish"
else:
return "bearish"
def getAvgPremarketIncrease(self, stock):
self.df = self.History(self.Symbol(stock), 15, 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) < 15) or (len(close) < 15):
return 0
for x in range(14):
tempOpen = open[x + 1]
tempClose = close[x]
percentChange = abs(((tempOpen - tempClose) / tempClose) * 100)
if (percentChange > 0):
numPositives = numPositives + 1
posSum = posSum + percentChange
if (numPositives == 0):
return 0
avg = (posSum) / numPositives
return avg
def getAvgMarketVolume(self):
totalSum = 0
for stock in self.stocks:
self.df = self.History(self.Symbol(stock), 9, Resolution.Daily)
currDayVolume = self.getCurrentDayVolume(stock)
if not 'volume' in self.df:
continue
volume = []
vol = self.df['volume']
vol.unstack('symbol')
sum = 0
for v in vol:
volume.append(v)
for v in volume:
sum = sum + v
sum = sum + currDayVolume
sum = sum / 10
totalSum = totalSum + sum
self.Debug("Total Sum: " + str(totalSum))
return (totalSum)
def getCurrentMarketVolume(self):
sum = 0
for stock in self.stocks:
currDayVolume = self.getCurrentDayVolume(stock)
sum = currDayVolume + sum
return sum
def getVAMP(self):
avgVol = self.getAvgMarketVolume()
currVolume = self.getCurrentMarketVolume()
adjSum = 0
for stock in self.stocks:
if not stock in self.universeOpenPrice:
continue
if not stock in self.universeClosePrice:
continue
vol = self.getCurrentDayVolume(stock)
open = self.universeOpenPrice[stock]
close = self.universeClosePrice[stock]
if open == 0:
continue
percentChange = ((close - open) / open) * 100
if (currVolume == 0):
continue
adjSum = adjSum + (percentChange * (vol / currVolume))
return adjSum
def getVolatilityScore(self, stock):
self.df = self.History(self.Symbol(stock), 7, Resolution.Daily)
if not 'open' in self.df:
return 0
if not 'close' in self.df:
return 0
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)
if (not('close') in self.df):
return True
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), 6, Resolution.Daily)
closePrices = self.df["close"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
sum = 0
if (len(close) < 6):
return 0
for i in range(6):
sum = sum + close[i]
sum = sum + self.universeClosePrice[stock]
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 getAvgVolume(self, stock):
self.df = self.History(self.Symbol(stock), 50, Resolution.Daily)
volumeByDay = self.df['volume']
volume = []
volumeByDay.unstack('symbol')
for v in volumeByDay:
volume.append(v)
if (len(volume) < 50):
return 0
sum = 0
for v in volume:
sum = sum + v
return (sum / 50)
def getCurrentDayVolume(self, stock):
hour = self.Time.hour
minute = self.Time.minute
'''
Assumes the market is actually open when this is run
'''
totalTime = (((hour - 9) * 60) + minute) - 29
self.df = self.History(self.Symbol(stock), totalTime, Resolution.Minute)
sum = 0
if not 'volume' in self.df:
return 0
volumeByMinute = self.df['volume']
volumeByMinute.unstack('symbol')
for v in volumeByMinute:
sum = sum + v
return sum
def getCurrentDayHigh(self, stock):
hour = self.Time.hour
minute = self.Time.minute
'''
Assumes the market is actually open when this is run
'''
totalTime = (((hour - 9) * 60) + minute) - 29
self.df = self.History(self.Symbol(stock), totalTime, Resolution.Minute)
highestPrice = 0
prices = self.df['high']
prices.unstack('symbol')
for price in prices:
if (price > highestPrice):
highestPrice = price
return highestPrice
def getCurrentDayLow(self, stock):
hour = self.Time.hour
minute = self.Time.minute
'''
Assumes the market is actually open when this is run
'''
totalTime = (((hour - 9) * 60) + minute) - 29
self.df = self.History(self.Symbol(stock), totalTime, Resolution.Minute)
lowestPrice = 999999999
if not 'low' in self.df:
return 0
prices = self.df['low']
prices.unstack('symbol')
for price in prices:
if (price < lowestPrice):
lowestPrice = price
return lowestPrice
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))
self.Debug("EMA: " + str(average))
return average
def trendingUp(self, stock):
self.df = self.History(self.Symbol(stock), 55, Resolution.Daily)
openPrices = self.df["open"]
closePrices = self.df["close"]
open = []
close = []
openPrices.unstack('symbol')
closePrices.unstack('symbol')
if (len(openPrices) < 55):
return False
if (len(closePrices) < 55):
return False
for prices in openPrices:
open.append(prices)
for prices in closePrices:
close.append(prices)
for i in range(5):
sum = 0
for j in range(50):
sum = sum + close[j + (4 - i)]
average = (sum / 50)
if ((average < close[54 - i]) and (average < open[54 - i])):
continue
else:
return False
return True
def runningAway(self, stock):
if (not ((stock in self.universeOpenPrice) and (stock in self.universeClosePrice))):
return False
self.df = self.History(self.Symbol(stock), 1, 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)
if (len(close) < 1) or (len(open) < 1):
return False
opening = self.universeOpenPrice[stock]
closing = self.universeClosePrice[stock]
test1 = (opening < closing)
test2 = (opening > open[0]) and (opening > close[0])
return test1 and test2
def isBelow7DayEMA(self, stock):
sevenEMA = self.get7DayEMA(stock)
currentPrice = self.universeClosePrice[stock]
if (sevenEMA == 0):
return True
return (currentPrice < sevenEMA)
def getBestStockState(self):
'''
First number is number of stocks in that state
second number is number of stocks which gained in that state
'''
perfectBearish = [0, 0]
perfectBullish = [0, 0]
bullish = [0, 0]
bearish = [0, 0]
neutral = [0, 0]
for stock in self.stocks:
state = self.getStockState(stock)
if not stock in self.universeOpenPrice:
continue
if not stock in self.universeClosePrice:
continue
opening = self.universeOpenPrice[stock]
closing = self.universeClosePrice[stock]
if (state == 'perfectBearish'):
perfectBearish[0] = perfectBearish[0] + 1
if (opening < closing):
perfectBearish[1] = perfectBearish[1] + 1
if (state == 'perfectBullish'):
perfectBullish[0] = perfectBullish[0] + 1
if (opening < closing):
perfectBullish[1] = perfectBullish[1] + 1
if (state == 'bullish'):
bullish[0] = bullish[0] + 1
if (opening < closing):
bullish[1] = bullish[1] + 1
if (state == 'bearish'):
bearish[0] = bearish[0] + 1
if (opening < closing):
bearish[1] = bearish[1] + 1
if (state == 'neutral'):
neutral[0] = neutral[0] + 1
if (opening < closing):
neutral[1] = neutral[1] + 1
perfectBearishScore = 0
perfectBullishScore = 0
bullishScore = 0
bearishScore = 0
neutralScore = 0
if (perfectBearish[0] != 0):
perfectBearishScore = (perfectBearish[1] / perfectBearish[0])
if (perfectBullish[0] != 0):
perfectBullishScore = (perfectBullish[1] / perfectBullish[0])
if (bullish[0] != 0):
bullishScore = (bullish[1] / bullish[0])
if (bearish[0] != 0):
bearishScore = (bearish[1] / bearish[0])
if (neutral[0] != 0):
neutralScore = (neutral[1] / neutral[0])
array = [perfectBearishScore, perfectBullishScore, bullishScore, bearishScore, neutralScore]
best = 0
bestPosition = 0
for i in range(5):
if array[i] > best:
best = array[i]
bestPosition = i
if (i == 0):
return 'perfectBearish'
if (i == 1):
return 'perfectBullish'
if (i == 2):
return 'bullish'
if (i == 3):
return 'bearish'
if (i == 4):
return 'neutral'
def getExperimental(self):
percentChange = 0
highestPercentChange = -(9999)
percentSum = 0
highestIncrease = None
skip = False
highestVolScore = -99999
highestPreMarket = 0
bearishVolume = 0
bestState = self.getBestStockState()
for stock in self.stocks:
state = self.getStockState(stock)
#if (state != bestState):
# continue
skip = False
if ((not (stock in self.universeOpenPrice)) or (not (stock in self.universeClosePrice))):
continue
opening = self.universeOpenPrice[stock]
closing = self.universeClosePrice[stock]
if (self.get20DayMovingAverage(stock) > closing):
continue
#score = self.getBearScore(stock)
score = self.getRSI(stock, 14)
if (score == 0):
continue
#if (score > 30):
# continue
currVol = self.getCurrentDayVolume(stock)
avgVol = self.getAvgVolume(stock)
#score = self.getRSIRelation(stock, 14, (30 * performance))
if self.trendingDown(stock):
continue
if (avgVol == 0):
continue
volChange = ((currVol - avgVol) / avgVol) * 100
score = self.getVolatilityScore(stock) * volChange
if (score > highestVolScore):
highestVolScore = score
highestIncrease = stock
return highestIncrease
def willSellOff(self, stock):
if (not ((stock in self.universeOpenPrice) and (stock in self.universeClosePrice))):
return False
self.df = self.History(self.Symbol(stock), 40, Resolution.Daily)
currVolume = self.getCurrentDayVolume(stock)
closePrices = self.df["close"]
highPrices = self.df['high']
volume = self.df['volume']
close = []
vol = []
high = []
closePrices.unstack('symbol')
volume.unstack('symbol')
highPrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
for v in volume:
vol.append(v)
for prices in highPrices:
high.append(prices)
if (len(close) < 40):
return True
if (len(vol) < 40):
return True
if (len(high) < 40):
return True
for i in range(40):
if self.universeClosePrice[stock] > close[i]:
if (vol[i] > currVolume):
return True
#if self.universeClosePrice[stock] > high[i]:
# return True
return False
def getExperimental2(self):
percentChange = 0
highestPercentChange = -(9999)
percentSum = 0
highestIncrease = None
skip = False
highestVolScore = 99999
highestPreMarket = 0
bearishVolume = 0
#bestState = self.getBestStockState()
for stock in self.stocks:
if not stock in self.universeOpenPrice:
continue
if not stock in self.universeClosePrice:
continue
opening = self.universeOpenPrice[stock]
closing = self.universeClosePrice[stock]
perChange = 100 * ((opening - closing) / opening)
score = perChange
if (score < highestVolScore):
highestVolScore = score
highestIncrease = stock
return highestIncrease
def get20DayMovingAverage(self, stock):
self.df = self.History(self.Symbol(stock), 19, Resolution.Daily)
if not 'close' in self.df:
return 0
closePrices = self.df["close"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
sum = 0
if (len(close) < 19):
return 0
for i in range(19):
sum = sum + close[i]
sum = sum + self.universeClosePrice[stock]
return (sum / 20)
def get10DayMovingAverage(self, stock):
self.df = self.History(self.Symbol(stock), 9, Resolution.Daily)
closePrices = self.df["close"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
sum = 0
if (len(close) < 9):
return 0
for i in range(9):
sum = sum + close[i]
sum = sum + self.universeClosePrice[stock]
return (sum / 10)
def getXDayMovingAverage(self, x, stock):
if (x > 1):
self.df = self.History(self.Symbol(stock), (x - 1), Resolution.Daily)
closePrices = self.df["close"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
sum = 0
if (len(close) < (x - 1)):
return 0
for i in range((x - 1)):
sum = sum + close[i]
sum = sum + self.universeClosePrice[stock]
return (sum / x)
def get20DayHighAverage(self, stock):
self.df = self.History(self.Symbol(stock), 19, Resolution.Daily)
closePrices = self.df["high"]
close = []
other = []
closePrices.unstack('symbol')
otherPrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
for prices in otherPrices:
other.append(prices)
sum = 0
if (len(close) < 19):
return 0
for i in range(19):
# percentChange = ((close[i] - other[i]) / other[i]) * 100
# if (percentChange < 5):
# return 0
sum = sum + close[i]
sum = sum + self.universeClosePrice[stock]
return (sum / 20)
def get20DayLowAverage(self, stock):
self.df = self.History(self.Symbol(stock), 20, Resolution.Daily)
closePrices = self.df["low"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
sum = 0
if (len(close) < 20):
return 0
for i in range(20):
sum = sum + close[i]
return (sum / 20)
def get10DayLowAverage(self, stock):
self.df = self.History(self.Symbol(stock), 10, Resolution.Daily)
closePrices = self.df["low"]
close = []
closePrices.unstack('symbol')
for prices in closePrices:
close.append(prices)
sum = 0
if (len(close) < 10):
return 0
for i in range(10):
sum = sum + close[i]
return (sum / 10)
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("Current Performance: " + str(performance))
#vamp = self.getVAMP()
deal = self.getExperimental2()
return deal
def modelsCorrectly(self, toBuy):
self.df = self.History(self.Symbol(toBuy), 2, Resolution.Daily)
openPrices = self.df["open"]
closePrices = self.df["close"]
lowPrices = self.df['low']
open = []
close = []
low = []
openPrices.unstack('symbol')
closePrices.unstack('symbol')
lowPrices.unstack('symbol')
for prices in openPrices:
open.append(prices)
for prices in closePrices:
close.append(prices)
for prices in lowPrices:
low.append(prices)
test = (close[0] > open[1])
lowest = self.universeLowestPrice[toBuy]
test2 = (low[0] == lowest) or (low[0] < (lowest * 1.05))
decision = ""
if (not test) or test2:
decision = "buy"
else:
decision = "sell"
if (decision == "buy"):
return self.universeClosePrice[toBuy] > self.universeOpenPrice[toBuy]
elif (decision == "sell"):
return self.universeOpenPrice[toBuy] > self.universeClosePrice[toBuy]
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.df = self.History(self.Symbol(toBuy), 1, 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)
#test3 = True
#test = test and test2 and test3
currVol = self.getCurrentDayVolume(toBuy)
avgVol = self.getAvgVolume(toBuy)
#test = (currVol * 0.5) < avgVol
test = (close[0] > self.universeOpenPrice[toBuy])
if not toBuy in self.universeLowestPrice:
return
lowest = self.universeLowestPrice[toBuy]
todayLow = self.getCurrentDayLow(toBuy)
test2 = (todayLow == lowest) or (todayLow < (lowest * 1.05))
#test3 = price > self.getXDayMovingAverage(5, toBuy)
#test = test3 and test
if (not self.modelsCorrectly(toBuy)):
if (not test) or test2:
self.MarketOrder(toBuy, numShares)
else:
return
self.MarketOrder(toBuy, (-1) * numShares)
else:
if not ((not test) or test2):
self.MarketOrder(toBuy, numShares)
else:
return
self.MarketOrder(toBuy, (-1) * numShares)
if not toBuy in self.Portfolio:
return
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 buyOverride(self, toBuy):
price = self.Securities[toBuy].Price
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)
if not toBuy in self.Portfolio:
return
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
def shortOverride(self, toBuy):
price = self.Securities[toBuy].Price
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, (-1) * numShares)
if not toBuy in self.Portfolio:
return
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
def sell(self, toSell):
if not self.sellingEnabled:
return
hour = self.Time.hour
minute = self.Time.minute
if (( not toSell.Value in self.boughtInPrice) or (not toSell in self.Portfolio )):
self.Liquidate(toSell)
numShares = self.Portfolio[toSell].Quantity
if (hour == 9) and (minute == 32):
if (numShares < 0):
if self.Portfolio[toSell].Price < self.boughtInPrice[toSell.Value]:
self.sellingEnabled = False
self.Liquidate()
else:
if self.Portfolio[toSell].Price > self.boughtInPrice[toSell.Value]:
self.sellingEnabled = False
self.Liquidate()
if (hour == 12) and (minute == 0):
if (numShares < 0):
if self.Portfolio[toSell].Price > self.boughtInPrice[toSell.Value]:
self.Liquidate()
return
self.sellingEnabled = False
self.MarketOrder(toSell, (-2) * numShares)
else:
if self.Portfolio[toSell].Price < self.boughtInPrice[toSell.Value]:
self.Liquidate()
return
self.sellingEnabled = False
self.MarketOrder(toSell, (-2) * numShares)
if (hour == 15) and (minute == 50):
self.Debug("\nMarket is about to close")
#ticket.Cancel("Buying new stocks")
#currentPrice = self.Portfolio[toSell].Price
#boughtIn = self.boughtInPrice[toSell.Value]
#percentChange = 100 * ((currentPrice - boughtIn) / boughtIn)
#if (percentChange > 5):
#if (currentPrice < boughtIn):
#return
# self.blacklist.append(toSell)
#self.allInvestments = []
self.Liquidate()
return
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
if (toSell == None):
return
self.Debug ("I have made it past the tests")
currentPrice = self.Portfolio[toSell].Price
boughtIn = self.boughtInPrice[toSell.Value]
settingsUpdated = False
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"
settingsUpdated = True
#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"
settingsUpdated = True
#ticket.Cancel("Updating StopMarketOrder")
#self.orderTickers[toSell] = self.StopMarketOrder(toSell, ( -1) * self.Portfolio[toSell].Quantity, self.peakPrices[toSell] * 0.98)
if settingsUpdated:
response = ticket.Update(updateSettings)
if (response.IsSuccess):
self.Debug("Updated Successfully")
return