//////////////////////////////////////////////////////////
// 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);
}