Advertisement IC Markets

Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Share, develop, and backtest custom MQL4/MQL5 Expert Advisors, Python data-scraping scripts, trading bots, and automated market alert systems.
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

3. Risk Management (SL/TP)

I used var variables (stopLossPrice and takeProfitPrice). In many scripts, SL/TP values recalculate every bar, which is incorrect. Here, the values are captured only at the moment the longCondition is met and remain fixed until the trade is closed.

4. Alerts

The alert_message parameter is embedded directly into strategy.entry.
To use this in live trading: When creating the Alert in TradingView, set the Condition to your strategy and in the Message box, type {{strategy.order.alert_message}}. This will push the exact Entry, SL, and TP prices to your phone/email/webhook.

5. Visual Confirmation

The background turns green when the Daily trend is bullish and red when bearish.
The script plots the active Stop Loss and Take Profit lines on your chart as soon as a trade is active, so you can visually verify the logic.

--------> End of output

It is interesting, how it was like about 70 percent faster.
At the end of this posts i will explain comparisome.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Recommended broker for automated trading & scalping IC Markets
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

Output from Gemma 4 31B:

Thought for 585.9 seconds

Output:

To achieve a perfect match between backtesting and live execution while ensuring zero repainting, we must handle the Multi-Timeframe (MTF) data with extreme care.

The most critical part of this script is how the Daily data is fetched. If we simply request the "current" Daily Close, the backtester will "cheat" by knowing the day's closing price before the day is actually over. To prevent this, we fetch the data from the last completed daily candle.

Here is the professional-grade Pine Script v6 strategy.

Code: Select all

//@version=6
strategy("Strict Non-Repainting 15m EMA/Daily Strategy", 
     overlay=true, 
     initial_capital=10000, 
     default_qty_type=strategy.percent_of_equity, 
     default_qty_value=10, 
     process_orders_on_close=true) // Essential: prevents intrabar "ghost" signals

// ==========================================
// --- Inputs ---
// ==========================================
emaLength    = input.int(20, "15m EMA Length", minval=1)
dailySmaLen  = input.int(50, "Daily SMA Length", minval=1)
dailyAtrLen  = input.int(14, "Daily ATR Length", minval=1)
slMultiplier = input.float(1.5, "Stop Loss (Daily ATR x)", step=0.1)
tpMultiplier = input.float(3.0, "Take Profit (Daily ATR x)", step=0.1)

// ==========================================
// --- MTF Data Handling (Non-Repainting) ---
// ==========================================
// To ensure the backtest matches live execution, we request data from the 
// LAST COMPLETED daily bar [1]. This ensures no "future leak" occurs.
[dSma, dAtr] = request.security(
     syminfo.tickerid, 
     "D", 
     [ta.sma(close, dailySmaLen)[1], ta.atr(dailyAtrLen)[1]], 
     lookahead=barmerge.lookahead_off
     )

// ==========================================
// --- Indicators & Logic ---
// ==========================================
// 15m EMA
ema15m = ta.ema(close, emaLength)

// ENTRY CONDITIONS
// Condition 1: 15m Close crosses over 15m EMA
crossUp = ta.crossover(close, ema15m)

// Condition 2: Current price is above the Daily 50 SMA 
// (Using the last confirmed Daily SMA value)
dailyFilter = close > dSma

longCondition = crossUp and dailyFilter

// ==========================================
// --- Execution & Risk Management ---
// ==========================================
// Variables to lock in SL/TP levels upon entry
var float tradeStopPrice = na
var float tradeTakeProfit = na

if longCondition
    // Calculate fixed prices at the moment of entry
    // We use the confirmed Daily ATR from the previous day's close
    float risk = dAtr * slMultiplier
    float reward = dAtr * tpMultiplier
    
    tradeStopPrice   := close - risk
    tradeTakeProfit := close + reward
    
    // Construct a detailed alert message for live execution
    string alertMsg = "LONG Entry | Price: " + str.tostring(close) + 
                      " | SL: " + str.tostring(tradeStopPrice) + 
                      " | TP: " + str.tostring(tradeTakeProfit)
    
    strategy.entry("Long", strategy.long, alert_message=alertMsg)

// Exit logic using hard price targets (Non-repainting exits)
if strategy.position_size > 0
    strategy.exit("Exit Long", "Long", stop=tradeStopPrice, limit=tradeTakeProfit, comment_loss="SL", comment_profit="TP")

// ==========================================
// --- Visuals ---
// ==========================================
// EMA Plot
plot(ema15m, color=color.blue, title="15m EMA 20")

// Daily SMA Plot (Mapped to current timeframe for visual check)
plot(dSma, color=color.orange, title="Confirmed Daily SMA 50", linewidth=2)

// Background highlight for trend filter
bgcolor(dailyFilter ? color.new(color.green, 90) : color.new(color.red, 90), title="Daily Filter Zone")

// Visual markers for signals
plotshape(longCondition, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small, title="Long Signal")

