| 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()