Overall Statistics |
Total Orders 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Start Equity 100000 End Equity 100000 Net Profit 0% Sharpe Ratio 0 Sortino Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 9.739 Tracking Error 0.064 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
# region imports from AlgorithmImports import * from datetime import timedelta # endregion class IVTSAlpha(AlphaModel): ''' Provides an implementation of ivts_alpha_model that returns insight for each security''' def __init__(self, type, direction, period, magnitude = None, confidence = None, weight = 0.2): '''Initializes a new instance of the ConstantAlphaModel class Args: type: The type of insight direction: The direction of the insight period: The period over which the insight with come to fruition magnitude: The predicted change in magnitude as a +- percentage confidence: The confidence in the insight weight: The portfolio weight of the insights''' self.type = type self.direction = direction self.period = period self.magnitude = magnitude self.confidence = confidence self.weight = weight self.securities = [] self.insights_time_by_symbol = {} def update(self, algorithm, data): ''' Creates a constant insight for each security as specified via the constructor Args: algorithm: The algorithm instance data: The new data available Returns: The new insights generated''' insights = [] for security in self.securities: # security price could be zero until we get the first data point. e.g. this could happen # when adding both forex and equities, we will first get a forex data point if security.price != 0 and self.should_emit_insight(algorithm.utc_time, security.symbol): insights.append(Insight(security.symbol, self.period, self.type, self.direction, self.magnitude, self.confidence, weight = self.weight)) return insights def on_securities_changed(self, algorithm, changes): ''' Event fired each time the we add/remove securities from the data feed Args: algorithm: The algorithm instance that experienced the change in securities changes: The security additions and removals from the algorithm''' for added in changes.added_securities: self.securities.append(added) # this will allow the insight to be re-sent when the security re-joins the universe for removed in changes.removed_securities: if removed in self.securities: self.securities.remove(removed) if removed.symbol in self.insights_time_by_symbol: self.insights_time_by_symbol.pop(removed.symbol) def should_emit_insight(self, utc_time, symbol): if symbol.is_canonical(): # canonical futures & options are none tradable return False generated_time_utc = self.insights_time_by_symbol.get(symbol) if generated_time_utc is not None: # we previously emitted a insight for this symbol, check it's period to see # if we should emit another insight if utc_time - generated_time_utc < self.period: return False # we either haven't emitted a insight for this symbol or the previous # insight's period has expired, so emit a new insight now for this symbol self.insights_time_by_symbol[symbol] = utc_time return True
# region imports from AlgorithmImports import * # endregion # Your New Python File
#region imports from AlgorithmImports import * from universe import * from alpha import * from portfolio import * #endregion class ConservativeApgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2024, 1, 1) self.set_end_date(2024, 1, 7) self.set_cash(100_000) self.set_brokerage_model(BrokerageName.INTERACTIVE_BROKERS_BROKERAGE, AccountType.MARGIN) # SPY 500 companies spy = self.add_equity("SPY", resolution = Resolution.MINUTE, data_normalization_mode = DataNormalizationMode.RAW).symbol self.set_benchmark(spy) # Subscribe price data unadjusted for splits and dividends ("raw") into the algorithm. Required for options and useful for more accurately modeling historical periods. self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW self.universe_settings.asynchronous = True self.add_universe_selection( OptionChainedUniverseSelectionModel( # Add 10 highest dollar trading volume securities to the universe. self.add_universe(self.universe.dollar_volume.top(10)), # Set contract filter to return only front month CALL options that have the strike price within 2 strike level. lambda option_filter_universe: option_filter_universe.strikes(-2, +2).front_month() ) ) self.set_alpha(IVTSAlpha(InsightType.PRICE, InsightDirection.UP, timedelta(1))) self.Settings.RebalancePortfolioOnInsightChanges = False self.Settings.RebalancePortfolioOnSecurityChanges = False self.set_portfolio_construction(StraddlePortfolio()) self.set_risk_management(NullRiskManagementModel()) self.set_execution(NullExecutionModel())
# region imports from AlgorithmImports import * from datetime import timedelta # endregion # Portfolio construction scaffolding class; basic method args. # Note: this seems equivalent to the EqualWeightingPortfolioConstructionModel class StraddlePortfolio(PortfolioConstructionModel): def __init__(self, rebalance = Resolution.DAILY, portfolio_bias = PortfolioBias.LONG_SHORT): '''Initialize a new instance of EqualWeightingPortfolioConstructionModel Args: rebalance: Rebalancing parameter. If it is a timedelta, date rules or Resolution, it will be converted into a function. If None will be ignored. The function returns the next expected rebalance time for a given algorithm UTC DateTime. The function returns null if unknown, in which case the function will be called again in the next loop. Returning current time will trigger rebalance. portfolio_bias: Specifies the bias of the portfolio (Short, Long/Short, Long)''' super().__init__() self.portfolio_bias = portfolio_bias # If the argument is an instance of Resolution or Timedelta # Redefine rebalancing_func rebalancing_func = rebalance if isinstance(rebalance, int): rebalance = Extensions.to_time_span(rebalance) if isinstance(rebalance, timedelta): rebalancing_func = lambda dt: dt + rebalance if rebalancing_func: self.set_rebalancing_func(rebalancing_func) # Determines the target percent for each insight def determine_target_percent(self, active_insights: List[Insight]) -> Dict[Insight, float]: targets = {} # give equal weighting to each security count = sum(x.direction != InsightDirection.FLAT and self.respect_portfolio_bias(x) for x in active_insights) percent = 0 if count == 0 else 1.0 / count for insight in active_insights: targets[insight] = (insight.direction if self.respect_portfolio_bias(insight) else InsightDirection.FLAT) * percent return targets def respect_portfolio_bias(self, insight): '''Method that will determine if a given insight respects the portfolio bias Args: insight: The insight to create a target for ''' return self.portfolio_bias == PortfolioBias.LONG_SHORT or insight.direction == self.portfolio_bias
# region imports from AlgorithmImports import * # endregion class ETFConstituentsUniverse(ETFConstituentsUniverseSelectionModel): def __init__(self, benchmark, universe_settings: UniverseSettings = None) -> None: super().__init__(benchmark, universe_settings, self.etf_constituents_filter) def etf_constituents_filter(self, constituents): return [c.symbol for c in constituents]