| Overall Statistics |
|
Total Orders 815 Average Win 0.16% Average Loss -0.15% Compounding Annual Return 3.003% Drawdown 3.900% Expectancy 0.076 Start Equity 100000 End Equity 104287.87 Net Profit 4.288% Sharpe Ratio -0.045 Sortino Ratio -0.046 Probabilistic Sharpe Ratio 26.954% Loss Rate 48% Win Rate 52% Profit-Loss Ratio 1.07 Alpha -0 Beta -0.013 Annual Standard Deviation 0.038 Annual Variance 0.001 Information Ratio -0.531 Tracking Error 0.234 Treynor Ratio 0.13 Total Fees $783.60 Estimated Strategy Capacity $5300000.00 Lowest Capacity Asset ENPH V5C9T324VA05 Portfolio Turnover 6.46% |
from AlgorithmImports import *
from QuantConnect.DataSource import *
class KavoutCompositeFactorBundleAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2019, 1, 1)
self.set_end_date(2020, 6, 1)
self.set_cash(100000)
self.last_time = datetime.min
self.add_universe(self.my_coarse_filter_function)
self.universe_settings.resolution = Resolution.MINUTE
def my_coarse_filter_function(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
sorted_by_dollar_volume = sorted([x for x in coarse if x.has_fundamental_data],
key=lambda x: x.dollar_volume, reverse=True)
selected = [x.symbol for x in sorted_by_dollar_volume[:100]]
return selected
def on_data(self, slice: Slice) -> None:
if self.last_time > self.time: return
# Accessing Data
points = slice.Get(KavoutCompositeFactorBundle)
sorted_by_score = sorted(points.items(), key=self.total_score)
long_symbols = [x[0].underlying for x in sorted_by_score[-10:]]
short_symbols = [x[0].underlying for x in sorted_by_score[:10]]
for symbol in [x.symbol for x in self.portfolio.Values if x.invested]:
if symbol not in long_symbols + short_symbols:
self.liquidate(symbol)
long_targets = [PortfolioTarget(symbol, 0.05) for symbol in long_symbols]
short_targets = [PortfolioTarget(symbol, -0.05) for symbol in short_symbols]
self.set_holdings(long_targets + short_targets)
self.last_time = Expiry.END_OF_DAY(self.time)
def on_securities_changed(self, changes: SecurityChanges) -> None:
for security in changes.added_securities:
# Requesting Data
kavout_composite_factor_bundle_symbol= self.add_data(KavoutCompositeFactorBundle, security.symbol).symbol
# Historical Data
history = self.history(kavout_composite_factor_bundle_symbol, 2, Resolution.DAILY)
self.debug(f"We got {len(history)} items from our history request")
def total_score(self, value: Tuple[Symbol, KavoutCompositeFactorBundle]) -> float:
'''Return the total score to integrate overall likelihood to outcompete, take equal weighting for each factor'''
value = value[1]
return value.growth + value.low_volatility + value.momentum + value.quality + value.value_factor