Overall Statistics
Total Orders
155
Average Win
4.29%
Average Loss
-1.45%
Compounding Annual Return
244.096%
Drawdown
22.900%
Expectancy
1.045
Start Equity
1000000
End Equity
1670988.52
Net Profit
67.099%
Sharpe Ratio
3.952
Sortino Ratio
5.786
Probabilistic Sharpe Ratio
90.016%
Loss Rate
48%
Win Rate
52%
Profit-Loss Ratio
2.95
Alpha
1.074
Beta
2.661
Annual Standard Deviation
0.37
Annual Variance
0.137
Information Ratio
4.199
Tracking Error
0.313
Treynor Ratio
0.549
Total Fees
$667.89
Estimated Strategy Capacity
$320000000.00
Lowest Capacity Asset
CMB R735QTJ8XC9X
Portfolio Turnover
9.62%
# # region imports
# from AlgorithmImports import *
# import pandas as pd
# from io import StringIO
# # endregion

# class MeasuredYellowJaguar(QCAlgorithm):

#     def Initialize(self):
#         self.SetStartDate(2024, 1, 1)
#         self.SetEndDate(2024, 5, 31)
#         self.SetCash(1000000)

#         csv_content = self.Download('https://drive.google.com/uc?export=download&id=1DMVvRfBDO-4IoLmEL2ZhxldXGCJfbi1G')
#         stocks_csv = pd.read_csv(StringIO(csv_content))
        
#         self.last_news_time = {}

#         self.UniverseSettings.Resolution = Resolution.Minute
#         self.AddUniverse(self.CoarseSelectionFunction)
#         self.AddData(BenzingaNews, "BenzingaNews")

#         for ticker in stocks_csv['Ticker']:
#             self.AddEquity(ticker, Resolution.Minute)
#             self.AddNewsSubscription(ticker)
#             self.Debug(f"Added stock: {ticker}")
        
#         self.Debug("Initialization for stocks complete")

#     def CoarseSelectionFunction(self, coarse):
#         filtered = [x.Symbol for x in coarse if x.Volume >= 1000000]
#         return filtered

#     def OnData(self, data):
#         for symbol in self.Securities.Keys:
#             if not self.Securities[symbol].Exchange.Hours.IsOpen(self.Time + timedelta(minutes=1), False):
#                 continue
            
#             if symbol not in data:
#                 continue
            
#             if self.HasRelevantNews(data, symbol):
#                 self.SetHoldings(symbol, 0.1)

#         if self.Time.hour == 15 and self.Time.minute == 59:
#             for security in self.Portfolio.Values:
#                 if security.Invested:
#                     self.Liquidate(security.Symbol)

#     def HasRelevantNews(self, data, symbol):
#         if symbol not in data:
#             return False
#         self.Debug(f"Searching news for {symbol}")
#         news = data[symbol]
#         for article in news:
#             if 'price' in article.Contents.lower() and 'target' in article.Contents.lower():
#                 if symbol not in self.last_news_time or self.last_news_time[symbol] < article.EndTime:
#                     self.last_news_time[symbol] = article.EndTime
#                     return True
#         return False

#     def OnSecuritiesChanged(self, changes):
#         for security in changes.AddedSecurities:
#             self.AddNewsSubscription(security.Symbol)

#         for security in changes.RemovedSecurities:
#             if security.Symbol in self.Securities:
#                 self.RemoveNewsSubscription(security.Symbol)

#     def AddNewsSubscription(self, symbol):
#         self.AddData(BenzingaNews, symbol)
#         self.Debug(f"Added news for {symbol}")

#     def RemoveNewsSubscription(self, symbol):
#         self.RemoveSecurity(symbol)
#         self.Debug(f"Removed news for {symbol}")

















# # region imports
# from AlgorithmImports import *
# import pandas as pd
# from io import StringIO
# from QuantConnect.DataSource import *
# # endregion

# class MeasuredYellowJaguar(QCAlgorithm):

