| Overall Statistics |
|
Total Trades 119 Average Win 0.09% Average Loss -0.09% Compounding Annual Return 1.452% Drawdown 0.500% Expectancy 0.134 Net Profit 0.724% Sharpe Ratio 1.166 Probabilistic Sharpe Ratio 55.009% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 0.97 Alpha 0.01 Beta 0.006 Annual Standard Deviation 0.009 Annual Variance 0 Information Ratio -1.498 Tracking Error 0.094 Treynor Ratio 1.844 Total Fees $220.15 |
from QuantConnect.Indicators import MovingAverageConvergenceDivergence
class BootCampTask(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2013, 12, 20)
self.SetEndDate(2014, 6, 21)
self.SetCash(1000000)
self.spy = self.AddFuture(Futures.Indices.SP500EMini)
self.spy.SetFilter(5, 120)
self.oi_contract = None
self.macd = None
self.takeProfit = None
self.stopLoss = None
def OnData(self, slice):
for chain in slice.FutureChains:
contracts = [contract for contract in chain.Value]
if len(contracts) == 0:
self.oi_contract = None
self.macd = None
break
contract = sorted(contracts, key=lambda k : k.OpenInterest, reverse=True)[0]
if self.oi_contract is not None and contract.Symbol == self.oi_contract.Symbol:
break
self.oi_contract = contract
self.macd = self.MACD(contract.Symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Minute)
if self.macd is None or not self.macd.IsReady:
return
symbol = self.oi_contract.Symbol
security = self.Securities[symbol]
price = security.Price
# Only new positions not invested
if security.Invested:
# Look to exit position
return
tolerance = 0.003
signalDeltaPercent = self.macd.Current.Value - self.macd.Signal.Current.Value
if signalDeltaPercent < -tolerance:
#Go long
self.MarketOrder(symbol, 1)
self.takeProfit = self.LimitOrder(symbol, -1, price*1.01)
self.stopLoss = self.StopMarketOrder(symbol, -1, price*0.99)
if signalDeltaPercent > tolerance:
#Go short
self.MarketOrder(symbol, -1)
self.takeProfit = self.LimitOrder(symbol, 1, price*0.99)
self.stopLoss = self.StopMarketOrder(symbol, 1, price*1.01)
def OnOrderEvent(self, orderEvent):
if orderEvent.Status != OrderStatus.Filled:
return
self.Cancel(orderEvent.OrderId)
def Cancel(self, id):
'''cancel one order if the other was filled'''
if self.takeProfit is not None and id == self.takeProfit.OrderId:
self.stopLoss.Cancel()
elif self.stopLoss is not None and id == self.stopLoss.OrderId:
self.takeProfit.Cancel()
else:
return
self.takeProfit = None
self.stopLoss = None