Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -2.531 Tracking Error 0.074 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
from datetime import datetime, timedelta ### <summary> ### Benzinga is a provider of news data. Their news is made in-house ### and covers stock related news such as corporate events. ### </summary> class BenzingaNewsAlgorithm(QCAlgorithm): def Initialize(self): self.words = { "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 } self.lastTrade = datetime(1, 1, 1) self.SetStartDate(2018, 6, 5) self.SetEndDate(2018, 8, 4) self.SetCash(100000) #aapl = self.AddEquity("AAPL", Resolution.Hour).Symbol #ibm = self.AddEquity("IBM", Resolution.Hour).Symbol self.AddUniverse(self.Universe.DollarVolume.Top(100)) #self.AddData(BenzingaNews, symbol) #self.AddData(BenzingaNews, ibm) def Update(self, algorithm, data): for symbol in self.ActiveSecurities.Keys: self.AddData(BenzingaNews, symbol) def OnData(self, data): if (self.Time - self.lastTrade) < timedelta(days=5): return # Get rid of our holdings after 5 days, and start fresh self.Liquidate() # Get all Benzinga data and loop over it for article in data.Get(BenzingaNews).Values: selectedSymbol = None # Use loop instead of list comprehension for clarity purposes # Select the same Symbol we're getting a data point for # from the articles list so that we can get the sentiment of the article # We use the underlying Symbol because the Symbols included in the `Symbols` property # are equity Symbols. for symbol in article.Symbols: if symbol == article.Symbol.Underlying: selectedSymbol = symbol break if selectedSymbol is None: raise Exception(f"Could not find current Symbol {article.Symbol.Underlying} even though it should exist") # The intersection of the article contents and the pre-defined words are the words that are included in both collections intersection = set(article.Contents.lower().split(" ")).intersection(list(self.words.keys())) # Get the words, then get the aggregate sentiment sentimentSum = sum([self.words[i] for i in intersection]) if sentimentSum >= 0.5: self.Log(f"Longing {article.Symbol.Underlying} with sentiment score of {sentimentSum}") self.SetHoldings(article.Symbol.Underlying, sentimentSum / 5) self.lastTrade = self.Time if sentimentSum <= -0.5: self.Log(f"Shorting {article.Symbol.Underlying} with sentiment score of {sentimentSum}") self.SetHoldings(article.Symbol.Underlying, sentimentSum / 5) self.lastTrade = self.Time def OnSecuritiesChanged(self, changes): for r in changes.RemovedSecurities: # If removed from the universe, liquidate and remove the custom data from the algorithm self.Liquidate(r.Symbol) self.RemoveSecurity(Symbol.CreateBase(BenzingaNews, r.Symbol, Market.USA)) #class SymbolData(object): #def __init__(self, symbol): #self.symbol = symbol #self.AddData(BenzingaNews, symbol)