| Overall Statistics |
|
Total Trades 992 Average Win 0.24% Average Loss -0.22% Compounding Annual Return 4.069% Drawdown 5.200% Expectancy 0.259 Net Profit 32.501% Sharpe Ratio 0.718 Probabilistic Sharpe Ratio 16.575% Loss Rate 39% Win Rate 61% Profit-Loss Ratio 1.06 Alpha 0.03 Beta -0.011 Annual Standard Deviation 0.04 Annual Variance 0.002 Information Ratio -0.503 Tracking Error 0.154 Treynor Ratio -2.518 Total Fees $43217.89 Estimated Strategy Capacity $1300000.00 Lowest Capacity Asset TMF UBTUG7D0B7TX |
import numpy as np
RESOLUTION = Resolution.Minute
LEVERAGE = 1.90
class BondThursdays(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 1, 1)
self.SetCash(1000000)
self.bnds = [
self.AddEquity("IEF", RESOLUTION).Symbol,
self.AddEquity("TIP", RESOLUTION).Symbol,
self.AddEquity("TMF", RESOLUTION).Symbol,
self.AddEquity("AGG", RESOLUTION).Symbol
]
self.mkt = self.AddEquity("SPY", RESOLUTION).Symbol
self.lookback = 60 #int(self.GetParameter("LOOKBACK"))
self.max_vol = 0.0075 #float(self.GetParameter("MAX_VOL"))
self.prices = RollingWindow[float](2)
self.daily_returns = RollingWindow[float](self.lookback)
self.ema = ExponentialMovingAverage(5)
self.std = 0
self.Warmup(self.mkt, self.lookback * 2)
self.Schedule.On(self.DateRules.EveryDay(self.mkt), self.TimeRules.AfterMarketOpen(self.mkt, 30), self.Update)
self.Schedule.On(self.DateRules.Every(DayOfWeek.Thursday), self.TimeRules.AfterMarketOpen(self.mkt, 10), self.Buy)
self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.AfterMarketOpen(self.mkt, 10), self.Sell)
def Warmup(self, symbol, lookback):
self.prices.Add(2.4) # random number
history = self.History(symbol, lookback, Resolution.Daily)
for time, prices in history.loc[symbol].iterrows():
self.ema.Update(self.Time, prices["close"])
self.prices.Add(prices["close"])
self.daily_returns.Add((self.prices[1] - prices["close"])/self.prices[1])
self.std = np.std(list(self.daily_returns))
def Update(self):
close = self.Securities[self.mkt].Close
self.ema.Update(self.Time, close)
self.prices.Add(close)
self.daily_returns.Add((self.prices[1] - close)/self.prices[1])
self.std = np.std(list(self.daily_returns))
def Buy(self):
buy = (self.std < self.max_vol) and (self.prices[0] > self.ema.Current.Value)
if not self.Portfolio.Invested and buy:
for bnd in self.bnds:
self.SetHoldings(bnd, LEVERAGE/(len(self.bnds) + 1))
def Sell(self):
if self.Portfolio.Invested:
self.Liquidate()