| Overall Statistics |
|
Total Orders 39 Average Win 0.64% Average Loss -0.44% Compounding Annual Return 4.307% Drawdown 1.800% Expectancy 0.222 Start Equity 100000 End Equity 101415.99 Net Profit 1.416% Sharpe Ratio -0.503 Sortino Ratio -0.435 Probabilistic Sharpe Ratio 40.150% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.44 Alpha -0.035 Beta 0.21 Annual Standard Deviation 0.048 Annual Variance 0.002 Information Ratio -0.791 Tracking Error 0.094 Treynor Ratio -0.115 Total Fees $37.00 Estimated Strategy Capacity $1300000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X Portfolio Turnover 30.23% Drawdown Recovery 38 |
# region imports
from AlgorithmImports import *
# endregion
class WarmUpCustomIndicatorAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.set_cash(100_000)
self.settings.seed_initial_prices = True
self._equity = self.add_equity("SPY", Resolution.DAILY)
self._equity.volatility = CustomVolatility(100)
# Warm the custom indicator with daily trade bars.
for bar in self.history[TradeBar](self._equity, self._equity.volatility.warm_up_period, Resolution.DAILY):
self._equity.volatility.update(bar)
self.register_indicator(self._equity, self._equity.volatility)
def on_data(self, data: Slice) -> None:
if not self._equity.volatility.is_ready:
return
# Buy if volatility is increasing.
if not self._equity.invested and self._equity.volatility.value > self._equity.volatility.previous.value:
self.set_holdings(self._equity, 1)
# Sell if volatility is decreasing or we are invested.
elif self._equity.invested and self._equity.volatility.value < self._equity.volatility.previous.value:
self.liquidate()
class CustomVolatility(PythonIndicator):
def __init__(self, period, trading_days_per_year=252):
super().__init__()
self.warm_up_period = period
self._trading_days_per_year = trading_days_per_year
self.value = 0
self._log_return = LogReturn(1)
self._standard_deviation = IndicatorExtensions.of(StandardDeviation(period), self._log_return)
def update(self, input_: BaseData):
# Annualized log-return volatility.
price = input_.value
if price <= 0:
return
self._log_return.update(input_.end_time, price)
if self.is_ready:
self.value = self._standard_deviation.current.value * math.sqrt(self._trading_days_per_year) * 100.0
return self.is_ready
@property
def is_ready(self) -> bool:
return self._standard_deviation.is_ready