| Overall Statistics |
|
Total Orders 1864 Average Win 1.14% Average Loss -0.35% Compounding Annual Return 13.280% Drawdown 26.500% Expectancy 0.292 Start Equity 100000.00 End Equity 240841.28 Net Profit 140.841% Sharpe Ratio 0.495 Sortino Ratio 0.656 Probabilistic Sharpe Ratio 10.268% Loss Rate 69% Win Rate 31% Profit-Loss Ratio 3.23 Alpha 0.069 Beta -0.001 Annual Standard Deviation 0.14 Annual Variance 0.02 Information Ratio -0.09 Tracking Error 0.217 Treynor Ratio -70.146 Total Fees $0.00 Estimated Strategy Capacity $100000.00 Lowest Capacity Asset BTCUSD E3 Portfolio Turnover 72.20% Drawdown Recovery 634 |
# region imports
from AlgorithmImports import *
# endregion
class BTCMACDD1H1(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
# Evaluate day trend signal at UTC+4
self._consolidator = TradeBarConsolidator(
timedelta(days=1),
start_time=timedelta(hours=4)
)
self._consolidator.data_consolidated += self._consolidation_handler
self.subscription_manager.add_consolidator(self._traded_asset, self._consolidator)
self._signal_date: datetime.date = datetime(1,1,1).date()
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
def on_data(self, slice: Slice) -> None:
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:
if self._signal_date == self.time.date():
# 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 _consolidation_handler(self, sender: object, consolidated_bar: TradeBar) -> None:
if consolidated_bar.close > consolidated_bar.open:
# takes daily signal with 1 day lag
self._signal_date = consolidated_bar.end_time.date() + timedelta(days=1)