|
| 1 | +import { describe, expect, it } from "vitest"; |
| 2 | +import { compilePine } from "../lib/compiler"; |
| 3 | +import { presets } from "../lib/presets"; |
| 4 | + |
| 5 | +const clone = <T,>(value: T): T => JSON.parse(JSON.stringify(value)); |
| 6 | + |
| 7 | +const expectedRsiPanePresets = [ |
| 8 | + "Balanced Intraday", |
| 9 | + "Fast EMA Scalper", |
| 10 | + "VWAP Session Trader", |
| 11 | + "4H Swing Trend", |
| 12 | + "Spot Accumulation", |
| 13 | + "Breakout Momentum", |
| 14 | + "RSI Divergence Reversal", |
| 15 | + "Selective Multi-Timeframe", |
| 16 | + "Long-Term Trend Guard" |
| 17 | +]; |
| 18 | + |
| 19 | +describe("integrated RSI pane preset coverage", () => { |
| 20 | + for (const name of expectedRsiPanePresets) { |
| 21 | + it(`${name} includes the integrated RSI pane`, () => { |
| 22 | + const preset = presets.find((item) => item.name === name); |
| 23 | + expect(preset).toBeDefined(); |
| 24 | + const code = compilePine(clone(preset!)); |
| 25 | + |
| 26 | + expect(code).toContain("// === Integrated RSI divergence pane ==="); |
| 27 | + expect(code).toContain('indicator("' + name + '", overlay=false'); |
| 28 | + expect(code).toContain(`divRsiLength = input.int(${preset!.momentum.rsiLength}`); |
| 29 | + expect(code).toContain(`divPivotLeft = input.int(${preset!.momentum.divergencePivot}`); |
| 30 | + expect(code).toContain(`divPivotRight = input.int(${preset!.momentum.divergencePivot}`); |
| 31 | + expect(code).toContain('plot(divRsi, "RSI divergence"'); |
| 32 | + }); |
| 33 | + } |
| 34 | + |
| 35 | + it("does not add an RSI pane when RSI and divergence are both disabled", () => { |
| 36 | + const preset = presets.find((item) => item.name === "Supertrend Volume"); |
| 37 | + expect(preset).toBeDefined(); |
| 38 | + const code = compilePine(clone(preset!)); |
| 39 | + |
| 40 | + expect(code).not.toContain("// === Integrated RSI divergence pane ==="); |
| 41 | + expect(code).toContain('indicator("Supertrend Volume", overlay=true'); |
| 42 | + }); |
| 43 | + |
| 44 | + it("enables trend-continuation hidden divergence defaults only where appropriate", () => { |
| 45 | + const swing = compilePine(clone(presets.find((item) => item.name === "4H Swing Trend")!)); |
| 46 | + const breakout = compilePine(clone(presets.find((item) => item.name === "Breakout Momentum")!)); |
| 47 | + const spot = compilePine(clone(presets.find((item) => item.name === "Spot Accumulation")!)); |
| 48 | + const longTerm = compilePine(clone(presets.find((item) => item.name === "Long-Term Trend Guard")!)); |
| 49 | + const scalper = compilePine(clone(presets.find((item) => item.name === "Fast EMA Scalper")!)); |
| 50 | + |
| 51 | + expect(swing).toContain('showHiddenBullDiv = input.bool(true'); |
| 52 | + expect(swing).toContain('showHiddenBearDiv = input.bool(true'); |
| 53 | + expect(breakout).toContain('showHiddenBullDiv = input.bool(true'); |
| 54 | + expect(breakout).toContain('showHiddenBearDiv = input.bool(true'); |
| 55 | + expect(spot).toContain('showHiddenBullDiv = input.bool(true'); |
| 56 | + expect(spot).toContain('showHiddenBearDiv = input.bool(false'); |
| 57 | + expect(longTerm).toContain('showHiddenBullDiv = input.bool(true'); |
| 58 | + expect(longTerm).toContain('showHiddenBearDiv = input.bool(false'); |
| 59 | + expect(scalper).toContain('showHiddenBullDiv = input.bool(false'); |
| 60 | + expect(scalper).toContain('showHiddenBearDiv = input.bool(false'); |
| 61 | + }); |
| 62 | +}); |
0 commit comments