// Plot active SL/TP levels
plot(strategy.position_size > 0 ? tradeStopPrice : na, color=color.red, style=plot.style_linebr, title="Active Stop Loss")
plot(strategy.position_size > 0 ? tradeTakeProfit : na, color=color.green, style=plot.style_linebr, title="Active Take Profit")
Attachments
Snímek obrazovky 2026-09-09 141339.png
Snímek obrazovky 2026-09-09 141339.png (54.3 KiB) Viewed 386 times
Snímek obrazovky 2026-09-09 133506.png
Snímek obrazovky 2026-09-09 133506.png (53.2 KiB) Viewed 386 times
Snímek obrazovky 2026-09-09 133453.png
Snímek obrazovky 2026-09-09 133453.png (117.07 KiB) Viewed 386 times
Snímek obrazovky 2026-09-09 133431.png
Snímek obrazovky 2026-09-09 133431.png (86.6 KiB) Viewed 386 times
Snímek obrazovky 2026-09-09 142156.png
Snímek obrazovky 2026-09-09 142156.png (77.51 KiB) Viewed 386 times
Snímek obrazovky 2026-09-09 142149.png
Snímek obrazovky 2026-09-09 142149.png (112.28 KiB) Viewed 386 times
Snímek obrazovky 2026-09-09 142142.png
Snímek obrazovky 2026-09-09 142142.png (100.63 KiB) Viewed 386 times
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

Why this script fulfills your requirements:

1. Strictly Non-Repainting

I have used request.security with lookahead=barmerge.lookahead_off and accessed the indicators via the index [1] (e.g., ta.sma(close, dailySmaLen)[1]).

The Logic: In a live market, you cannot know the Daily SMA of "today" until the day closes. By using the value of the last completed day, the script uses only data that was historically available at that exact 15-minute timestamp.

2. Backtest matches Live Execution

Two specific settings ensure the 1:1 match:

process_orders_on_close=true: By default, strategies can execute "mid-bar" in backtesting, which is often impossible in live trading without slippage. Setting this to true forces the strategy to wait for the 15m bar to close before calculating the entry and executing at the open of the next bar.
Fixed Exit Prices: The Stop Loss and Take Profit are calculated once at the moment of entry and stored in var variables. They do not shift as the Daily ATR changes tomorrow, mirroring exactly how a real broker order works.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

3. No False Intrabar Triggers

Because process_orders_on_close is active, the ta.crossover logic is only finalized when the candle closes. If the price spikes above the EMA and then drops back down before the 15m candle finishes, no trade is triggered and no alert is fired.

How to set up the Alert for Live Trading:
Add the strategy to your 15-minute chart.
Click the Alert button.
Under Condition, select the strategy name.
In the Message field, delete everything and enter: {{strategy.order.alert_message}}
This will send the specific entry price, SL, and TP values directly to your phone or webhook.

---------> End of output.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

The Grading Rubric: Where the Models Will Fail

When you run this on your local workstation, evaluate the generated code against these three specific traps.

Trap 1: The MTF Lookahead Leak

Because the strategy runs on a 15m chart but requests Daily data, an inferior model will write something like this:
dailyClose = request.security(syminfo.tickerid, "D", close)

Why it fails: This pulls the current, unclosed Daily candle into the 15m chart. During live trading, that Daily close fluctuates for 24 hours, causing the 15m signals to appear and vanish retroactively.

The correct AI answer: A model that understands Pine Script v6 will explicitly offset the data using [1] and disable lookahead to force the use of the last confirmed daily bar:

Code: Select all

dailyClose = request.security(syminfo.tickerid, "D", close[1], lookahead = barmerge.lookahead_off)
Trap 2: The Intrabar Flicker

An LLM trained on generic code will write the entry logic like a standard if statement:

Code: Select all

if ta.crossover(close, ema20) and dailyClose > dailySma
Why it fails: On a live chart, this evaluates on every tick. If a price spikes mid-candle, the condition becomes true, an alert fires, and a trade enters. If the price drops before the 15m candle closes, the crossover disappears from history, but the live trade remains.
The correct AI answer: The model must gate the execution to ensure the bar is closed. It should either check the previous confirmed bar (close[1]) or explicitly use the barstate variable:

Code: Select all

if ta.crossover(close, ema20) and dailyClose > dailySma and barstate.isconfirmed
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

Trap 3: The Drifting Stop Loss

Watch how the LLM handles the mathematical calculation for the Stop Loss (SL) and Take Profit (TP). A hallucinating model will calculate it continuously:

Code: Select all

sl = close - (dailyAtr * 1.5)
Why it fails: Since close and dailyAtr change, the stop loss will recalculate on every single bar after the trade is opened, causing the exit orders to drift.
The correct AI answer: The model should recognize that order parameters must be locked at the exact moment of entry. It should use the var keyword to initialize the variable, or explicitly lock the calculation inside the entry execution block so it doesn't update on subsequent bars.

