This script implements a fully panel-driven EUR/USD trend-following strategy that uses a custom linear regression slope as its main trend filter and exposes all key parameters through a Zorro control panel. The LinearRegressionSlope function computes the slope of a regression line over a configurable number of bars (SlopePeriod), and this slope is used, together with a configurable SMA (SmaPeriod) and RSI (RsiPeriod), to assess trend and overbought/oversold conditions. Global parameters define whether trading is enabled, the risk per trade as a percentage of equity, ATR period and ATR-based stop multiplier, as well as minimum and maximum stop distances and position sizes. A click handler reacts to user edits in the panel: it toggles trading on/off, updates numeric parameters entered in the panel cells, and provides a “ResetEq” button to reset capital for demo/testing. In run(), all parameters are first sanitized with clamp() to keep them within sensible bounds, then indicators (SMA, RSI, ATR) and the regression slope are calculated, the slope is displayed in the panel, and position size is derived from risk percent, equity, and stop size. The panel is created once at INITRUN with labeled rows for each parameter and updated every bar for the live slope value, while the trading logic simply enters a long position when trading is enabled, price crosses above the SMA, and normalized RSI is below 0.7, plotting the normalized RSI for visual monitoring.

Code
//////////////////////////////////////////////////////////
// Linear regression slope with custom period
//////////////////////////////////////////////////////////
var LinearRegressionSlope(vars Data, int Period)
{
	var sumX = 0;
	var sumY = 0;
	var sumXY = 0;
	var sumX2 = 0;
	int i;

	for(i = 0; i < Period; i++) {
		sumX += i;
		sumY += Data[i];
		sumXY += i * Data[i];
		sumX2 += i * i;
	}

	var numerator = Period * sumXY - sumX * sumY;
	var denominator = Period * sumX2 - sumX * sumX;

	if(denominator != 0)
		return numerator / denominator;
	else
		return 0;
}

//////////////////////////////////////////////////////////
// Global Parameters (editable via panel)
//////////////////////////////////////////////////////////

int EnableTrade    = 1;    // trading on/off
var InputRiskPct   = 1.0;  // risk per trade in percent

int SlopePeriod    = 10;   // bars used for regression slope
int SmaPeriod      = 20;   // SMA period
int RsiPeriod      = 14;   // RSI period
int AtrPeriod      = 14;   // ATR period

var StopATRMult    = 2.0;  // stop = ATR * this
var StopMin        = 10;   // min stop (price distance)
var StopMax        = 50;   // max stop

var PosMin         = 1;    // min position size
var PosMax         = 5;    // max position size

var DisplaySlope   = 0;    // for live slope display in the panel

//////////////////////////////////////////////////////////
// Click handler for panel interactions
//////////////////////////////////////////////////////////
function click(int row,int col)
{
	string Text;

	if(!is(RUNNING)) return;   // ignore when script not running
	if(row < 0) return;        // ignore Result/Action/Asset events

	Text = panelGet(row,col);

	// Row / column mapping
	// 0: Enable trading (button)
	// 1: Risk %
	// 2: Slope period
	// 3: SMA period
	// 4: RSI period
	// 5: ATR period
	// 6: Stop ATR mult
	// 7: Stop min
	// 8: Stop max
	// 9: Pos min
	// 10: Pos max
	// 11: Reset equity button

	if(row == 0 && col == 1) {
		// Toggle trading
		if(EnableTrade)
			EnableTrade = 0;
		else
			EnableTrade = 1;

		panelSet(0,1, ifelse(EnableTrade,"On","Off"),0,0,4);
	}
	else if(row == 1 && col == 1) {
		InputRiskPct = atof(Text);
	}
	else if(row == 2 && col == 1) {
		SlopePeriod = atoi(Text);
	}
	else if(row == 3 && col == 1) {
		SmaPeriod = atoi(Text);
	}
	else if(row == 4 && col == 1) {
		RsiPeriod = atoi(Text);
	}
	else if(row == 5 && col == 1) {
		AtrPeriod = atoi(Text);
	}
	else if(row == 6 && col == 1) {
		StopATRMult = atof(Text);
	}
	else if(row == 7 && col == 1) {
		StopMin = atof(Text);
	}
	else if(row == 8 && col == 1) {
		StopMax = atof(Text);
	}
	else if(row == 9 && col == 1) {
		PosMin = atof(Text);
	}
	else if(row == 10 && col == 1) {
		PosMax = atof(Text);
	}
	else if(row == 11 && col == 0) {
		// Reset equity button
		Capital = 100000; // demo reset
	}
}

