Overall Statistics
Total Trades
2865
Average Win
0.82%
Average Loss
-0.15%
Compounding Annual Return
8.891%
Drawdown
10.700%
Expectancy
0.325
Net Profit
86.303%
Sharpe Ratio
0.84
Loss Rate
79%
Win Rate
21%
Profit-Loss Ratio
5.31
Alpha
0.069
Beta
0.017
Annual Standard Deviation
0.084
Annual Variance
0.007
Information Ratio
-0.272
Tracking Error
0.161
Treynor Ratio
4.096
Total Fees
$14469.59
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, "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,
            "scandal": -0.5, "hack": -0.5
       }
       self.SetStartDate(2009, 6, 10)
       self.SetEndDate(2019, 10, 3)
       self.SetCash(100000)
       aapl = self.AddEquity("AAPL", Resolution.Daily).Symbol
       self.aaplCustom = self.AddData(TiingoNews, aapl).Symbol
       self.AddEquity("VGT", Resolution.Daily)
       
   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])
       if sentiment >= 0:
           self.SetHoldings("VGT", sentiment)