| Overall Statistics |
|
Total Orders 2420 Average Win 0.93% Average Loss -0.38% Compounding Annual Return 9.178% Drawdown 26.100% Expectancy 0.148 Start Equity 100000.00 End Equity 185702.09 Net Profit 85.702% Sharpe Ratio 0.329 Sortino Ratio 0.389 Probabilistic Sharpe Ratio 6.807% Loss Rate 66% Win Rate 34% Profit-Loss Ratio 2.41 Alpha 0.039 Beta 0.003 Annual Standard Deviation 0.119 Annual Variance 0.014 Information Ratio -0.245 Tracking Error 0.203 Treynor Ratio 13.798 Total Fees $0.00 Estimated Strategy Capacity $87000.00 Lowest Capacity Asset BTCUSD E3 Portfolio Turnover 93.77% Drawdown Recovery 647 |
# region imports
from AlgorithmImports import *
# endregion
class HyperActiveAsparagusBarracuda(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2018, 12, 1)
self.set_cash(100_000)
self.set_time_zone('UTC')
fast_period: int = 12
slow_period: int = 26
crossover: int = 9
self._traded_asset: Symbol = self.add_crypto('BTCUSD', Resolution.HOUR, market=Market.BITFINEX).symbol
self._daily_macd: MovingAverageConvergenceDivergence = MovingAverageConvergenceDivergence(fast_period, slow_period, crossover, MovingAverageType.EXPONENTIAL)
self._hour_macd: MovingAverageConvergenceDivergence = self.macd(self._traded_asset, fast_period, slow_period, crossover, MovingAverageType.EXPONENTIAL, Resolution.HOUR)
self._daily_signal_flag: bool = False
self._update_flag: bool = False
# Update daily indicator at UTC+4 according to documentation
self.schedule.on(
self.date_rules.every_day(),
self.time_rules.at(4,0),
self._update
)
self.schedule.on(
self.date_rules.every_day(),
self.time_rules.at(0,0),
self._rebalance
)
def on_data(self, slice: Slice) -> None:
# Update MACD indicator daily
if self._update_flag:
self._update_flag = False
if slice.bars.contains_key(self._traded_asset):
bar = slice.bars[self._traded_asset]
self._daily_macd.update(bar.end_time, bar.close)
if self.portfolio.invested:
# Liquidate at first negative hour candle
if slice[self._traded_asset].close < slice[self._traded_asset].open:
self.liquidate()
if self._daily_signal_flag:
# Evaluate hourly signal
if (self._hour_macd.current.value > self._hour_macd.signal.current.value and
self._hour_macd.previous.value <= self._hour_macd.signal.previous.value):
if not self.portfolio.invested:
self.set_holdings(self._traded_asset, 1)
def _update(self) -> None:
self._update_flag = True
def _rebalance(self) -> None:
# Evaluate daily signal
if self._daily_macd.is_ready:
self._daily_signal_flag = self._daily_macd.current.value > self._daily_macd.signal.current.value