My prediction: You will likely see the 12B and 26B MoE models fail Traps 1 and 3, while the dense 31B model has the highest probability of passing Trap 1 due to better context retention of TradingView's documentation.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

Deep-Dive Analysis

1. Gemma 4 12B (Dense) — The Critical Repainting Flaws

While the 12B model understood basic Pine Script v6 syntax and properly used var to lock the stop loss, it failed both critical repainting checks:

The MTF Leak: It called request.security(..., [ta.sma(close, smaLength), ta.atr(atrLength)], lookahead=barmerge.lookahead_off) without historical bar indexing ([1]). On historical bars, request.security without an explicit offset pulls the closing value of that day, causing historical backtests to trade on future daily closes that were unknown at the 15m mark.

Intrabar Ghost Orders: It omitted process_orders_on_close = true in the strategy() declaration and did not check barstate.isconfirmed. On a live chart, an intrabar wick crossing the EMA would trigger a trade that could later vanish on the historical backtest if price pulled back before the candle closed.

2. Gemma 4 26B A4B (MoE) — The Surprise Standout

The concern with Mixture of Experts (MoE) models has always been routing instability on niche domain languages like Pine Script. However, the 26B A4B model performed exceptionally well:

Flawless MTF Handling: It retrieved [close[1], ta.sma(close, dailySmaLen)[1], ta.atr(dailyAtrLen)[1]] alongside lookahead = barmerge.lookahead_off. By indexing every series with [1], it completely neutralized lookahead bias.

Strict Logic Interpretation: When instructed that the Daily Close must be above the Daily SMA, 26B was the only model to explicitly pull the previous Daily Close (dClose > dSma).

Execution Gating: It recognized that strategies evaluate on bar close only if declared with process_orders_on_close = true, adding it directly into the strategy header.

3. Gemma 4 31B (Dense) — Solid, Robust Architecture

The 31B dense model passed all three traps without hesitation:

It encapsulated both indicators inside the tuple with [1] indexing (ta.sma(close, dailySmaLen)[1]).

It added process_orders_on_close = true and included clean comments explaining why intrabar ghost signals occur.

Its logic differed slightly from the 26B: it evaluated close > dSma (15m close above confirmed Daily SMA) rather than evaluating Daily Close against Daily SMA. Both are valid trend-following implementations, though 26B followed the exact wording more literally.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3027
Joined: Mon Jul 20, 2026 1:28 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PTScalper »

Key Takeaways for Quant Traders

Avoid Sub-20B Models for Strategy Code: The 12B model produces code that compiles cleanly and looks convincing, but contains subtle backtest-distorting leaks that would ruin live performance.

MoE Efficiency Wins the Round: The 26B A4B model offers the best balance of speed and precision. Because it only computes ~4B active parameters per token, generation latency is drastically lower than the 31B dense model while matching (and in some areas exceeding) its syntactical accuracy.

Always Audit MTF Calls: Regardless of which local model you deploy, always verify that request.security() expressions use [1] indexing on higher-timeframe data when lookahead_off is active.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PropScalpDesk
Posts: 273
Joined: Sat Sep 19, 2026 7:50 pm

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by PropScalpDesk »

PTScalper wrote:Watch how the LLM handles the mathematical calculation for the stop loss. A hallucinating model will calculate it continuously off live close instead of fixing it at entry.
That drifting-stop trap is exactly why I distrust “paste and profit” Pine from any model size. 12B vs 31B matters for code fluency; it does not matter if you skip verification. From this desk every alert and strategy script gets a dry-run: does SL lock at entry, does TP use the same series direction, do I understand the 15m alert path before I enable it.

Practical rule: if I cannot explain the stop math in one sentence without reading the script again, it stays off. Local LLM is a junior assistant, not the risk manager.

On prop accounts I am stricter — no experimental alerts on challenge risk until the same logic survived personal demo costs.

Do you pin SL at entry in all your generated scripts, or have you caught a model rewriting it bar-by-bar?
LondonScalper
Posts: 701
Joined: Sat Sep 05, 2026 7:54 am

Re: Local LLMs for Pine Script v6: Gemma 4 (12B vs. 26B MoE vs. 31B)

Post by LondonScalper »

PTScalper wrote:How to set up the Alert: Add the script to your chart. Select the 15m timeframe. Click the "Alert" icon. In the Condition dropdown, select the strategy. In the Message box, use: {{strategy.order.
Alert wiring with dynamic SL/TP in the message is the part teams forget until the phone shows a useless “order” ping. Fine for a personal London desk if the size is already capped elsewhere.

I keep alerts as assistants, not as autopilots. The 15m condition can be right while the M1 spread at the moment of fill is wrong. Human confirm still sits between ping and click on my book.

Useful setup notes — thank you for spelling the alert message pattern clearly.

Do you require a second confirm on the phone, or does the alert alone trigger a manual entry?
Post Reply