| Overall Statistics |
|
Total Trades 64 Average Win 44.75% Average Loss -10.81% Compounding Annual Return 28.596% Drawdown 84.900% Expectancy 2.558 Net Profit 7935.717% Sharpe Ratio 0.796 Probabilistic Sharpe Ratio 8.181% Loss Rate 31% Win Rate 69% Profit-Loss Ratio 4.14 Alpha 0.204 Beta 0.652 Annual Standard Deviation 0.32 Annual Variance 0.102 Information Ratio 0.577 Tracking Error 0.308 Treynor Ratio 0.391 Total Fees $354574.95 Estimated Strategy Capacity $140000.00 Lowest Capacity Asset DFAX R735QTJ8XC9X |
#region imports
from AlgorithmImports import *
#endregion
class NetCurrentAssetValue(QCAlgorithm):
def Initialize(self):
#rebalancing should occur in July
self.SetStartDate(2005,1,1) #Set Start Date
# self.SetEndDate(2018,7,15) #Set End Date
self.SetCash(1000000) #Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Daily
self.previous_fine = None
self.filtered_fine = None
self.AddUniverse(self.CoarseSelectionFunction,self.FineSelectionFunction)
self.AddEquity("SPY", Resolution.Daily)
#monthly scheduled event but will only rebalance once a year
self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.At(23, 0), self.rebalance)
self.months = -1
self.yearly_rebalance = False
def CoarseSelectionFunction(self, coarse):
if self.yearly_rebalance:
# drop stocks which have no fundamental data
self.filtered_coarse = [x.Symbol for x in coarse if (x.HasFundamentalData)]
# and (x.Market == "usa")]
return self.filtered_coarse
else:
return []
def FineSelectionFunction(self, fine):
if self.yearly_rebalance:
self.filtered_fine = [x for x in fine if (float(x.CompanyProfile.EnterpriseValue) < 0)]
sorted_filter = sorted(self.filtered_fine, key=lambda x: x.CompanyProfile.EnterpriseValue)
self.filtered_fine = [i.Symbol for i in sorted_filter]
ev = [x for x in fine if (float(x.CompanyProfile.EnterpriseValue) < 0)]
self.Debug(self.Time)
self.Debug(len(ev))
return self.filtered_fine
else:
return []
def rebalance(self):
#yearly rebalance
self.months+=1
if self.months%12 == 0:
self.yearly_rebalance = True
def OnData(self, data):
if not self.yearly_rebalance: return
if self.filtered_fine:
portfolio_size = int(len(self.filtered_fine)/10)
#pick the upper decile to short and the lower decile to long
long_stocks = self.filtered_fine[:portfolio_size]
stocks_invested = [x.Key for x in self.Portfolio]
for i in stocks_invested:
#liquidate the stocks not in the filtered balance sheet accrual list
if i not in self.filtered_fine:
self.Liquidate(i)
#long the stocks in the list
elif i in long_stocks:
self.SetHoldings(i, 1/(portfolio_size))
#short the stocks in the list
self.yearly_rebalance = False
self.filtered_fine = False