| Overall Statistics |
|
Total Orders 3365 Average Win 0.35% Average Loss -0.49% Compounding Annual Return 15.305% Drawdown 17.800% Expectancy 0.039 Start Equity 100000.00 End Equity 133055.75 Net Profit 33.056% Sharpe Ratio 0.731 Sortino Ratio 0.686 Probabilistic Sharpe Ratio 32.140% Loss Rate 40% Win Rate 60% Profit-Loss Ratio 0.72 Alpha 0.128 Beta -0.092 Annual Standard Deviation 0.153 Annual Variance 0.024 Information Ratio -0.238 Tracking Error 0.276 Treynor Ratio -1.225 Total Fees $0.00 Estimated Strategy Capacity $530000.00 Lowest Capacity Asset BTCUSD 2XR Portfolio Turnover 220.02% Drawdown Recovery 98 |
#region imports
from AlgorithmImports import *
#endregion
class CryingVioletCaterpillar(QCAlgorithm):
def initialize(self):
self.set_start_date(2020,1,1)
self.set_end_date(2022,1,1)
self.set_cash(100000)
self.btc=self.add_crypto("BTCUSD",Resolution.MINUTE)
self.MACD=self.macd(self.btc.symbol,12,26,9,MovingAverageType.EXPONENTIAL,Resolution.MINUTE)
self.BB=self.bb(self.btc.symbol,20,2,MovingAverageType.SIMPLE,Resolution.MINUTE)
self.position_size=0.8
self.last_trade_time=datetime.min
self.min_trade_interval=timedelta(minutes=15)
self.set_warm_up(50)
def on_data(self,data:Slice):
if self.is_warming_up or not data.contains_key(self.btc.symbol):
return
if not(self.MACD.is_ready and self.BB.is_ready):
return
current_time=self.time
if current_time-self.last_trade_time<self.min_trade_interval:
return
price=data[self.btc.symbol].close
macd_value=self.MACD.current.value
macd_signal=self.MACD.signal.current.value
macd_histogram=self.MACD.histogram.current.value
bb_upper=self.BB.upper_band.current.value
bb_middle=self.BB.middle_band.current.value
bb_lower=self.BB.lower_band.current.value
bb_width=(bb_upper-bb_lower)/bb_middle
strong_long_signal=(
macd_value>macd_signal and
macd_histogram>0 and
price<=bb_lower*1.002 and
bb_width>0.02
)
strong_short_signal=(
macd_value<macd_signal and
macd_histogram<0 and
price>=bb_upper*0.998 and
bb_width>0.02
)
moderate_long_signal=(
macd_value>macd_signal and
price<bb_middle and
not self.portfolio[self.btc.symbol].is_long
)
moderate_short_signal=(
macd_value<macd_signal and
price>bb_middle and
not self.portfolio[self.btc.symbol].is_short
)
exit_long_strong=(
(price>bb_upper and macd_histogram<0)
)
exit_short_strong=(
(price<bb_lower and macd_histogram>0)
)
exit_long_moderate=(
price>bb_middle and
macd_value<macd_signal
)
exit_short_moderate=(
price<bb_middle and
macd_value>macd_signal
)
current_holdings=self.portfolio[self.btc.symbol].quantity
if current_holdings==0:
if strong_long_signal:
self.set_holdings(self.btc.symbol,self.position_size)
self.last_trade_time=current_time
self.debug(f"STRONGLONGat{price:.2f}|MACD:{macd_histogram:.4f}")
elif strong_short_signal:
self.set_holdings(self.btc.symbol,-self.position_size)
self.last_trade_time=current_time
self.debug(f"STRONGshortat{price:.2f}|MACD:{macd_histogram:.4f}")
elif moderate_long_signal and bb_width>0.015:
self.set_holdings(self.btc.symbol,self.position_size*0.6)
self.last_trade_time=current_time
self.debug(f"MODERATELONGat{price:.2f}")
elif moderate_short_signal and bb_width>0.015:
self.set_holdings(self.btc.symbol,-self.position_size*0.6)
self.last_trade_time=current_time
self.debug(f"MODERATEshortat{price:.2f}")
elif current_holdings>0:
if exit_long_strong:
self.liquidate(self.btc.symbol)
self.last_trade_time=current_time
self.debug(f"EXITLONGSTRONGat{price:.2f}")
elif exit_long_moderate and abs(current_holdings)<self.portfolio.total_portfolio_value*self.position_size*0.7:
self.liquidate(self.btc.symbol)
self.last_trade_time=current_time
self.debug(f"EXITLONGMODERATEat{price:.2f}")
elif current_holdings<0:
if exit_short_strong:
self.liquidate(self.btc.symbol)
self.last_trade_time=current_time
self.debug(f"EXITshortSTRONGat{price:.2f}")
elif exit_short_moderate and abs(current_holdings)<self.portfolio.total_portfolio_value*self.position_size*0.7:
self.liquidate(self.btc.symbol)
self.last_trade_time=current_time
self.debug(f"EXITshortMODERATEat{price:.2f}")