Overall Statistics
Total Trades
893
Average Win
0.40%
Average Loss
-0.23%
Compounding Annual Return
-16.424%
Drawdown
28.800%
Expectancy
-0.154
Net Profit
-16.464%
Sharpe Ratio
-0.63
Probabilistic Sharpe Ratio
2.767%
Loss Rate
69%
Win Rate
31%
Profit-Loss Ratio
1.77
Alpha
-0.12
Beta
0.073
Annual Standard Deviation
0.166
Annual Variance
0.028
Information Ratio
-1.652
Tracking Error
0.192
Treynor Ratio
-1.429
Total Fees
$2287.48
from QuantConnect.Data.Custom.Tiingo import *


class ParticleTachyonReplicator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 1)  # Set Start Date
        self.SetEndDate(2020, 1, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        
        self.AddUniverseSelection(
           FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine)
        )
        
        self.AddAlpha(KeywordNewsAlpha())
        
        self.SetPortfolioConstruction(InsightWeightingPortfolioConstructionModel())  # Each news piece with the keywords increases the weight
        
        self.SetExecution(ImmediateExecutionModel())
        
        self.UniverseSettings.Resolution = Resolution.Daily
        
    def SelectCoarse(self, coarse):
        return [c.Symbol for c in coarse if c.DollarVolume > 1e8]

    def SelectFine(self, fine):
        return [f.Symbol for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology] 


class KeywordNewsAlpha:
    
    def __init__(self):
        self.keywords = {'privacy concern', 'compromised', 'vulnerability', 'security flaw'}
        
        self.alt_data_symbols = {}
    
    def Update(self, algorithm, slice):
        insights = []
        
        tiingo_news = slice.Get(TiingoNews)
        
        for t in tiingo_news.Values:
            if [w for w in self.keywords if w in t.Title.strip().lower()]:  # Examples of phrases in the title
                for symbol in t.Symbols:  # Tagged securities
                    if symbol in algorithm.ActiveSecurities.Keys:  # In our universe
                        insights.append(Insight.Price(symbol, timedelta(3), InsightDirection.Down,None,None,None,1))  # Increment short weight for stock
        
        return insights

    def OnSecuritiesChanged(self, algorithm, changes):
        for added in changes.AddedSecurities:
            self.alt_data_symbols[added.Symbol] = algorithm.AddData(TiingoNews, added.Symbol).Symbol
            
        for removed in changes.RemovedSecurities:
            symbol = self.alt_data_symbols.pop(removed.Symbol, None)
            
            if symbol:
                algorithm.RemoveSecurity(removed.Symbol)