//@version=6
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 PineForge
// PineForge Owned Strategy: Kiln Power Efficiency
// Squared displacement efficiency gates otherwise ordinary trend transitions.
strategy("PineForge — Kiln Power Efficiency", overlay=true,
initial_capital=100000,
default_qty_type=strategy.fixed, default_qty_value=2,
pyramiding=0, commission_type=strategy.commission.percent,
commission_value=0.05, slippage=1,
margin_long=100, margin_short=100,
process_orders_on_close=false, calc_on_order_fills=false)
trendLength = input.int(43, "Trend EMA Length", minval=5, group="Trend")
efficiencyLength = input.int(18, "Efficiency Window", minval=3, group="Efficiency")
minimumEfficiency = input.float(0.035, "Minimum Squared Efficiency", minval=0.001, maxval=1.0, step=0.001, group="Efficiency")
atrLength = input.int(18, "ATR Length", minval=2, group="Risk")
maximumAtrLoss = input.float(2.7, "Maximum ATR Loss", minval=0.5, step=0.1, group="Risk")
trendLine = ta.ema(close, trendLength)
atrValue = ta.atr(atrLength)
displacement = math.abs(close - close[efficiencyLength])
pathProxy = math.max(atrValue * efficiencyLength, syminfo.mintick)
efficiency = math.pow(displacement / pathProxy, 2)
enterLong = ta.crossover(close, trendLine) and efficiency > minimumEfficiency
trendEnded = ta.crossunder(close, trendLine) or efficiency < minimumEfficiency * 0.35
riskExceeded = strategy.position_size > 0 and close < strategy.position_avg_price - atrValue * maximumAtrLoss
if strategy.position_size == 0 and enterLong
strategy.entry("Kiln Long", strategy.long)
else if strategy.position_size > 0 and (trendEnded or riskExceeded)
strategy.close("Kiln Long", comment=riskExceeded ? "ATR risk" : "Efficiency ended")
plot(trendLine, "Trend EMA", color=color.orange)
plot(efficiency, "Squared Efficiency", color=color.red, display=display.data_window)