0

I need some help on a simple strategy code I have written. This is my 1st code on it. I have an issue with mon code written on PineScript.

PineScript doesnt calculate my SL, TP and quantity size properly and I cannot figure out why.

My strategy is : when there are 4 green candles in a row after 1 red candle, to enter a long position on the 5th candle (no matters if it is red or green).

the SL price = (the close price of the 4th green candle from the red candle + the open price of the 2nd green candle from the red candle)/2

Diff = Difference between entry price - SL price. This value in price will be used to calculate the TP price

the TP price = entry price + (2*Diff) The "2" means I have a risk reward of 2, I risk 1 to win 2.

Also I want to risk 1% on each trade of my account balance. For example if my account balance is 200 000$, I want to risk 2000$ So if the Diff (Difference between entry price - SL price) is 2$, I want to buy 1000 units of the share for ETH as 2000$/2$. Based on my risk reward, all my lossing trades should always be 1% of my account balance and all my winning trades should always be 2%. But when I look at the trades, the percentages dont follow anything.

But PineScript doesnt do it properly. It does detect the pattern that I want to trade and goes in in the 5th candle but the exit point doesnt work properly either the SL or TP and quantity.

I dont know if my instructions of the SL is wrong or whatever. Do you have any idea ?

This is my current code and see below some picture of the trades :

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/

//@version=5

strategy("4 Green Candle Strategy", overlay=true,shorttitle = "4GCS")

// 1. User Input //

i_rewardmulti = input.float(2.0, "Risk Reward", minval = 1.0, step = 0.5, group = "4 Green Candle Strategy Settings")
i_risk = input.float(1.0, "Percentage to risk per trade", minval = 0.1, step = 0.05, group = "4 Green Candle Strategy Settings")
ibtstarttime = input.time(title="Start Backtest", defval=timestamp("01 Jan 2022 00:00 +0000"), group="Backtest Period")
ibtendtime = input.time(title="End Backtest", defval=timestamp("01 Jan 2099"), group="Backtest Period")

// ---------------------------------------------------- Strategy Settings -----------------------------------------------//

// 2. Conditions of a valid setup //
ValidSetup = close[4] < open[4] and close[3] > close[4] and close[2] > close[3] and close[1] > close[2] and close > close[1] and barstate.isconfirmed

// 3. Confirmation of a valid setup //
ValidLong = ValidSetup and strategy.position_size==0 and barstate.isconfirmed

// 4. Calculation of TP, SL, balance risked and position size risked //

EntryPrice = close
long_SLprice = (close + open[2])*0.5
long_diff_EntryPrice_and_StopLossExitPrice = close - long_SLprice
long_TPprice = EntryPrice + (i_rewardmulti * long_diff_EntryPrice_and_StopLossExitPrice)
balance = (strategy.initial_capital + strategy.netprofit)
balance_limited = (balance > 0 ? balance : 0)
balance_risked = (i_risk/100) * balance
position_size_risked = (balance_risked/long_diff_EntryPrice_and_StopLossExitPrice)

// 5. Save of SL, TP and position size if a valid setup is detected //
var trade_entry = 0.0
var trade_SL = 0.0
var trade_TP = 0.0
var trade_direction = 0

// 6. Detection of a valid long and trigger alerts //
trade_entry := EntryPrice
trade_SL := long_SLprice
trade_TP := long_TPprice
trade_direction := 1

// 7. Enter a trade whenever a valid setup is detected //
if ValidLong
    strategy.entry("Long", strategy.long, qty=position_size_risked)

// 8. Exit a trade whenever a TP or SL is hit //
if strategy.position_size > 0
    strategy.exit("Long Exit", from_entry = "Long", limit= trade_TP, stop = trade_SL)

// 9. Draw trade data and Price action setup arrow //
plot (series = strategy.position_size !=0 and ValidLong ? trade_SL : na, title = "Trade Stop Price", color=color.red, style = plot.style_linebr)
plot (series = strategy.position_size !=0 and ValidLong ? trade_TP : na, title = "Trade TP Price", color=color.green, style = plot.style_linebr)
plotshape(series = ValidLong ? 1 : na, style =shape.triangleup, location = location.belowbar, color=color.green, title = "Bullish Setup")


// ------------------------------------------------------ End of Code -------------------------------------------------//

enter image description here

Normally on the trade which started at 22.00 (10pm) after it detected 4 green candles after 1 red candle, based on my TP strategy, it should have exit at 1212.84$ after the TP value was 1.84$ but it exit at a higher price that it was supposed to do. And the profit in percentage is 1.57% when it should always be 2% and you can see below on a lossing trade, the percentage lost is 0.12% when it should always be 1%.

Do you have any idea on why it does work properly ? Is there a mistake in my code ?

Thanks, Ulrich

I tried to change number the reference of the candle eg candle [2] to candle [1], the detection went wrong.

Ulrich
  • 3
  • 1

2 Answers2

1

When you run strategy.exit() function with a stop loss or TP order, such order is issued to the broker emulator. If a previous order is already issued, it cancels the previous order and issue the new one.

In you case, you are issuing an order each bar the the strategy.position_size is greater the 0, and on each order you are calculating the price all over again. That means that each time you issue the order, the close price and open[2] price are different (and again, you are issuing them on each bar you are inside a trade).

For example, here is a script on which the order is issued only once after a trade is made:

//@version=5
strategy("My strategy", overlay=true, margin_long=100, margin_short=100)

tp_price = close * 1.1
sl_price = close * 0.9

longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
    strategy.entry("Long", strategy.long)

    strategy.exit("Exit Long", "Long", limit = tp_price, stop = sl_price)

And here is the result (the TP price is 10% above the close price when the long condition has been met):

but if I change the script just a bit and run the strategy.exit() order function on each time the strategy.position_size is greater than 0, it will look like this:

//@version=5
strategy("My strategy", overlay=true, margin_long=100, margin_short=100)

tp_price = close * 1.1
sl_price = close * 0.9

longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
    strategy.entry("Long", strategy.long)

if strategy.position_size > 0
    strategy.exit("Exit Long", "Long", limit = tp_price, stop = sl_price)

The reason for the difference is that it calculates close price on each bar where strategy.position_size is greater than 0:

That's a long explanation to an extremely simple fix - just run strategy.exit() right after strategy.entry()

if ValidLong
    strategy.entry("Long", strategy.long, qty=position_size_risked)
    strategy.exit("Long Exit", from_entry = "Long", limit= trade_TP, stop = trade_SL)
mr_statler
  • 1,913
  • 2
  • 3
  • 14
0

You write :
' For example if my account balance is 200 000$, I want to risk 2000$ So if the Diff (Difference between entry price - SL price) is 2$, I want to buy 1000 units of the share for ETH as 2000$/2$.'

But to buy 1000 units at 2000$, you will need 2 000 000$.
As Pinescript know you have 200 000$, it will buy 100 units.
The 2% calculation for your win trade is based on 1000 units, not 100.

G.Lebret
  • 2,826
  • 2
  • 16
  • 27