| Overall Statistics |
|
Total Trades 4924 Average Win 0.08% Average Loss -0.02% Compounding Annual Return 11.174% Drawdown 55.300% Expectancy 3.711 Net Profit 497.385% Sharpe Ratio 0.629 Probabilistic Sharpe Ratio 4.734% Loss Rate 8% Win Rate 92% Profit-Loss Ratio 4.11 Alpha 0.108 Beta -0.087 Annual Standard Deviation 0.159 Annual Variance 0.025 Information Ratio 0.02 Tracking Error 0.235 Treynor Ratio -1.143 Total Fees $45121.26 |
class VerticalQuantumAtmosphericScrubbers(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2003, 3, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.dict = {}
self.AddEquity("SPY", Resolution.Minute)
#define our bb indicator for SPY
self.bb = self.BB("SPY", 20, 2, MovingAverageType.Simple, Resolution.Minute);
#tradelock keeps track of whether our entry conditions have been met
# if trade lock is true, entry conditions are not yet met, we cannot enter a trade
# if trade lock is false, entry conditions have been met and we can now enter a trade
# when available
self.loweBollingerFirstHit = False
self.lowerLow = 0.0
self.tradeBuyReady = False
self.upperBollingerFirstHit = False
self.tradeSellReady = False
self.buyPrice = 0
self.buyAndHold = False
self.buyPartial = False
self.partialPurchasePrice = False
def OnData(self, data):
#make sure our indicator is ready
if not self.bb.IsReady:
return
price = self.Securities["SPY"].Price
if self.buyAndHold is False:
#if the price is below 0% BB
if price < self.bb.LowerBand.Current.Value and self.Portfolio["SPY"].Invested is False and self.bb.LowerBand.Current.Value < self.lowerLow:
#if we are already in a long position, we liquidate and cut our losses
#if self.Portfolio["SPY"].Invested:
#self.Liquidate()
#we set trade lock to false, allowing us to enter a trade next time price crosses above 0% BB
self.lowerLow = self.bb.LowerBand.Current.Value
self.SetHoldings("SPY", .3)
self.partialPurchasePrice = price
self.buyPartial = True
if price > self.bb.LowerBand.Current.Value and self.Portfolio["SPY"].Invested is False and self.tradeBuyReady is False:
self.tradeBuyReady = True
if price>self.partialPurchasePrice:
self.Liquidate()
self.buyPartial = False
#if the price is above 0% BB and also trade lock is false
if price <= self.bb.LowerBand.Current.Value and self.tradeBuyReady is True and self.bb.LowerBand.Current.Value > self.lowerLow and self.Portfolio["SPY"].Invested is False:
#we enter a long position
self.SetHoldings("SPY", 1)
self.buyPrice = price
self.watchOut = False
self.tradeBuyReady = False
self.lowerLow = 0
if price > 0 and price<self.buyPrice and (self.buyPrice - price)/self.buyPrice > 3 and self.Portfolio["SPY"].Invested :
self.Liquidate()
if price >= self.bb.UpperBand.Current.Value and self.Portfolio["SPY"].Invested and self.upperBollingerFirstHit is False and price > self.buyPrice:
#if the price crosses the upperband and we have a long position
#we liquidate for profit
self.upperBollingerFirstHit = True
self.Liquidate()
if price < self.bb.UpperBand.Current.Value and self.upperBollingerFirstHit is True and self.tradeSellReady is False and price > self.buyPrice and self.Portfolio["SPY"].Invested:
self.tradeSellReady = True
if price >= self.bb.UpperBand.Current.Value and self.tradeSellReady is True and price > self.buyPrice and self.Portfolio["SPY"].Invested:
self.Liquidate()
self.tradeSellReady = False
self.upperBollingerFirstHit = False
else:
self.SetHoldings("SPY", 1)