#     def Initialize(self):
#         self.SetStartDate(2024, 1, 1)
#         self.SetStartDate(2024, 5, 31)
#         self.SetCash(1000000)
#         self.newsdata={}
#         self.selectedStocks={}
#         csv_content  = self.Download('https://drive.google.com/uc?export=download&id=1DMVvRfBDO-4IoLmEL2ZhxldXGCJfbi1G')
#         # stocks_csv = pd.read_csv(self.Download('https://drive.google.com/uc?export=download&id=1DMVvRfBDO-4IoLmEL2ZhxldXGCJfbi1G'))
#         stocks_csv = pd.read_csv(StringIO(csv_content))
#         self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 30), self.ClearSelectedStocks)
#         # for ticker in stocks_csv['Ticker']:
#         #     benzinga_symbol=self.AddEquity(ticker, Resolution.Minute).Symbol
#         #     self.newsdata= self.AddData(BenzingaNews, benzinga_symbol).Symbol
#         #     history = self.history(self.newsdata, 1, Resolution.MINUTE)
#         # self.benzinga_symbol = self.AddEquity('TSLA', Resolution.Minute).Symbol
#         # self.newsdata = self.AddData(BenzingaNews, self.benzinga_symbol)
#         self.filtered_tickers = []
#         self.UniverseSettings.Resolution = Resolution.Minute
#         self.AddUniverse(self.CoarseSelectionFunction)
    
#     def ClearSelectedStocks(self):
#         self.selectedStocks = {}


#     def CoarseSelectionFunction(self, coarse):
#         filtered = [x.Symbol for x in coarse if x.Volume >= 1000000]
#         self.filtered_tickers = filtered
#         return filtered


#     def OnData(self, slice: Slice) -> None:
#         # for symbol in self.filtered_tickers:
#         for security in self.Securities.Values:
#             if slice.contains_key(self.newsdata[security.Symbol.Value]):
#                 # if slice[self.benzinga_symbol].contents.lower():
#                 news = slice[self.newsdata[security.Symbol.Value]].contents.lower()
#                 # self.log(f"{self.benzinga_symbol} title at {slice.time}: {news.title}")
#                 if self.filled==0 and "target" in news and "price" in news:
#                     selectedStocks[security.Symbol]=1
#         for key in selectedStocks.keys():          
#             self.SetHoldings(key, 1/len(selectedStocks))
                  

#         if self.Time.hour == 15 and self.Time.minute == 59:
#             for security in self.Portfolio.values():
#                 if security.Invested:
#                     self.Liquidate(security.Symbol)
















from AlgorithmImports import *
import pandas as pd
from io import StringIO
from QuantConnect.DataSource import *
import re
from datetime import datetime, timedelta
import pytz

URL = 'https://drive.google.com/uc?export=download&id=1DMVvRfBDO-4IoLmEL2ZhxldXGCJfbi1G'

