5

My strategy() is fully working but now I'm trying to manage how money is put in the trade.

HERE'S MY CURRENT SITUATION :
I have a SL set at the lowest low of the last 10 bars and a TP set at 1.5xSL.
My strategy.exit :

strategy.exit("EXIT LONG","LONG", stop=longSL, limit=longTP)

Until here, everything is working fine.

THE PROBLEM :
Even though I use :

strategy("TEST MACD DEFAULT", shorttitle="MACD", overlay=true, initial_capital=1000, default_qty_type=strategy.equity, default_qty_value=1, currency=currency.EUR, process_orders_on_close=true, pyramiding=0)

The money is not put in the trade the way I want.

WHAT I WANT :
I have a capital of 1000€.
I want my SL (which is already set at the lowest low of the last 10 bars) to be 1% of my capital = 10€.
My TP being 1.5xSL, so it would be 15€.
Meaning that for each trade I lose, I lose 10€ and for each trade I win, I win 15€.
But this is not what I have : enter image description here

QUESTION :
How can I achieve this ?

HERE'S MY CODE (only for long positions) :

//@version=4
strategy("TEST MACD DEFAULT", shorttitle="MACD", overlay=true, initial_capital=1000, default_qty_type=strategy.cash, default_qty_value=10, currency=currency.EUR, process_orders_on_close=true, pyramiding=0)

// MACD
[macdLine, signalLine, _] = macd(close, 12, 26, 9)

// EMA 200
ema = ema(close, 200)
plot(ema, title="EMA 200", color=color.yellow, linewidth=2)

// LONG CONDITIONS
longCheckCondition = barssince(crossover(macdLine, signalLine))
longCondition1 = longCheckCondition <= 3 ? true : false
longCondition2 = macdLine < 0 and signalLine < 0
longCondition3 = close > ema
longCondition = longCondition1 and longCondition2 and longCondition3 and strategy.opentrades == 0

// STOP LOSS
float longSL = na
longSL := longCondition ? lowest(low, 11)[1] : longSL[1]

// TAKE PROFIT
longEntryPrice = close
longDiffSL = abs(longEntryPrice - longSL)
float longTP = na
longTP := longCondition ? close + (1.5 * longDiffSL) : longTP[1]

// ENTRY/EXIT
if longCondition
  strategy.entry("LONG", strategy.long)
  strategy.exit("EXIT LONG","LONG", stop=longSL, limit=longTP)

// PLOT STOP LOSS
longPlotSL = strategy.opentrades > 0 and strategy.position_size > 0 ? longSL : na
plot(longPlotSL, title='LONG STOP LOSS', linewidth=2, style=plot.style_linebr, color=color.red)

// PLOT TAKE PROFIT
longPlotTP = strategy.opentrades > 0 and strategy.position_size > 0 ? longTP : na
plot(longPlotTP, title='LONG TAKE PROFIT', linewidth=2, style=plot.style_linebr, color=color.green)
PepeW
  • 477
  • 1
  • 8
  • 24

1 Answers1

9

If you really want to use your starting capital throughout your script to size your stops, you will need to save its value on the first bar using:

var initialCapital = strategy.equity

If instead you want to use your current equity, then use strategy.equity.

Here we use the first option. The trick is to size the position using the stop's value so that the stop represents the target % of capital that you are willing to risk, and then specify that size in the strategy.entry() call using the qty= parameter.

You can change the key values through your script's Inputs:

//@version=4
strategy("TEST MACD DEFAULT", shorttitle="MACD", overlay=true, precision = 4, initial_capital=1000, default_qty_type=strategy.cash, default_qty_value=10, currency=currency.EUR, process_orders_on_close=true, pyramiding=0)
i_pctStop = input(1., "% of Risk to Starting Equity Use to Size Positions") / 100
i_tpFactor = input(1.5, "Factor of stop determining target profit")

// Save the strat's equity on the first bar, which is equal to initial capital.
var initialCapital = strategy.equity

// MACD
[macdLine, signalLine, _] = macd(close, 12, 26, 9)

// EMA 200
ema = ema(close, 200)
plot(ema, title="EMA 200", color=color.yellow, linewidth=2)

// LONG CONDITIONS
longCheckCondition = barssince(crossover(macdLine, signalLine))
longCondition1 = longCheckCondition <= 3 ? true : false
longCondition2 = macdLine < 0 and signalLine < 0
longCondition3 = close > ema
longCondition = longCondition1 and longCondition2 and longCondition3 and strategy.opentrades == 0

// STOP LOSS
float longSL = na
longSL := longCondition ? lowest(low, 11)[1] : longSL[1]

// TAKE PROFIT
longEntryPrice = close
longDiffSL = abs(longEntryPrice - longSL)
float longTP = na
longTP := longCondition ? close + (i_tpFactor * longDiffSL) : longTP[1]

positionValue = initialCapital * i_pctStop / (longDiffSL / longEntryPrice)
positionSize = positionValue / longEntryPrice

// ENTRY/EXIT
if longCondition
    strategy.entry("LONG", strategy.long, qty=positionSize)
    strategy.exit("EXIT LONG","LONG", stop=longSL, limit=longTP)

// PLOT STOP LOSS
longPlotSL = strategy.opentrades > 0 and strategy.position_size > 0 ? longSL : na
plot(longPlotSL, title='LONG STOP LOSS', linewidth=2, style=plot.style_linebr, color=color.red)

// PLOT TAKE PROFIT
longPlotTP = strategy.opentrades > 0 and strategy.position_size > 0 ? longTP : na
plot(longPlotTP, title='LONG TAKE PROFIT', linewidth=2, style=plot.style_linebr, color=color.green)

enter image description here

Great way to manage your risk. Congrats.


[2020.09.05 EDIT]

I overlooked strategy.initial_capital when writing this solution.

var initialCapital = strategy.initial_capital

can be used instead of:

var initialCapital = strategy.equity
PineCoders-LucF
  • 8,288
  • 2
  • 12
  • 21
  • Perfect you nailed it ! Thank you very much ! I still have 2 questions (that may be linked to each other) : 1. When you calculate positionSize, are you converting pip value into contracts ? (if yes, where did you find the formula) 2. Why it's not exactly 10€ a loss and 15€ a win ? @PineCoders-LucF – PepeW Jul 21 '20 at 14:26
  • The formula is an industry standard. Nothing original ) If you use leverage, your formula will require adaptation. The absolute value of the loss/target numbers can vary with commission and slippage, or if your orders aren't executed on the close but on the next open and there is a gap. – PineCoders-LucF Jul 21 '20 at 18:48
  • Oh ok I see ! After some research I find out that I can use directly : `positionSize = (initialCapital * i_pctStop) / longDiffSL`. Why did you do an extra step with _positionValue_ ? – PepeW Jul 21 '20 at 22:36
  • Hey ! So I'm using `positionSize = (initialCapital * i_pctStop) / longDiffSL` but it's only working with `currency=currency.NONE`. If I use `currency=currency.EUR`, I need to convert my `initialCapital` to the 2nd currency. But to do this I need the cross rate between EUR and the second currency. It's easy to get when working on EURXXX pairs but not on the rest (for example CADJPY). So do you know a way to get the cross rate of EUR for each second currency or another way to solve this problem ? @PineCoders-LucF – PepeW Jul 24 '20 at 09:58