| Overall Statistics |
|
Total Trades 228 Average Win 0.37% Average Loss 0% Compounding Annual Return 8.116% Drawdown 7.100% Expectancy 0 Net Profit 117.947% Sharpe Ratio 1.435 Probabilistic Sharpe Ratio 90.764% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.07 Beta -0.026 Annual Standard Deviation 0.047 Annual Variance 0.002 Information Ratio -0.277 Tracking Error 0.167 Treynor Ratio -2.593 Total Fees $232.93 |
class EqualWeightingPortfolioConstructionModelLoke(PortfolioConstructionModel):
'''Provides an implementation of IPortfolioConstructionModel that gives equal weighting to all securities.
The target percent holdings of each security is 1/N where N is the number of securities.
For insights of direction InsightDirection.Up, long targets are returned and
for insights of direction InsightDirection.Down, short targets are returned.'''
def __init__(self, rebalancingParam = Resolution.Daily, portfolioBias = PortfolioBias.LongShort):
'''Initialize a new instance of EqualWeightingPortfolioConstructionModel
Args:
rebalancingParam: Rebalancing parameter. If it is a timedelta, date rules or Resolution, it will be converted into a function.
If None will be ignored.
The function returns the next expected rebalance time for a given algorithm UTC DateTime.
The function returns null if unknown, in which case the function will be called again in the
next loop. Returning current time will trigger rebalance.
portfolioBias: Specifies the bias of the portfolio (Short, Long/Short, Long)'''
self.portfolioBias = portfolioBias
#self.QQQ_100 = QQQ_100
# If the argument is an instance of Resolution or Timedelta
# Redefine rebalancingFunc
rebalancingFunc = rebalancingParam
if isinstance(rebalancingParam, int):
rebalancingParam = Extensions.ToTimeSpan(rebalancingParam)
if isinstance(rebalancingParam, timedelta):
rebalancingFunc = lambda dt: dt + rebalancingParam
if rebalancingFunc:
self.SetRebalancingFunc(rebalancingFunc)
def DetermineTargetPercent(self, activeInsights):
'''Will determine the target percent for each insight
Args:
activeInsights: The active insights to generate a target for'''
result = {}
# give equal weighting to each security
count = sum(x.Direction != InsightDirection.Flat and self.RespectPortfolioBias(x) for x in activeInsights)
#loke percent = 0 if count == 0 else 1.0 / count
percent = 0.5 #Loke hardcode percentag as 70% and 30% for 2 stocks
i = 0
activeInsights =activeInsights[:2] #Loke remove third stock
for insight in activeInsights:
result[insight] = (insight.Direction if self.RespectPortfolioBias(insight) else InsightDirection.Flat) * percent
if (i==0):
percent = 0.3 #LOke
else:
percent = 0.0 #LOke
i += 1
return result
def RespectPortfolioBias(self, insight):
'''Method that will determine if a given insight respects the portfolio bias
Args:
insight: The insight to create a target for
'''
return self.portfolioBias == PortfolioBias.LongShort or insight.Direction == self.portfolioBias
class GlobalTacticalAssetAllocationBase(QCAlgorithm):
QQQ_100 = 0
def Initialize(self):
self.SetStartDate(datetime.now() - timedelta(365*10))
self.SetEndDate(datetime.now() - timedelta(5))
self.SetCash(100000)
self.UniverseSettings.Resolution = Resolution.Daily
symbols = [ Symbol.Create("QQQ", SecurityType.Equity, Market.USA), #US Large Cap
Symbol.Create("IEF", SecurityType.Equity, Market.USA), #US Bond
#Symbol.Create("VXX", SecurityType.Equity, Market.USA), #US SP500
#Symbol.Create("VEA", SecurityType.Equity, Market.USA), #Developed Foreign Stocks (2007/8)
#Symbol.Create("IEF", SecurityType.Equity, Market.USA), #US 10Y Gov.Bonds
#Symbol.Create("DBC", SecurityType.Equity, Market.USA), #GSCI Commodities (2006/3)
#Symbol.Create("VNQ", SecurityType.Equity, Market.USA) #US RealEstate
]
self.AddUniverseSelection(ManualUniverseSelectionModel(symbols))#select stocks
#if enable third stock, the performance drop a lot even though set third stock to 0%
#vxx = self.AddEquity("VXX", Resolution.Daily)
#vxx.SetDataNormalizationMode(DataNormalizationMode.Raw)
#self.AddAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(days = 20*365), None, None))#generate signal to buy/sell
self.AddAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(days = 30), None, None))#generate signal to buy/sell
self.Settings.RebalancePortfolioOnInsightChanges = False#True
self.Settings.RebalancePortfolioOnSecurityChanges = False#True
#self.SetPortfolioConstruction( EqualWeightingPortfolioConstructionModel(self.DateRules.MonthStart()) )#Loke .MonthStart()) )
#self.SetPortfolioConstruction( EqualWeightingPortfolioConstructionModelLoke(self.DateRules.MonthStart()) )#Loke .MonthStart()) )
self.SetPortfolioConstruction( EqualWeightingPortfolioConstructionModelLoke( self.DateRules.MonthStart()) )#Loke .MonthStart()) )
# Use the Alpha Streams Brokerage Model
self.SetBrokerageModel(AlphaStreamsBrokerageModel())
#self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
self.SetExecution( ImmediateExecutionModel() ) #execute immediate market order in brokerage
self.AddRiskManagement( NullRiskManagementModel() )
# 1) Setting a Benchmark to plot with equity
self.benchmarkTicker = 'SPY'
self.SetBenchmark(self.benchmarkTicker)
self.initBenchmarkPrice = None
def UpdateBenchmarkValue(self):
''' Simulate buy and hold the Benchmark '''
if self.initBenchmarkPrice is None:
self.initBenchmarkCash = self.Portfolio.Cash
self.initBenchmarkPrice = self.Benchmark.Evaluate(self.Time)
self.benchmarkValue = self.initBenchmarkCash
else:
currentBenchmarkPrice = self.Benchmark.Evaluate(self.Time)
self.benchmarkValue = (currentBenchmarkPrice / self.initBenchmarkPrice) * self.initBenchmarkCash
def OnData(self, data):
# 2) simulate buy and hold the benchmark and plot its daily value as we are using daily data.
# Otherwise schedule when to call this function!
#self.UpdateBenchmarkValue()
#self.Plot('Strategy Equity', self.benchmarkTicker, self.benchmarkValue)
"""
if (self.Securities["VXX"].Close > 50):
self.QQQ_100 = 1
self.Debug("High VXX executed on " + str(self.Time) + str(self.Securities["VXX"].Close))
if (self.Securities["VXX"].Close < 30):
self.QQQ_100 = 0
"""