JayRogers

Strategy Code Example - Risk Management

*** THIS IS JUST AN EXAMPLE OF STRATEGY RISK MANAGEMENT CODE IMPLEMENTATION ***

For my own future reference, and for anyone else who needs it.

Pine script strategy code can be confusing and awkward, so I finally sat down and had a little think about it and put something together that actually works (i think...)

Code is commented where I felt might be necessary (pretty much everything..) and covers:
  • Take Profit
  • Stop Loss
  • Trailing Stop
  • Trailing Stop Offset
...and details how to handle the input values for these in a way that allows them to be disabled if set to 0, without breaking the strategy.exit functionality or requiring a silly amount of statement nesting.

Also shows how to use functions (or variables/series) to execute trade entries and exits.

Cheers!
Open-source script

In true TradingView spirit, the author of this script has published it open-source, so traders can understand and verify it. Cheers to the author! You may use it for free, but reuse of this code in a publication is governed by House Rules. You can favorite it to use it on a chart.

Want to use this script on a chart?
//@version=2

strategy(title = "Strategy Code Example", shorttitle = "Strategy Code Example", overlay = true, pyramiding = 0, default_qty_type = strategy.percent_of_equity, default_qty_value = 10, currency = currency.GBP)

// Revision:        1
// Author:          @JayRogers
//
// *** THIS IS JUST AN EXAMPLE OF STRATEGY RISK MANAGEMENT CODE IMPLEMENTATION ***

// === GENERAL INPUTS ===
// short ma
maFastSource   = input(defval = open, title = "Fast MA Source")
maFastLength   = input(defval = 14, title = "Fast MA Period", minval = 1)
// long ma
maSlowSource   = input(defval = open, title = "Slow MA Source")
maSlowLength   = input(defval = 21, title = "Slow MA Period", minval = 1)

// === STRATEGY RELATED INPUTS ===
tradeInvert     = input(defval = false, title = "Invert Trade Direction?")
// the risk management inputs
inpTakeProfit   = input(defval = 1000, title = "Take Profit", minval = 0)
inpStopLoss     = input(defval = 200, title = "Stop Loss", minval = 0)
inpTrailStop    = input(defval = 200, title = "Trailing Stop Loss", minval = 0)
inpTrailOffset  = input(defval = 0, title = "Trailing Stop Loss Offset", minval = 0)

// === RISK MANAGEMENT VALUE PREP ===
// if an input is less than 1, assuming not wanted so we assign 'na' value to disable it.
useTakeProfit   = inpTakeProfit  >= 1 ? inpTakeProfit  : na
useStopLoss     = inpStopLoss    >= 1 ? inpStopLoss    : na
useTrailStop    = inpTrailStop   >= 1 ? inpTrailStop   : na
useTrailOffset  = inpTrailOffset >= 1 ? inpTrailOffset : na

// === SERIES SETUP ===
/// a couple of ma's..
maFast = ema(maFastSource, maFastLength)
maSlow = ema(maSlowSource, maSlowLength)

// === PLOTTING ===
fast = plot(maFast, title = "Fast MA", color = green, linewidth = 2, style = line, transp = 50)
slow = plot(maSlow, title = "Slow MA", color = red, linewidth = 2, style = line, transp = 50)

// === LOGIC ===
// is fast ma above slow ma?
aboveBelow = maFast >= maSlow ? true : false
// are we inverting our trade direction?
tradeDirection = tradeInvert ? aboveBelow ? false : true : aboveBelow ? true : false

// === STRATEGY - LONG POSITION EXECUTION ===
enterLong() => not tradeDirection[1] and tradeDirection // functions can be used to wrap up and work out complex conditions
exitLong() => tradeDirection[1] and not tradeDirection
strategy.entry(id = "Long", long = true, when = enterLong()) // use function or simple condition to decide when to get in
strategy.close(id = "Long", when = exitLong()) // ...and when to get out
// === STRATEGY - SHORT POSITION EXECUTION ===
enterShort() => tradeDirection[1] and not tradeDirection
exitShort() => not tradeDirection[1] and tradeDirection
strategy.entry(id = "Short", long = false, when = enterShort())
strategy.close(id = "Short", when = exitShort())

// === STRATEGY RISK MANAGEMENT EXECUTION ===
// finally, make use of all the earlier values we got prepped
strategy.exit("Exit Long", from_entry = "Long", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
strategy.exit("Exit Short", from_entry = "Short", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
If you like what I do, consider buying me a nice fresh cup of tea :)

https://paypal.me/JayRogersKreations

Comments

how will you create alerts on
strategy.exit("Exit Long", from_entry = "Long", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
strategy.exit("Exit Short", from_entry = "Short", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)


as those are functions of strategy.exit, right?
+18 Reply
Hello nice one but I am wondering how to calculate takeprofit and stoploss in percents rather than pips. Just can not figure it out. Thanks for any idea
+14 Reply
Trail stop = Fake strategy
+8 Reply
dysrupt Virtual_Machinist
@Virtual_Machinist, explain? im scripting now, just curios
+1 Reply
@dysrupt, trailing stop creates incorrect backtest results, no matter what method you use to determine it. if you are exiting with trailing stop strategy condition its no good (skews results positive in a huge way)
+3 Reply
dysrupt theheirophant
@theheirophant, thanks for the reply. My thought process is, if the condition is "close<stop", in theory, the candle close would be the exact point of order close. Unless the stop was based on a higher resolution, resulting in major re-painting issues.
Reply
Thanks a Ton man, i will remember you in my whole life..this post is my turning point in my trading journey. God Bless you!
+8 Reply
This trailing stop is massively flawed. If you have a 20 pip trailing stop, it finds the next candle whose highest (long) or lowest (short) value is greater than 20 pips, and uses that as the final value. So if you long and the next candle's high is +70 pips, then you've just profited 70 pips!
+5 Reply
Hey do you find issues with the trailing stop in backtesting?

I find it gives a false value for the exit. If the trailing stop is triggered, it reports the trade close as either high or low of the bar, seemingly depending if you are long or short - giving wildly succesful backtest results , but false ones.

Anyone else get this?
+5 Reply
Objredline BobVanders
@BobVanders, I'm having a similar issue it sounds like:

strategy.exit("Exit long", from_entry="Long", qty = 20, stop = (close-R_value), comment = "xxx"

The problem is, say I pyramid entered in 3 times 20 shares, but only one of the pyramid entries satisfies the stop condition. The List of Trades will show all 3 pyramid entries were exited. However on the plot, it will only show one -20 qty "xxx" exit.

With trail_points and trail_offset, it is the same problem exiting the entire set of pyramid buys.

In addition with trail_points and _trail_offset, either I'm not understanding what these two parameters mean, or it's not calculating it right. I understand it as this: strategy.exit context: trail_points = 1000, trail_offset=200. As: once position is up 10%, it will sell if it then falls 2%. Can someone shed light on if this understanding is correct?
Reply
Home Stock Screener Forex Screener Crypto Screener Economic Calendar About Chart Features Pricing Refer a friend House Rules Help Center Website & Broker Solutions Widgets Charting Solutions Lightweight Charting Library Blog & News Twitter
Profile Profile Settings Account and Billing Referred friends Coins My Support Tickets Help Center Private Messages Chat Sign Out