Back

Moving Average cross in python with stop loss

hello,

I used the example of Moving Average Cross in Python (by Quantconnect) https://www.quantconnect.com/forum/discussion/1013/moving-average-cross-in-python/p1

class MovingAverageCrossAlgorithm(QCAlgorithm):
'''In this example we look at the canonical 15/30 day moving average cross. This algorithm
will go long when the 15 crosses above the 30 and will liquidate when the 15 crosses
back below the 30.'''

def __init__(self):
self.symbol = "SPY"
self.previous = None
self.fast = None
self.slow = None
self.stopMarketTicket = None
self.quantity = -1

def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

self.SetStartDate(2019, 1, 1) #Set Start Date
self.SetEndDate(2020, 1, 1) #Set End Date
self.SetCash(1000) #Set Strategy Cash
# Find more symbols here: http://quantconnect.com/data
self.AddSecurity(SecurityType.Equity, self.symbol, Resolution.Hour)

# create a 15 day exponential moving average
self.fast = self.EMA(self.symbol, 15, Resolution.Hour);

# create a 30 day exponential moving average
self.slow = self.EMA(self.symbol, 30, Resolution.Hour);


def OnData(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.

Arguments:
data: TradeBars IDictionary object with your stock data
'''
# a couple things to notice in this method:
# 1. We never need to 'update' our indicators with the data, the engine takes care of this for us
# 2. We can use indicators directly in math expressions
# 3. We can easily plot many indicators at the same time

# wait for our slow ema to fully initialize
if not self.slow.IsReady:
return

holdings = self.Portfolio[self.symbol].Quantity
self.Log("Holdings: {0}".format(self.Portfolio[self.symbol].Quantity))

# we only want to go long if we're currently short or flat
if holdings <= 0 and self.quantity==-1:
# if the fast is greater than the slow, we'll go long
if self.fast.Current.Value > self.slow.Current.Value:
self.Log("BUY >> {0}".format(self.Securities[self.symbol].Price))
self.stopMarketTicket = self.StopLimitOrder(self.symbol, self.CalculateOrderQuantity(self.symbol, 1.0), 0.95*self.slow.Current.Value, self.slow.Current.Value)
self.quantity = 0
# self.SetHoldings(self.symbol, 0.67)

# we only want to liquidate if we're currently long
# if the fast is less than the slow we'll liquidate our long
if holdings > 0 and self.fast.Current.Value < self.slow.Current.Value:
self.Log("SELL >> {0}".format(self.Securities[self.symbol].Price))
self.Liquidate(self.symbol)
self.quantity = -1


def OnOrderEvent(self, orderEvent):

if orderEvent.Status != OrderStatus.Filled:
return

#2. Check if we hit our stop loss (Compare the orderEvent.Id with the stopMarketTicket.OrderId)
# It's important to first check if the ticket isn't null (i.e. making sure it has been submitted)
if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId:
self.Log("Asset Price >> {0}".format(self.Portfolio[self.symbol].Price))

however, I wanted to have a stop limit order and hence, I updated the code accordingly. Now since, we are putting the order, quantconnect will issue a ticket which needs to be matched in another method `Onorderevent`. I am using `self.quantity` but for some reason my order never gets filled and `holdings` are always `0.0`.

Update Backtest







0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


So the issue is with `self.quantity`. I added this because my order was not getting filled as soon as the breakout happens. My target is to fill the order as soon as the breakout happens. Further, I do not want an error of :

Insufficient buying power to complete order

Hence, I added the `self.quantity`. The thing that I do not understand is why it gives the above error at first place? If my order is not filled then I should have enough cash anyways. 

0

Hey Amulya,

The trade does not fill because the stop price is never triggered. The order submitted on 01-08-2019 has a stop price of 233.08 and limit price of 245.34. The price of SPY at that time was 248.30 and continued to climb throughout 2019, which means the stop price was never triggered. If you extend the end date until June 2020, you'll find that the order is filled in March 2020, when SPY fell below 233. Try using stop/limit prices that are closer to the price of the asset.

Best
Rahul

1

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Update Backtest





0

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.


Loading...

This discussion is closed