| Overall Statistics |
|
Total Trades 1148 Average Win 0.74% Average Loss -0.52% Compounding Annual Return 11.896% Drawdown 11.700% Expectancy 0.476 Net Profit 287.061% Sharpe Ratio 1.05 Probabilistic Sharpe Ratio 51.371% Loss Rate 39% Win Rate 61% Profit-Loss Ratio 1.42 Alpha 0.052 Beta 0.287 Annual Standard Deviation 0.08 Annual Variance 0.006 Information Ratio -0.226 Tracking Error 0.122 Treynor Ratio 0.294 Total Fees $0.00 Estimated Strategy Capacity $6900000.00 Lowest Capacity Asset VTI S551B7YE6N39 |
import numpy as np
import pandas as pd
import random
import math
# hello
class CasualRedOrangeJackal(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.InitCash = 100000
self.AddEquity("SPY", Resolution.Minute)
self.MKT = self.AddEquity("SPY", Resolution.Daily).Symbol
self.spy = []
self.i = 1000
self.basket = ['VTI', 'VXUS', 'VNQ', 'BND', 'GLD', 'EFA', 'TLT', 'IEF', 'QQQ']
for ticker in self.basket:
self.AddEquity(ticker, Resolution.Minute)
self.Securities[ticker].FeeModel = ConstantFeeModel(0)
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.At(0, 0), Action(self.ScheduleEndOfMonthRebalance))
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.BeforeMarketClose('SPY', 5), Action(self.Rebalance))
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose('SPY', 0), self.record_vars)
def record_vars(self):
hist = self.History(self.MKT, 2, Resolution.Daily)['close'].unstack(level= 0).dropna()
self.spy.append(hist[self.MKT].iloc[-1])
spy_perf = self.spy[-1] / self.spy[0] * self.InitCash
self.Plot('Strategy Equity', 'SPY', spy_perf)
def ScheduleEndOfMonthRebalance(self):
month_last_day = DateTime(self.Time.year, self.Time.month, DateTime.DaysInMonth(self.Time.year, self.Time.month))
trading_days = self.TradingCalendar.GetDaysByType(TradingDayType.BusinessDay, self.Time, month_last_day)
#get the last day in trading_days
for x in trading_days:
self.month_last_trading_day = x.Date.date()
def Rebalance(self):
if self.Time.date() == self.month_last_trading_day:
dataframe = self.History(self.basket, 180, Resolution.Daily)
df = dataframe['close'].unstack(level=0)
self.Liquidate()
self.Debug(self.Portfolio.Cash)
self.adaptive_asset_allocation(df, 4, 20, 180, self.Portfolio.Cash, 1)
def adaptive_asset_allocation(self, df, nlargest, volatility_window, return_window, portfolio_value, leverage):
window_returns = np.log(df.iloc[-1]) - np.log(df.iloc[0])
nlargest = list(window_returns.nlargest(nlargest).index)
returns = df[nlargest].pct_change()
returns_cov_normalized = returns[-volatility_window:].apply(lambda x: np.log(1+x)).cov()
returns_corr_normalized = returns[-volatility_window:].apply(lambda x: np.log(1+x)).corr()
returns_std = returns.apply(lambda x: np.log(1+x)).std()
port_returns = []
port_volatility = []
port_weights = []
num_assets = len(returns.columns)
num_portfolios = 100
individual_rets = window_returns[nlargest]
for port in range(num_portfolios):
weights = np.random.random(num_assets)
weights = weights/np.sum(weights)
port_weights.append(weights)
rets = np.dot(weights, individual_rets)
port_returns.append(rets)
var = returns_cov_normalized.mul(weights, axis=0).mul(weights, axis=1).sum().sum()
sd = np.sqrt(var)
ann_sd = sd * np.sqrt(256)
port_volatility.append(ann_sd)
data = {'Returns': port_returns, 'Volatility': port_volatility}
hover_data = []
for counter, symbol in enumerate(nlargest):
data[symbol] = [w[counter] for w in port_weights]
hover_data.append(symbol)
portfolios_V1 = pd.DataFrame(data)
min_var_portfolio = portfolios_V1.iloc[portfolios_V1['Volatility'].idxmin()]
max_sharpe_portfolio = portfolios_V1.iloc[(portfolios_V1['Returns'] / portfolios_V1['Volatility']).idxmax()]
proportions = min_var_portfolio[nlargest]
index = 0
for proportion in proportions:
self.SetHoldings(nlargest[index], proportion * leverage)
self.Debug('{}% of portfolio in {}'.format(proportion * leverage, nlargest[index]))
index += 1