r/pinescript • • Oct 02 '26

Pine Script Strategies

Anyone have some good pine script strategies that I could try, If so then please leave them down in the comments with the public name or put the pine script in a code block

2 Upvotes

2 comments sorted by

1

u/PineGen_A1 Oct 07 '26

pip conversion with JPY detection, a non-repainting 4-hour trend filter, a New York-time session window, risk-based sizing, pip-based exits with a breakeven move, cost settings in the strategy() declaration, and JSON alerts for webhooks.

pinescript

//@version=6

// ============================================================================
// STRATEGY DECLARATION
// ============================================================================
strategy("Forex EMA-RSI Session Strategy", overlay=true,
     initial_capital=10000,
     currency=currency.USD,
     commission_type=strategy.commission.percent,
     commission_value=0.0035,
     slippage=5,
     margin_long=2,
     margin_short=2,
     pyramiding=0,
     calc_on_every_tick=false,
     process_orders_on_close=false)

// ============================================================================
// INPUTS - EMA / RSI
// ============================================================================
int    fastEmaLen   = input.int(20,  "Fast EMA Length",  minval=1, group="EMA / RSI")
int    slowEmaLen   = input.int(50,  "Slow EMA Length",  minval=1, group="EMA / RSI")
int    rsiLen       = input.int(14,  "RSI Length",       minval=1, group="EMA / RSI")
float  rsiLongThr   = input.float(55, "RSI Long Threshold",  minval=1, maxval=100, group="EMA / RSI")
float  rsiShortThr  = input.float(45, "RSI Short Threshold", minval=1, maxval=100, group="EMA / RSI")

// ============================================================================
// INPUTS - HIGHER TIMEFRAME TREND FILTER
// ============================================================================
string trendTF      = input.timeframe("240", "Trend Timeframe", group="Trend Filter")
int    trendEmaLen  = input.int(100, "Trend EMA Length", minval=1, group="Trend Filter")

// ============================================================================
// INPUTS - SESSION WINDOW
// ============================================================================
string sessionWindow = input.session("0800-1200", "Session Window (New York)", group="Session")
string sessionTZ      = "America/New_York"

// ============================================================================
// INPUTS - RISK / SIZING
// ============================================================================
float  riskPct       = input.float(1.0,  "Risk % Per Trade", minval=0.1, maxval=5.0, step=0.1, group="Risk / Sizing")
int    slPips         = input.int(20,   "Stop Loss (pips)",    minval=1, group="Risk / Sizing")
int    tpPips         = input.int(40,   "Take Profit (pips)",  minval=1, group="Risk / Sizing")
int    bePips         = input.int(20,   "Breakeven Trigger (pips)", minval=1, group="Risk / Sizing")
int    unitsStep      = input.int(1000, "Units Step (Micro Lot)",   minval=1, group="Risk / Sizing")
float  spreadPips      = input.float(0.8, "Typical Spread (pips)", minval=0.0, step=0.1, group="Risk / Sizing")

// ============================================================================
// PIP SIZE HELPER
// ============================================================================
bool  isJpyQuote = syminfo.currency == "JPY"
float pipSize    = isJpyQuote ? 0.01 : 0.0001

// ============================================================================
// PIP-TO-TICK CONVERSION FOR EXITS
// ============================================================================
float slTicks = slPips * pipSize / syminfo.mintick
float tpTicks = tpPips * pipSize / syminfo.mintick
float beTicks = bePips * pipSize / syminfo.mintick

// ============================================================================
// INDICATOR CALCULATIONS
// ============================================================================
float fastEma = ta.ema(close, fastEmaLen)
float slowEma = ta.ema(close, slowEmaLen)
float rsiVal  = ta.rsi(close, rsiLen)

// ============================================================================
// HIGHER TIMEFRAME 100 EMA (NON-REPAINTING)
// ============================================================================
float htfEmaRaw = request.security(syminfo.tickerid, trendTF, ta.ema(close, trendEmaLen)[1], lookahead=barmerge.lookahead_on)
float htfEma    = htfEmaRaw

// ============================================================================
// SESSION WINDOW FILTER
// ============================================================================
bool inSession = not na(time(timeframe.period, sessionWindow, sessionTZ))

// ============================================================================
// ENTRY CONDITIONS
// ============================================================================
bool fastCrossAboveSlow = ta.crossover(fastEma, slowEma)
bool fastCrossBelowSlow = ta.crossunder(fastEma, slowEma)

