| Overall Statistics |
|
Total Orders 326 Average Win 1.41% Average Loss -1.08% Compounding Annual Return -0.648% Drawdown 12.600% Expectancy -0.011 Start Equity 100000 End Equity 96799.23 Net Profit -3.201% Sharpe Ratio -0.6 Sortino Ratio -0.467 Probabilistic Sharpe Ratio 0.265% Loss Rate 57% Win Rate 43% Profit-Loss Ratio 1.31 Alpha -0.056 Beta 0.212 Annual Standard Deviation 0.066 Annual Variance 0.004 Information Ratio -0.91 Tracking Error 0.126 Treynor Ratio -0.188 Total Fees $1393.22 Estimated Strategy Capacity $6300000.00 Lowest Capacity Asset SVXY V0H08FY38ZFP Portfolio Turnover 5.58% Drawdown Recovery 794 |
from AlgorithmImports import *
class NadionHorizontalCircuit(QCAlgorithm):
_stop_market_ticket = None
_stop_market_fill_time = datetime.min
_highest_price = 0
def initialize(self):
self.set_start_date(self.end_date - timedelta(5*365))
self.set_cash(100_000)
# Define the target volaility.
self._target_portfolio_sigma = 0.12
# Add the asset to trade.
self._equity = self.add_equity('SVXY', Resolution.DAILY)
# Add some indicators.
self._roc = self.roc(self._equity, 5)
self._atr = self.atr(self._equity, 20)
self._std = IndicatorExtensions.of(StandardDeviation(30), self.roc(self._equity, 1))
# Warm up the indicators.
self.set_warm_up(timedelta(60))
def on_data(self, data):
# Check that enough time has passed since we hit the stop loss.
if self.is_warming_up or (self.time - self._stop_market_fill_time).days < 2:
return
if not self.portfolio.invested:
# Scan for entries.
if self._roc.current.value > 0:
volatility = self._std.current.value * np.sqrt(252)
# Calculate the quantity to trade based on the targeted vol.
weight = self._target_portfolio_sigma / volatility
quantity = self.calculate_order_quantity(self._equity, weight)
self.market_order(self._equity, quantity)
# Add the stop loss.
self._stop_market_ticket = self.stop_market_order(
self._equity,
-quantity,
self._get_stop_price()
)
else:
if self._roc.current.value > 0:
# Update the stop price if the stock has gone up.
if self._equity.price > self._highest_price:
self._highest_price = self._equity.price
self._stop_market_ticket.update_stop_price(self._get_stop_price())
else:
# Close the trade.
self.liquidate()
self._highest_price = 0
def _get_stop_price(self):
return self._equity.price - 2 * self._atr.current.value
def on_order_event(self, order_event):
# Record when the stop loss fills.
if (order_event.Status == OrderStatus.FILLED and
order_event.ticket.order_type == OrderType.STOP_MARKET):
self._stop_market_fill_time = self.time