| Overall Statistics |
|
Total Trades 462 Average Win 0.46% Average Loss -0.30% Compounding Annual Return 26.220% Drawdown 5.900% Expectancy 0.131 Net Profit 7.999% Sharpe Ratio 1.687 Loss Rate 56% Win Rate 44% Profit-Loss Ratio 1.56 Alpha -0.061 Beta 15.31 Annual Standard Deviation 0.143 Annual Variance 0.02 Information Ratio 1.549 Tracking Error 0.143 Treynor Ratio 0.016 Total Fees $13738.56 |
import numpy as np
import pandas as pd
class MyAlgo(QCAlgorithm):
def __init__(self):
# Number of stocks to pass filtering process
self.num_filter = 2
def Initialize(self):
self.SetCash(1000000)
# Start and end dates for the backtest.
self.SetStartDate(2015,1,1)
self.SetEndDate(2015,5,1)
self.spy = self.AddEquity("SPY")
self.security_list = ["JPM", "BRK.B","BAC", "WFC", "C", "GS", "USB",
"MS", "PNC", "AXP", "BLK","SCHW", "CB", "BK","CME","AIG","MET","SPGI","COF"]
for i in range(len(self.security_list)):
self.AddEquity(self.security_list[i],Resolution.Minute)
# Schedule the rebalance function to execute at the begining of each month
self.Schedule.On(self.DateRules.EveryDay("SPY"),
self.TimeRules.AfterMarketOpen("SPY",30),
Action(self.rebalance))
def OnData(self, data):
pass
def rebalance(self):
# ---------------------------------------------------------------
# Stocks History ----------------------------------
# ---------------------------------------------------------------
history = self.History(self.security_list, 6, Resolution.Daily)
price_history = history['close'].unstack(level=0)
# ---------------------------------------------------------------
# Pct Change -------------------------------------------------
# ---------------------------------------------------------------
# Raw DF
d1 = price_history.values
d2 = price_history.columns
df1 = pd.DataFrame(d1, columns = d2)
df1 = df1.dropna()
pct_change_df1 = df1.pct_change(periods=5).iloc[-1]
# Sorting
rank_df1 = pct_change_df1.rank(ascending = False)
sort_df1 = rank_df1.sort_values(ascending = True)
sort_bottom_df1 = rank_df1.sort_values(ascending = False)
#self.Log('\n' + 'Sorted :' + '\n' + str(sort_df1) + '\n'+str(sort_bottom_df1)+'\n')
# lists
top_list = sort_df1[:self.num_filter].index.tolist()
bottom_list = sort_bottom_df1[:self.num_filter].index.tolist()
total_list = top_list + bottom_list
weight = 0.9/self.num_filter
# Mean-Reversion --------------------------------------------
for i in self.security_list:
if i not in total_list:
self.Liquidate(i)
if i in top_list:
self.SetHoldings(i, -weight)
if i in bottom_list:
self.SetHoldings(i, weight)
invested = [ x.Symbol.Value for x in self.Portfolio.Values if x.Invested ]
self.Log("invested: " + str(invested))