| Overall Statistics |
|
Total Orders 297 Average Win 0.15% Average Loss -0.07% Compounding Annual Return 44.876% Drawdown 10.800% Expectancy 1.677 Start Equity 100000 End Equity 144876.23 Net Profit 44.876% Sharpe Ratio 1.807 Sortino Ratio 2.181 Probabilistic Sharpe Ratio 81.800% Loss Rate 15% Win Rate 85% Profit-Loss Ratio 2.16 Alpha 0.047 Beta 1.255 Annual Standard Deviation 0.155 Annual Variance 0.024 Information Ratio 1.083 Tracking Error 0.087 Treynor Ratio 0.223 Total Fees $314.48 Estimated Strategy Capacity $270000000.00 Lowest Capacity Asset BYND X45I7544YKIT Portfolio Turnover 1.73% |
from AlgorithmImports import *
from QuantConnect.DataSource import *
class SECReport8KAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2019, 1, 1)
self.set_end_date(2019, 12, 31)
self.set_cash(100000)
self.universe_settings.resolution = Resolution.DAILY
self.add_universe(self.coarse_selector)
self.dataset_symbol_by_symbol = {}
self.long_symbols = []
self.rebalance = False
# Request underlying equity data.
ibm = self.add_equity("IBM", Resolution.DAILY).symbol
# Add news data for the underlying IBM asset
earnings_filing = self.add_data(SECReport10Q, ibm, Resolution.DAILY).symbol
# Request 120 days of history with the SECReport10Q IBM custom data Symbol
history = self.history(SECReport10Q, earnings_filing, 120, Resolution.DAILY)
# Count the number of items we get from our history request
self.debug(f"We got {len(history)} items from our history request")
def coarse_selector(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
coarse = sorted([cf for cf in coarse if cf.has_fundamental_data],
key=lambda cf: cf.dollar_volume, reverse=True)[:10]
return [cf.symbol for cf in coarse]
def on_data(self, slice: Slice) -> None:
# Get all SEC data and loop over it
for report in slice.Get(SECReport8K).Values:
underlying_symbol = report.symbol.underlying
# Skip the Symbol if it's no longer in the universe
if underlying_symbol not in self.dataset_symbol_by_symbol:
if underlying_symbol in self.long_symbols:
self.rebalance = True
self.long_symbols.remove(underlying_symbol)
continue
# Get the length of all contents contained within the report
report_text_length = sum([len(i.text) for i in report.report.documents])
if report_text_length > 20000:
if underlying_symbol not in self.long_symbols:
self.rebalance = True
self.long_symbols.append(underlying_symbol)
elif underlying_symbol in self.long_symbols:
self.rebalance = True
self.long_symbols.remove(underlying_symbol)
if not self.rebalance:
return
self.rebalance = False
portfolio_targets = []
equal_weighting = 1 / len(self.long_symbols) if len(self.long_symbols) > 0 else 0
for symbol, security_holding in self.portfolio.items():
weight = 0
if symbol in self.long_symbols:
weight = equal_weighting
elif not security_holding.invested:
continue
portfolio_targets.append(PortfolioTarget(symbol, weight))
self.set_holdings(portfolio_targets)
def on_securities_changed(self, changes: SecurityChanges) -> None:
for security in changes.added_securities:
self.dataset_symbol_by_symbol[security.symbol] = self.add_data(SECReport8K, security.symbol).symbol
for security in changes.removed_securities:
dataset_symbol = self.dataset_symbol_by_symbol.pop(security.symbol, None)
if dataset_symbol:
self.remove_security(dataset_symbol)