Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profit target and stop loss #8

Open
degiere opened this issue Apr 15, 2014 · 4 comments
Open

Profit target and stop loss #8

degiere opened this issue Apr 15, 2014 · 4 comments

Comments

@degiere
Copy link
Contributor

degiere commented Apr 15, 2014

Any suggestions for implementing stop loss and profit target exits? I would be willing to write and contribute any changes to the code with some input.

@ematvey
Copy link
Owner

ematvey commented Apr 16, 2014

You could do something like sell = ohlc.L < sl; sell_price = sl, pandas' vectorized operations will take care of the rest. Similarly for take profits. I don't think this kind of code should be in the library.

@degiere
Copy link
Contributor Author

degiere commented Apr 18, 2014

Ok, I think I see how you could avoid any changes to the library and keep this in just the signals.

For example, here's a variation of the moving average example that closes open trades after 20 days if there's no reversal. So different exits could be appended to sell and cover like this:

days = 20
buy = (ms > ml) & (ms.shift() < ml.shift())
short = (ms < ml) & (ms.shift() > ml.shift())
sell = buy.shift(days) | short
cover = short.shift(days) | buy

A stop loss and profit target would need to reference the entry price back where the entry signal was True to compare to the current low. I'm not seeing how to do a vectorized version of this though.

Any pointers?

@degiere
Copy link
Contributor Author

degiere commented May 13, 2014

Here's a potential solution. For trading platforms that support an intrabar stop or profit target though there didn't seem to be a way to handle intrabar exits other than shifting the exit signal to the previous bar. This seems like a bit of a hack but appears to work correctly. Better ideas?

def stop(entry, price, exit_price, amount, ohlc, direction='long'):
    """ Stop loss with fill intrabar at stop price """
    df = entry.shift() * price
    df[df == 0] = None
    return df.ffill()
    dfp = None
    if direction is 'long':
        dfp = df - amount
        df = ohlc.L < dfp
    if direction is 'short':
        dfp = df + amount
        df = ohlc.H > dfp
    df = df.shift(-1)
    df = df.ffill()
    exit_price[df] = dfp[df]
    return df, exit_price

# default entry price to open of next bar
buyprice = sellprice = shortprice = coverprice = ohlc.O

buy = (ms > ml) & (ms.shift() < ml.shift())
short = (ms < ml) & (ms.shift() > ml.shift())

# where stop hit, override exit price to stop loss
sstop, sellprice = stop(buy, buyprice, sellprice, stp_amt, ohlc, direction='long')
sell = sstop | short.copy()
cstop, coverprice = stop(short, shortprice, coverprice, stp_amt, ohlc, direction='short')
cover = cstop | buy.copy()

If this is the right direction, this issue can be closed. I may just spin off a separate strategy component repository to keep building blocks like this.

@trbck
Copy link

trbck commented Jul 24, 2014

@degiere great stop function!

I got it working with little modifications and it looks fine to me but I am not sure:

def stop(entry, price, exit_price, amount, ohlc, direction='long'):
    """ Stop loss with fill intrabar at stop price """
    df = entry.shift() * price
    df[df == 0] = None
    #original function gave a return of df.ffill()
    df =  df.ffill()
    #fix float32 - float64 error here
    df = df.astype("float32")
    dfp = None
    if direction is 'long':
        dfp = df - amount
        df = ohlc.low < dfp
    if direction is 'short':
        dfp = df + amount
        df = ohlc.high > dfp
    df = df.shift(-1)
    df = df.ffill()
    exit_price[df] = dfp[df]
    return df, exit_price

# default entry price to open of next bar
buyprice = sellprice = shortprice = coverprice = df.close
buy = EMA(df, short=10, long=50)["buy"] #talib EMA signal crossover function
stp_amt = 400. #for ^GDAXI symbol


# where stop hit, override exit price to stop loss
sstop, sellprice = stop(buy, buyprice, sellprice, stp_amt, df, direction='long')
sell = sstop

I think it would also be a good idea to put a percentage value as stop amount (stp_amt) don't you think?

@schiorean schiorean mentioned this issue Nov 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants