ajiim

🎁

Nov 1st, 2026
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 44.98 KB | None | 0 0
  1. //@version=6
  2. indicator("Flux Chartsβ„’ - SFX Algo", shorttitle = "Flux Chartsβ„’ - SFX Algo", overlay = true, max_labels_count = 500, max_lines_count = 500, max_bars_back = 500)
  3.  
  4. const string GRP_ALGO = "Algorithm Settings"
  5. const string GRP_TP = "Take Profit Settings"
  6. const string GRP_OVR = "Overlays"
  7. const string GRP_DASH = "Dashboard"
  8. const string GRP_ALERT = "Alerts"
  9. const string GRP_THEME = "Theme"
  10.  
  11. const string TT_SENS = "Sensitivity determines how frequently signals appear. A higher sensitivity would lead to more frequent signals (Buy & Sell) appearing on your chart."
  12. const string TT_STRENGTH = "Signal Strength helps filter out low-rated signals based on our Stochastic Weighting Algorithm. A higher signal strength will lead to fewer signals on your chart. A higher-rated signal doesn't necessarily make it a better signal than a lower-rated signal."
  13. const string TT_TIME = "Time Weighting allows you to choose how much historic data the indicator uses when interpreting data for the signals.\n\nRecent Trends: only recent market data is used (recency bias).\nMixed Trends: a balance between enough data points and recency bias.\nLongterm Trends: more historic data is used, weighting the overall past performance of each metric."
  14. const string TT_MINSTAR = "Filters out signals with a star rating below this value (1 - 5)."
  15. const string TT_STYLE = "Adapts the algorithm's internal lengths to your trading approach. Scalper = faster, Day Trader = balanced, Swing Trader = slower and smoother."
  16. const string TT_AI = "Automatically finds and sets the best sensitivity for the current ticker by evaluating multiple sensitivity candidates against recent price action. The Sensitivity input is used during the warm-up period."
  17. const string TT_METHOD = "Dynamic: TP levels use the take profit inputs (% Profit or ATR) and the Auto Stop-Loss uses the SFX sub-trend with your Risk Tolerance.\nKey Levels: TP & SL are placed at nearby market structure key levels (swing highs / lows).\nVolatility Bands: TP & SL are placed at the volatility band layers.\nSignal Rating: TP & SL distances adapt to the star rating of the signal."
  18. const string TT_TP = "Enable / disable each take profit level (labels & notifications). Values are used by the Dynamic TP / SL Method as % Profit from entry or as ATR multiples."
  19. const string TT_REPEAT = "When enabled, a new take profit signal & notification is generated every time price retests a take profit level that was already reached."
  20. const string TT_TPOPT = "Dynamic method only. Optimizes the take profit distances using the average maximum favorable excursion of the most recent SFX signals."
  21. const string TT_AUTOSL = "Automatically finds stop-loss exits. With the Dynamic method the SFX Algo's sub-trends are combined with your Risk Tolerance setting."
  22. const string TT_RISK = "Low = tighter stop-loss, Medium = balanced, High = wider stop-loss."
  23. const string TT_RT = "Draws realtime TP & SL lines and labels for the latest signal. Only available for the Key Levels TP / SL Method."
  24. const string TT_VB = "The volatility bands show areas of potential reversals. Tight bands = consolidation, which could lead to an impulsive move."
  25. const string TT_TC = "The colored candles (green & red) simplify the market into basic uptrends and downtrends."
  26. const string TT_STARS = "Displays the star rating (1 - 5) within the Buy & Sell labels. When disabled, stronger signals are marked with a '+' symbol."
  27. const string TT_RATINGLBL = "Displays a label every time the rating of the active signal is upgraded or downgraded. Buy & Sell labels take priority over rating labels."
  28. const string TT_TRAIL = "Displays the SFX trend trail and its fill towards price."
  29. const string TT_WAVE = "Highlights the retracement zone (0.382 - 0.618) of the current SFX trend leg."
  30. const string TT_GAUSS = "The Gauss Ribbon smooths out recent price movements using a Gaussian algorithm. The space between the upper and lower bands shows how volatile the market is. Band retests can confirm the strength of the trend."
  31. const string TT_WEBHOOK = "Formats all alert() notifications as JSON for webhooks: signal, rating, pre-determined TP & SL levels, ticker id object (incl. futures data) and Heikin Ashi safe prices."
  32.  
  33. const int AI_CANDIDATES = 10
  34. const int AI_WARMUP = 200
  35. const int RT_EXTEND = 25
  36. const int PIVOT_MEMORY = 60
  37. const int MFE_MEMORY = 30
  38.  
  39. int sensitivityInput = input.int(75, "Sensitivity", minval = 1, maxval = 100, group = GRP_ALGO, tooltip = TT_SENS)
  40. int signalStrength = input.int(25, "Signal Strength", minval = 0, maxval = 100, group = GRP_ALGO, tooltip = TT_STRENGTH)
  41. string timeWeighting = input.string("Recent Trends", "Time Weighting", options = ["Recent Trends", "Mixed Trends", "Longterm Trends"], group = GRP_ALGO, tooltip = TT_TIME)
  42. int minStarRating = input.int(4, "Minimum Star Rating", minval = 1, maxval = 5, group = GRP_ALGO, tooltip = TT_MINSTAR)
  43. string tradingStyle = input.string("Swing Trader", "Trading Style", options = ["Scalper", "Day Trader", "Swing Trader"], group = GRP_ALGO, tooltip = TT_STYLE)
  44. bool aiOptimizer = input.bool(false, "AI Sensitivity Optimizer", group = GRP_ALGO, tooltip = TT_AI)
  45.  
  46. string tpSlMethod = input.string("Key Levels", "TP / SL Method", options = ["Dynamic", "Key Levels", "Volatility Bands", "Signal Rating"], group = GRP_TP, tooltip = TT_METHOD)
  47. bool tp1On = input.bool(true, "", inline = "tp1", group = GRP_TP)
  48. float tp1Val = input.float(0.5, "Take profit 1 at", minval = 0.0, step = 0.1, inline = "tp1", group = GRP_TP)
  49. string tp1Unit = input.string("% Profit", "", options = ["% Profit", "ATR"], inline = "tp1", group = GRP_TP, tooltip = TT_TP)
  50. bool tp2On = input.bool(true, "", inline = "tp2", group = GRP_TP)
  51. float tp2Val = input.float(1.5, "Take profit 2 at", minval = 0.0, step = 0.1, inline = "tp2", group = GRP_TP)
  52. string tp2Unit = input.string("% Profit", "", options = ["% Profit", "ATR"], inline = "tp2", group = GRP_TP)
  53. bool tp3On = input.bool(true, "", inline = "tp3", group = GRP_TP)
  54. float tp3Val = input.float(3.0, "Take profit 3 at", minval = 0.0, step = 0.1, inline = "tp3", group = GRP_TP)
  55. string tp3Unit = input.string("% Profit", "", options = ["% Profit", "ATR"], inline = "tp3", group = GRP_TP)
  56. bool repeatTP = input.bool(false, "Repeat Take Profit Signals", group = GRP_TP, tooltip = TT_REPEAT)
  57. bool tpOptimize = input.bool(false, "Take Profit Level Optimization", group = GRP_TP, tooltip = TT_TPOPT)
  58. bool autoSL = input.bool(true, "Auto Stop-Loss", group = GRP_TP, tooltip = TT_AUTOSL)
  59. string riskTolerance = input.string("Medium", "Risk Tolerance", options = ["Low", "Medium", "High"], group = GRP_TP, tooltip = TT_RISK)
  60. bool realtimeLines = input.bool(false, "Realtime TP / SL Lines & Labels", group = GRP_TP, tooltip = TT_RT)
  61.  
  62. bool showVB = input.bool(true, "Volatility Bands", group = GRP_OVR, tooltip = TT_VB)
  63. bool showTPLabel = input.bool(true, "Take Profit Label", group = GRP_OVR)
  64. bool showTrendColor = input.bool(true, "Trend Coloring", group = GRP_OVR, tooltip = TT_TC)
  65. string trendColorMode = input.string("Bar Color", "Trend Coloring Mode", options = ["Bar Color", "Bar Color + Wicks"], group = GRP_OVR)
  66. bool showStrength = input.bool(true, "Strength Rating", group = GRP_OVR, tooltip = TT_STARS)
  67. bool showRatingLabels = input.bool(false, "Signal Rating Labels", group = GRP_OVR, tooltip = TT_RATINGLBL)
  68. bool showTrail = input.bool(true, "Trend Trail", group = GRP_OVR, tooltip = TT_TRAIL)
  69. bool showWave = input.bool(false, "Retracement Wave", group = GRP_OVR, tooltip = TT_WAVE)
  70. bool showGauss = input.bool(false, "Gauss Ribbon", group = GRP_OVR, tooltip = TT_GAUSS)
  71.  
  72. bool showRatingDash = input.bool(false, "Signal Ratings Dashboard", inline = "rd", group = GRP_DASH)
  73. string ratingDashPos = input.string("Bottom Right", "", options = ["Top Right", "Middle Right", "Bottom Right", "Top Left", "Middle Left", "Bottom Left", "Top Center", "Bottom Center"], inline = "rd", group = GRP_DASH)
  74. bool showTrendDash = input.bool(false, "Trend Dashboard", inline = "td", group = GRP_DASH)
  75. string trendDashPos = input.string("Top Right", "", options = ["Top Right", "Middle Right", "Bottom Right", "Top Left", "Middle Left", "Bottom Left", "Top Center", "Bottom Center"], inline = "td", group = GRP_DASH)
  76. string tableSizeInput = input.string("Small", "Table Size", options = ["Tiny", "Small", "Normal", "Large"], group = GRP_DASH)
  77.  
  78. bool alertTP = input.bool(true, "Take Profit", group = GRP_ALERT)
  79. bool alertBuy = input.bool(false, "Buy Alert", inline = "bs", group = GRP_ALERT)
  80. bool alertSell = input.bool(false, "Sell Alert", inline = "bs", group = GRP_ALERT)
  81. bool alertSL = input.bool(false, "Stop Loss", group = GRP_ALERT)
  82. bool alertUpgrade = input.bool(false, "Rating Upgrade", inline = "rt", group = GRP_ALERT)
  83. bool alertDowngrade = input.bool(false, "Rating Downgrade", inline = "rt", group = GRP_ALERT)
  84. bool webhookOn = input.bool(false, "Webhook Formatting", group = GRP_ALERT, tooltip = TT_WEBHOOK)
  85.  
  86. color bullColor = input.color(#089981, "Bullish", inline = "trend", group = GRP_THEME)
  87. color bearColor = input.color(#f23645, "Bearish", inline = "trend", group = GRP_THEME)
  88. color vbUpperColor = input.color(#f23645, "Volatility Bands", inline = "vb", group = GRP_THEME)
  89. color vbLowerColor = input.color(#089981, "", inline = "vb", group = GRP_THEME)
  90. color tpMarkerColor = input.color(#2962ff, "Take Profit Marker", group = GRP_THEME)
  91. color tpLineColor = input.color(#089981, "TP Lines", inline = "lv", group = GRP_THEME)
  92. color slLineColor = input.color(#f23645, "SL Lines", inline = "lv", group = GRP_THEME)
  93. color labelTextColor = input.color(color.white, "Label Text", group = GRP_THEME)
  94. string labelSizeInput = input.string("Normal", "Label Size", options = ["Tiny", "Small", "Normal", "Large", "Huge"], group = GRP_THEME)
  95.  
  96. type TradeState
  97. int dir = 0
  98. float entry = na
  99. int entryBar = na
  100. float tp1 = na
  101. float tp2 = na
  102. float tp3 = na
  103. float sl = na
  104. bool hit1 = false
  105. bool hit2 = false
  106. bool hit3 = false
  107. bool armed1 = false
  108. bool armed2 = false
  109. bool armed3 = false
  110. bool slHit = false
  111. bool active = false
  112. int rating = 0
  113. float maxFav = na
  114.  
  115. f_factor(float sens) =>
  116. 0.5 + (100.0 - sens) / 100.0 * 5.5
  117.  
  118. f_rating(float frac) =>
  119. float f = nz(frac, 0.0)
  120. math.max(1, math.min(5, 1 + int(math.floor(f * 5.0))))
  121.  
  122. f_stars(int rating) =>
  123. string s = ""
  124. for i = 1 to 5
  125. s := s + (i <= rating ? "β˜…" : "β˜†")
  126. s
  127.  
  128. f_signalText(int dir, int rating, bool showStars) =>
  129. string base = dir == 1 ? "BUY" : "SELL"
  130. showStars ? base + " " + str.tostring(rating) + "β˜†" : rating >= 4 ? base + "+" : base
  131.  
  132. f_fmt(float price, string pattern) =>
  133. na(price) ? "-" : str.tostring(math.round_to_mintick(price), pattern)
  134.  
  135. f_num(float v) =>
  136. na(v) ? "null" : str.tostring(math.round_to_mintick(v))
  137.  
  138. f_size(string s) =>
  139. switch s
  140. "Tiny" => size.tiny
  141. "Small" => size.small
  142. "Normal" => size.normal
  143. "Large" => size.large
  144. "Huge" => size.huge
  145. => size.normal
  146.  
  147. f_position(string p) =>
  148. switch p
  149. "Top Right" => position.top_right
  150. "Middle Right" => position.middle_right
  151. "Bottom Right" => position.bottom_right
  152. "Top Left" => position.top_left
  153. "Middle Left" => position.middle_left
  154. "Bottom Left" => position.bottom_left
  155. "Top Center" => position.top_center
  156. "Bottom Center" => position.bottom_center
  157. => position.top_right
  158.  
  159. f_trail(float factor, simple int atrLen) =>
  160. float atrValue = ta.atr(atrLen)
  161. float upBase = hl2 - factor * atrValue
  162. float dnBase = hl2 + factor * atrValue
  163. var float up = na
  164. var float dn = na
  165. var int dir = 1
  166. float prevUp = nz(up, upBase)
  167. float prevDn = nz(dn, dnBase)
  168. up := close[1] > prevUp ? math.max(upBase, prevUp) : upBase
  169. dn := close[1] < prevDn ? math.min(dnBase, prevDn) : dnBase
  170. if dir == -1 and close > prevDn
  171. dir := 1
  172. else if dir == 1 and close < prevUp
  173. dir := -1
  174. float trailValue = dir == 1 ? up : dn
  175. [trailValue, dir, up, dn]
  176.  
  177. f_logFactor(int prediction, int outcome, float lossMag, float eta) =>
  178. bool wrong = prediction != 0 and outcome != 0 and prediction != outcome
  179. wrong ? math.log(1.0 - eta * lossMag) : 0.0
  180.  
  181. f_sfxCore(float factor, simple int atrLen, simple int wmWindow, simple int rsiLen, simple int fastLen, simple int slowLen, simple int midLen, simple int stLen) =>
  182. [trailValue, trailDirection, trailUpper, trailLower] = f_trail(factor, atrLen)
  183. float atrValue = ta.atr(atrLen)
  184. float rsiValue = ta.rsi(close, rsiLen)
  185. [macdLine, macdSignal, macdHist] = ta.macd(close, fastLen, slowLen, 9)
  186. [stValue, stDirection] = ta.supertrend(3.0, stLen)
  187. float chBasis = ta.ema(close, midLen)
  188. var int chDir = 1
  189. if close > chBasis + atrValue
  190. chDir := 1
  191. else if close < chBasis - atrValue
  192. chDir := -1
  193. float emaFast = ta.ema(close, fastLen)
  194. float emaSlow = ta.ema(close, slowLen)
  195. int p1 = rsiValue >= 50 ? 1 : -1
  196. int p2 = macdLine >= macdSignal ? 1 : -1
  197. int p3 = stDirection < 0 ? 1 : -1
  198. int p4 = chDir
  199. int p5 = emaFast >= emaSlow ? 1 : -1
  200. int p6 = chBasis >= nz(chBasis[1], chBasis) ? 1 : -1
  201. float move = close - nz(close[1], close)
  202. int outcome = move > 0 ? 1 : move < 0 ? -1 : 0
  203. float prevAtr = nz(atrValue[1])
  204. float lossMag = prevAtr > 0 ? math.min(1.0, 0.5 + 0.5 * math.abs(move) / prevAtr) : 0.5
  205. float eta = 0.4
  206. float lw1 = nz(math.sum(f_logFactor(nz(p1[1]), outcome, lossMag, eta), wmWindow))
  207. float lw2 = nz(math.sum(f_logFactor(nz(p2[1]), outcome, lossMag, eta), wmWindow))
  208. float lw3 = nz(math.sum(f_logFactor(nz(p3[1]), outcome, lossMag, eta), wmWindow))
  209. float lw4 = nz(math.sum(f_logFactor(nz(p4[1]), outcome, lossMag, eta), wmWindow))
  210. float lw5 = nz(math.sum(f_logFactor(nz(p5[1]), outcome, lossMag, eta), wmWindow))
  211. float lw6 = nz(math.sum(f_logFactor(nz(p6[1]), outcome, lossMag, eta), wmWindow))
  212. float lwMax = math.max(lw1, lw2, lw3, lw4, lw5, lw6)
  213. float w1 = math.exp(lw1 - lwMax)
  214. float w2 = math.exp(lw2 - lwMax)
  215. float w3 = math.exp(lw3 - lwMax)
  216. float w4 = math.exp(lw4 - lwMax)
  217. float w5 = math.exp(lw5 - lwMax)
  218. float w6 = math.exp(lw6 - lwMax)
  219. float wSum = w1 + w2 + w3 + w4 + w5 + w6
  220. float bullW = (p1 == 1 ? w1 : 0.0) + (p2 == 1 ? w2 : 0.0) + (p3 == 1 ? w3 : 0.0) + (p4 == 1 ? w4 : 0.0) + (p5 == 1 ? w5 : 0.0) + (p6 == 1 ? w6 : 0.0)
  221. float bullFraction = wSum > 0 ? bullW / wSum : 0.5
  222. [trailValue, trailDirection, trailUpper, trailLower, bullFraction, atrValue]
  223.  
  224. f_signalEngine(int trailDirection, float bullFraction, float strengthPct, int minStars) =>
  225. var int pendDir = 0
  226. var int pendBar = 0
  227. bool flip = trailDirection != nz(trailDirection[1], trailDirection)
  228. if flip
  229. pendDir := trailDirection
  230. pendBar := bar_index
  231. float dirFrac = trailDirection == 1 ? bullFraction : 1.0 - bullFraction
  232. int rating = f_rating(dirFrac)
  233. bool inWindow = pendDir != 0 and trailDirection == pendDir and bar_index - pendBar <= 3
  234. bool passes = inWindow and dirFrac * 100.0 >= strengthPct and rating >= minStars
  235. bool buySig = passes and pendDir == 1
  236. bool sellSig = passes and pendDir == -1
  237. if passes or (pendDir != 0 and not inWindow)
  238. pendDir := 0
  239. [buySig, sellSig, rating]
  240.  
  241. f_sfxSentiment(float factor, simple int atrLen, simple int wmWindow, simple int rsiLen, simple int fastLen, simple int slowLen, simple int midLen, simple int stLen, float strengthPct, int minStars) =>
  242. [tValue, tDir, tUp, tDn, bFrac, aValue] = f_sfxCore(factor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen)
  243. [bSig, sSig, sRating] = f_signalEngine(tDir, bFrac, strengthPct, minStars)
  244. var int state = 0
  245. if bSig
  246. state := 1
  247. else if sSig
  248. state := -1
  249. state == 0 ? tDir : state
  250.  
  251. f_gaussAlpha(int period, int poles) =>
  252. float beta = (1.0 - math.cos(2.0 * math.pi / period)) / (math.pow(2.0, 1.0 / poles) - 1.0)
  253. math.sqrt(beta * beta + 2.0 * beta) - beta
  254.  
  255. f_pole(float src, float alpha) =>
  256. var float state = na
  257. state := na(state) ? src : na(src) ? state : alpha * src + (1.0 - alpha) * state
  258. state
  259.  
  260. f_gauss(float src, float alpha) =>
  261. float s1 = f_pole(src, alpha)
  262. float s2 = f_pole(s1, alpha)
  263. float s3 = f_pole(s2, alpha)
  264. f_pole(s3, alpha)
  265.  
  266. f_dynDist(float value, string unitType, float entry, float atrValue) =>
  267. unitType == "% Profit" ? entry * value / 100.0 : value * atrValue
  268.  
  269. f_keyLevels(int dir, array<float> resArr, array<float> supArr, float entry, float unit) =>
  270. array<float> tpPool = supArr
  271. array<float> slPool = resArr
  272. if dir == 1
  273. tpPool := resArr
  274. slPool := supArr
  275. array<float> dists = array.new<float>()
  276. for v1 in tpPool
  277. float dv1 = (v1 - entry) * dir
  278. if dv1 > unit * 0.25
  279. dists.push(dv1)
  280. dists.sort(order.ascending)
  281. float d1 = na
  282. float d2 = na
  283. float d3 = na
  284. float lastD = 0.0
  285. int found = 0
  286. for dv2 in dists
  287. if found >= 3
  288. break
  289. if dv2 - lastD >= unit * 0.5
  290. found += 1
  291. if found == 1
  292. d1 := dv2
  293. else if found == 2
  294. d2 := dv2
  295. else
  296. d3 := dv2
  297. lastD := dv2
  298. float stepD = unit * 1.5
  299. d1 := na(d1) ? stepD : d1
  300. d2 := na(d2) ? d1 + stepD : d2
  301. d3 := na(d3) ? d2 + stepD : d3
  302. float sd = na
  303. for v3 in slPool
  304. float dv3 = (entry - v3) * dir
  305. if dv3 > unit * 0.25
  306. sd := na(sd) ? dv3 : math.min(sd, dv3)
  307. sd := na(sd) ? unit * 2.0 : sd + unit * 0.1
  308. [entry + d1 * dir, entry + d2 * dir, entry + d3 * dir, entry - sd * dir]
  309.  
  310. f_sanitize(int dir, float entry, float t1, float t2, float t3, float sl, float unit) =>
  311. float u = math.max(nz(unit, syminfo.mintick), syminfo.mintick)
  312. float d1 = math.max(nz((t1 - entry) * dir, u), u * 0.25)
  313. float d2 = math.max(nz((t2 - entry) * dir, d1 + u), d1 + u * 0.25)
  314. float d3 = math.max(nz((t3 - entry) * dir, d2 + u), d2 + u * 0.25)
  315. float ds = math.max(nz((entry - sl) * dir, u * 1.5), u * 0.25)
  316. [math.round_to_mintick(entry + dir * d1), math.round_to_mintick(entry + dir * d2), math.round_to_mintick(entry + dir * d3), math.round_to_mintick(entry - dir * ds)]
  317.  
  318. f_tpCheck(int dir, float level, bool wasHit, bool wasArmed, bool repeatOn) =>
  319. bool fire = false
  320. bool retest = false
  321. bool hitState = wasHit
  322. bool armedState = wasArmed
  323. if not na(level) and dir != 0
  324. bool touched = dir == 1 ? high >= level : low <= level
  325. bool closedBack = dir == 1 ? close < level : close > level
  326. if not hitState
  327. if touched
  328. fire := true
  329. hitState := true
  330. armedState := closedBack
  331. else
  332. if armedState and touched and repeatOn
  333. retest := true
  334. armedState := closedBack or (armedState and not touched)
  335. [fire, retest, hitState, armedState]
  336.  
  337. f_recordMfe(TradeState t, array<float> hist, int memory) =>
  338. if t.dir != 0 and not na(t.entry) and t.entry > 0 and not na(t.maxFav)
  339. hist.push(math.max((t.maxFav - t.entry) * t.dir / t.entry * 100.0, 0.0))
  340. if hist.size() > memory
  341. hist.shift()
  342. true
  343.  
  344. f_tickerJson() =>
  345. string j = '{"symbol":"' + syminfo.ticker + '","exchange":"' + syminfo.prefix + '","type":"' + syminfo.type + '","currency":"' + syminfo.currency + '"'
  346. if syminfo.type == "futures"
  347. j := j + ',"root":"' + syminfo.root + '","pointvalue":' + str.tostring(syminfo.pointvalue) + ',"mintick":' + str.tostring(syminfo.mintick)
  348. j + '}'
  349.  
  350. f_webhookJson(string action, string evt, int dir, float price, int rating, float t1, float t2, float t3, float sl, string extra) =>
  351. string j = '{"action":"' + action + '","event":"' + evt + '","direction":"' + (dir == 1 ? 'bullish' : 'bearish') + '"'
  352. j := j + ',"ticker":"' + syminfo.ticker + '","ticker_id":' + f_tickerJson()
  353. j := j + ',"interval":"' + timeframe.period + '","time":' + str.tostring(time, '#')
  354. j := j + ',"price":' + f_num(price) + ',"chart_close":' + f_num(close) + ',"rating":' + str.tostring(rating)
  355. j := j + ',"tp1":' + f_num(t1) + ',"tp2":' + f_num(t2) + ',"tp3":' + f_num(t3) + ',"sl":' + f_num(sl)
  356. j + extra + '}'
  357.  
  358. f_plainMsg(string evt, float price, string details, string pattern) =>
  359. "Flux Chartsβ„’ - SFX Algo | " + evt + " | " + syminfo.ticker + " (" + timeframe.period + ") | Price: " + f_fmt(price, pattern) + details
  360.  
  361. f_levelDetails(int rating, float t1, float t2, float t3, float sl, string pattern) =>
  362. " | Rating: " + str.tostring(rating) + "β˜† | TP1: " + f_fmt(t1, pattern) + " | TP2: " + f_fmt(t2, pattern) + " | TP3: " + f_fmt(t3, pattern) + " | SL: " + f_fmt(sl, pattern)
  363.  
  364. f_tpAlert(int lvl, int dir, float lvlPrice, bool isRetest, bool asJson, float price, int rating, float t1, float t2, float t3, float sl, string pattern) =>
  365. string evt = "Take Profit " + str.tostring(lvl) + (isRetest ? " Retest" : "")
  366. string side = dir == 1 ? " (Bullish)" : " (Bearish)"
  367. string ext = ',"tp_level":' + str.tostring(lvl) + ',"tp_price":' + f_num(lvlPrice) + ',"retest":' + (isRetest ? 'true' : 'false')
  368. asJson ? f_webhookJson("take_profit", evt, dir, price, rating, t1, t2, t3, sl, ext) : f_plainMsg(evt + side, price, " | Level: " + f_fmt(lvlPrice, pattern), pattern)
  369.  
  370. f_rtText(int kind, float price, bool done, string pattern) =>
  371. (kind == 0 ? "SL " : "TP ") + f_fmt(price, pattern) + (done ? (kind == 0 ? " ❌" : " βœ…") : "")
  372.  
  373. var string pricePattern = "#,##0"
  374. if barstate.isfirst
  375. int dec = 0
  376. float mt = syminfo.mintick
  377. while dec < 8 and math.abs(mt * math.pow(10, dec) - math.round(mt * math.pow(10, dec))) > 0.0000001
  378. dec += 1
  379. pricePattern := dec > 0 ? "#,##0." + str.repeat("0", dec) : "#,##0"
  380.  
  381. float styleMult = tradingStyle == "Scalper" ? 0.7 : tradingStyle == "Swing Trader" ? 1.5 : 1.0
  382. int baseWindow = timeWeighting == "Recent Trends" ? 30 : timeWeighting == "Mixed Trends" ? 75 : 150
  383. int atrLen = math.max(2, math.round(10 * styleMult))
  384. int rsiLen = math.max(2, math.round(14 * styleMult))
  385. int fastLen = math.max(2, math.round(12 * styleMult))
  386. int slowLen = math.max(fastLen + 1, math.round(26 * styleMult))
  387. int midLen = math.max(5, math.round(50 * styleMult))
  388. int stLen = math.max(2, math.round(10 * styleMult))
  389. int wmWindow = math.max(5, math.round(baseWindow * styleMult))
  390. int vbLen = math.max(20, math.round(100 * styleMult))
  391. int vbSmooth = math.max(2, math.round(vbLen * 0.3))
  392. int gaussLen = math.max(10, math.round(60 * styleMult))
  393. int pivLen = math.max(3, math.round(5 * styleMult))
  394. float riskMult = riskTolerance == "Low" ? 0.75 : riskTolerance == "High" ? 1.5 : 1.0
  395.  
  396. float atrMain = ta.atr(atrLen)
  397.  
  398. var array<float> aiUp = array.new<float>(AI_CANDIDATES, na)
  399. var array<float> aiDn = array.new<float>(AI_CANDIDATES, na)
  400. var array<int> aiDir = array.new<int>(AI_CANDIDATES, 1)
  401. var array<float> aiScore = array.new<float>(AI_CANDIDATES, 0.0)
  402. var float aiBestSens = float(sensitivityInput)
  403. float aiDecay = 1.0 - 1.0 / math.max(50.0, wmWindow * 4.0)
  404.  
  405. if aiOptimizer and barstate.isconfirmed and not na(atrMain) and bar_index > 0
  406. float barRet = close[1] != 0 ? close / close[1] - 1.0 : 0.0
  407. float flipCost = close != 0 ? 0.25 * atrMain / close : 0.0
  408. int bestIdx = -1
  409. float bestVal = na
  410. for i = 0 to AI_CANDIDATES - 1
  411. float cFactor = f_factor(10.0 * (i + 1))
  412. float upBase = hl2 - cFactor * atrMain
  413. float dnBase = hl2 + cFactor * atrMain
  414. float pUp = nz(aiUp.get(i), upBase)
  415. float pDn = nz(aiDn.get(i), dnBase)
  416. int pDir = aiDir.get(i)
  417. float nUp = close[1] > pUp ? math.max(upBase, pUp) : upBase
  418. float nDn = close[1] < pDn ? math.min(dnBase, pDn) : dnBase
  419. int nDir = pDir == -1 and close > pDn ? 1 : pDir == 1 and close < pUp ? -1 : pDir
  420. float nScore = aiScore.get(i) * aiDecay + pDir * barRet - (nDir != pDir ? flipCost : 0.0)
  421. aiUp.set(i, nUp)
  422. aiDn.set(i, nDn)
  423. aiDir.set(i, nDir)
  424. aiScore.set(i, nScore)
  425. if na(bestVal) or nScore > bestVal
  426. bestVal := nScore
  427. bestIdx := i
  428. if bar_index >= AI_WARMUP and bestIdx >= 0
  429. aiBestSens := 10.0 * (bestIdx + 1)
  430.  
  431. float effSensitivity = aiOptimizer and bar_index >= AI_WARMUP ? aiBestSens : float(sensitivityInput)
  432. float effFactor = f_factor(effSensitivity)
  433.  
  434. [trailLine, trailDir, trailUp, trailDn, bullFrac, atrVal] = f_sfxCore(effFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen)
  435. [subLine, subDir, subUp, subDn] = f_trail(effFactor * 0.5, atrLen)
  436. [buySignal, sellSignal, signalRating] = f_signalEngine(trailDir, bullFrac, signalStrength, minStarRating)
  437. float smBullFrac = ta.ema(bullFrac, 5)
  438.  
  439. float vbBasis = ta.ema(ta.ema(hlc3, vbLen), vbSmooth)
  440. float vbDev = ta.ema(ta.stdev(hlc3, vbLen), vbSmooth)
  441. float vbUpIn = vbBasis + vbDev * 1.5
  442. float vbUpMid = vbBasis + vbDev * 2.25
  443. float vbUpOut = vbBasis + vbDev * 3.0
  444. float vbLoIn = vbBasis - vbDev * 1.5
  445. float vbLoMid = vbBasis - vbDev * 2.25
  446. float vbLoOut = vbBasis - vbDev * 3.0
  447.  
  448. float gaussAlpha = f_gaussAlpha(gaussLen, 4)
  449. float gaussMid = f_gauss(close, gaussAlpha)
  450. float gaussRange = f_gauss(ta.tr(true), gaussAlpha)
  451. float gaussUp = gaussMid + gaussRange * 1.5
  452. float gaussLo = gaussMid - gaussRange * 1.5
  453. bool gaussBull = gaussMid >= nz(gaussMid[1], gaussMid)
  454.  
  455. float pivHigh = ta.pivothigh(high, pivLen, pivLen)
  456. float pivLow = ta.pivotlow(low, pivLen, pivLen)
  457. var array<float> resLevels = array.new<float>()
  458. var array<float> supLevels = array.new<float>()
  459. if not na(pivHigh)
  460. resLevels.unshift(pivHigh)
  461. if resLevels.size() > PIVOT_MEMORY
  462. resLevels.pop()
  463. if not na(pivLow)
  464. supLevels.unshift(pivLow)
  465. if supLevels.size() > PIVOT_MEMORY
  466. supLevels.pop()
  467. float swingLowRef = ta.lowest(low, pivLen * 2)
  468. float swingHighRef = ta.highest(high, pivLen * 2)
  469.  
  470. float mtfFactor = f_factor(sensitivityInput)
  471. int mtf3S = request.security(syminfo.tickerid, "3", f_sfxSentiment(mtfFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen, signalStrength, minStarRating))
  472. int mtf15S = request.security(syminfo.tickerid, "15", f_sfxSentiment(mtfFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen, signalStrength, minStarRating))
  473. int mtf30S = request.security(syminfo.tickerid, "30", f_sfxSentiment(mtfFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen, signalStrength, minStarRating))
  474. int mtf60S = request.security(syminfo.tickerid, "60", f_sfxSentiment(mtfFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen, signalStrength, minStarRating))
  475. int mtf240S = request.security(syminfo.tickerid, "240", f_sfxSentiment(mtfFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen, signalStrength, minStarRating))
  476. int mtfDS = request.security(syminfo.tickerid, "D", f_sfxSentiment(mtfFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen, signalStrength, minStarRating))
  477. int mtfWS = request.security(syminfo.tickerid, "W", f_sfxSentiment(mtfFactor, atrLen, wmWindow, rsiLen, fastLen, slowLen, midLen, stLen, signalStrength, minStarRating))
  478.  
  479. float realClose = request.security(ticker.standard(syminfo.tickerid), timeframe.period, close)
  480.  
  481. var array<float> mfeHistory = array.new<float>()
  482. float avgMfe = mfeHistory.size() > 0 ? mfeHistory.avg() : na
  483.  
  484. var TradeState trade = TradeState.new()
  485. bool newSignal = buySignal or sellSignal
  486.  
  487. int checkDir = trade.dir
  488. float chkT1 = trade.tp1
  489. float chkT2 = trade.tp2
  490. float chkT3 = trade.tp3
  491. float chkSL = trade.sl
  492. int chkRate = trade.rating
  493. bool tp1Fire = false
  494. bool tp2Fire = false
  495. bool tp3Fire = false
  496. bool tp1Retest = false
  497. bool tp2Retest = false
  498. bool tp3Retest = false
  499. bool slFire = false
  500.  
  501. if trade.active and bar_index > trade.entryBar
  502. trade.maxFav := trade.dir == 1 ? math.max(nz(trade.maxFav, high), high) : math.min(nz(trade.maxFav, low), low)
  503. [f1, r1, h1, a1] = f_tpCheck(trade.dir, trade.tp1, trade.hit1, trade.armed1, repeatTP)
  504. [f2, r2, h2, a2] = f_tpCheck(trade.dir, trade.tp2, trade.hit2, trade.armed2, repeatTP)
  505. [f3, r3, h3, a3] = f_tpCheck(trade.dir, trade.tp3, trade.hit3, trade.armed3, repeatTP)
  506. trade.hit1 := h1
  507. trade.hit2 := h2
  508. trade.hit3 := h3
  509. trade.armed1 := a1
  510. trade.armed2 := a2
  511. trade.armed3 := a3
  512. tp1Fire := f1 and tp1On
  513. tp2Fire := f2 and tp2On
  514. tp3Fire := f3 and tp3On
  515. tp1Retest := r1 and tp1On
  516. tp2Retest := r2 and tp2On
  517. tp3Retest := r3 and tp3On
  518. if not na(trade.sl)
  519. bool slTouched = trade.dir == 1 ? low <= trade.sl : high >= trade.sl
  520. if slTouched
  521. slFire := true
  522. trade.slHit := true
  523. trade.active := false
  524. f_recordMfe(trade, mfeHistory, MFE_MEMORY)
  525.  
  526. bool tp1Event = tp1Fire or tp1Retest
  527. bool tp2Event = tp2Fire or tp2Retest
  528. bool tp3Event = tp3Fire or tp3Retest
  529. bool anyTPEvent = tp1Event or tp2Event or tp3Event
  530. bool longTPEvent = anyTPEvent and checkDir == 1
  531. bool shortTPEvent = anyTPEvent and checkDir == -1
  532.  
  533. if newSignal
  534. if trade.active
  535. f_recordMfe(trade, mfeHistory, MFE_MEMORY)
  536. int d = buySignal ? 1 : -1
  537. float entry = close
  538. float unit = nz(atrVal, close * 0.01)
  539. float rT1 = na
  540. float rT2 = na
  541. float rT3 = na
  542. float rSL = na
  543. if tpSlMethod == "Dynamic"
  544. bool useOpt = tpOptimize and mfeHistory.size() >= 3 and not na(avgMfe)
  545. float optPct = useOpt ? avgMfe : 0.0
  546. rT1 := entry + d * (useOpt ? entry * optPct * 0.4 / 100.0 : f_dynDist(tp1Val, tp1Unit, entry, unit))
  547. rT2 := entry + d * (useOpt ? entry * optPct * 0.8 / 100.0 : f_dynDist(tp2Val, tp2Unit, entry, unit))
  548. rT3 := entry + d * (useOpt ? entry * optPct * 1.2 / 100.0 : f_dynDist(tp3Val, tp3Unit, entry, unit))
  549. float subRef = d == 1 ? subUp : subDn
  550. float subDist = na(subRef) ? unit * 1.5 : math.max((entry - subRef) * d, unit * 0.25)
  551. rSL := entry - d * subDist * riskMult
  552. else if tpSlMethod == "Key Levels"
  553. [k1, k2, k3, kS] = f_keyLevels(d, resLevels, supLevels, entry, unit)
  554. rT1 := k1
  555. rT2 := k2
  556. rT3 := k3
  557. rSL := kS
  558. else if tpSlMethod == "Volatility Bands"
  559. rT1 := d == 1 ? vbUpIn : vbLoIn
  560. rT2 := d == 1 ? vbUpMid : vbLoMid
  561. rT3 := d == 1 ? vbUpOut : vbLoOut
  562. rSL := d == 1 ? vbLoOut : vbUpOut
  563. else
  564. float rUnit = unit * (0.6 + 0.3 * signalRating)
  565. rT1 := entry + d * rUnit
  566. rT2 := entry + d * rUnit * 2.0
  567. rT3 := entry + d * rUnit * 3.0
  568. rSL := entry - d * unit * (2.5 - 0.25 * signalRating)
  569. [c1, c2, c3, cS] = f_sanitize(d, entry, rT1, rT2, rT3, rSL, unit)
  570. trade.dir := d
  571. trade.entry := entry
  572. trade.entryBar := bar_index
  573. trade.tp1 := c1
  574. trade.tp2 := c2
  575. trade.tp3 := c3
  576. trade.sl := autoSL ? cS : na
  577. trade.hit1 := false
  578. trade.hit2 := false
  579. trade.hit3 := false
  580. trade.armed1 := false
  581. trade.armed2 := false
  582. trade.armed3 := false
  583. trade.slHit := false
  584. trade.active := true
  585. trade.maxFav := entry
  586.  
  587. int prevRating = trade.rating
  588. int ratingDelta = 0
  589. if newSignal
  590. trade.rating := signalRating
  591. else if trade.dir != 0 and barstate.isconfirmed
  592. float liveFrac = trade.dir == 1 ? nz(smBullFrac, 0.5) : 1.0 - nz(smBullFrac, 0.5)
  593. int upCand = f_rating(liveFrac - 0.03)
  594. int dnCand = f_rating(liveFrac + 0.03)
  595. if upCand > trade.rating
  596. ratingDelta := upCand - trade.rating
  597. trade.rating := upCand
  598. else if dnCand < trade.rating
  599. ratingDelta := dnCand - trade.rating
  600. trade.rating := dnCand
  601. bool ratingUpgrade = ratingDelta > 0
  602. bool ratingDowngrade = ratingDelta < 0
  603.  
  604. var float waveStart = na
  605. var float waveExt = na
  606. if newSignal
  607. waveStart := trade.dir == 1 ? math.min(nz(swingLowRef, low), low) : math.max(nz(swingHighRef, high), high)
  608. waveExt := trade.dir == 1 ? high : low
  609. else if trade.dir == 1
  610. waveExt := math.max(waveExt, high)
  611. waveStart := math.min(waveStart, low)
  612. else if trade.dir == -1
  613. waveExt := math.min(waveExt, low)
  614. waveStart := math.max(waveStart, high)
  615. float waveRange = math.abs(waveExt - waveStart)
  616. float wave382 = trade.dir == 1 ? waveExt - waveRange * 0.382 : waveExt + waveRange * 0.382
  617. float wave618 = trade.dir == 1 ? waveExt - waveRange * 0.618 : waveExt + waveRange * 0.618
  618. bool waveVisible = showWave and trade.dir != 0 and not newSignal
  619.  
  620. string labelSize = f_size(labelSizeInput)
  621.  
  622. pVbUpIn = plot(showVB ? vbUpIn : na, "Upper Band Inner", color.new(vbUpperColor, 80), 1, editable = false)
  623. pVbUpMid = plot(showVB ? vbUpMid : na, "Upper Band Middle", color.new(vbUpperColor, 85), 1, editable = false)
  624. pVbUpOut = plot(showVB ? vbUpOut : na, "Upper Band Outer", color.new(vbUpperColor, 80), 1, editable = false)
  625. pVbLoIn = plot(showVB ? vbLoIn : na, "Lower Band Inner", color.new(vbLowerColor, 80), 1, editable = false)
  626. pVbLoMid = plot(showVB ? vbLoMid : na, "Lower Band Middle", color.new(vbLowerColor, 85), 1, editable = false)
  627. pVbLoOut = plot(showVB ? vbLoOut : na, "Lower Band Outer", color.new(vbLowerColor, 80), 1, editable = false)
  628. fill(pVbUpIn, pVbUpMid, color.new(vbUpperColor, 86), "Upper Volatility Zone")
  629. fill(pVbUpMid, pVbUpOut, color.new(vbUpperColor, 92), "Upper Volatility Outer Zone")
  630. fill(pVbLoIn, pVbLoMid, color.new(vbLowerColor, 86), "Lower Volatility Zone")
  631. fill(pVbLoMid, pVbLoOut, color.new(vbLowerColor, 92), "Lower Volatility Outer Zone")
  632.  
  633. pBodyMid = plot(barstate.isfirst ? na : (open + close) / 2, "Body Middle", display = display.none, editable = false)
  634. pTrailUp = plot(showTrail and trailDir == 1 ? trailLine : na, "Bullish Trail", bullColor, 2, plot.style_linebr)
  635. pTrailDn = plot(showTrail and trailDir == -1 ? trailLine : na, "Bearish Trail", bearColor, 2, plot.style_linebr)
  636. fill(pBodyMid, pTrailUp, color.new(bullColor, 78), "Bullish Trail Fill")
  637. fill(pBodyMid, pTrailDn, color.new(bearColor, 78), "Bearish Trail Fill")
  638.  
  639. color gaussCol = gaussBull ? bullColor : bearColor
  640. pGaussUp = plot(showGauss ? gaussUp : na, "Gauss Upper", color.new(gaussCol, 50), 1)
  641. pGaussMid = plot(showGauss ? gaussMid : na, "Gauss Ribbon", gaussCol, 2)
  642. pGaussLo = plot(showGauss ? gaussLo : na, "Gauss Lower", color.new(gaussCol, 50), 1)
  643. fill(pGaussUp, pGaussLo, color.new(gaussCol, 88), "Gauss Ribbon Fill")
  644.  
  645. color waveCol = trade.dir == 1 ? bullColor : bearColor
  646. pWave382 = plot(waveVisible ? wave382 : na, "Retracement Wave 0.382", color.new(waveCol, 30), 1, plot.style_linebr)
  647. pWave618 = plot(waveVisible ? wave618 : na, "Retracement Wave 0.618", color.new(waveCol, 30), 1, plot.style_linebr)
  648. fill(pWave382, pWave618, color.new(waveCol, 85), "Retracement Wave Fill")
  649.  
  650. color candleCol = trailDir == 1 ? bullColor : bearColor
  651. color candleWick = trendColorMode == "Bar Color + Wicks" ? candleCol : na
  652. plotcandle(showTrendColor ? open : na, showTrendColor ? high : na, showTrendColor ? low : na, showTrendColor ? close : na, title = "Trend Coloring", color = candleCol, wickcolor = candleWick, bordercolor = candleCol)
  653.  
  654. plotshape(showTPLabel and longTPEvent, "Long Take Profit", shape.xcross, location.abovebar, tpMarkerColor, text = "TP", textcolor = labelTextColor, size = size.small)
  655. plotshape(showTPLabel and shortTPEvent, "Short Take Profit", shape.xcross, location.belowbar, tpMarkerColor, text = "TP", textcolor = labelTextColor, size = size.small)
  656. plotshape(autoSL and slFire and checkDir == 1, "Long Stop Loss", shape.xcross, location.belowbar, slLineColor, text = "SL", textcolor = labelTextColor, size = size.small)
  657. plotshape(autoSL and slFire and checkDir == -1, "Short Stop Loss", shape.xcross, location.abovebar, slLineColor, text = "SL", textcolor = labelTextColor, size = size.small)
  658.  
  659. if buySignal
  660. label.new(bar_index, low, f_signalText(1, trade.rating, showStrength), yloc = yloc.belowbar, style = label.style_label_up, color = bullColor, textcolor = labelTextColor, size = labelSize, tooltip = "SFX Bullish Signal\nRating: " + f_stars(trade.rating) + f_levelDetails(trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, pricePattern))
  661. if sellSignal
  662. label.new(bar_index, high, f_signalText(-1, trade.rating, showStrength), yloc = yloc.abovebar, style = label.style_label_down, color = bearColor, textcolor = labelTextColor, size = labelSize, tooltip = "SFX Bearish Signal\nRating: " + f_stars(trade.rating) + f_levelDetails(trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, pricePattern))
  663.  
  664. if showRatingLabels and ratingDelta != 0 and not newSignal
  665. string rTxt = (ratingDelta > 0 ? "β–² " : "β–Ό ") + str.tostring(trade.rating) + "β˜†"
  666. label.new(bar_index, trade.dir == 1 ? low : high, rTxt, yloc = trade.dir == 1 ? yloc.belowbar : yloc.abovebar, style = trade.dir == 1 ? label.style_label_up : label.style_label_down, color = color.new(trade.dir == 1 ? bullColor : bearColor, 45), textcolor = labelTextColor, size = size.tiny)
  667.  
  668. var array<line> rtLines = array.new<line>()
  669. var array<label> rtLabels = array.new<label>()
  670. var array<int> rtKinds = array.new<int>()
  671. bool rtEnabled = realtimeLines and tpSlMethod == "Key Levels"
  672.  
  673. if newSignal
  674. for ln in rtLines
  675. line.delete(ln)
  676. for lb in rtLabels
  677. label.delete(lb)
  678. rtLines.clear()
  679. rtLabels.clear()
  680. rtKinds.clear()
  681. if rtEnabled
  682. for k = 0 to 3
  683. bool enabled = k == 0 ? (autoSL and not na(trade.sl)) : k == 1 ? tp1On : k == 2 ? tp2On : tp3On
  684. if enabled
  685. float lvl = k == 0 ? trade.sl : k == 1 ? trade.tp1 : k == 2 ? trade.tp2 : trade.tp3
  686. color lc = k == 0 ? slLineColor : tpLineColor
  687. rtLines.push(line.new(bar_index, lvl, bar_index + RT_EXTEND, lvl, color = lc, style = line.style_dashed, width = 1))
  688. rtLabels.push(label.new(bar_index + RT_EXTEND, lvl, f_rtText(k, lvl, false, pricePattern), style = label.style_label_left, color = color.new(color.black, 100), textcolor = lc, size = labelSize))
  689. rtKinds.push(k)
  690.  
  691. if barstate.islast and rtLines.size() > 0
  692. for i = 0 to rtLines.size() - 1
  693. int k = rtKinds.get(i)
  694. float lvl = k == 0 ? trade.sl : k == 1 ? trade.tp1 : k == 2 ? trade.tp2 : trade.tp3
  695. bool done = k == 0 ? trade.slHit : k == 1 ? trade.hit1 : k == 2 ? trade.hit2 : trade.hit3
  696. line.set_x2(rtLines.get(i), bar_index + RT_EXTEND)
  697. label.set_x(rtLabels.get(i), bar_index + RT_EXTEND)
  698. label.set_text(rtLabels.get(i), f_rtText(k, lvl, done, pricePattern))
  699.  
  700. plot(trade.dir != 0 ? trade.rating : na, "Signal Rating", display = display.data_window)
  701. plot(ratingDelta, "Rating Change", display = display.data_window)
  702. plot(buySignal ? 1 : 0, "Bullish Signal", display = display.data_window)
  703. plot(sellSignal ? 1 : 0, "Bearish Signal", display = display.data_window)
  704. plot(effSensitivity, "Active Sensitivity", display = display.data_window)
  705.  
  706. string tblSize = f_size(tableSizeInput)
  707. color tblBg = color.new(#131722, 5)
  708. color tblCell = color.new(#1e222d, 0)
  709. color tblHead = color.new(#2a2e39, 0)
  710. color tblLine = color.new(#363a45, 0)
  711.  
  712. var table ratingTable = na
  713. var table trendTable = na
  714. if showRatingDash and na(ratingTable)
  715. ratingTable := table.new(f_position(ratingDashPos), 2, 4, bgcolor = tblBg, frame_color = tblLine, frame_width = 1, border_color = tblLine, border_width = 1)
  716. if showTrendDash and na(trendTable)
  717. trendTable := table.new(f_position(trendDashPos), 2, 8, bgcolor = tblBg, frame_color = tblLine, frame_width = 1, border_color = tblLine, border_width = 1)
  718.  
  719. if barstate.islast
  720. if not na(ratingTable)
  721. color dirCol = trade.dir == 1 ? bullColor : trade.dir == -1 ? bearColor : color.gray
  722. table.cell(ratingTable, 0, 0, "SFX Algo", text_color = labelTextColor, text_size = tblSize, bgcolor = dirCol)
  723. table.cell(ratingTable, 1, 0, "Signal Rating", text_color = labelTextColor, text_size = tblSize, bgcolor = dirCol)
  724. table.cell(ratingTable, 0, 1, "Signal", text_color = labelTextColor, text_size = tblSize, bgcolor = tblCell, text_halign = text.align_left)
  725. table.cell(ratingTable, 1, 1, trade.dir == 1 ? "Bullish" : trade.dir == -1 ? "Bearish" : "Neutral", text_color = labelTextColor, text_size = tblSize, bgcolor = color.new(dirCol, 35))
  726. table.cell(ratingTable, 0, 2, "Rating", text_color = labelTextColor, text_size = tblSize, bgcolor = tblCell, text_halign = text.align_left)
  727. table.cell(ratingTable, 1, 2, trade.dir != 0 ? f_stars(trade.rating) : "-", text_color = labelTextColor, text_size = tblSize, bgcolor = color.new(dirCol, 35))
  728. table.cell(ratingTable, 0, 3, "Sensitivity", text_color = labelTextColor, text_size = tblSize, bgcolor = tblCell, text_halign = text.align_left)
  729. table.cell(ratingTable, 1, 3, str.tostring(effSensitivity, "#") + (aiOptimizer ? " (AI)" : ""), text_color = labelTextColor, text_size = tblSize, bgcolor = color.new(dirCol, 35))
  730. if not na(trendTable)
  731. table.cell(trendTable, 0, 0, "Timeframe", text_color = labelTextColor, text_size = tblSize, bgcolor = tblHead)
  732. table.cell(trendTable, 1, 0, "SFX Sentiment", text_color = labelTextColor, text_size = tblSize, bgcolor = tblHead)
  733. array<string> tfNames = array.from("3 Minute", "15 Minute", "30 Minute", "1 Hour", "4 Hour", "1 Day", "1 Week")
  734. array<int> tfStates = array.from(mtf3S, mtf15S, mtf30S, mtf60S, mtf240S, mtfDS, mtfWS)
  735. for i = 0 to 6
  736. int st = tfStates.get(i)
  737. color stCol = st == 1 ? bullColor : st == -1 ? bearColor : color.gray
  738. table.cell(trendTable, 0, i + 1, tfNames.get(i), text_color = labelTextColor, text_size = tblSize, bgcolor = tblCell, text_halign = text.align_left)
  739. table.cell(trendTable, 1, i + 1, st == 1 ? "Bullish" : st == -1 ? "Bearish" : "Neutral", text_color = labelTextColor, text_size = tblSize, bgcolor = color.new(stCol, 25))
  740.  
  741. float alertPrice = nz(realClose, close)
  742.  
  743. if buySignal and alertBuy
  744. alert(webhookOn ? f_webhookJson("buy", "Bullish Signal", 1, alertPrice, trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, "") : f_plainMsg("Bullish Signal", alertPrice, f_levelDetails(trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, pricePattern), pricePattern), alert.freq_once_per_bar_close)
  745. if sellSignal and alertSell
  746. alert(webhookOn ? f_webhookJson("sell", "Bearish Signal", -1, alertPrice, trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, "") : f_plainMsg("Bearish Signal", alertPrice, f_levelDetails(trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, pricePattern), pricePattern), alert.freq_once_per_bar_close)
  747.  
  748. if alertTP and tp1Event
  749. alert(f_tpAlert(1, checkDir, chkT1, tp1Retest and not tp1Fire, webhookOn, alertPrice, chkRate, chkT1, chkT2, chkT3, chkSL, pricePattern), alert.freq_once_per_bar_close)
  750. if alertTP and tp2Event
  751. alert(f_tpAlert(2, checkDir, chkT2, tp2Retest and not tp2Fire, webhookOn, alertPrice, chkRate, chkT1, chkT2, chkT3, chkSL, pricePattern), alert.freq_once_per_bar_close)
  752. if alertTP and tp3Event
  753. alert(f_tpAlert(3, checkDir, chkT3, tp3Retest and not tp3Fire, webhookOn, alertPrice, chkRate, chkT1, chkT2, chkT3, chkSL, pricePattern), alert.freq_once_per_bar_close)
  754.  
  755. if alertSL and slFire
  756. string slEvt = "Stop Loss" + (checkDir == 1 ? " (Bullish)" : " (Bearish)")
  757. alert(webhookOn ? f_webhookJson("stop_loss", "Stop Loss", checkDir, alertPrice, chkRate, chkT1, chkT2, chkT3, chkSL, ',"sl_price":' + f_num(chkSL)) : f_plainMsg(slEvt, alertPrice, " | Level: " + f_fmt(chkSL, pricePattern), pricePattern), alert.freq_once_per_bar_close)
  758.  
  759. if ratingUpgrade and alertUpgrade
  760. string upEvt = "Rating Upgrade (" + (trade.dir == 1 ? "Bullish" : "Bearish") + ")"
  761. alert(webhookOn ? f_webhookJson("rating_upgrade", upEvt, trade.dir, alertPrice, trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, ',"previous_rating":' + str.tostring(prevRating)) : f_plainMsg(upEvt, alertPrice, " | " + str.tostring(prevRating) + "β˜† β†’ " + str.tostring(trade.rating) + "β˜†", pricePattern), alert.freq_once_per_bar_close)
  762. if ratingDowngrade and alertDowngrade
  763. string dnEvt = "Rating Downgrade (" + (trade.dir == 1 ? "Bullish" : "Bearish") + ")"
  764. alert(webhookOn ? f_webhookJson("rating_downgrade", dnEvt, trade.dir, alertPrice, trade.rating, trade.tp1, trade.tp2, trade.tp3, trade.sl, ',"previous_rating":' + str.tostring(prevRating)) : f_plainMsg(dnEvt, alertPrice, " | " + str.tostring(prevRating) + "β˜† β†’ " + str.tostring(trade.rating) + "β˜†", pricePattern), alert.freq_once_per_bar_close)
Advertisement
Add Comment
Please, Sign In to add comment