Skip to content

Commit e3eaf97

Browse files
committed
feat: integrate RSI divergence pane into Fast EMA Scalper
1 parent da35b80 commit e3eaf97

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

lib/compiler-v14.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { compilePine as compileBase } from "./compiler-v13";
2+
import type { StrategyConfig } from "./types";
3+
4+
const appendForceOverlay = (line: string): string => {
5+
if (line.includes("force_overlay=")) return line;
6+
return `${line.slice(0, -1)}, force_overlay=true)`;
7+
};
8+
9+
export function compilePine(config: StrategyConfig): string {
10+
let code = compileBase(config);
11+
const useIntegratedRsiPane = config.name === "Fast EMA Scalper" && config.outputMode === "indicator";
12+
13+
if (!useIntegratedRsiPane) return code;
14+
15+
const declaration = `indicator("${config.name}", overlay=true, max_labels_count=500, max_lines_count=500)`;
16+
const paneDeclaration = `indicator("${config.name}", overlay=false, max_labels_count=500, max_lines_count=500)`;
17+
if (!code.includes(declaration)) {
18+
throw new Error("Compiler transform anchor missing: Fast EMA Scalper indicator declaration");
19+
}
20+
code = code.replace(declaration, paneDeclaration);
21+
22+
let overlayVisuals = 0;
23+
code = code.replace(/^(bgcolor|plot)\(.*\)$/gm, (line) => {
24+
overlayVisuals += 1;
25+
return appendForceOverlay(line);
26+
});
27+
28+
code = code.replace(/^\s*label\.new\(.*\)$/gm, (line) => {
29+
overlayVisuals += 1;
30+
return appendForceOverlay(line);
31+
});
32+
33+
if (config.execution.showDashboard) {
34+
const tablePattern = /var table dashboard = table\.new\(position\.top_right, 2, (\d+), border_width=1\)/;
35+
if (!tablePattern.test(code)) {
36+
throw new Error("Compiler transform anchor missing: Fast EMA Scalper dashboard table");
37+
}
38+
code = code.replace(
39+
tablePattern,
40+
"var table dashboard = table.new(position.top_right, 2, $1, border_width=1, force_overlay=true)"
41+
);
42+
}
43+
44+
if (overlayVisuals === 0) {
45+
throw new Error("Compiler transform anchor missing: Fast EMA Scalper overlay visuals");
46+
}
47+
48+
const alertsAnchor = "// === Alerts ===";
49+
if (!code.includes(alertsAnchor)) {
50+
throw new Error("Compiler transform anchor missing: alerts section");
51+
}
52+
53+
const divergencePane = `// === Integrated RSI divergence pane ===
54+
divRsiLength = input.int(14, "Divergence RSI period", minval=1)
55+
divPivotLeft = input.int(5, "Divergence pivot left", minval=1)
56+
divPivotRight = input.int(5, "Divergence pivot right", minval=1)
57+
divRangeMinimum = input.int(5, "Divergence minimum pivot range", minval=1)
58+
divRangeMaximum = input.int(60, "Divergence maximum pivot range", minval=2)
59+
showRegularBullDiv = input.bool(true, "Show regular bullish divergence")
60+
showHiddenBullDiv = input.bool(true, "Show hidden bullish divergence")
61+
showRegularBearDiv = input.bool(true, "Show regular bearish divergence")
62+
showHiddenBearDiv = input.bool(true, "Show hidden bearish divergence")
63+
64+
divRsi = ta.rsi(close, divRsiLength)
65+
divRegularBullColor = color.green
66+
divRegularBearColor = color.red
67+
divHiddenBullColor = color.new(color.green, 35)
68+
divHiddenBearColor = color.new(color.red, 35)
69+
divTransparentColor = color.new(color.white, 100)
70+
71+
plot(divRsi, "RSI divergence", linewidth=2, color=color.rgb(41, 98, 255))
72+
divMiddleLine = hline(50, "RSI middle", color=color.rgb(120, 123, 134), linestyle=hline.style_dotted)
73+
divOverboughtLine = hline(70, "RSI overbought", color=color.rgb(120, 123, 134), linestyle=hline.style_dotted)
74+
divOversoldLine = hline(30, "RSI oversold", color=color.rgb(120, 123, 134), linestyle=hline.style_dotted)
75+
fill(divOverboughtLine, divOversoldLine, "RSI divergence background", color=color.rgb(33, 150, 243, 90))
76+
77+
divPivotLowFound = not na(ta.pivotlow(divRsi, divPivotLeft, divPivotRight))
78+
divPivotHighFound = not na(ta.pivothigh(divRsi, divPivotLeft, divPivotRight))
79+
80+
divInRange(condition) =>
81+
divBarsSince = ta.barssince(condition)
82+
divRangeMinimum <= divBarsSince and divBarsSince <= divRangeMaximum
83+
84+
divPreviousLowInRange = divInRange(divPivotLowFound[1])
85+
divRsiHigherLow = divRsi[divPivotRight] > ta.valuewhen(divPivotLowFound, divRsi[divPivotRight], 1) and divPreviousLowInRange
86+
divPriceLowerLow = low[divPivotRight] < ta.valuewhen(divPivotLowFound, low[divPivotRight], 1)
87+
divRegularBullAlert = divPriceLowerLow and divRsiHigherLow and divPivotLowFound
88+
divRegularBull = showRegularBullDiv and divRegularBullAlert
89+
plot(divPivotLowFound ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Regular bullish divergence", linewidth=2, color=divRegularBull ? divRegularBullColor : divTransparentColor)
90+
plotshape(divRegularBull ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Regular bullish label", text="Bull", style=shape.labelup, location=location.absolute, color=divRegularBullColor, textcolor=color.white)
91+
92+
divRsiLowerLow = divRsi[divPivotRight] < ta.valuewhen(divPivotLowFound, divRsi[divPivotRight], 1) and divPreviousLowInRange
93+
divPriceHigherLow = low[divPivotRight] > ta.valuewhen(divPivotLowFound, low[divPivotRight], 1)
94+
divHiddenBullAlert = divPriceHigherLow and divRsiLowerLow and divPivotLowFound
95+
divHiddenBull = showHiddenBullDiv and divHiddenBullAlert
96+
plot(divPivotLowFound ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Hidden bullish divergence", linewidth=2, color=divHiddenBull ? divHiddenBullColor : divTransparentColor)
97+
plotshape(divHiddenBull ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Hidden bullish label", text="H Bull", style=shape.labelup, location=location.absolute, color=divHiddenBullColor, textcolor=color.white)
98+
99+
divPreviousHighInRange = divInRange(divPivotHighFound[1])
100+
divRsiLowerHigh = divRsi[divPivotRight] < ta.valuewhen(divPivotHighFound, divRsi[divPivotRight], 1) and divPreviousHighInRange
101+
divPriceHigherHigh = high[divPivotRight] > ta.valuewhen(divPivotHighFound, high[divPivotRight], 1)
102+
divRegularBearAlert = divPriceHigherHigh and divRsiLowerHigh and divPivotHighFound
103+
divRegularBear = showRegularBearDiv and divRegularBearAlert
104+
plot(divPivotHighFound ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Regular bearish divergence", linewidth=2, color=divRegularBear ? divRegularBearColor : divTransparentColor)
105+
plotshape(divRegularBear ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Regular bearish label", text="Bear", style=shape.labeldown, location=location.absolute, color=divRegularBearColor, textcolor=color.white)
106+
107+
divRsiHigherHigh = divRsi[divPivotRight] > ta.valuewhen(divPivotHighFound, divRsi[divPivotRight], 1) and divPreviousHighInRange
108+
divPriceLowerHigh = high[divPivotRight] < ta.valuewhen(divPivotHighFound, high[divPivotRight], 1)
109+
divHiddenBearAlert = divPriceLowerHigh and divRsiHigherHigh and divPivotHighFound
110+
divHiddenBear = showHiddenBearDiv and divHiddenBearAlert
111+
plot(divPivotHighFound ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Hidden bearish divergence", linewidth=2, color=divHiddenBear ? divHiddenBearColor : divTransparentColor)
112+
plotshape(divHiddenBear ? divRsi[divPivotRight] : na, offset=-divPivotRight, title="Hidden bearish label", text="H Bear", style=shape.labeldown, location=location.absolute, color=divHiddenBearColor, textcolor=color.white)
113+
114+
alertcondition(divRegularBullAlert, "Regular bullish divergence", "A new regular bullish RSI divergence was confirmed.")
115+
alertcondition(divHiddenBullAlert, "Hidden bullish divergence", "A new hidden bullish RSI divergence was confirmed.")
116+
alertcondition(divRegularBearAlert, "Regular bearish divergence", "A new regular bearish RSI divergence was confirmed.")
117+
alertcondition(divHiddenBearAlert, "Hidden bearish divergence", "A new hidden bearish RSI divergence was confirmed.")
118+
119+
`;
120+
121+
return code.replace(alertsAnchor, divergencePane + alertsAnchor);
122+
}

0 commit comments

Comments
 (0)