Overall Statistics
Total Trades
282
Average Win
0.22%
Average Loss
-0.04%
Compounding Annual Return
2.789%
Drawdown
1.900%
Expectancy
0.241
Net Profit
0.878%
Sharpe Ratio
0.512
Probabilistic Sharpe Ratio
36.528%
Loss Rate
81%
Win Rate
19%
Profit-Loss Ratio
5.43
Alpha
0.023
Beta
-0.064
Annual Standard Deviation
0.038
Annual Variance
0.001
Information Ratio
-0.215
Tracking Error
0.131
Treynor Ratio
-0.303
Total Fees
$398.24
from QuantConnect.Data.Custom.Tiingo import *

class TiingoNLPDemonstration(QCAlgorithm):

    def Initialize(self):
        # Predefine a dictionary of words with scores to scan for in the description
        # of the Tiingo news article
        self.wordSentiment = {
            "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.SetStartDate(2019, 6, 10)
        self.SetEndDate(2019, 10, 3)
        self.SetCash(100000)
        
        aapl = self.AddEquity("QQQ", Resolution.Daily).Symbol
        self.aaplCustom = self.AddData(TiingoNews, aapl).Symbol
        
        # Request underlying equity data.
        ibm = self.AddEquity("QQQ", Resolution.Minute).Symbol
        # Add news data for the underlying IBM asset
        news = self.AddData(TiingoNews, ibm).Symbol
        # Request 60 days of history with the TiingoNews IBM Custom Data Symbol
        history = self.History(TiingoNews, news, 60, Resolution.Daily)
        
        # Count the number of items we get from our history request
        self.Debug(f"We got {len(history)} items from our history request")
        
    def OnData(self, data):
        # Confirm that the data is in the collection
        if not data.ContainsKey(self.aaplCustom):
            return
        
        # Gets the data from the slice
        article = data[self.aaplCustom]
        
        # Article descriptions come in all caps. Lower and split by word
        descriptionWords = article.Description.lower().split(" ")
        
        # Take the intersection of predefined words and the words in the
        # description to get a list of matching words
        intersection = set(self.wordSentiment.keys()).intersection(descriptionWords)
        
        # Get the sum of the article's sentiment, and go long or short
        # depending if it's a positive or negative description
        sentiment = sum([self.wordSentiment[i] for i in intersection])
        
        self.SetHoldings(article.Symbol.Underlying, sentiment)