| Overall Statistics |
|
Total Trades 11 Average Win 0% Average Loss -8.93% Compounding Annual Return -19.552% Drawdown 42.000% Expectancy -1 Net Profit -31.836% Sharpe Ratio -0.927 Probabilistic Sharpe Ratio 0.064% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.132 Beta 0.502 Annual Standard Deviation 0.141 Annual Variance 0.02 Information Ratio -0.938 Tracking Error 0.141 Treynor Ratio -0.261 Total Fees $13.67 Estimated Strategy Capacity $360000000.00 Lowest Capacity Asset QQQ RIWIV7K5Z9LX Portfolio Turnover 1.68% |
# region imports
from AlgorithmImports import *
# endregion
class DancingAsparagusChimpanzee(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021,8, 1) # Set Start Date
self.SetEndDate(2023, 5, 5) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.leverage = 0.99 # Set Leverage
# stocks
self.STK1 = self.AddEquity("QQQ", Resolution.Daily).Symbol
self.STK2 = self.AddEquity("SPY", Resolution.Daily).Symbol
self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY"), self.rebalance)
self.look_back_period = 63 # LookBack period
self.SetWarmUp(self.look_back_period)
self.weight = 0.99
def returns(self, symbol, period):
closing_bars = self.History(symbol, TimeSpan.FromDays(period), Resolution.Daily).close
self.Debug('{}'.format(closing_bars.size))
return (closing_bars[-1] - closing_bars[0]) / closing_bars[-1]
# Check if any assets from symbol list has negative return for lookBack period
def negative_returns_check(self, symbol_list):
for symbol in symbol_list:
if self.returns(symbol, self.look_back_period) < 0:
return True
return False
def liquidate_all_pos(self, symbol_list):
for symbol in symbol_list:
if self.Portfolio[symbol].IsLong:
self.Liquidate(symbol)
# choose best performer
def find_best_performer(self, symbol_list):
max_return = self.returns(symbol_list[0], self.look_back_period)
max_return_symbol = symbol_list[0]
for i in range(2, len(symbol_list)):
if self.returns(symbol_list[i], self.look_back_period) > max_return:
max_return = self.returns(symbol_list[i], self.look_back_period)
max_return_symbol = symbol_list[i]
return max_return_symbol
def allocate_safely(self, symbol):
# check if invested
stock_invested = [x.Symbol.Value for x in self.Portfolio.Values if x.Invested]
if symbol.Value not in stock_invested:
self.SetHoldings(symbol, self.weight)
def check_group(self, symbol_list):
# check if return is positive
if self.negative_returns_check(symbol_list):
# if negative
# liquidate positions if any
self.liquidate_all_pos(symbol_list)
else:
# and find best performer
buy_symbol = self.find_best_performer(symbol_list)
self.allocate_safely(buy_symbol)
def rebalance(self):
# check stocks
self.check_group([self.STK1, self.STK2])