Overall Statistics
Total Trades
21
Average Win
1.97%
Average Loss
-0.31%
Compounding Annual Return
46.220%
Drawdown
3.300%
Expectancy
4.950
Net Profit
17.138%
Sharpe Ratio
3.68
Probabilistic Sharpe Ratio
93.487%
Loss Rate
20%
Win Rate
80%
Profit-Loss Ratio
6.44
Alpha
0.373
Beta
-0.001
Annual Standard Deviation
0.101
Annual Variance
0.01
Information Ratio
0.602
Tracking Error
0.164
Treynor Ratio
-261.17
Total Fees
$28.56
Estimated Strategy Capacity
$840000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
from AlgorithmImports import *
from QuantConnect.DataSource import RegalyticsRegulatoryArticle

class RegalyticsDataAlgorithm(QCAlgorithm):
    
    last_news_date = datetime.min
    target_holdings = 1
    negative_sentiment_phrases = ["emergency rule", "proposed rule change", "development of rulemaking"] 
    news_affect_duration = timedelta(days = 2)
    
    def Initialize(self):
        self.SetStartDate(2021, 1, 1)
        self.SetEndDate(2021, 6, 1)
        self.SetCash(100000) 
        
        self.symbol = self.AddEquity("SPY", Resolution.Daily).Symbol
        
        # Requesting data
        self.regalytics_symbol = self.AddData(RegalyticsRegulatoryArticle, "REG").Symbol
        
        # Historical data
        history = self.History(self.regalytics_symbol, 7, Resolution.Daily)
        self.Debug(f"We got {len(history)} items from our history request")
        
    def OnData(self, data):
        if data.ContainsKey(self.regalytics_symbol) and data[self.regalytics_symbol] is not None:
            article = data[self.regalytics_symbol]
            title = article.Title.lower()
            
            # Signal an exit from the market when regulatory articles with negative sentiment are released
            for phrase in self.negative_sentiment_phrases:
                if phrase in title:
                    self.target_holdings = 0
                    self.last_news_date = data.Time
        
        # Signal an entry if we've waited long enough for the market to digest the negative news
        if self.target_holdings == 0 and self.last_news_date + self.news_affect_duration < data.Time:
            self.target_holdings = 1
        
        # Rebalance if we need to and there is data available in the current slice
        if data.ContainsKey(self.symbol) and data[self.symbol] is not None:
            if (self.target_holdings == 1) != self.Portfolio.Invested:
                self.SetHoldings(self.symbol, self.target_holdings)