//////////////////////////////////////////////////////////
// Main strategy
//////////////////////////////////////////////////////////
function run() 
{
	vars Price;
	var sma, rsi, slopeVal, trend, atr, stopLevel, normRSI;
	var tradeRisk, posSize;
	string txt;

	set(PARAMETERS);
	BarPeriod = 15;
	StartDate = 20220101;
	asset("EUR/USD");

	// Clamp and sanitize parameter ranges to avoid nonsense
	SlopePeriod = clamp(SlopePeriod, 5, 200);
	SmaPeriod   = clamp(SmaPeriod,   2, 200);
	RsiPeriod   = clamp(RsiPeriod,   2, 200);
	AtrPeriod   = clamp(AtrPeriod,   2, 200);

	StopATRMult = clamp(StopATRMult, 0.5, 10);
	StopMin     = clamp(StopMin,     1,  500);
	StopMax     = clamp(StopMax,     StopMin, 1000);

	PosMin      = clamp(PosMin, 0.01, 100);
	PosMax      = clamp(PosMax, PosMin, 1000);

	InputRiskPct = clamp(InputRiskPct, 0.1, 20); // 0.1% .. 20%

	Price = series(priceClose());
	sma   = SMA(Price, SmaPeriod);
	rsi   = RSI(Price, RsiPeriod);

	slopeVal    = LinearRegressionSlope(Price, SlopePeriod);
	DisplaySlope = slopeVal;
	trend       = sign(slopeVal);

	atr       = ATR(AtrPeriod);
	stopLevel = clamp(atr * StopATRMult, StopMin, StopMax);
	normRSI   = clamp(rsi / 100, 0, 1);

	// Risk-based position sizing using percentage from panel
	tradeRisk = InputRiskPct / 100 * Equity;
	posSize   = clamp(tradeRisk / fix0(stopLevel), PosMin, PosMax);

	// Panel setup only once at init
	if(is(INITRUN))
	{
		// 12 rows, 2 columns, default color (0), cell width 80 px
		panel(12,2,0,80);

		// Row 0: Enable trading button
		panelSet(0,0,"Enable",0,0,1);
		panelSet(0,1, ifelse(EnableTrade,"On","Off"),0,0,4);

		// Row 1: Risk %
		panelSet(1,0,"Risk %",0,0,1);
		txt = strf("%.2f",InputRiskPct);
		panelSet(1,1,txt,0,0,2);

		// Row 2: Slope period
		panelSet(2,0,"SlopePer",0,0,1);
		txt = strf("%i",SlopePeriod);
		panelSet(2,1,txt,0,0,2);

		// Row 3: SMA period
		panelSet(3,0,"SMA Per",0,0,1);
		txt = strf("%i",SmaPeriod);
		panelSet(3,1,txt,0,0,2);

		// Row 4: RSI period
		panelSet(4,0,"RSI Per",0,0,1);
		txt = strf("%i",RsiPeriod);
		panelSet(4,1,txt,0,0,2);

		// Row 5: ATR period
		panelSet(5,0,"ATR Per",0,0,1);
		txt = strf("%i",AtrPeriod);
		panelSet(5,1,txt,0,0,2);

		// Row 6: Stop ATR mult
		panelSet(6,0,"Stop xATR",0,0,1);
		txt = strf("%.2f",StopATRMult);
		panelSet(6,1,txt,0,0,2);

		// Row 7: Stop min
		panelSet(7,0,"StopMin",0,0,1);
		txt = strf("%.2f",StopMin);
		panelSet(7,1,txt,0,0,2);

		// Row 8: Stop max
		panelSet(8,0,"StopMax",0,0,1);
		txt = strf("%.2f",StopMax);
		panelSet(8,1,txt,0,0,2);

		// Row 9: Pos min
		panelSet(9,0,"PosMin",0,0,1);
		txt = strf("%.2f",PosMin);
		panelSet(9,1,txt,0,0,2);

		// Row 10: Pos max
		panelSet(10,0,"PosMax",0,0,1);
		txt = strf("%.2f",PosMax);
		panelSet(10,1,txt,0,0,2);

		// Row 11: Reset + Slope display (label; value updated each bar)
		panelSet(11,0,"ResetEq",0,0,4);
		txt = strf("%.4f",DisplaySlope);
		panelSet(11,1,txt,0,0,1);
	}

	// Update slope display every bar
	txt = strf("%.4f",DisplaySlope);
	panelSet(11,1,txt,0,0,1);

	// Trading logic
	if(EnableTrade && crossOver(Price, sma) && normRSI < 0.7)
		enterLong(posSize);

	plot("RSI", normRSI, NEW, RED);
}