-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.pine
More file actions
189 lines (153 loc) · 9.8 KB
/
Copy pathmain.pine
File metadata and controls
189 lines (153 loc) · 9.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=6
indicator("Smart Money Concept (SMC)", "SMC - Entry Model", overlay = true, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500)
// --- Theme Detection ---
// Detect dark vs light mode by sampling chart background brightness
bool isDark = color.r(chart.bg_color) + color.g(chart.bg_color) + color.b(chart.bg_color) < 382 // < 127 avg
// --- Adaptive Color Palette ---
// Backgrounds
color BG_HEADER = isDark ? color.new(#1a1d2e, 0) : color.new(#1e3a5f, 0)
color BG_ROW_EVEN = isDark ? color.new(#0f1117, 0) : color.new(#f0f4f8, 0)
color BG_ROW_ODD = isDark ? color.new(#161923, 0) : color.new(#e2e8f0, 0)
// Text colors
color TEXT_PRIMARY = isDark ? color.new(#e8eaf0, 0) : color.new(#0d1117, 0)
color TEXT_SECONDARY = isDark ? color.new(#a0a8b8, 0) : color.new(#2d3748, 0)
color TEXT_ON_COLOR = color.white
// Status colors — vivid enough for both themes
color BULL_COLOR = isDark ? color.new(#00c896, 0) : color.new(#00875a, 0) // Green
color BEAR_COLOR = isDark ? color.new(#ff4d6a, 0) : color.new(#c0392b, 0) // Red
color NEUTRAL_COLOR = isDark ? color.new(#4d9fff, 0) : color.new(#1a6fc4, 0) // Blue
color WAIT_COLOR = isDark ? color.new(#4a5068, 0) : color.new(#8fa3b1, 0) // Gray
color SWEPT_COLOR = isDark ? color.new(#f59e0b, 0) : color.new(#b45309, 0) // Amber
color CONFIRM_COLOR = isDark ? color.new(#a855f7, 0) : color.new(#6d28d9, 0) // Purple
// Liquidity line colors
color LIQ_LINE_COLOR = isDark ? color.new(#ff6b6b, 85) : color.new(#c0392b, 70)
// Session background
color SESSION_BG = isDark ? color.new(#4d9fff, 96) : color.new(#1a6fc4, 93)
// Trade box colors
color TP_BG = isDark ? color.new(#00c896, 88) : color.new(#00875a, 85)
color SL_BG = isDark ? color.new(#ff4d6a, 88) : color.new(#c0392b, 85)
// --- Inputs ---
string htfTimeframeInput = input.timeframe("60", "HTF Timeframe (Bias/Liquidity)", tooltip = "The timeframe used to identify the main trend and key liquidity levels (e.g., 1H).")
string londonSessionInput = input.session("0800-1630:1234567", "London Session", tooltip = "London Session hours in UTC.")
int pivotLenInput = input.int(3, "Pivot Lookback", minval = 1, group = "Structure")
float minRrInput = input.float(2.5, "Minimum Risk:Reward", minval = 0.5, group = "Strategy")
string tablePosInput = input.string("top_right", "Dashboard Position", options = ["top_right", "bottom_right", "top_left", "bottom_left"], group = "Visuals")
// --- Structure and Liquidity Logic ---
detectStructure(int pLen) =>
var float confirmedHigh = na
var float confirmedLow = na
var int currentTrend = 0
float ph = ta.pivothigh(high, pLen, pLen)
float pl = ta.pivotlow(low, pLen, pLen)
bool isBos = false
bool isChoch = false
if not na(ph)
confirmedHigh := ph
if not na(pl)
confirmedLow := pl
if not na(confirmedHigh) and close > confirmedHigh
if currentTrend == -1
isChoch := true
currentTrend := 1
else if currentTrend == 1
isBos := true
else
currentTrend := 1
confirmedHigh := na
if not na(confirmedLow) and close < confirmedLow
if currentTrend == 1
isChoch := true
currentTrend := -1
else if currentTrend == -1
isBos := true
else
currentTrend := -1
confirmedLow := na
[currentTrend, confirmedHigh, confirmedLow, isBos, isChoch]
// --- Session and MTF Data ---
isLondon = not na(time(timeframe.period, londonSessionInput, "UTC"))
[htfTrend, htfHigh, htfLow, htfIsBos, htfIsChoch] = request.security(syminfo.tickerid, htfTimeframeInput, detectStructure(pivotLenInput), gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
[ltfTrend, ltfHigh, ltfLow, ltfIsBos, ltfIsChoch] = detectStructure(pivotLenInput)
// --- Liquidity Sweep Logic ---
var float htfLiqHigh = na
var float htfLiqLow = na
if not na(htfHigh)
htfLiqHigh := htfHigh
if not na(htfLow)
htfLiqLow := htfLow
bool sweptHigh = high > htfLiqHigh and close < htfLiqHigh
bool sweptLow = low < htfLiqLow and close > htfLiqLow
// --- Strategy State ---
bool step1Ok = htfTrend != 0
bool step2Ok = not na(htfLiqHigh) and not na(htfLiqLow)
bool step3Ok = isLondon
var bool hasSwept = false
if isLondon and (sweptHigh or sweptLow)
hasSwept := true
if not isLondon
hasSwept := false
bool reactionOk = hasSwept and ltfIsChoch and ((sweptLow and ltfTrend == 1) or (sweptHigh and ltfTrend == -1))
// --- Entry, SL, TP ---
float entryPrice = close
float stopLoss = reactionOk ? (ltfTrend == 1 ? ta.lowest(low, 5) : ta.highest(high, 5)) : na
float takeProfit = reactionOk ? (ltfTrend == 1 ? htfLiqHigh : htfLiqLow) : na
// --- Dashboard ---
var table smcTable = table.new(
tablePosInput == "top_right" ? position.top_right :
tablePosInput == "bottom_right" ? position.bottom_right :
tablePosInput == "top_left" ? position.top_left : position.bottom_left,
2, 8,
border_width = 1,
border_color = isDark ? color.new(#2a3050, 0) : color.new(#b0c0d0, 0),
frame_color = isDark ? color.new(#2a3050, 0) : color.new(#b0c0d0, 0),
frame_width = 2)
if barstate.islast
// --- Row 0: Title Header ---
table.cell(smcTable, 0, 0, "⬡ SMC Strategy", bgcolor = BG_HEADER, text_color = color.white, text_size = size.small, text_halign = text.align_left)
table.cell(smcTable, 1, 0, isDark ? "◑ DARK" : "◐ LIGHT", bgcolor = BG_HEADER, text_color = isDark ? color.new(#a0a8b8, 0) : color.new(#94a3b8, 0), text_size = size.tiny)
// --- Row 1: HTF Trend ---
table.cell(smcTable, 0, 1, "① HTF Trend " + htfTimeframeInput + "m", bgcolor = BG_ROW_ODD, text_color = TEXT_SECONDARY, text_size = size.tiny, text_halign = text.align_left)
table.cell(smcTable, 1, 1,
htfTrend == 1 ? "▲ BULLISH" :
htfTrend == -1 ? "▼ BEARISH" : "— WAIT",
bgcolor =
htfTrend == 0 ? WAIT_COLOR :
htfTrend == 1 ? BULL_COLOR : BEAR_COLOR,
text_color = TEXT_ON_COLOR, text_size = size.tiny)
// --- Row 2: Liquidity Mapping ---
table.cell(smcTable, 0, 2, "② Liquidity Levels", bgcolor = BG_ROW_EVEN, text_color = TEXT_SECONDARY, text_size = size.tiny, text_halign = text.align_left)
table.cell(smcTable, 1, 2, step2Ok ? "✦ MAPPED" : "— WAIT", bgcolor = step2Ok ? NEUTRAL_COLOR : WAIT_COLOR, text_color = TEXT_ON_COLOR, text_size = size.tiny)
// --- Row 3: Session ---
table.cell(smcTable, 0, 3, "③ London Session", bgcolor = BG_ROW_ODD, text_color = TEXT_SECONDARY, text_size = size.tiny, text_halign = text.align_left)
table.cell(smcTable, 1, 3, step3Ok ? "● ACTIVE" : "○ CLOSED", bgcolor = step3Ok ? BULL_COLOR : BEAR_COLOR, text_color = TEXT_ON_COLOR, text_size = size.tiny)
// --- Row 4: Sweep ---
table.cell(smcTable, 0, 4, "④ Liquidity Sweep", bgcolor = BG_ROW_EVEN, text_color = TEXT_SECONDARY, text_size = size.tiny, text_halign = text.align_left)
table.cell(smcTable, 1, 4, hasSwept ? "⚡ SWEPT" : "— WAITING", bgcolor = hasSwept ? SWEPT_COLOR : WAIT_COLOR, text_color = TEXT_ON_COLOR, text_size = size.tiny)
// --- Row 5: LTF Confirmation ---
table.cell(smcTable, 0, 5, "⑤ LTF Confirmation", bgcolor = BG_ROW_ODD, text_color = TEXT_SECONDARY, text_size = size.tiny, text_halign = text.align_left)
table.cell(smcTable, 1, 5, reactionOk ? "✔ CHoCH CONFIRMED" : "— WAITING", bgcolor = reactionOk ? CONFIRM_COLOR : WAIT_COLOR, text_color = TEXT_ON_COLOR, text_size = size.tiny)
// --- Row 6: Trade Direction ---
string dirText = reactionOk ? (ltfTrend == 1 ? "▲ LONG" : "▼ SHORT") : "— NO SETUP"
color dirBg = reactionOk ? (ltfTrend == 1 ? BULL_COLOR : BEAR_COLOR) : WAIT_COLOR
table.cell(smcTable, 0, 6, "⑥ Direction", bgcolor = BG_ROW_EVEN, text_color = TEXT_SECONDARY, text_size = size.tiny, text_halign = text.align_left)
table.cell(smcTable, 1, 6, dirText, bgcolor = dirBg, text_color = TEXT_ON_COLOR, text_size = size.tiny)
// --- Row 7: Trade Levels ---
table.cell(smcTable, 0, 7, "⑦ Entry / SL / TP", bgcolor = BG_ROW_ODD, text_color = TEXT_SECONDARY, text_size = size.tiny, text_halign = text.align_left)
string tradeText = reactionOk ?
"E: " + str.tostring(entryPrice, "#.##") +
" SL: " + str.tostring(stopLoss, "#.##") +
" TP: " + str.tostring(takeProfit, "#.##") : "Waiting for setup…"
table.cell(smcTable, 1, 7, tradeText, bgcolor = reactionOk ? dirBg : WAIT_COLOR, text_color = TEXT_ON_COLOR, text_size = size.tiny)
// --- Session Background ---
bgcolor(isLondon ? SESSION_BG : na)
// --- Liquidity Lines ---
line.new(bar_index - 10, htfLiqHigh, bar_index, htfLiqHigh, color = isDark ? color.new(#ff6b6b, 0) : color.new(#c0392b, 0), style = line.style_dotted, width = 2)
line.new(bar_index - 10, htfLiqLow, bar_index, htfLiqLow, color = isDark ? color.new(#ff6b6b, 0) : color.new(#c0392b, 0), style = line.style_dotted, width = 2)
// --- Signals ---
plotshape(reactionOk and ltfTrend == 1, "Buy Signal", shape.triangleup, location.belowbar, BULL_COLOR, size = size.small, text = "BUY ✔", textcolor = BULL_COLOR)
plotshape(reactionOk and ltfTrend == -1, "Sell Signal", shape.triangledown, location.abovebar, BEAR_COLOR, size = size.small, text = "SELL ✔", textcolor = BEAR_COLOR)
// --- Trade Boxes ---
if reactionOk
box.new(bar_index, takeProfit, bar_index + 10, entryPrice, bgcolor = TP_BG, border_color = BULL_COLOR, border_width = 1, text = "TP", text_size = size.tiny, text_color = BULL_COLOR)
box.new(bar_index, entryPrice, bar_index + 10, stopLoss, bgcolor = SL_BG, border_color = BEAR_COLOR, border_width = 1, text = "SL", text_size = size.tiny, text_color = BEAR_COLOR)