Back

Setting a stop loss and take profit

Hi, I've been looking through the help section and have not found much that relates to setting SL/TP levels in market execution orders. I've tried to come up with solutions to this problem and heres what I have brainstormed so far http://imgur.com/a/FpsJl I know right now that the SL/TP is based off the close, how can I base it off of the price of an executed order?

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.


Hi Christian,

I've attached a backtest in which I've taken your code and made the necessary modifications to make some basic orders. Generally speaking, the Python equivalent of a C# private variable is one that is defined using the self. prefix, which initializes it globally, such as
 

class Algorithm(QCAlgorithm):

def Initialize(self):
# .... Cash, start date, add securities, etc
self.globalVariable = 'This is a global variable whose value is this string'

def OnData(self, data):
localVariable = 'This is a local variable confined to the OnData() method'
self.anotherGlobalVariable = 'This is another global variable, initialized using self.'

self.Log(self.globalVariable)
self.Log(localVariable)
self.Log(self.anotherGlobalVariable)

self.TestFunction()

def TestFunction(self):
self.Log(self.globalVariable)
self.Log(localVariable) #### This will fail
self.Log(self.anotherGlobalVariable)

 

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.


Thanks a lot! 

 

That cleard up quite a bit, however when I am running a backtest, it seams to fill all orders at once, and it does not seam to reackt at SL ot TP? resaulting in a buy and hold.

import pandas
import numpy as np
### <summary>
### Simple RSI Strategy intended to provide a minimal algorithm example using
### one indicator
### </summary>
class RSIAlgorithm(QCAlgorithm):


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.'''


# Set our main strategy parameters
self.SetStartDate(2013,1, 1) # Set Start Date
self.SetEndDate(2014,1,1) # Set End Date
self.SetCash(10000) # Set Strategy Cash

RSI_Period = 14 # RSI Look back period
self.RSI_OB = 60 # RSI Overbought level
self.RSI_OS = 40 # RSI Oversold level
self.Allocate = 2 # Percentage of captital to allocate
self.tolerance = 0.00015
self.spread = 20/10000
self.first_stg_up = 0
self.first_stg_down = 0
self.trend = 0
self.trend_n = 0

self.symbol = "EURUSD"

## Rename variables for percentages to make more readable and less confusing
self.tpPercent = 20/10000
self.slPercent = 10/10000


## Reassign these to be variables for Order Tickets
self.tp = None
self.sl = None
self.holdings = 0
self.quant = 10000


# Find more symbols here: http://quantconnect.com/data
self.AddForex("EURUSD", Resolution.Minute)

self.RSI_Ind = self.RSI("EURUSD", RSI_Period)
self.bb_ind = self.BB("EURUSD", 20, 1, MovingAverageType.Simple);
self.slow = self.SMA("EURUSD", 20, Resolution.Hour)
self.fast = self.SMA("EURUSD", 7, Resolution.Hour)



# Ensure that the Indicator has enough data before trading,.
self.SetWarmUp(20)





def OnData(self, data):

trend_sma = np.where(self.fast.Current.Value > self.slow.Current.Value,1,0)
spread = self.bb_ind.UpperBand.Current.Value - self.bb_ind.LowerBand.Current.Value
spread_bin = np.where(spread > self.spread,1,0)
# Check if we are in the market
fxOpen = data[self.symbol].Open
fxClose = data[self.symbol].Close
price = data[self.symbol].Price
if trend_sma == 1 and fxClose > fxOpen and fxClose >= self.bb_ind.UpperBand.Current.Value:
self.trend = 1



if trend_sma == 0 and fxClose < fxOpen and fxClose <= self.bb_ind.LowerBand.Current.Value :
self.trend = -1



if spread_bin == 0:
self.first_stg_up = 0
self.first_stg_down = 0
self.trend = 0
self.trend_n = 0


if not self.Portfolio.Invested and not self.IsWarmingUp:
# If not, we check the RSI Indicator
if self.trend == 1 :
#
## you need to assign to self.order or else variable will remain local
self.order = self.MarketOrder(self.symbol, self.quant)

## you need to define fxClose or else the orders won't be properly placed
fxClose = data[self.symbol].Close

## you need to replace sl with self.sl, as you want these to be global variables
## otherwise, they will not be accessible outside of OnData
self.sl = self.StopMarketOrder(self.symbol, -self.quant, fxClose - self.slPercent)
self.tp = self.LimitOrder(self.symbol, -self.quant, fxClose + self.tpPercent)



if self.trend == -1 :
self.order = self.MarketOrder(self.symbol, -self.quant)

## you need to define fxClose or else the orders won't be properly placed
fxClose = data[self.symbol].Close

## you need to replace sl with self.sl, as you want these to be global variables
## otherwise, they will not be accessible outside of OnData
self.sl = self.StopMarketOrder(self.symbol, self.quant, fxClose - self.tpPercent)
self.tp = self.LimitOrder(self.symbol, self.quant, fxClose + self.slPercent)




def OnOrderEvent(self, orderEvent):

## This will check for the boolean value of whether or not the order has been filled
if not (orderEvent.Status == 'Filled'):
return

## python doesn't support null. Instead, check for None
if (self.tp is None) or (self.sl is None):
return


filledOrderid = orderEvent.OrderId

if self.tp == filledOrderId:
self.sl.Cancel()

if self.sl == filledOrderId:
self.tp.Cancel()

 

0

Hi Christian,

Here are a few places that could go wrong:

1. in line 112-113, you might want to reconsider the use of stop order and limit order. Here is some information as reference.

2. since you defined some percentage (self.tpPercent and self.slPercent), does it make more sense to multiply by (1 +/- percentage) instead of directly add/substract them?

3. in line 129, filledOrderid => filledOrderId

4. in line 131 & 134, I believe you want to compare order ids. This would work as you expected:

if self.tp.OrderId == filledOrderId: 
...


And you could use self.Liquidate() to cancel any unfilled order.

Here is my attempt. Hope it helps!

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.


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