-
Notifications
You must be signed in to change notification settings - Fork 2
/
1-11-tiingo-sentiment-analysis-on-stocks.py
68 lines (56 loc) · 2.74 KB
/
1-11-tiingo-sentiment-analysis-on-stocks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from QuantConnect.Data.Custom.Tiingo import *
from datetime import datetime, timedelta
import numpy as np
class TiingoNewsSentimentAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2016, 11, 1)
self.SetEndDate(2017, 3, 1)
symbols = [Symbol.Create("AAPL", SecurityType.Equity, Market.USA),
Symbol.Create("NKE", SecurityType.Equity, Market.USA)]
self.SetUniverseSelection(ManualUniverseSelectionModel(symbols))
self.SetAlpha(NewsSentimentAlphaModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.SetExecution(ImmediateExecutionModel())
self.SetRiskManagement(NullRiskManagementModel())
class NewsData():
def __init__(self, symbol):
self.Symbol = symbol
self.Window = RollingWindow[float](100)
class NewsSentimentAlphaModel(AlphaModel):
def __init__(self):
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
}
def Update(self, algorithm, data):
insights = []
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)
sentiment = sum(self.newsData[symbol].Window)
if sentiment > 5:
insights.append(Insight.Price(symbol, timedelta(1), InsightDirection.Up))
return insights
def OnSecuritiesChanged(self, algorithm, changes):
for security in changes.AddedSecurities:
symbol = security.Symbol
newsAsset = algorithm.AddData(TiingoNews, symbol)
self.newsData[symbol] = NewsData(newsAsset.Symbol)
for security in changes.RemovedSecurities:
newsData = self.newsData.pop(security.Symbol, None)
if newsData is not None:
algorithm.RemoveSecurity(newsData.Symbol)