class MeasuredYellowJaguar(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2024, 1, 1)
        self.SetEndDate(2024, 5, 31)
        self.SetCash(1000000)
        self.benzinga_symbols = []

        def add_news(ticker):
            symbol = self.AddEquity(ticker, Resolution.Minute).Symbol
            return self.AddData(BenzingaNews, symbol)
        
        content = self.Download(URL)
        # tickers = [x for x in content.split('\r\n')[1:] if x]
        tickers = ['AAPL', 'TSLA', 'NVDA', 'MSFT', 'GOOG', 'META', 'JPM', 'AMZN', 'V', 'AMD']
        self.symbols = [add_news(ticker).Symbol for ticker in tickers]

    def OnData(self, slice: Slice) -> None:
        for symbol, news in slice.Get(BenzingaNews).items():
            underlying = symbol.Underlying

            # if underlying not in self.benzinga_symbols:
            #     self.AddEquity(underlying.Value, Resolution.Minute)
            #     self.benzinga_symbols.append(underlying)

            if 'price' in news.Contents.lower() and 'target' in news.Contents.lower() and self.Time.hour <= 15 and self.Time >= datetime(self.Time.year, self.Time.month, self.Time.day, 9, 30):
                
                report_keywords = ['earnings', 'sec', 'financial report', 'quarter', 'quarterly']
                if any(keyword in news.Contents.lower() for keyword in report_keywords):
                    continue

                target_price_patterns = [
                    r'target price of \$(\d+(\.\d+)?)',
                    r'price target of \$(\d+(\.\d+)?)',
                    r'price to \$(\d+(\.\d+)?)',
                    r'price (rise|increase|move) to \$(\d+(\.\d+)?)',
                    r'price (target|goal|aim) .*? \$(\d+(\.\d+)?)',
                    r'target .*? \$(\d+(\.\d+)?)'
                ]

                combined_pattern = re.compile('|'.join(target_price_patterns))
                matches = combined_pattern.findall(news.Contents)

                target_prices = set()
                for match in matches:
                    for price in match:
                        if price and re.match(r'\d+(\.\d+)?', price):
                            target_prices.add(float(price))

                if target_prices:
                    target_price = max(target_prices)
                    current_price = self.Securities[underlying].Price

                    self.Log(f'Target price for {underlying} is {target_price}, current price is {current_price}')

                    if target_price > current_price:
                        free_margin = self.Portfolio.MarginRemaining
                        leverage = self.Securities[underlying].Holdings.Leverage

                        shares_to_buy = free_margin / (current_price * leverage)
                        if shares_to_buy > 0:
                            self.MarketOrder(underlying, int(shares_to_buy))

            if (news.CreatedAt.replace(tzinfo=pytz.UTC) + timedelta(minutes=50)) <= self.Time.replace(tzinfo=pytz.UTC) <= (news.CreatedAt.replace(tzinfo=pytz.UTC) + timedelta(minutes=59)):
                for security in self.Portfolio.Values:
                    if security.Invested:
                        self.Liquidate(security.Symbol)
            
            elif self.Time.hour == 15 and self.Time.minute == 59:
                for security in self.Portfolio.Values:
                    if security.Invested:
                        self.Liquidate(security.Symbol)


            # if self.Time.hour == 15:
            #     for security in self.Portfolio.Values:
            #         if security.Invested:
            #             self.Liquidate(security.Symbol)

    # def OnData(self, slice: Slice) -> None:
    #     for benzinga_symbol in self.benzinga_symbols:
    #         if slice.ContainsKey(benzinga_symbol):
    #             news = slice[benzinga_symbol]
    #             if isinstance(news, list):
    #                 for article in news:
    #                     if "price" in article.Contents.lower() and "target" in article.Contents.lower():
    #                         for symbol in self.filtered_tickers:
    #                             if symbol in self.Securities and self.Securities[symbol].Volume >= 1000000:
    #                                 self.SetHoldings(symbol, 0.01)

    #     if self.Time.hour == 15 and self.Time.minute == 59:
    #         for security in self.Portfolio.Values:
    #             if security.Invested:
    #                 self.Liquidate(security.Symbol)










# from AlgorithmImports import *
# from QuantConnect.DataSource import *

# class BenzingaNewsDataAlgorithm(QCAlgorithm):

#     current_holdings = 0
#     target_holdings = 0
#     # word_scores = {
#     #     'good': 1, 'great': 1, 'best': 1, 'growth': 1,
#     #     'bad': -1, 'terrible': -1, 'worst': -1, 'loss': -1}

#     def initialize(self) -> None:
#         self.set_start_date(2024, 1, 1)
#         self.set_end_date(2024, 5, 30)
#         self.set_cash(100000)
        
#         # Requesting data
#         self.aapl = self.add_equity("TSLA", Resolution.MINUTE).symbol
#         self.benzinga_symbol = self.add_data(BenzingaNews, self.aapl)
        
#         # Historical data
#         # history = self.history(self.benzinga_symbol, 1, Resolution.Minute)
#         self.debug(f"We got {len(history)} items from our history request")
        
#     def on_data(self, slice: Slice) -> None:
#         if slice.contains_key(self.benzinga_symbol):
#             # Assign a sentiment score to the news article
#             content_words = slice[self.benzinga_symbol].contents.lower()
#             score = 0
#             if "price" in content_words and "target" in content_words:
#                 self.set_holdings(self.aapl, 0.05)
#                 self.Schedule.On(self.TimeRules.At(self.Time.hour + 2, self.Time.minute), self.SellPosition)
        
#         # Ensure we have AAPL data in the current Slice
#         if not (slice.contains_key(self.aapl) and slice[self.aapl] is not None and not slice[self.aapl].is_fill_forward):
#             return
        
#         # Buy or sell if the sentiment has changed from our current holdings
#         # if self.current_holdings != self.target_holdings:
#         #     self.set_holdings(self.aapl, self.target_holdings)
#         #     self.current_holdings = self.target_holdings

#         if self.Time.hour == 15 and self.Time.minute == 59:
#             if self.Portfolio.Invested:
#                 self.Liquidate()