from QuantConnect.Data.Custom.Tiingo import *
from datetime import datetime, timedelta
import numpy as np
class GunStocks(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 1, 1)
self.SetCash(1000000)
self.tickers = ["AXON", "AOBC", "RGR", "VSTO", "SPWH", "OLN", "SWBI"]
symbols = []
for i in self.tickers:
symbols.append(Symbol.Create(i, SecurityType.Equity, Market.USA))
self.UniverseSettings.Resolution = Resolution.Daily
self.SetUniverseSelection(ManualUniverseSelectionModel(symbols))
self.SetAlpha(GunStocksAlphaModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.SetExecution(ImmediateExecutionModel())
self.SetRiskManagement(TrailingStopRiskManagementModel(0.02))
class GunStocksAlphaModel(AlphaModel):
def __init__(self, news_history_length = 100):
self.news_history_length = news_history_length
self.newsData = {}
self.wordScores = {
"bad": -0.5, "good": 0.5, "negative": -0.5,
"great": 0.5, "growth": 0.5, "fail": -0.5,
"failed": -0.5, "success": 0.5, "nailed": 0.5,
"beat": 0.5, "missed": -0.5, "profitable": 0.5,
"beneficial": 0.5, "right": 0.5, "positive": 0.5,
"large":0.5, "attractive": 0.5, "sound": 0.5,
"excellent": 0.5, "wrong": -0.5, "unproductive": -0.5,
"lose": -0.5, "missing": -0.5, "mishandled": -0.5,
"un_lucrative": -0.5, "up": 0.5, "down": -0.5,
"unproductive": -0.5, "poor": -0.5, "wrong": -0.5,
"worthwhile": 0.5, "lucrative": 0.5, "solid": 0.5,
"conflict": 0.5, "peace": -0.5, "contracts": 0.5, "equipment": 0.5,
"war": 0.5, "scandal": -0.5, "bribe": -0.5, "tax": -0.5,
"gun": 0.5, "stocks": 0.5, "stock": 0.5, "invest": 0.5,
"optamistic": 0.5, "sell": -0.5, "buy": 0.5, "gained": 0.5,
"lost": -0.5, "riots": 0.5, "riot": 0.5, "terrorism": 0.5,
"frightened": 0.5, "violence": 0.5
}
self.senators = {
1999 : "R",
2000 : "R",
2001 : "D",
2002 : "D",
2003 : "R",
2004 : "R",
2005 : "R",
2006 : "R",
2007 : "D",
2008 : "D",
2009 : "D",
2010 : "D",
2011 : "D",
2012 : "D",
2013 : "D",
2014 : "D",
2015 : "R",
2016 : "R",
2017 : "R",
2018 : "R",
2019 : "R",
2020 : "R"
}
self.lastmonth = -1
def Update(self, algorithm, data):
# Gather news
news = data.Get(TiingoNews)
for article in news.Values:
words = article.Description.lower().split(" ")
score = sum([self.wordScores[word] for word in words
if word in self.wordScores])
symbol = article.Symbol.Underlying
self.newsData[symbol].Window.Add(score)
insights = []
month = algorithm.Time.month
if month == self.lastmonth or \
not (algorithm.Time.hour == 0 and algorithm.Time.minute == 0 and algorithm.Time.second == 0):
return insights
self.lastmonth = month
politicalPoints = 3 * (1 if self.senators[algorithm.Time.year] == 'D' else -1)
for symbol in self.newsData.keys():
sentiment = sum(self.newsData[symbol].Window) + politicalPoints
if sentiment > 10:
insights.append(Insight.Price(symbol, timedelta(days=5), InsightDirection.Up, None, None))
elif sentiment < -1:
insights.append(Insight.Price(symbol, timedelta(days=5), InsightDirection.Down, None, None))
return insights
def OnSecuritiesChanged(self, algorithm, changes):
for security in changes.AddedSecurities:
symbol = security.Symbol
news_symbol = algorithm.AddData(TiingoNews, symbol).Symbol
self.newsData[symbol] = NewsData(news_symbol, self.news_history_length)
for security in changes.RemovedSecurities:
newsData = self.newsData.pop(security.Symbol, None)
if newsData is not None:
algorithm.RemoveSecurity(newsData.Symbol)
class NewsData():
def __init__(self, symbol, news_history_length):
self.Symbol = symbol
self.Window = RollingWindow[float](news_history_length)