ajiim

🎁

Oct 14th, 2026
1,228
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 44.80 KB | None | 1 0
  1. //@version=6
  2. indicator("Ocs Ai Trader", shorttitle = "Ocs Ai Trader", overlay = true, max_bars_back = 500, max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500)
  3.  
  4. const string GRP_GEN = "General Settings"
  5. const string GRP_TSP = "Time Series Processing Layer"
  6. const string GRP_SPL = "Signal Processing Layer"
  7. const string GRP_FLT = "Filters"
  8. const string GRP_ML = "Machine Learning (KNN)"
  9. const string GRP_GAU = "Gaussian Structure"
  10. const string GRP_VTE = "Virtual Trade Emulator"
  11. const string GRP_SR = "Support & Resistance"
  12. const string GRP_DSP = "Display"
  13. const string GRP_TBL = "Backtesting Compiler (Stats Table)"
  14. const string GRP_COL = "Colors"
  15.  
  16. const string TXT_TINY = "Tiny"
  17. const string TXT_SMALL = "Small"
  18. const string TXT_NORMAL = "Normal"
  19. const string TXT_LARGE = "Large"
  20. const string HIT_BOOKED = "✓Booked"
  21. const string HIT_PLAIN = "Hit"
  22.  
  23. i_confirmBar = input.bool(true, "Show Trade Signal only when bar is confirmed", group = GRP_GEN, tooltip = "When enabled, signals are produced on bar close only (no repaint).")
  24. i_isPremium = input.bool(true, "Is your TradingView Subscription Premium and above ?", group = GRP_GEN, tooltip = "Premium plans can read second based intrabar data for a precise Volume Delta. If your plan is not Premium, UNCHECK this option.")
  25. i_ltf = input.timeframe("1", "Lower Timeframe to use if TradingView Subscription is not premium !", group = GRP_GEN, tooltip = "Lower timeframe used for the Volume Delta when the Premium option is unchecked. Ignored if it is not lower than the chart timeframe.")
  26. i_textSize = input.string(TXT_SMALL, "Text Size :", options = [TXT_TINY, TXT_SMALL, TXT_NORMAL, TXT_LARGE], group = GRP_GEN)
  27. i_sensitivity = input.float(1.0, "Signal Sensitivity", minval = 0.1, maxval = 5.0, step = 0.1, group = GRP_GEN, tooltip = "Exponential Probability Squeeze factor. Higher values produce more decisive probabilities and more signals.")
  28. i_alertPass = input.string("", "Alert Passcode", group = GRP_GEN, tooltip = "Optional passcode appended to every alert() message (useful for webhook authentication).")
  29.  
  30. i_dcMin = input.int(8, "Dominant Cycle Period Min", minval = 4, maxval = 50, group = GRP_TSP, inline = "dc")
  31. i_dcMax = input.int(48, "Max", minval = 10, maxval = 100, group = GRP_TSP, inline = "dc", tooltip = "Bounds of the Ehlers Homodyne Dominant Cycle. The detected cycle is used as the dynamic length of the adaptive calculations.")
  32. i_amaFast = input.int(2, "Adaptive Moving Average Fast", minval = 1, group = GRP_TSP, inline = "ama")
  33. i_amaSlow = input.int(30, "Slow", minval = 2, group = GRP_TSP, inline = "ama")
  34. i_stFactor = input.float(3.0, "Supertrend Factor", minval = 0.5, step = 0.1, group = GRP_TSP, inline = "st")
  35. i_stAtrLen = input.int(10, "ATR", minval = 1, group = GRP_TSP, inline = "st")
  36. i_stochLen = input.int(14, "Relative Strength Stochastics Length", minval = 2, group = GRP_TSP, inline = "sto")
  37. i_stochSmooth = input.int(3, "Smooth", minval = 1, group = GRP_TSP, inline = "sto")
  38. i_cvdLen = input.int(21, "Cumulative Volume Delta Length", minval = 2, group = GRP_TSP)
  39. i_trixLen = input.int(14, "TRIX Length", minval = 2, group = GRP_TSP, inline = "trix")
  40. i_trixSig = input.int(9, "Signal", minval = 1, group = GRP_TSP, inline = "trix")
  41.  
  42. i_conf = input.float(0.60, "Probability Distribution Confidence", minval = 0.50, maxval = 0.95, step = 0.01, group = GRP_SPL, tooltip = "Minimum bullish probability for long intents (and maximum for short intents = 1 - value).")
  43. i_probAvg = input.int(3, "Probability Average Length", minval = 1, maxval = 20, group = GRP_SPL)
  44. i_probVarMax = input.float(0.30, "Probability Variable Filter (Max StDev)", minval = 0.01, maxval = 1.0, step = 0.01, group = GRP_SPL)
  45. i_lmsLen = input.int(16, "Adaptive LMS Filter Order", minval = 2, maxval = 64, group = GRP_SPL, inline = "lms")
  46. i_lmsMu = input.float(0.05, "Step (mu)", minval = 0.001, maxval = 1.0, step = 0.001, group = GRP_SPL, inline = "lms")
  47. i_fisherTol = input.float(0.25, "Fisher Transform Tolerance", minval = 0.0, maxval = 3.0, step = 0.05, group = GRP_SPL)
  48. i_qrLen = input.int(20, "Quadratic Regression / Trimean Length", minval = 5, maxval = 200, group = GRP_SPL)
  49. i_useCvdDiv = input.bool(true, "CVD Divergence Signal Structure", group = GRP_SPL, inline = "div")
  50. i_divLen = input.int(14, "Lookback", minval = 3, group = GRP_SPL, inline = "div")
  51.  
  52. i_useRegime = input.bool(true, "Regime Filter", group = GRP_FLT, inline = "reg")
  53. i_regimeThr = input.float(-0.1, "Threshold", minval = -10.0, maxval = 10.0, step = 0.1, group = GRP_FLT, inline = "reg")
  54. i_useVolFilter = input.bool(true, "Volatility Probability Filter", group = GRP_FLT)
  55. i_useAtrImpulse = input.bool(true, "Impulsive ATR Filter", group = GRP_FLT, inline = "imp")
  56. i_atrImpMult = input.float(0.75, "Multiplier", minval = 0.1, step = 0.05, group = GRP_FLT, inline = "imp")
  57. i_useVolDeriv = input.bool(true, "Volatility Derivative Filter (Elder)", group = GRP_FLT, inline = "vd")
  58. i_volDerivTol = input.float(0.15, "Tolerance", minval = 0.0, step = 0.01, group = GRP_FLT, inline = "vd")
  59. i_useTrix = input.bool(true, "TRIX Strength / Weakness Analyser", group = GRP_FLT)
  60. i_useCvd = input.bool(true, "Cumulative Volume Delta Regime Filter", group = GRP_FLT)
  61. i_useMarubozu = input.bool(true, "Marubozu Abnormality Detection", group = GRP_FLT, inline = "maru")
  62. i_maruBody = input.float(0.85, "Body Ratio", minval = 0.5, maxval = 1.0, step = 0.01, group = GRP_FLT, inline = "maru")
  63.  
  64. i_useKnn = input.bool(true, "K-Nearest Neighbour Classification", group = GRP_ML)
  65. i_knnK = input.int(8, "Neighbours (K)", minval = 1, maxval = 50, group = GRP_ML)
  66. i_knnWindow = input.int(1000, "Training Window (Samples)", minval = 50, maxval = 5000, group = GRP_ML)
  67. i_knnStride = input.int(4, "Sampling Stride", minval = 1, maxval = 20, group = GRP_ML)
  68. i_knnHorizon = input.int(4, "Prediction Horizon (Bars)", minval = 1, maxval = 50, group = GRP_ML)
  69. i_knnWeight = input.float(0.50, "KNN Weight in Final Probability", minval = 0.0, maxval = 1.0, step = 0.05, group = GRP_ML)
  70.  
  71. i_gaussAdaptive = input.bool(true, "Adaptive Length (Dominant Cycle)", group = GRP_GAU)
  72. i_gaussLen = input.int(21, "Gaussian Length", minval = 2, group = GRP_GAU, inline = "gau")
  73. i_gaussPoles = input.int(4, "Poles", minval = 1, maxval = 4, group = GRP_GAU, inline = "gau")
  74. i_gaussMult = input.float(1.5, "Band ATR Multiplier", minval = 0.1, step = 0.1, group = GRP_GAU)
  75. i_baseLen = input.int(144, "Gaussian Baseline Length", minval = 10, group = GRP_GAU)
  76.  
  77. i_atrLenTrade = input.int(14, "ATR Length", minval = 1, group = GRP_VTE)
  78. i_tMult = input.float(1.0, "Target Step (ATR)", minval = 0.1, step = 0.05, group = GRP_VTE)
  79. i_stopMult = input.float(2.25, "Stop Distance (ATR)", minval = 0.1, step = 0.05, group = GRP_VTE)
  80. i_showT45 = input.bool(false, "Dynamic Target 4 & Target 5", group = GRP_VTE)
  81. i_recoveryBars = input.int(10, "Recovery Window (Bars)", minval = 0, maxval = 100, group = GRP_VTE, tooltip = "After the stop is touched, a trade that still reaches T1 within this window is counted as a T1 Win (With Recoveries).")
  82. i_labelOffset = input.int(4, "Levels Label Offset (Bars)", minval = 1, maxval = 100, group = GRP_VTE, tooltip = "Distance, in bars, between the last bar and the level labels.")
  83. i_hitStyle = input.string(HIT_BOOKED, "Target Hit Text", options = [HIT_BOOKED, HIT_PLAIN], group = GRP_VTE)
  84.  
  85. i_showVolSR = input.bool(true, "Volume Float Support & Resistance", group = GRP_SR)
  86. i_srPivotLen = input.int(10, "Pivot Length", minval = 2, group = GRP_SR, inline = "vsr")
  87. i_srVolMult = input.float(1.2, "Volume Multiplier", minval = 0.1, step = 0.1, group = GRP_SR, inline = "vsr")
  88. i_srMaxBars = input.int(60, "Max Extension (Bars)", minval = 5, maxval = 500, group = GRP_SR)
  89. i_showPivots = input.bool(true, "Pivotal Points & Lines", group = GRP_SR)
  90. i_pivLen = input.int(20, "Pivot Length", minval = 2, group = GRP_SR, inline = "piv")
  91. i_pivMaxBars = input.int(50, "Max Extension (Bars)", minval = 5, maxval = 500, group = GRP_SR, inline = "piv")
  92. i_maxZones = input.int(20, "Max Zones Kept On Chart", minval = 2, maxval = 100, group = GRP_SR)
  93.  
  94. i_showBand = input.bool(true, "Gaussian Trend Band", group = GRP_DSP, inline = "band")
  95. i_bandWidth = input.int(10, "Thickness", minval = 1, maxval = 30, group = GRP_DSP, inline = "band")
  96. i_showBaseline = input.bool(true, "Gaussian Baseline", group = GRP_DSP)
  97. i_showDots = input.bool(true, "Probability Triangles", group = GRP_DSP)
  98. i_showBarColor = input.bool(true, "Colour Signal Candles", group = GRP_DSP)
  99. i_showHistory = input.bool(false, "Historical Buy Sell Positions by Algo", group = GRP_DSP)
  100. i_showLevels = input.bool(true, "Targets, Strength & Stop Levels", group = GRP_DSP)
  101.  
  102. i_showTable = input.bool(true, "Show Stats Table", group = GRP_TBL)
  103. i_tablePos = input.string("Bottom Left", "Position", options = ["Top Left", "Top Center", "Top Right", "Middle Left", "Middle Right", "Bottom Left", "Bottom Center", "Bottom Right"], group = GRP_TBL, inline = "tbl")
  104. i_tableSize = input.string(TXT_TINY, "Size", options = [TXT_TINY, TXT_SMALL, TXT_NORMAL, TXT_LARGE], group = GRP_TBL, inline = "tbl")
  105.  
  106. i_colBandBull = input.color(color.new(#4caf50, 82), "Trend Band Bull", group = GRP_COL, inline = "c1")
  107. i_colBandBear = input.color(color.new(#f23645, 82), "Bear", group = GRP_COL, inline = "c1")
  108. i_colDotBull = input.color(color.new(#81c784, 30), "Triangles Bull", group = GRP_COL, inline = "c2")
  109. i_colDotBear = input.color(color.new(#ef9a9a, 20), "Bear", group = GRP_COL, inline = "c2")
  110. i_colDotNeut = input.color(color.new(#9598a1, 25), "Triangles Neutral", group = GRP_COL, inline = "c2b")
  111. i_colDotWarn = input.color(color.new(#ffb74d, 10), "Caution", group = GRP_COL, inline = "c2b")
  112. i_colBaseline = input.color(color.new(#a5d6a7, 40), "Gaussian Baseline", group = GRP_COL)
  113. i_colBuyBar = input.color(#7ee8c4, "Signal Candle Buy", group = GRP_COL, inline = "c3")
  114. i_colSellBar = input.color(#f4a6d7, "Sell", group = GRP_COL, inline = "c3")
  115. i_colBuyTgt = input.color(#2962ff, "Buy Targets Text", group = GRP_COL, inline = "b1")
  116. i_colBuyTgtBg = input.color(color.new(#2962ff, 90), "Bg", group = GRP_COL, inline = "b1")
  117. i_colBuyTgtLn = input.color(color.new(#4caf50, 30), "Line", group = GRP_COL, inline = "b1")
  118. i_colBuyEnt = input.color(#089981, "Buy Strength Text", group = GRP_COL, inline = "b2")
  119. i_colBuyEntBg = input.color(color.new(#4caf50, 88), "Bg", group = GRP_COL, inline = "b2")
  120. i_colBuyEntLn = input.color(#2e9d4a, "Line", group = GRP_COL, inline = "b2")
  121. i_colBuyStp = input.color(#f23645, "Buy Stop Text", group = GRP_COL, inline = "b3")
  122. i_colBuyStpBg = input.color(color.new(#f7525f, 88), "Bg", group = GRP_COL, inline = "b3")
  123. i_colBuyStpLn = input.color(color.new(#f23645, 30), "Line", group = GRP_COL, inline = "b3")
  124. i_colSellTgt = input.color(#f23645, "Sell Targets Text", group = GRP_COL, inline = "s1")
  125. i_colSellTgtBg = input.color(color.new(#f23645, 90), "Bg", group = GRP_COL, inline = "s1")
  126. i_colSellTgtLn = input.color(color.new(#f23645, 30), "Line", group = GRP_COL, inline = "s1")
  127. i_colSellEnt = input.color(#f23645, "Sell Weakness Text", group = GRP_COL, inline = "s2")
  128. i_colSellEntBg = input.color(color.new(#ff9800, 85), "Bg", group = GRP_COL, inline = "s2")
  129. i_colSellEntLn = input.color(#f23645, "Line", group = GRP_COL, inline = "s2")
  130. i_colSellStp = input.color(#2962ff, "Sell Stop Text", group = GRP_COL, inline = "s3")
  131. i_colSellStpBg = input.color(color.new(#4caf50, 88), "Bg", group = GRP_COL, inline = "s3")
  132. i_colSellStpLn = input.color(color.new(#2962ff, 30), "Line", group = GRP_COL, inline = "s3")
  133. i_colBrand = input.color(#f7525f, "Brand Text", group = GRP_COL, inline = "c7")
  134. i_colBrandBg = input.color(color.new(#ff9800, 88), "Background", group = GRP_COL, inline = "c7")
  135. i_colVolZone = input.color(color.new(#787b86, 85), "Volume Float Zones", group = GRP_COL)
  136. i_colPivZone = input.color(color.new(#2196f3, 85), "Pivotal Zones", group = GRP_COL)
  137. i_colLong = input.color(#089981, "Stats Long", group = GRP_COL, inline = "c8")
  138. i_colShort = input.color(#f23645, "Short", group = GRP_COL, inline = "c8")
  139. i_colTblBg = input.color(#ffffff, "Table Background", group = GRP_COL, inline = "c9")
  140. i_colTblText = input.color(#1e3a8a, "Text", group = GRP_COL, inline = "c9")
  141. i_colTblBorder = input.color(#b2b5be, "Border", group = GRP_COL, inline = "c9")
  142.  
  143. const string VERSION_TXT = "Ocs AI ML V.312"
  144. const string BRAND_TXT = "Ocs Ai Trader"
  145. const string RECOVERY_TXT = "(With Recoveries)"
  146. const float EPS = 1e-10
  147. const int WARMUP_MULT = 2
  148. const float ZONE_MIN_ATR = 0.25
  149. const float PIV_ZONE_ATR = 0.50
  150. const float BRAND_GAP = 0.60
  151. const string ARROW_UP = "▲ "
  152. const string ARROW_DN = "▼ "
  153. const string WARN_ICON = "⚠ "
  154. const color TXT_DARK = #131722
  155.  
  156. type TradeState
  157. int dir = 0
  158. int sigBar = 0
  159. float trigger = na
  160. float stop = na
  161. float t1 = na
  162. float t2 = na
  163. float t3 = na
  164. float t4 = na
  165. float t5 = na
  166. bool triggered = false
  167. bool t1Hit = false
  168. bool t2Hit = false
  169. bool t3Hit = false
  170. bool t4Hit = false
  171. bool t5Hit = false
  172. bool stopHit = false
  173. int stopBar = na
  174. bool closed = false
  175.  
  176. type Stats
  177. int longTotal = 0
  178. int shortTotal = 0
  179. int longWins = 0
  180. int shortWins = 0
  181.  
  182. type Zone
  183. box bx
  184. float top
  185. float bottom
  186. int dir
  187. int startBar
  188. bool active = true
  189.  
  190. f_tanh(float x) =>
  191. float xc = math.max(math.min(nz(x), 20.0), -20.0)
  192. float e2 = math.exp(2.0 * xc)
  193. (e2 - 1.0) / (e2 + 1.0)
  194.  
  195. f_smooth(float src, float alpha) =>
  196. float s = na
  197. s := na(s[1]) ? src : alpha * src + (1.0 - alpha) * s[1]
  198. s
  199.  
  200. f_rma(float src, float len) =>
  201. f_smooth(src, 1.0 / math.max(len, 1.0))
  202.  
  203. f_rsi(float src, int len) =>
  204. float chg = src - nz(src[1], src)
  205. float up = f_rma(math.max(chg, 0.0), len)
  206. float dn = f_rma(math.max(-chg, 0.0), len)
  207. dn <= EPS ? 100.0 : up <= EPS ? 0.0 : 100.0 - 100.0 / (1.0 + up / dn)
  208.  
  209. f_normalize(float src, float lo, float hi) =>
  210. var float hMin = 1e10
  211. var float hMax = -1e10
  212. hMin := math.min(nz(src, hMin), hMin)
  213. hMax := math.max(nz(src, hMax), hMax)
  214. lo + (hi - lo) * (nz(src) - hMin) / math.max(hMax - hMin, EPS)
  215.  
  216. f_vwma(float src, float vol, int len) =>
  217. float den = math.sum(vol, len)
  218. den > EPS ? math.sum(src * vol, len) / den : src
  219.  
  220. f_kama(float src, int len, int fastLen, int slowLen) =>
  221. float change = math.abs(src - nz(src[len], src))
  222. float noise = math.sum(math.abs(src - nz(src[1], src)), len)
  223. float er = noise > EPS ? change / noise : 0.0
  224. float fastSc = 2.0 / (fastLen + 1.0)
  225. float slowSc = 2.0 / (slowLen + 1.0)
  226. float sc = math.pow(er * (fastSc - slowSc) + slowSc, 2)
  227. float k = na
  228. k := na(k[1]) ? src : k[1] + sc * (src - k[1])
  229. k
  230.  
  231. f_dominantCycle(float src, int minP, int maxP) =>
  232. float period = 0.0
  233. float smoothP = 0.0
  234. float i2 = 0.0
  235. float q2 = 0.0
  236. float re = 0.0
  237. float im = 0.0
  238. float prevPeriod = nz(period[1], 15.0)
  239. float smooth = (4.0 * src + 3.0 * nz(src[1], src) + 2.0 * nz(src[2], src) + nz(src[3], src)) / 10.0
  240. float adj = 0.075 * prevPeriod + 0.54
  241. float detrender = (0.0962 * smooth + 0.5769 * nz(smooth[2]) - 0.5769 * nz(smooth[4]) - 0.0962 * nz(smooth[6])) * adj
  242. float q1 = (0.0962 * detrender + 0.5769 * nz(detrender[2]) - 0.5769 * nz(detrender[4]) - 0.0962 * nz(detrender[6])) * adj
  243. float i1 = nz(detrender[3])
  244. float jI = (0.0962 * i1 + 0.5769 * nz(i1[2]) - 0.5769 * nz(i1[4]) - 0.0962 * nz(i1[6])) * adj
  245. float jQ = (0.0962 * q1 + 0.5769 * nz(q1[2]) - 0.5769 * nz(q1[4]) - 0.0962 * nz(q1[6])) * adj
  246. i2 := 0.2 * (i1 - jQ) + 0.8 * nz(i2[1])
  247. q2 := 0.2 * (q1 + jI) + 0.8 * nz(q2[1])
  248. re := 0.2 * (i2 * nz(i2[1]) + q2 * nz(q2[1])) + 0.8 * nz(re[1])
  249. im := 0.2 * (i2 * nz(q2[1]) - q2 * nz(i2[1])) + 0.8 * nz(im[1])
  250. float p = im != 0.0 and re != 0.0 ? 2.0 * math.pi / math.atan(im / re) : prevPeriod
  251. p := math.min(p, 1.5 * prevPeriod)
  252. p := math.max(p, 0.67 * prevPeriod)
  253. p := math.max(math.min(p, maxP), minP)
  254. period := 0.2 * p + 0.8 * prevPeriod
  255. smoothP := 0.33 * period + 0.67 * nz(smoothP[1], period)
  256. smoothP
  257.  
  258. f_gaussian(float src, float len, int poles) =>
  259. float beta = (1.0 - math.cos(2.0 * math.pi / math.max(len, 2.0))) / (math.pow(2.0, 1.0 / poles) - 1.0)
  260. float alpha = -beta + math.sqrt(beta * beta + 2.0 * beta)
  261. float x = 1.0 - alpha
  262. float f = na
  263. float f1 = nz(f[1], src)
  264. float f2 = nz(f[2], f1)
  265. float f3 = nz(f[3], f2)
  266. float f4 = nz(f[4], f3)
  267. f := switch poles
  268. 1 => alpha * src + x * f1
  269. 2 => math.pow(alpha, 2) * src + 2.0 * x * f1 - math.pow(x, 2) * f2
  270. 3 => math.pow(alpha, 3) * src + 3.0 * x * f1 - 3.0 * math.pow(x, 2) * f2 + math.pow(x, 3) * f3
  271. => math.pow(alpha, 4) * src + 4.0 * x * f1 - 6.0 * math.pow(x, 2) * f2 + 4.0 * math.pow(x, 3) * f3 - math.pow(x, 4) * f4
  272. f
  273.  
  274. f_trailBand(float base, float atrv, float mult, float src) =>
  275. float a = nz(atrv, high - low)
  276. float upRaw = base - mult * a
  277. float dnRaw = base + mult * a
  278. float upT = na
  279. float dnT = na
  280. int dir = 1
  281. float upPrev = nz(upT[1], upRaw)
  282. float dnPrev = nz(dnT[1], dnRaw)
  283. upT := nz(src[1], src) > upPrev ? math.max(upRaw, upPrev) : upRaw
  284. dnT := nz(src[1], src) < dnPrev ? math.min(dnRaw, dnPrev) : dnRaw
  285. int prevDir = nz(dir[1], 1)
  286. dir := prevDir == -1 and src > dnPrev ? 1 : prevDir == 1 and src < upPrev ? -1 : prevDir
  287. float trail = dir == 1 ? upT : dnT
  288. [trail, dir]
  289.  
  290. f_fisher(float src, int len) =>
  291. float hh = ta.highest(src, len)
  292. float ll = ta.lowest(src, len)
  293. float rng = hh - ll
  294. float v = 0.0
  295. v := 0.66 * (rng > EPS ? (src - ll) / rng - 0.5 : 0.0) + 0.67 * nz(v[1])
  296. v := math.max(math.min(v, 0.999), -0.999)
  297. float fish = 0.0
  298. fish := 0.5 * math.log((1.0 + v) / (1.0 - v)) + 0.5 * nz(fish[1])
  299. fish
  300.  
  301. f_lmsPredict(float src, simple int len, float mu) =>
  302. var array<float> w = array.new_float(len, 0.0)
  303. float pred = 0.0
  304. float energy = EPS
  305. for i = 0 to len - 1
  306. float xi = nz(src[i + 1])
  307. pred += w.get(i) * xi
  308. energy += xi * xi
  309. float err = nz(src) - pred
  310. for i = 0 to len - 1
  311. w.set(i, w.get(i) + mu * err * nz(src[i + 1]) / energy)
  312. float nxt = 0.0
  313. for i = 0 to len - 1
  314. nxt += w.get(i) * nz(src[i])
  315. nxt
  316.  
  317. f_quadReg(float src, simple int n) =>
  318. float sx = 0.0
  319. float sx2 = 0.0
  320. float sx3 = 0.0
  321. float sx4 = 0.0
  322. float sy = 0.0
  323. float sxy = 0.0
  324. float sx2y = 0.0
  325. for i = 0 to n - 1
  326. float x = n - 1.0 - i
  327. float y = nz(src[i], src)
  328. sx += x
  329. sx2 += x * x
  330. sx3 += x * x * x
  331. sx4 += x * x * x * x
  332. sy += y
  333. sxy += x * y
  334. sx2y += x * x * y
  335. float det = n * (sx2 * sx4 - sx3 * sx3) - sx * (sx * sx4 - sx3 * sx2) + sx2 * (sx * sx3 - sx2 * sx2)
  336. float a = src
  337. float b = 0.0
  338. float c = 0.0
  339. if math.abs(det) > EPS
  340. a := (sy * (sx2 * sx4 - sx3 * sx3) - sx * (sxy * sx4 - sx3 * sx2y) + sx2 * (sxy * sx3 - sx2 * sx2y)) / det
  341. b := (n * (sxy * sx4 - sx3 * sx2y) - sy * (sx * sx4 - sx3 * sx2) + sx2 * (sx * sx2y - sxy * sx2)) / det
  342. c := (n * (sx2 * sx2y - sxy * sx3) - sx * (sx * sx2y - sxy * sx2) + sy * (sx * sx3 - sx2 * sx2)) / det
  343. float xn = n - 1.0
  344. [a + b * xn + c * xn * xn, b + 2.0 * c * xn]
  345.  
  346. f_trimean(float src, int len) =>
  347. float q1 = ta.percentile_linear_interpolation(src, len, 25)
  348. float q2 = ta.median(src, len)
  349. float q3 = ta.percentile_linear_interpolation(src, len, 75)
  350. (q1 + 2.0 * q2 + q3) / 4.0
  351.  
  352. f_regimeFilter(float src, float threshold) =>
  353. float value1 = 0.0
  354. float value2 = 0.0
  355. float klmf = 0.0
  356. value1 := 0.2 * (src - nz(src[1], src)) + 0.8 * nz(value1[1])
  357. value2 := 0.1 * (high - low) + 0.8 * nz(value2[1])
  358. float omega = value2 != 0.0 ? math.abs(value1 / value2) : 0.0
  359. float alpha = (-omega * omega + math.sqrt(math.pow(omega, 4) + 16.0 * math.pow(omega, 2))) / 8.0
  360. klmf := alpha * src + (1.0 - alpha) * nz(klmf[1], src)
  361. float absSlope = math.abs(klmf - nz(klmf[1], klmf))
  362. float avgSlope = nz(ta.ema(absSlope, 200))
  363. float normDecline = avgSlope != 0.0 ? (absSlope - avgSlope) / avgSlope : 0.0
  364. normDecline >= threshold
  365.  
  366. f_knnPredict(array<float> a1, array<float> a2, array<float> a3, array<float> a4, array<float> a5, array<int> lbl, float q1, float q2, float q3, float q4, float q5, int k, int stride) =>
  367. array<float> dists = array.new_float()
  368. array<int> votes = array.new_int()
  369. int n = lbl.size()
  370. if n > 0
  371. for i = 0 to n - 1 by stride
  372. float d = math.log(1.0 + math.abs(a1.get(i) - q1)) + math.log(1.0 + math.abs(a2.get(i) - q2)) + math.log(1.0 + math.abs(a3.get(i) - q3)) + math.log(1.0 + math.abs(a4.get(i) - q4)) + math.log(1.0 + math.abs(a5.get(i) - q5))
  373. int sz = dists.size()
  374. bool accept = sz < k
  375. if not accept
  376. accept := d < dists.get(sz - 1)
  377. if accept
  378. int pos = 0
  379. while pos < sz
  380. if dists.get(pos) > d
  381. break
  382. pos += 1
  383. dists.insert(pos, d)
  384. votes.insert(pos, lbl.get(i))
  385. if dists.size() > k
  386. dists.pop()
  387. votes.pop()
  388. float s = 0.0
  389. for v in votes
  390. s += v
  391. votes.size() > 0 ? s / votes.size() : 0.0
  392.  
  393. f_reached(int dir, float lvl) =>
  394. dir == 1 ? high >= lvl : low <= lvl
  395.  
  396. f_stopped(int dir, float lvl) =>
  397. dir == 1 ? low <= lvl : high >= lvl
  398.  
  399. f_updateZones(array<Zone> zones, int maxBars) =>
  400. for z in zones
  401. if z.active
  402. z.bx.set_right(bar_index)
  403. bool broken = z.dir == 1 ? close < z.bottom : close > z.top
  404. if broken or bar_index - z.startBar >= maxBars
  405. z.active := false
  406. zones.size()
  407.  
  408. f_addZone(array<Zone> zones, Zone z, int maxKeep) =>
  409. zones.push(z)
  410. if zones.size() > maxKeep
  411. Zone old = zones.shift()
  412. old.bx.delete()
  413. zones.size()
  414.  
  415. f_drawLevel(array<line> lns, array<label> lbs, int x1, int x2, float y, color lineCol, string lineStyle, int width, string txt, color txtCol, color bgCol, string txtSize, bool bold) =>
  416. lns.push(line.new(x1, y, x2, y, xloc = xloc.bar_index, color = lineCol, style = lineStyle, width = width))
  417. label lb = label.new(x2, y, txt, xloc = xloc.bar_index, color = bgCol, style = label.style_label_left, textcolor = txtCol, size = txtSize, textalign = text.align_left)
  418. if bold
  419. lb.set_text_formatting(text.format_bold)
  420. lbs.push(lb)
  421. lns.size()
  422.  
  423. f_fmt(float v) =>
  424. str.tostring(v, format.mintick)
  425.  
  426. f_targetText(int dir, string name, float lvl, bool hit) =>
  427. string arrow = hit or dir == 1 ? ARROW_UP : ARROW_DN
  428. string suffix = hit ? (i_hitStyle == HIT_BOOKED ? " " + HIT_BOOKED : ", " + HIT_PLAIN) : ""
  429. arrow + name + " at " + f_fmt(lvl) + suffix
  430.  
  431. f_pct(int wins, int total) =>
  432. total > 0 ? str.tostring(wins * 100.0 / total, "#.##") + " %" : "0 %"
  433.  
  434. f_tablePosition(string s) =>
  435. switch s
  436. "Top Left" => position.top_left
  437. "Top Center" => position.top_center
  438. "Top Right" => position.top_right
  439. "Middle Left" => position.middle_left
  440. "Middle Right" => position.middle_right
  441. "Bottom Center" => position.bottom_center
  442. "Bottom Right" => position.bottom_right
  443. => position.bottom_left
  444.  
  445. f_textSize(string s) =>
  446. switch s
  447. TXT_SMALL => size.small
  448. TXT_NORMAL => size.normal
  449. TXT_LARGE => size.large
  450. => size.tiny
  451.  
  452. float volSafe = na(volume) or volume <= 0 ? 1.0 : volume
  453. float barRange = high - low
  454. float atr14 = ta.atr(14)
  455. float atrTrade = ta.atr(i_atrLenTrade)
  456. float atrSafe = math.max(nz(atr14, barRange), EPS)
  457.  
  458. float dcPeriod = f_dominantCycle(hl2, i_dcMin, i_dcMax)
  459. int dynLen = math.max(i_dcMin, math.min(i_dcMax, math.round(nz(dcPeriod, i_gaussLen))))
  460.  
  461. int chartSec = timeframe.in_seconds(timeframe.period)
  462. string premiumLtf = chartSec <= 3600 ? "1" : chartSec <= 14400 ? "5" : chartSec <= 86400 ? "15" : "60"
  463. string wantedLtf = i_isPremium ? premiumLtf : i_ltf
  464. string ltfTf = timeframe.in_seconds(wantedLtf) < chartSec ? wantedLtf : timeframe.period
  465. [ltfUpArr, ltfDnArr] = request.security_lower_tf(syminfo.tickerid, ltfTf, [close > open ? nz(volume) : 0.0, close < open ? nz(volume) : 0.0], ignore_invalid_symbol = true)
  466. bool useLtf = ltfTf != timeframe.period and ltfUpArr.size() > 0
  467. float ltfUp = useLtf ? nz(ltfUpArr.sum()) : 0.0
  468. float ltfDn = useLtf ? nz(ltfDnArr.sum()) : 0.0
  469. float estBuy = barRange > 0 ? volSafe * (close - low) / barRange : volSafe * 0.5
  470. float estSell = volSafe - estBuy
  471. float barDelta = useLtf ? ltfUp - ltfDn : estBuy - estSell
  472. float cvd = ta.cum(barDelta)
  473. float cvdEma = ta.ema(cvd, i_cvdLen)
  474. float cvdOsc = (cvd - nz(cvdEma, cvd)) / math.max(nz(ta.stdev(barDelta, i_cvdLen)), EPS)
  475. float cvdSlope = nz(ta.change(cvdEma))
  476.  
  477. float obvV = ta.cum(math.sign(nz(ta.change(close))) * volSafe)
  478. float obvFast = ta.ema(obvV, 5)
  479. float obvMid = ta.ema(obvV, 13)
  480. float obvSlow = ta.ema(obvV, 34)
  481. float obvStd = math.max(nz(ta.stdev(obvV, 34)), EPS)
  482. float obvImpulse = (0.2 * (obvV - nz(obvFast, obvV)) + 0.5 * (nz(obvFast, obvV) - nz(obvMid, obvV)) + 0.3 * (nz(obvMid, obvV) - nz(obvSlow, obvV))) / obvStd
  483.  
  484. float trixE = ta.ema(ta.ema(ta.ema(math.log(close), i_trixLen), i_trixLen), i_trixLen)
  485. float trix = 10000.0 * nz(ta.change(trixE))
  486. float trixSignal = ta.ema(trix, i_trixSig)
  487. float trixNorm = trix / math.max(nz(ta.stdev(trix, 50)), EPS)
  488.  
  489. float vwmaV = f_vwma(close, volSafe, dynLen)
  490. float kamaV = f_kama(close, dynLen, i_amaFast, i_amaSlow)
  491. float rsiV = f_rsi(close, dynLen)
  492. float stochRsiK = ta.sma(ta.stoch(rsiV, rsiV, rsiV, i_stochLen), i_stochSmooth)
  493. [stLine, stDir] = ta.supertrend(i_stFactor, i_stAtrLen)
  494. float fisherV = f_fisher(hl2, dynLen)
  495.  
  496. float gaussLenF = i_gaussAdaptive ? float(dynLen) : float(i_gaussLen)
  497. float gaussBase = f_gaussian(hlc3, gaussLenF, i_gaussPoles)
  498. [bandTrail, bandDir] = f_trailBand(gaussBase, atr14, i_gaussMult, close)
  499. float baseline = f_gaussian(close, i_baseLen, 4)
  500.  
  501. float lmsSrc = close - gaussBase
  502. float lmsNext = f_lmsPredict(lmsSrc, i_lmsLen, i_lmsMu)
  503. float lmsStd = math.max(nz(ta.stdev(lmsSrc, 50)), EPS)
  504. [qrFit, qrSlope] = f_quadReg(close, i_qrLen)
  505. float trimeanV = f_trimean(close, i_qrLen)
  506. float hyperV = f_tanh((close - nz(close[dynLen], close)) / math.max(atrSafe * math.sqrt(dynLen), EPS))
  507.  
  508. float c1 = f_tanh((close - vwmaV) / atrSafe)
  509. float c2 = f_tanh((close - kamaV) / atrSafe)
  510. float c3 = (rsiV - 50.0) / 50.0
  511. float c4 = (nz(stochRsiK, 50.0) - 50.0) / 50.0
  512. float c5 = stDir < 0 ? 1.0 : -1.0
  513. float c6 = math.abs(fisherV) > i_fisherTol ? f_tanh(fisherV) : 0.0
  514. float c7 = f_tanh(trixNorm)
  515. float c8 = f_tanh(cvdOsc)
  516. float c9 = f_tanh(obvImpulse)
  517. float c10 = f_tanh(nz(lmsNext) / lmsStd)
  518. float c11 = f_tanh(nz(qrSlope) * 5.0 / atrSafe)
  519. float c12 = hyperV
  520. float c13 = f_tanh((close - nz(trimeanV, close)) / atrSafe)
  521. float tsScore = (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9 + c10 + c11 + c12 + c13) / 13.0
  522.  
  523. float probRaw = 1.0 / (1.0 + math.exp(-4.0 * i_sensitivity * tsScore))
  524. float probAvg = nz(ta.sma(probRaw, i_probAvg), probRaw)
  525. float probStd = nz(ta.stdev(probRaw, 5))
  526.  
  527. float feat1 = c3
  528. float feat2 = f_tanh(fisherV / 2.0)
  529. float feat3 = f_normalize(trixNorm, -1.0, 1.0)
  530. float feat4 = f_normalize(cvdOsc, -1.0, 1.0)
  531. float feat5 = c4
  532.  
  533. var array<float> knnA1 = array.new_float()
  534. var array<float> knnA2 = array.new_float()
  535. var array<float> knnA3 = array.new_float()
  536. var array<float> knnA4 = array.new_float()
  537. var array<float> knnA5 = array.new_float()
  538. var array<int> knnLbl = array.new_int()
  539.  
  540. if i_useKnn and bar_index > i_knnHorizon
  541. int lbl = close > close[i_knnHorizon] ? 1 : close < close[i_knnHorizon] ? -1 : 0
  542. knnA1.push(feat1[i_knnHorizon])
  543. knnA2.push(feat2[i_knnHorizon])
  544. knnA3.push(feat3[i_knnHorizon])
  545. knnA4.push(feat4[i_knnHorizon])
  546. knnA5.push(feat5[i_knnHorizon])
  547. knnLbl.push(lbl)
  548. if knnLbl.size() > i_knnWindow
  549. knnA1.shift()
  550. knnA2.shift()
  551. knnA3.shift()
  552. knnA4.shift()
  553. knnA5.shift()
  554. knnLbl.shift()
  555.  
  556. float knnScore = i_useKnn ? f_knnPredict(knnA1, knnA2, knnA3, knnA4, knnA5, knnLbl, feat1, feat2, feat3, feat4, feat5, i_knnK, i_knnStride) : 0.0
  557. float knnProb = (knnScore + 1.0) / 2.0
  558. float knnW = i_useKnn ? i_knnWeight : 0.0
  559. float finalProb = probAvg * (1.0 - knnW) + knnProb * knnW
  560.  
  561. bool regimeOk = f_regimeFilter(ohlc4, i_regimeThr)
  562. bool volOk = nz(ta.atr(1)) > nz(ta.atr(10))
  563. bool atrImpulseOk = nz(ta.atr(5)) >= nz(ta.sma(ta.tr(true), 30)) * i_atrImpMult
  564. float volDeriv = (atrSafe - nz(atr14[3], atrSafe)) / atrSafe
  565. bool volDerivOk = nz(ta.ema(volDeriv, 3)) >= -i_volDerivTol
  566. bool trixLongOk = trix >= nz(trixSignal, trix) or trix > 0
  567. bool trixShortOk = trix <= nz(trixSignal, trix) or trix < 0
  568. bool cvdLongOk = cvdSlope >= 0
  569. bool cvdShortOk = cvdSlope <= 0
  570. float bodySize = math.abs(close - open)
  571. bool isMarubozu = barRange > 0 and bodySize / barRange >= i_maruBody and barRange >= atrSafe * 1.2
  572. bool bullMarubozu = isMarubozu and close > open
  573. bool bearMarubozu = isMarubozu and close < open
  574. bool probVarOk = probStd <= i_probVarMax
  575.  
  576. float pLow = ta.lowest(low, i_divLen)
  577. float pHigh = ta.highest(high, i_divLen)
  578. float cLow = ta.lowest(cvd, i_divLen)
  579. float cHigh = ta.highest(cvd, i_divLen)
  580. bool bullDiv = pLow < nz(pLow[i_divLen], pLow) and cLow > nz(cLow[i_divLen], cLow)
  581. bool bearDiv = pHigh > nz(pHigh[i_divLen], pHigh) and cHigh < nz(cHigh[i_divLen], cHigh)
  582.  
  583. bool barOk = not i_confirmBar or barstate.isconfirmed
  584.  
  585. bool filtersLong = (not i_useRegime or regimeOk) and (not i_useVolFilter or volOk) and (not i_useAtrImpulse or atrImpulseOk) and (not i_useVolDeriv or volDerivOk) and (not i_useTrix or trixLongOk) and (not i_useCvd or cvdLongOk or bullDiv) and (not i_useMarubozu or not bearMarubozu) and probVarOk
  586. bool filtersShort = (not i_useRegime or regimeOk) and (not i_useVolFilter or volOk) and (not i_useAtrImpulse or atrImpulseOk) and (not i_useVolDeriv or volDerivOk) and (not i_useTrix or trixShortOk) and (not i_useCvd or cvdShortOk or bearDiv) and (not i_useMarubozu or not bullMarubozu) and probVarOk
  587.  
  588. bool rawLong = bandDir == 1 and (finalProb >= i_conf or (i_useCvdDiv and bullDiv and finalProb > 0.5))
  589. bool rawShort = bandDir == -1 and (finalProb <= 1.0 - i_conf or (i_useCvdDiv and bearDiv and finalProb < 0.5))
  590.  
  591. var int lastDir = 0
  592. bool buySignal = false
  593. bool sellSignal = false
  594.  
  595. if barOk and bar_index > i_dcMax * WARMUP_MULT
  596. if rawLong and filtersLong and lastDir != 1
  597. buySignal := true
  598. lastDir := 1
  599. else if rawShort and filtersShort and lastDir != -1
  600. sellSignal := true
  601. lastDir := -1
  602.  
  603. var TradeState cur = na
  604. var Stats stats = Stats.new()
  605.  
  606. bool evTriggered = false
  607. bool evT1 = false
  608. bool evT2 = false
  609. bool evT3 = false
  610. bool evT4 = false
  611. bool evT5 = false
  612. bool evStop = false
  613. int evDir = 0
  614.  
  615. if not na(cur)
  616. if not cur.closed and not cur.triggered and bar_index > cur.sigBar
  617. if f_reached(cur.dir, cur.trigger)
  618. cur.triggered := true
  619. evTriggered := true
  620. evDir := cur.dir
  621. if cur.dir == 1
  622. stats.longTotal := stats.longTotal + 1
  623. else
  624. stats.shortTotal := stats.shortTotal + 1
  625. if not cur.closed and cur.triggered
  626. evDir := cur.dir
  627. if not cur.stopHit and f_stopped(cur.dir, cur.stop)
  628. cur.stopHit := true
  629. cur.stopBar := bar_index
  630. evStop := true
  631. if not cur.t1Hit and f_reached(cur.dir, cur.t1)
  632. cur.t1Hit := true
  633. evT1 := true
  634. if cur.dir == 1
  635. stats.longWins := stats.longWins + 1
  636. else
  637. stats.shortWins := stats.shortWins + 1
  638. if not cur.stopHit
  639. if cur.t1Hit and not cur.t2Hit and f_reached(cur.dir, cur.t2)
  640. cur.t2Hit := true
  641. evT2 := true
  642. if cur.t2Hit and not cur.t3Hit and f_reached(cur.dir, cur.t3)
  643. cur.t3Hit := true
  644. evT3 := true
  645. if i_showT45 and cur.t3Hit and not cur.t4Hit and f_reached(cur.dir, cur.t4)
  646. cur.t4Hit := true
  647. evT4 := true
  648. if i_showT45 and cur.t4Hit and not cur.t5Hit and f_reached(cur.dir, cur.t5)
  649. cur.t5Hit := true
  650. evT5 := true
  651. bool finalTargetHit = i_showT45 ? cur.t5Hit : cur.t3Hit
  652. if finalTargetHit
  653. cur.closed := true
  654. else if cur.stopHit
  655. if cur.t1Hit or bar_index - cur.stopBar >= i_recoveryBars
  656. cur.closed := true
  657.  
  658. if buySignal or sellSignal
  659. int d = buySignal ? 1 : -1
  660. float a = nz(atrTrade, barRange)
  661. float trg = d == 1 ? high : low
  662. if not na(cur) and not cur.closed
  663. cur.closed := true
  664. cur := TradeState.new(dir = d, sigBar = bar_index, trigger = trg, stop = trg - d * i_stopMult * a, t1 = trg + d * 1.0 * i_tMult * a, t2 = trg + d * 2.0 * i_tMult * a, t3 = trg + d * 3.0 * i_tMult * a, t4 = trg + d * 4.0 * i_tMult * a, t5 = trg + d * 5.0 * i_tMult * a)
  665.  
  666. plot(i_showBand and bandDir == 1 ? bandTrail : na, "Gaussian Band Bull", i_colBandBull, i_bandWidth, plot.style_linebr)
  667. plot(i_showBand and bandDir == -1 ? bandTrail : na, "Gaussian Band Bear", i_colBandBear, i_bandWidth, plot.style_linebr)
  668. plot(i_showBaseline ? baseline : na, "Gaussian Baseline", i_colBaseline, 1)
  669.  
  670. bool dotCaution = bullMarubozu or bearMarubozu or not probVarOk
  671. bool dotCautionDn = dotCaution and (bullMarubozu or (not bearMarubozu and finalProb >= 0.5))
  672. bool dotCautionUp = dotCaution and not dotCautionDn
  673. bool dotBull = not dotCaution and finalProb >= i_conf
  674. bool dotBear = not dotCaution and finalProb <= 1.0 - i_conf
  675. bool dotNeutUp = not dotCaution and not dotBull and not dotBear and finalProb >= 0.5
  676. bool dotNeutDn = not dotCaution and not dotBull and not dotBear and finalProb < 0.5
  677.  
  678. plotshape(i_showDots and dotBull and not buySignal, "Bull Probability", shape.triangleup, location.belowbar, i_colDotBull, size = size.tiny)
  679. plotshape(i_showDots and dotBear and not sellSignal, "Bear Probability", shape.triangledown, location.abovebar, i_colDotBear, size = size.tiny)
  680. plotshape(i_showDots and dotNeutUp, "Neutral Up Probability", shape.triangleup, location.belowbar, i_colDotNeut, size = size.tiny)
  681. plotshape(i_showDots and dotNeutDn, "Neutral Down Probability", shape.triangledown, location.abovebar, i_colDotNeut, size = size.tiny)
  682. plotshape(i_showDots and dotCautionDn, "Caution Down", shape.triangledown, location.abovebar, i_colDotWarn, size = size.tiny)
  683. plotshape(i_showDots and dotCautionUp, "Caution Up", shape.triangleup, location.belowbar, i_colDotWarn, size = size.tiny)
  684.  
  685. plotshape(i_showHistory and buySignal, "Buy Position", shape.labelup, location.belowbar, i_colLong, text = "Buy", textcolor = color.white, size = size.tiny)
  686. plotshape(i_showHistory and sellSignal, "Sell Position", shape.labeldown, location.abovebar, i_colShort, text = "Sell", textcolor = color.white, size = size.tiny)
  687.  
  688. barcolor(i_showBarColor and buySignal ? i_colBuyBar : i_showBarColor and sellSignal ? i_colSellBar : na, title = "Signal Candles")
  689.  
  690. var array<Zone> volZones = array.new<Zone>()
  691. var array<Zone> pivZones = array.new<Zone>()
  692.  
  693. float volAvg = ta.sma(volSafe, 20)
  694. float srPH = ta.pivothigh(high, i_srPivotLen, i_srPivotLen)
  695. float srPL = ta.pivotlow(low, i_srPivotLen, i_srPivotLen)
  696. float pvPH = ta.pivothigh(high, i_pivLen, i_pivLen)
  697. float pvPL = ta.pivotlow(low, i_pivLen, i_pivLen)
  698.  
  699. if i_showVolSR
  700. f_updateZones(volZones, i_srMaxBars)
  701. bool volFloat = volSafe[i_srPivotLen] >= nz(volAvg[i_srPivotLen]) * i_srVolMult
  702. float minH = nz(atr14[i_srPivotLen], atrSafe) * ZONE_MIN_ATR
  703. int leftX = bar_index - i_srPivotLen
  704. if not na(srPH) and volFloat
  705. float zt = srPH
  706. float zb = math.max(open[i_srPivotLen], close[i_srPivotLen])
  707. zb := zt - zb < minH ? zt - minH : zb
  708. f_addZone(volZones, Zone.new(box.new(leftX, zt, bar_index, zb, border_color = color(na), bgcolor = i_colVolZone), zt, zb, -1, leftX), i_maxZones)
  709. if not na(srPL) and volFloat
  710. float zb = srPL
  711. float zt = math.min(open[i_srPivotLen], close[i_srPivotLen])
  712. zt := zt - zb < minH ? zb + minH : zt
  713. f_addZone(volZones, Zone.new(box.new(leftX, zt, bar_index, zb, border_color = color(na), bgcolor = i_colVolZone), zt, zb, 1, leftX), i_maxZones)
  714.  
  715. if i_showPivots
  716. f_updateZones(pivZones, i_pivMaxBars)
  717. float pivH = nz(atr14[i_pivLen], atrSafe) * PIV_ZONE_ATR
  718. int pivX = bar_index - i_pivLen
  719. if not na(pvPH)
  720. f_addZone(pivZones, Zone.new(box.new(pivX, pvPH, bar_index, pvPH - pivH, border_color = color(na), bgcolor = i_colPivZone), pvPH, pvPH - pivH, -1, pivX), i_maxZones)
  721. if not na(pvPL)
  722. f_addZone(pivZones, Zone.new(box.new(pivX, pvPL + pivH, bar_index, pvPL, border_color = color(na), bgcolor = i_colPivZone), pvPL + pivH, pvPL, 1, pivX), i_maxZones)
  723.  
  724. var array<line> lvlLines = array.new<line>()
  725. var array<label> lvlLabels = array.new<label>()
  726.  
  727. if barstate.islast
  728. for ln in lvlLines
  729. ln.delete()
  730. for lb in lvlLabels
  731. lb.delete()
  732. lvlLines.clear()
  733. lvlLabels.clear()
  734. if i_showLevels and not na(cur)
  735. string lblSize = f_textSize(i_textSize)
  736. bool isLong = cur.dir == 1
  737. int xr = bar_index + i_labelOffset
  738. int xl = math.max(cur.sigBar - 1, 0)
  739. float aGap = nz(atrTrade, atrSafe)
  740.  
  741. color tgtTxt = isLong ? i_colBuyTgt : i_colSellTgt
  742. color tgtBg = isLong ? i_colBuyTgtBg : i_colSellTgtBg
  743. color tgtLn = isLong ? i_colBuyTgtLn : i_colSellTgtLn
  744. color entTxt = isLong ? i_colBuyEnt : i_colSellEnt
  745. color entBg = isLong ? i_colBuyEntBg : i_colSellEntBg
  746. color entLn = isLong ? i_colBuyEntLn : i_colSellEntLn
  747. color stpTxt = isLong ? i_colBuyStp : i_colSellStp
  748. color stpBg = isLong ? i_colBuyStpBg : i_colSellStpBg
  749. color stpLn = isLong ? i_colBuyStpLn : i_colSellStpLn
  750.  
  751. if i_showT45
  752. f_drawLevel(lvlLines, lvlLabels, xl, xr, cur.t5, tgtLn, line.style_dotted, 1, f_targetText(cur.dir, "T5", cur.t5, cur.t5Hit), tgtTxt, tgtBg, lblSize, false)
  753. f_drawLevel(lvlLines, lvlLabels, xl, xr, cur.t4, tgtLn, line.style_dotted, 1, f_targetText(cur.dir, "T4", cur.t4, cur.t4Hit), tgtTxt, tgtBg, lblSize, false)
  754. f_drawLevel(lvlLines, lvlLabels, xl, xr, cur.t3, tgtLn, line.style_dotted, 1, f_targetText(cur.dir, "T3", cur.t3, cur.t3Hit), tgtTxt, tgtBg, lblSize, false)
  755. f_drawLevel(lvlLines, lvlLabels, xl, xr, cur.t2, tgtLn, line.style_dotted, 1, f_targetText(cur.dir, "T2", cur.t2, cur.t2Hit), tgtTxt, tgtBg, lblSize, false)
  756. f_drawLevel(lvlLines, lvlLabels, xl, xr, cur.t1, tgtLn, line.style_dotted, 1, f_targetText(cur.dir, "T1", cur.t1, cur.t1Hit), tgtTxt, tgtBg, lblSize, false)
  757.  
  758. string entryTxt = (isLong ? ARROW_UP + "Strength Above " : ARROW_DN + "Weakness Below ") + f_fmt(cur.trigger) + (cur.triggered ? ",\nTriggered" : "")
  759. f_drawLevel(lvlLines, lvlLabels, xl, xr, cur.trigger, entLn, line.style_solid, 2, entryTxt, entTxt, entBg, lblSize, true)
  760.  
  761. string stopTxt = WARN_ICON + "Stop at " + f_fmt(cur.stop) + (cur.stopHit ? ", " + HIT_PLAIN : "")
  762. f_drawLevel(lvlLines, lvlLabels, xl, xr, cur.stop, stpLn, line.style_dotted, 1, stopTxt, stpTxt, stpBg, lblSize, false)
  763.  
  764. lvlLabels.push(label.new(xr, cur.stop - cur.dir * aGap * BRAND_GAP, BRAND_TXT, xloc = xloc.bar_index, color = i_colBrandBg, style = label.style_label_left, textcolor = i_colBrand, size = lblSize, textalign = text.align_center))
  765.  
  766. string statLongRate = f_pct(stats.longWins, stats.longTotal)
  767. string statShortRate = f_pct(stats.shortWins, stats.shortTotal)
  768.  
  769. var table statsTbl = table.new(f_tablePosition(i_tablePos), 4, 4, bgcolor = i_colTblBg, frame_color = i_colTblBorder, frame_width = 1, border_color = i_colTblBorder, border_width = 1)
  770.  
  771. if barstate.islast
  772. table.clear(statsTbl, 0, 0, 3, 3)
  773. if i_showTable
  774. string ts = f_textSize(i_tableSize)
  775. color longBg = color.new(i_colLong, 88)
  776. color shortBg = color.new(i_colShort, 88)
  777. table.cell(statsTbl, 0, 0, VERSION_TXT, text_color = i_colTblText, text_size = ts, text_halign = text.align_left)
  778. table.cell(statsTbl, 1, 0, "Stats", text_color = i_colTblText, text_size = ts, bgcolor = color.new(i_colTblText, 92))
  779. table.cell(statsTbl, 2, 0, "Long", text_color = i_colLong, text_size = ts, bgcolor = longBg)
  780. table.cell(statsTbl, 3, 0, "Short", text_color = i_colShort, text_size = ts, bgcolor = shortBg)
  781. table.cell(statsTbl, 0, 1, "", text_size = ts)
  782. table.cell(statsTbl, 1, 1, "Total Trades", text_color = i_colTblText, text_size = ts, text_halign = text.align_right)
  783. table.cell(statsTbl, 2, 1, str.tostring(stats.longTotal), text_color = TXT_DARK, text_size = ts)
  784. table.cell(statsTbl, 3, 1, str.tostring(stats.shortTotal), text_color = TXT_DARK, text_size = ts)
  785. table.cell(statsTbl, 0, 2, RECOVERY_TXT, text_color = i_colTblText, text_size = ts)
  786. table.cell(statsTbl, 1, 2, "T1 Wins", text_color = i_colTblText, text_size = ts, text_halign = text.align_right)
  787. table.cell(statsTbl, 2, 2, str.tostring(stats.longWins), text_color = TXT_DARK, text_size = ts)
  788. table.cell(statsTbl, 3, 2, str.tostring(stats.shortWins), text_color = TXT_DARK, text_size = ts)
  789. table.cell(statsTbl, 0, 3, "", text_color = i_colTblText, text_size = ts)
  790. table.cell(statsTbl, 1, 3, "T1 Win %", text_color = i_colTblText, text_size = ts, text_halign = text.align_right)
  791. table.cell(statsTbl, 2, 3, statLongRate, text_color = TXT_DARK, text_size = ts)
  792. table.cell(statsTbl, 3, 3, statShortRate, text_color = TXT_DARK, text_size = ts)
  793.  
  794. alertcondition(buySignal, "Ocs Ai Trader : Buy Signal", "Ocs Ai Trader : Buy Signal on {{ticker}} ({{interval}}) at {{close}}")
  795. alertcondition(sellSignal, "Ocs Ai Trader : Sell Signal", "Ocs Ai Trader : Sell Signal on {{ticker}} ({{interval}}) at {{close}}")
  796. alertcondition(buySignal or sellSignal, "Ocs Ai Trader : Any Signal", "Ocs Ai Trader : New Signal on {{ticker}} ({{interval}}) at {{close}}")
  797. alertcondition(evTriggered, "Ocs Ai Trader : Strength / Weakness Triggered", "Ocs Ai Trader : Entry Triggered on {{ticker}} ({{interval}}) at {{close}}")
  798. alertcondition(evT1, "Ocs Ai Trader : T1 Hit", "Ocs Ai Trader : T1 Hit on {{ticker}} ({{interval}})")
  799. alertcondition(evT2, "Ocs Ai Trader : T2 Hit", "Ocs Ai Trader : T2 Hit on {{ticker}} ({{interval}})")
  800. alertcondition(evT3, "Ocs Ai Trader : T3 Hit", "Ocs Ai Trader : T3 Hit on {{ticker}} ({{interval}})")
  801. alertcondition(evT4, "Ocs Ai Trader : T4 Hit", "Ocs Ai Trader : T4 Hit on {{ticker}} ({{interval}})")
  802. alertcondition(evT5, "Ocs Ai Trader : T5 Hit", "Ocs Ai Trader : T5 Hit on {{ticker}} ({{interval}})")
  803. alertcondition(evStop, "Ocs Ai Trader : Stop Hit", "Ocs Ai Trader : Stop Hit on {{ticker}} ({{interval}})")
  804.  
  805. string passTxt = str.length(i_alertPass) > 0 ? " | Passcode: " + i_alertPass : ""
  806. string side = evDir == 1 ? "Long" : "Short"
  807.  
  808. if buySignal or sellSignal
  809. string sigTxt = BRAND_TXT + " : " + (buySignal ? "BUY " : "SELL ") + syminfo.ticker + " (" + timeframe.period + ")" + (buySignal ? " | Strength Above " : " | Weakness Below ") + f_fmt(cur.trigger) + " | T1 " + f_fmt(cur.t1) + " | T2 " + f_fmt(cur.t2) + " | T3 " + f_fmt(cur.t3) + (i_showT45 ? " | T4 " + f_fmt(cur.t4) + " | T5 " + f_fmt(cur.t5) : "") + " | Stop " + f_fmt(cur.stop) + passTxt
  810. alert(sigTxt, alert.freq_once_per_bar_close)
  811. if evTriggered
  812. alert(BRAND_TXT + " : " + side + " Triggered on " + syminfo.ticker + " (" + timeframe.period + ") at " + f_fmt(close) + passTxt, alert.freq_once_per_bar)
  813. if evT1 or evT2 or evT3 or evT4 or evT5
  814. string tgt = evT5 ? "T5" : evT4 ? "T4" : evT3 ? "T3" : evT2 ? "T2" : "T1"
  815. alert(BRAND_TXT + " : " + side + " " + tgt + " Hit on " + syminfo.ticker + " (" + timeframe.period + ") at " + f_fmt(close) + passTxt, alert.freq_once_per_bar)
  816. if evStop
  817. alert(BRAND_TXT + " : " + side + " Stop Hit on " + syminfo.ticker + " (" + timeframe.period + ") at " + f_fmt(close) + passTxt, alert.freq_once_per_bar)
Add Comment
Please, Sign In to add comment