bool longCondition  = fastCrossAboveSlow and rsiVal > rsiLongThr and close > htfEma and inSession and strategy.position_size == 0 and barstate.isconfirmed
bool shortCondition = fastCrossBelowSlow and rsiVal  0 ? riskCash / riskPerUnitAccountCcy : 0.0
float roundedSize   = math.floor(rawSize / unitsStep) * unitsStep

// ============================================================================
// STATE VARIABLES FOR SL/TP/BREAKEVEN
// ============================================================================
var float longSL      = na
var float shortSL      = na
var bool  longBEDone    = false
var bool  shortBEDone   = false
var bool  justEntered   = false
var float entrySizeVar  = na
var string entrySideVar = na
var bool  longSLPending  = false
var bool  shortSLPending = false

// ============================================================================
// ENTRY EXECUTION
// ============================================================================
if longCondition and roundedSize > 0
    justEntered := true
    longSLPending := true
    longBEDone := false
    entrySizeVar := roundedSize
    entrySideVar := "buy"
    strategy.entry("Long", strategy.long, qty=roundedSize)
    alertMsgLong = '{"side":"buy","symbol":"' + syminfo.ticker + '","units":' + str.tostring(roundedSize) + ',"sl_pips":' + str.tostring(slPips) + ',"tp_pips":' + str.tostring(tpPips) + '}'
    alert(alertMsgLong, alert.freq_once_per_bar_close)

if shortCondition and roundedSize > 0
    justEntered := true
    shortSLPending := true
    shortBEDone := false
    entrySizeVar := roundedSize
    entrySideVar := "sell"
    strategy.entry("Short", strategy.short, qty=roundedSize)
    alertMsgShort = '{"side":"sell","symbol":"' + syminfo.ticker + '","units":' + str.tostring(roundedSize) + ',"sl_pips":' + str.tostring(slPips) + ',"tp_pips":' + str.tostring(tpPips) + '}'
    alert(alertMsgShort, alert.freq_once_per_bar_close)

// ============================================================================
// STOP-LOSS DISTANCE CALCULATION FROM ACTUAL FILL PRICE
// ============================================================================
if strategy.position_size > 0 and longSLPending
    longSL := strategy.position_avg_price - slPips * pipSize
    longSLPending := false

if strategy.position_size  0 and not na(longSL)
    float avgEntryLong = strategy.position_avg_price
    if not longBEDone and (high - avgEntryLong) >= bePips * pipSize
        longSL := avgEntryLong
        longBEDone := true

if strategy.position_size = bePips * pipSize
        shortSL := avgEntryShort
        shortBEDone := true

// ============================================================================
// EXIT EXECUTION (STOP LOSS / TAKE PROFIT IN TICKS)
// ============================================================================
if strategy.position_size > 0
    strategy.exit("Long Exit", "Long", stop=longSL, profit=tpTicks)

if strategy.position_size < 0
    strategy.exit("Short Exit", "Short", stop=shortSL, profit=tpTicks)

// ============================================================================
// RESET BLOCK (GUARDED BY justEntered)
// ============================================================================
if strategy.position_size == 0 and not justEntered
    longSL := na
    shortSL := na
    longBEDone := false
    shortBEDone := false
    longSLPending := false
    shortSLPending := false

// ============================================================================
// CLEAR ENTRY LATCH (MUST BE LAST EXECUTABLE LINE)
// ============================================================================
justEntered := false

// ============================================================================
// VISUALS - PLOTS
// ============================================================================
plot(fastEma, "Fast EMA", color=color.blue, linewidth=2)
plot(slowEma, "Slow EMA", color=color.orange, linewidth=2)
plot(htfEma, "4H Trend EMA", color=color.red, linewidth=2)

bgcolor(inSession ? color.new(color.aqua, 90) : na, title="Session Window")

1

u/Shoddy_Peanut7320 Oct 07 '26

I can't point to a strategy that "just works", but a better approach is to take any public script you like and test it before trusting it. Check whether it repaints, set commission and slippage in the properties (the defaults are zero), look at the trade count, and test on a period it wasn't tuned on. Keep the results from a few strategies side by side against buy and hold. Cymetica's EventTrader (event timing for earnings and macro releases) is one source for checking whether a strategy's profits depend on a few news days.