├── GitLemon ├── GitLemon - Simple Edition └── Gitlemon - Conservative (enters on E) /GitLemon: -------------------------------------------------------------------------------- 1 | //@version=4 2 | //GitLemon 3 | study(title="GitLemon", shorttitle="GitLemon", overlay=true, precision=8) 4 | 5 | 6 | // INPUTS 7 | src = input(title="Source", type=input.source, defval=close) 8 | 9 | globalwidth = input(9, minval=5, title="Global Max Width of W/M") 10 | globaloffset = input(0, minval=0, title="Global Offset of W/M") 11 | 12 | includePrice = input(defval=true, title="Use price") 13 | strictPrice = input(defval=false, title="Strict") 14 | //rangePrice = input(9, minval=5, title="Max. width of price W/M") // e.g. allow an price W/M to form over 7 bars. 15 | //offsetPrice = input(0, minval=0, title="Max. offset of price W/M") // e.g. allow an price W/M to form 1 bar in history. Keep this number low. The goal is to synch the market structure over multiple indicators. 16 | rangePrice = globalwidth 17 | offsetPrice = globaloffset 18 | 19 | includeOBV = input(defval=true, title="Use OBV") 20 | strictOBV = input(defval=false, title="Strict") 21 | //rangeOBV = input(9, minval=5, title="Max. width of OBV W/M") 22 | //offsetOBV = input(0, minval=0, title="Max. offset of OBV W/M") 23 | rangeOBV = globalwidth 24 | offsetOBV = globaloffset 25 | 26 | includeWly = input(defval=true, title="Use Willy") 27 | includeWillyStupid = input(defval=false, title="Use Willy stupid") 28 | strictWly = input(defval=false, title="Strict") 29 | //rangeWly = input(9, minval=5, title="Max. width of Willy W/M") 30 | //offsetWly = input(0, minval=0, title="Max. offset of Willy W/M") 31 | rangeWly = globalwidth 32 | offsetWly = globaloffset 33 | lengthWly = input(21, minval=1, title="Willy length") 34 | lengthWlyEma = input(13, minval=1, title="Willy length ema") 35 | 36 | 37 | includeMFI = input(defval=false, title="Use MFI") 38 | strictMFI = input(defval=true, title="Strict") 39 | //rangeMFI = input(9, minval=5, title="Max. width of MFI W/M") 40 | //offsetMFI = input(0, minval=0, title="Max. offset of MFI W/M") 41 | rangeMFI = globalwidth 42 | offsetMFI = globaloffset 43 | lengthMFI = input(14, minval=1, title="MFI length") 44 | 45 | includeRSI = input(defval=false, title="Use RSI") 46 | strictRSI = input(defval=true, title="Strict") 47 | //rangeRSI = input(9, minval=5, title="Max. width of RSI W/M") 48 | //offsetRSI = input(0, minval=0, title="Max. offset of RSI W/M") 49 | rangeRSI = globalwidth 50 | offsetRSI = globaloffset 51 | lengthRSI = input(14, minval=1, title="RSI length") 52 | 53 | includeDMI = input(defval=false, title="Use DMI (DI+ & DI-)") 54 | strictDMI = input(defval=true, title="Strict") 55 | //rangeDMI = input(9, minval=5, title="Max. width of DMI W/M") 56 | //offsetDMI = input(0, minval=0, title="Max. offset of DMI W/M") 57 | rangeDMI = globalwidth 58 | offsetDMI = globaloffset 59 | lengthDMI = input(14, minval=1, title="DMI length") 60 | 61 | includeWithinRLZ = input(defval=false, title="Price within RLZ") 62 | includeBelowRLZ = input(defval=false, title="Price above/below RLZ") 63 | upperBoundRLZ = input(defval=61.8, minval=0.0, maxval=100.0, title="Upper bound of RLZ (fib)") 64 | lowerBoundRLZ = input(defval=78.6, minval=0.0, maxval=100.0, title="Lower bound of RLZ (fib)") 65 | lengthPeriodRLZ = input(defval=200, minval=5, title="Lookback period (bars)") 66 | showRLZLong = input(defval=false, title="Draw RLZ long") 67 | showRLZShort = input(defval=false, title="Draw RLZ short") 68 | 69 | ATH = highest(high, lengthPeriodRLZ) 70 | ATL = lowest(low, lengthPeriodRLZ) 71 | 72 | Leverage = input(1) 73 | USDRiskPerTrade = input(defval=1, title="Fixed risk amount per trade in USD", type=input.integer) // Changing to $1 from $50 74 | 75 | HideStatistics = input(false) 76 | DisplayEquityCurve = input(false) 77 | 78 | // commission = input(title="Estimated commission per round-turn in USD", defval=0.1744) 79 | commission = input(title="Estimated commission per round-turn in USD", defval=0.2) 80 | 81 | // FOR TTM SQUEEZE MODULE 82 | strict = input(false, title="Enabled (original) or Disabled (strict)") 83 | length = input(20, minval=1, title="BB Length") 84 | mult = input(2.0, minval=0.001, maxval=50, title="StDev") 85 | 86 | useTrueRange = input(true) 87 | klength = input(20, minval=1, title="Keltner Length") 88 | kmult = input(2.0, title="Multiplier") 89 | ksrc = input(close, title="Keltner Source") 90 | 91 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 92 | // NON-INPUT VARIABLES 93 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 94 | 95 | Min_Trade_Risk = atr(14) 96 | Max_Trade_Risk = 2*atr(14) 97 | StatisticsVerticalOffset = 3*atr(14) 98 | 99 | low_m1 = security(syminfo.tickerid, "1", low) 100 | high_m1 = security(syminfo.tickerid, "1", high) 101 | 102 | range = ATH - ATL 103 | 104 | // FOR SQUEEZE MODULE 105 | basis = sma(src, length) 106 | dev = mult * stdev(src, length) 107 | upper = basis + dev 108 | lower = basis - dev 109 | 110 | ma = ema(src, klength) 111 | ranger = useTrueRange ? tr : high - low 112 | rangema = ema(ranger, klength) 113 | kupper = ma + rangema * kmult 114 | klower = ma - rangema * kmult 115 | //c = color.blue 116 | 117 | bband(length, mult) => 118 | sma(close, length) + mult * stdev(close, length) 119 | keltner(length, mult) => 120 | ema(close, length) + mult * ema(tr, length) 121 | 122 | diff = bband(length, 2) - keltner(length, 1) 123 | 124 | 125 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 126 | /// Level definitions: 127 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 128 | 129 | tradeactive = false 130 | tradeactive := nz(tradeactive[1]) 131 | 132 | 133 | // STOP Level: 134 | StopLevel = 0.00000 135 | StopLevel := nz(StopLevel[1]) 136 | 137 | // Entry Level: 138 | EntryLevel = 0.00000 139 | EntryLevel := nz(EntryLevel[1]) 140 | 141 | // TP Level: 142 | TPLevel = 0.00000 143 | TPLevel := nz(TPLevel[1]) 144 | 145 | // Breakeven Level: 146 | BELevel = 0.00000 147 | BELevel := nz(BELevel[1]) 148 | 149 | // stopdistance 150 | stopdistance = 0.00000 151 | stopdistance := nz(stopdistance[1]) 152 | 153 | // TradeSizeInXBT 154 | TradeSizeInXBT = 0.00000 155 | TradeSizeInXBT := nz(TradeSizeInXBT[1]) 156 | 157 | // TradeSizeInUSD 158 | TradeSizeInUSD = 0 159 | TradeSizeInUSD := nz(TradeSizeInUSD[1]) 160 | 161 | //PositionMarginXBT 162 | PositionMarginXBT = 0.00000 163 | PositionMarginXBT := nz(PositionMarginXBT[1]) 164 | 165 | //MaxPosMarginXBT 166 | MaxPosMarginXBT = 0.00000 167 | MaxPosMarginXBT := nz(MaxPosMarginXBT[1]) 168 | 169 | // Long and Short trade definitions: 170 | //============================================================= 171 | Longtradeactive = false 172 | Longtradeactive := Longtradeactive[1] 173 | 174 | Shorttradeactive = false 175 | Shorttradeactive := Shorttradeactive[1] 176 | 177 | //CALCULATIONS 178 | 179 | 180 | is_rlz_long = barssince(highest(high, lengthPeriodRLZ)) >= 181 | barssince(lowest(low, lengthPeriodRLZ)) 182 | is_rlz_short = barssince(highest(high, lengthPeriodRLZ)) < 183 | barssince(lowest(low, lengthPeriodRLZ)) 184 | 185 | longUpperRLZ = showRLZLong ? (1 - upperBoundRLZ / 100) * range + ATL : na 186 | longLowerRLZ = showRLZLong ? (1 - lowerBoundRLZ / 100) * range + ATL : na 187 | longWithinRLZ = longUpperRLZ >= src and src >= longLowerRLZ 188 | longBelowRLZ = longLowerRLZ > src 189 | // Moved below Plot for Trade Size for Autoview Testing 190 | // // Plot 0 191 | // p1 = plot(longUpperRLZ, color=color.green, title="61.8 (long)") 192 | // // Plot 1 193 | // p2 = plot(longLowerRLZ, color=color.green, title="78.6 (long)") 194 | // fill(p1, p2, color=#7DCEA0, transp=90, title="RLZ long") 195 | 196 | shortUpperRLZ = showRLZShort ? ATH - (1 - upperBoundRLZ / 100) * range : na 197 | shortLowerRLZ = showRLZShort ? ATH - (1 - lowerBoundRLZ / 100) * range : na 198 | shortWithinRLZ = shortUpperRLZ <= src and src <= shortLowerRLZ 199 | shortAboveRLZ = shortLowerRLZ < src 200 | // // Plot 2 201 | // p3 = plot(shortUpperRLZ, color=color.red, title="78.6 (short)") 202 | // // Plot 3 203 | // p4 = plot(shortLowerRLZ, color=color.red, title="61.8 (short)") 204 | // fill(p3, p4, color=#cd6155, transp=90, title="RLZ short") 205 | 206 | includeSMA = input(defval=false, title="Price above/below SMA") 207 | lengthSMA = input(20, minval=1, title="SMA length") 208 | 209 | // limit by period option 210 | limitPeriod = input(defval=false, title="Limit period (increases perfomance)") 211 | lengthPeriod = input(245, minval=1, title="Length of period (hours)") 212 | 213 | hours_in_milliseconds = 1000 * 60 * 60 214 | withinPeriod = not limitPeriod or timenow - time < hours_in_milliseconds * lengthPeriod 215 | 216 | // quickLook = input(defval = true, title = "Quick Look") // ignores historic data and will plot a signal on the chart 217 | // show_order_details = input(defval = true, title = "Show entry / stoploss / target") // show entry, stoploss and target (toggling this doesn't work) 218 | show_order_details = true 219 | entrySource = input(title="Source for Entry", type=input.source, defval=close) 220 | stopLossSource = input(title="Source for StopLoss", type=input.source, defval=open) 221 | stopLossPercentage = input(defval=0.033, minval=0, maxval=100, step=0.01, title="Stop loss %") 222 | riskRewardRatio = input(defval=3.0, minval=0.0, title="Risk to Reward 1-to-") 223 | 224 | // removed the barstate.isreadltime as it seems to be causing a race condition preventing alerts from firing 225 | //show = not barstate.isrealtime and (includePrice or includeOBV or includeRSI or includeWly or includeMFI or includeDMI) 226 | show = includePrice or includeOBV or includeRSI or includeWly or includeMFI or includeDMI 227 | //showPotential = barstate.isrealtime and (includePrice or includeOBV or includeRSI or includeWly or includeMFI or includeDMI) and option_potential 228 | 229 | // create a series of obv, mfi, rsi, sma and willy values 230 | change_1 = change(src) 231 | OBVs = cum(change(src) > 0 ? volume : change_1 < 0 ? -volume : 0 * volume) 232 | // caclulate mfi series 233 | upper_s = sum(volume * (change(hlc3) <= 0 ? 0 : hlc3), lengthMFI) 234 | lower_s = sum(volume * (change(hlc3) >= 0 ? 0 : hlc3), lengthMFI) 235 | MFIs = rsi(upper_s, lower_s) 236 | RSIs = rsi(src,lengthRSI) 237 | SMAs = sma(src, lengthSMA) 238 | // make willy series 239 | upperWly = highest(lengthWly) 240 | lowerWly = lowest(lengthWly) 241 | WLYs = 100 * (src - upperWly) / (upperWly - lowerWly) 242 | emaWly = ema(WLYs, lengthWlyEma) 243 | 244 | series_a_above_series_b(seriesA, seriesB, aRange) => 245 | result = true 246 | for i = 0 to aRange - 1 by 1 247 | if seriesB[i] > seriesA[i] 248 | result := false 249 | break 250 | result := result 251 | result 252 | 253 | series_a_below_series_b(seriesA, seriesB, aRange) => 254 | result = true 255 | for i = 0 to aRange - 1 by 1 256 | if seriesB[i] < seriesA[i] 257 | result := false 258 | break 259 | result := result 260 | result 261 | 262 | dirmov(len) => 263 | up = change(high) 264 | down = -change(low) 265 | truerange = rma(tr, len) 266 | plus = fixnan(100 * rma(up > down and up > 0 ? up : 0, len) / truerange) 267 | minus = fixnan(100 * rma(down > up and down > 0 ? down : 0, len) / truerange) 268 | [plus, minus] 269 | 270 | data_W(aSeries, aRange, anOffset, strict) => 271 | e = 0 272 | d = 0 273 | c = 0 274 | b = 0 275 | a = 0 276 | valueE = aSeries[0] 277 | valueD = aSeries[0] 278 | valueC = aSeries[0] 279 | valueB = aSeries[0] 280 | valueA = aSeries[0] 281 | found = false 282 | 283 | for offset = 0 to anOffset by 1 284 | if found 285 | break 286 | e := 0 287 | d := 0 288 | c := 0 289 | b := 0 290 | a := 0 291 | valueE := aSeries[0] 292 | valueC := aSeries[0] 293 | valueD := aSeries[0] 294 | valueB := aSeries[0] 295 | valueA := aSeries[0] 296 | 297 | for i = 1 to aRange - 1 by 1 298 | // find d 299 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueC == aSeries[0] 300 | d := i + offset 301 | valueD := aSeries[i + offset] 302 | continue 303 | if d == 0 304 | break 305 | // find c 306 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueB == aSeries[0] 307 | c := i + offset 308 | valueC := aSeries[i + offset] 309 | continue 310 | if c == 0 311 | break 312 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueA == aSeries[0] 313 | b := i + offset 314 | valueB := aSeries[i + offset] 315 | continue 316 | if b == 0 317 | break 318 | if aSeries[i + offset] > aSeries[i + offset - 1] 319 | a := i + offset 320 | valueA := aSeries[i + offset] 321 | continue 322 | if a == 0 323 | break 324 | // W found if we have found point A, and point B has a lower value than point D 325 | found := a > 0 and a != b and c != 0 and d != 0 and aSeries[e] > aSeries[c] and 326 | aSeries[d] < aSeries[e] and aSeries[d] < aSeries[c] and 327 | (aSeries[b] <= aSeries[d] or not strict) and aSeries[b] < aSeries[a] 328 | found 329 | entry = found ? aSeries[c] : na 330 | stopLoss = found ? aSeries[b] * ((100 - stopLossPercentage) / 100) : na 331 | target = found ? entry + (entry - stopLoss) * riskRewardRatio : na 332 | [found, entry, stopLoss, target, a, b, c, d, e] 333 | 334 | data_M(aSeries, aRange, anOffset, strict) => 335 | e = 0 336 | d = 0 337 | c = 0 338 | b = 0 339 | a = 0 340 | valueE = aSeries[0] 341 | valueD = aSeries[0] 342 | valueC = aSeries[0] 343 | valueB = aSeries[0] 344 | valueA = aSeries[0] 345 | found = false 346 | 347 | for offset = 0 to anOffset by 1 348 | if found 349 | break 350 | e := 0 351 | d := 0 352 | c := 0 353 | b := 0 354 | a := 0 355 | valueE := aSeries[0] 356 | valueC := aSeries[0] 357 | valueD := aSeries[0] 358 | valueB := aSeries[0] 359 | valueA := aSeries[0] 360 | 361 | for i = 1 to aRange - 1 by 1 362 | // find d 363 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueC == aSeries[0] 364 | d := i + offset 365 | valueD := aSeries[i + offset] 366 | continue 367 | if d == 0 368 | break 369 | // find c 370 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueB == aSeries[0] 371 | c := i + offset 372 | valueC := aSeries[i + offset] 373 | continue 374 | if c == 0 375 | break 376 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueA == aSeries[0] 377 | b := i + offset 378 | valueB := aSeries[i + offset] 379 | continue 380 | if b == 0 381 | break 382 | if aSeries[i + offset] < aSeries[i + offset - 1] 383 | a := i + offset 384 | valueA := aSeries[i + offset] 385 | continue 386 | if a == 0 387 | break 388 | // M found if we have found point A, and point B has a greater value than point D 389 | found := a > 0 and a != b and c != 0 and d != 0 and aSeries[e] < aSeries[c] and 390 | aSeries[d] > aSeries[e] and aSeries[d] > aSeries[c] and 391 | (aSeries[b] >= aSeries[d] or not strict) and aSeries[b] > aSeries[a] 392 | found 393 | entry = found ? aSeries[c] : na 394 | stopLoss = found ? aSeries[b] * ((100 + stopLossPercentage) / 100) : na 395 | target = found ? entry - (stopLoss - entry) * riskRewardRatio : na 396 | [found, entry, stopLoss, target, a, b, c, d, e] 397 | 398 | 399 | find_W(aSeries, aRange, anOffset, strict) => 400 | [found, entry, stopLoss, target, a, b, c, d, e] = data_W(aSeries, aRange, anOffset, strict) 401 | found 402 | 403 | find_M(aSeries, aRange, anOffset, strict) => 404 | [found, entry, stopLoss, target, a, b, c, d, e] = data_M(aSeries, aRange, anOffset, strict) 405 | found 406 | 407 | // Direction Movement Index 408 | [DIplus, DIminus] = dirmov(lengthDMI) 409 | 410 | // calculate if price is below/above SMA 411 | HighAboveSMA = includeSMA == false or series_a_above_series_b(high, SMAs, rangePrice) 412 | LowBelowSMA = includeSMA == false or series_a_below_series_b(low, SMAs, rangePrice) 413 | 414 | label_1 = 'davo' 415 | label_entry = 'entry' 416 | 417 | // PLOT DAV-O 418 | [W_found, W_entry, W_stopLoss, W_target, W_pointA, W_pointB, W_pointC, W_pointD, W_pointE] = data_W(src, rangePrice, offsetPrice, strictPrice) 419 | [M_found, M_entry, M_stopLoss, M_target, M_pointA, M_pointB, M_pointC, M_pointD, M_pointE] = data_M(src, rangePrice, offsetPrice, strictPrice) 420 | priceW = includePrice == false or W_found 421 | priceM = includePrice == false or M_found 422 | 423 | OBVw = includeOBV == false or find_W(OBVs, rangeOBV, offsetOBV, strictOBV) 424 | OBVm = includeOBV == false or find_M(OBVs, rangeOBV, offsetOBV, strictOBV) 425 | MFIw = includeMFI == false or find_W(MFIs, rangeMFI, offsetMFI, strictMFI) 426 | MFIm = includeMFI == false or find_M(MFIs, rangeMFI, offsetMFI, strictMFI) 427 | RSIw = includeRSI == false or find_M(RSIs, rangeRSI, offsetRSI, strictRSI) // we are searching for M's here to be a bull 428 | RSIm = includeRSI == false or find_W(RSIs, rangeRSI, offsetRSI, strictRSI) // we are searching for W's here to be a bear 429 | Wlyw = includeWly == false or find_W(WLYs, rangeWly, offsetWly, strictWly) 430 | Wlym = includeWly == false or find_M(WLYs, rangeWly, offsetWly, strictWly) 431 | DMIw = includeDMI == false or find_W(DIplus, rangeDMI, offsetDMI, strictDMI) and 432 | find_M(DIminus, rangeDMI, offsetDMI, strictDMI) 433 | DMIm = includeDMI == false or find_M(DIplus, rangeDMI, offsetDMI, strictDMI) and 434 | find_W(DIminus, rangeDMI, offsetDMI, strictDMI) 435 | RLZw = includeWithinRLZ == false and includeBelowRLZ == false or 436 | includeWithinRLZ == true and longWithinRLZ or 437 | includeBelowRLZ == true and longBelowRLZ 438 | RLZm = includeWithinRLZ == false and includeBelowRLZ == false or 439 | includeWithinRLZ == true and shortWithinRLZ or 440 | includeBelowRLZ == true and shortAboveRLZ 441 | 442 | longCondition = LowBelowSMA and priceW and OBVw and MFIw and RSIw and Wlyw and DMIw and 443 | withinPeriod and (includeWillyStupid == false or emaWly < -80) and RLZw 444 | shortCondition = HighAboveSMA and priceM and OBVm and MFIm and RSIm and Wlym and DMIm and 445 | withinPeriod and (includeWillyStupid == false or emaWly > -20) and RLZm 446 | 447 | // calculate entry, stoploss and target 448 | entrySourceLong = entrySource == low ? high : entrySource 449 | entrySourceShort = entrySource == high ? low : entrySource 450 | stopSourceLong = stopLossSource == high ? low : stopLossSource 451 | stopSourceShort = stopLossSource == low ? high : stopLossSource 452 | 453 | long_entry = show and longCondition and not longCondition[1] ? entrySourceLong[W_pointC] : na 454 | lowest_1 = lowest(stopSourceLong, rangePrice) 455 | long_stoploss = show and longCondition and not longCondition[1] ? 456 | lowest_1 * ((100 - stopLossPercentage) / 100) : na 457 | long_target = show and longCondition and not longCondition[1] ? 458 | long_entry + (long_entry - long_stoploss) * riskRewardRatio : na 459 | short_entry = show and shortCondition and not shortCondition[1] ? entrySourceShort[M_pointC] : 460 | na 461 | highest_1 = highest(stopSourceShort, rangePrice) 462 | short_stoploss = show and shortCondition and not shortCondition[1] ? 463 | highest_1 * ((100 + stopLossPercentage) / 100) : na 464 | short_target = show and shortCondition and not shortCondition[1] ? 465 | short_entry - (short_stoploss - short_entry) * riskRewardRatio : na 466 | 467 | entry = long_entry ? long_entry : short_entry ? short_entry : na 468 | stoploss = long_stoploss ? long_stoploss : short_stoploss ? short_stoploss : na 469 | target = long_target ? long_target : short_target ? short_target : na 470 | 471 | // define plot settings for entry, stoploss and target 472 | transparency = show_order_details ? 0 : 100 473 | clr_entry = show and (longCondition or shortCondition) ? color.white : na 474 | clr_stoploss = show and (longCondition or shortCondition) ? color.red : na 475 | clr_target = show and (longCondition or shortCondition) ? color.lime : na 476 | 477 | //FOR SQUEEZE MODULE 478 | //============================================================ 479 | e1 = (highest(high, length) + lowest(low, length)) / 2 + sma(close, length) 480 | osc = linreg(close - e1 / 2, length, 0) 481 | osc_color = osc[1] < osc[0] ? osc[0] >= 0 ? #00ffff : #cc00cc : osc[0] >= 0 ? #009b9b : #ff9bff 482 | 483 | SQON = strict and diff < 0 ? true : not strict and kupper > upper and klower < lower ? true : false 484 | mid_color = SQON ? color.red : color.green 485 | 486 | //============================================================ 487 | // Alerts for Trade opening 488 | //============================================================ 489 | //======================================================= 490 | // Added by Joshua 2-10-20 for Autoview 491 | // plot(entry_buy, title='Entry Buy', transp=100) 492 | // e=bitmex-testnet s=xbtusd b=long q=100 fp={{plot(\"Entry Buy\")}} l=10 t=limit 493 | 494 | // Going to use market orders at first. 495 | // SYNTAX FOR AUTOVIEW // 496 | // b=long e=bitmex-testnet l={{plot("Leverage")}} q={{plot("TradeSizeInUSD")}} t=market // From Peter - Go Long 497 | // b=short e=bitmex-testnet l={{plot("Leverage")}} q={{plot("TradeSizeInUSD")}} t=market // From Peter - Go Short 498 | // c=position e=bitmex-testnet t=market ro=1 // Closes all open positions at market w/ reduce only flag - Closing Signals Alert // Tested Successfully 499 | // message="e=bitmex-testnet s=xbtusd b=long q=100 fp={{plot(\"Entry Buy\")}} l=10 t=limit" 500 | // alertcondition(close > 0, title='Lemon Entry Trade Sig Long', message="e=bitmex-testnet s=xbtusd b=long q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") // added close>0 for testing 501 | alertcondition(show and longCondition and not longCondition[1] and SQON, title='Lemon Entry Trade Sig Long', message='{{ticker}} LONG') // Original Code 502 | // alertcondition(show and longCondition and not longCondition[1] and SQON, title='Lemon Entry Trade Sig Long', message="e=bitmex-testnet s=xbtusd b=long q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") // Orig 503 | 504 | // alertcondition(high > 0, title='Lemon Entry Trade Sig Short', message="e=bitmex-testnet s=xbtusd b=short q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") // added close>0 for testing 505 | alertcondition(show and shortCondition and not shortCondition[1] and SQON, title='Lemon Entry Trade Sig Short', message="{{ticker}} SHORT") // Original Code 506 | // alertcondition(show and shortCondition and not shortCondition[1] and SQON, title='Lemon Entry Trade Sig Short', message="e=bitmex-testnet s=xbtusd b=short q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") 507 | 508 | 509 | //============================================================ 510 | //Plots for trade signal 511 | //============================================================ 512 | 513 | Shorttradetrigger = if (show and shortCondition and not shortCondition[1] and SQON) 514 | StopLevel := highest_1 * ((100 + stopLossPercentage) / 100) 515 | EntryLevel := entrySourceShort[M_pointC] 516 | TPLevel := short_entry - (short_stoploss - short_entry) * riskRewardRatio 517 | BELevel := EntryLevel - (StopLevel - EntryLevel) 518 | stopdistance := StopLevel - EntryLevel 519 | TradeSizeInXBT := USDRiskPerTrade / stopdistance 520 | TradeSizeInUSD := round(EntryLevel * TradeSizeInXBT) //remove factor 1000 for live trading 521 | PositionMarginXBT := (round(100000 * TradeSizeInXBT / Leverage)) / 100000 522 | MaxPosMarginXBT := (round(100000 * USDRiskPerTrade / Min_Trade_Risk / Leverage)) / 100000 523 | tradeactive := true 524 | Shorttradeactive := true 525 | 526 | Longtradetrigger = if (show and longCondition and not longCondition[1] and SQON) 527 | StopLevel := lowest_1 * ((100 - stopLossPercentage) / 100) 528 | EntryLevel := entrySourceLong[W_pointC] 529 | TPLevel := long_entry + (long_entry - long_stoploss) * riskRewardRatio 530 | BELevel := (EntryLevel - StopLevel) + EntryLevel 531 | stopdistance := EntryLevel - StopLevel 532 | TradeSizeInXBT := USDRiskPerTrade / stopdistance 533 | TradeSizeInUSD := round(EntryLevel * TradeSizeInXBT) //remove factor 1000 for live trading 534 | PositionMarginXBT := (round(100000 * TradeSizeInXBT / Leverage)) / 100000 535 | MaxPosMarginXBT := (round(100000 * USDRiskPerTrade / Min_Trade_Risk / Leverage)) / 100000 536 | tradeactive := true 537 | Longtradeactive := true 538 | 539 | 540 | // Plot 0 541 | plot(TradeSizeInUSD, title="TradeSizeInUSD", transp=100) // This will be the q= 542 | // Plot 1 543 | plot(EntryLevel, title="EntryLevel", transp=100) // This will be the fp= after testing using market orders 544 | // Plot 2 545 | plot(USDRiskPerTrade, title="USDRiskPerTrade", transp=100) // Shows risk per trade/loss. Multiply by Risk/Reward for Win estimates 546 | // Plot 3 547 | plot(riskRewardRatio, title="riskRewardRatio", transp=100) 548 | 549 | // PLOT RLZ Moved From Above Section 550 | // Plot 551 | p1 = plot(longUpperRLZ, color=color.green, title="61.8 (long)") 552 | // Plot 553 | p2 = plot(longLowerRLZ, color=color.green, title="78.6 (long)") 554 | fill(p1, p2, color=#7DCEA0, transp=90, title="RLZ long") 555 | // Plot 3 556 | p3 = plot(shortUpperRLZ, color=color.red, title="78.6 (short)") 557 | // Plot 4 558 | p4 = plot(shortLowerRLZ, color=color.red, title="61.8 (short)") 559 | fill(p3, p4, color=#cd6155, transp=90, title="RLZ short") 560 | 561 | 562 | // PLOT LEMON 563 | plotshape(show and longCondition and not longCondition[1] and SQON, title="Lemon long", style=shape.triangleup, location=location.belowbar, color=color.lime, text="LONG") 564 | plotshape(show and shortCondition and not shortCondition[1] and SQON, title="Lemon short", style=shape.triangledown, location=location.abovebar, color=color.red, text="SHORT") 565 | plotshape(show and longCondition[1], title="Lemon long confirmed", style=shape.cross, location=location.bottom, color=color.lime, text="alert", transp=100) 566 | plotshape(show and shortCondition[1], title="Lemon short confirmed", style=shape.cross, location=location.top, color=color.red, text="alert", transp=100) 567 | 568 | 569 | if Shorttradeactive == true 570 | Shorttradetrigger := false 571 | 572 | if Longtradeactive == true 573 | Longtradetrigger := false 574 | 575 | 576 | // Plot Levels: 577 | pl1 = plot (StopLevel, title = "stoplevel", color=color.red) 578 | pl2 = plot (EntryLevel, title = "entrylevel", color=color.white) 579 | pl3 = plot (BELevel, title = "breakevenlevel", color=color.blue) 580 | pl4 = plot (TPLevel, title = "TPlevel", color=color.green) 581 | 582 | fill(pl1, pl2, color=color.red, transp=65) 583 | fill(pl2, pl3, color=color.blue, transp=65) 584 | fill(pl3, pl4, color=color.green, transp=65) 585 | 586 | 587 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 588 | // Define and plot conflicting candles: 589 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 590 | 591 | // Subtypes of conflicting bars: 592 | //------------------------------------------------------------------------------------------------------- 593 | 594 | // Bartype 3a is a candle which crosses both BELevel and EntryLevel and has its close above the midline between BELevel and EntryLevel (longs) 595 | // respecively has its close below the midline between BELevel and EntryLevel (shorts) 596 | // In case of a Bartype 3a the logic shall NOT consider a trade as closed as break-even, but shall assume trade continuation with activated break-even-flag. 597 | //------------------------------------------------------------------------------------------------------- 598 | 599 | Bartype3_a_long = high > BELevel and high < TPLevel and low < EntryLevel and low > StopLevel and close > ((BELevel + EntryLevel)/2) and Longtradeactive 600 | Bartype3_a_short = high > EntryLevel and high < StopLevel and low < BELevel and low > TPLevel and close < ((BELevel + EntryLevel)/2) and Shorttradeactive 601 | //barcolor(Bartype3_a_long or Bartype3_a_short? color.purple : na) 602 | 603 | //Bartype3_a_Counter = 0 604 | //Bartype3_a_Counter := nz(Bartype3_a_Counter[1]) 605 | //if Bartype3_a_long or Bartype3_a_short 606 | // Bartype3_a_Counter := Bartype3_a_Counter + 1 607 | 608 | // Bartype 4a is a candle which crosses TPLevel, BELevel and EntryLevel and has its close above BELevel (longs) respectively close below BELevel (shorts) 609 | // In case of a Bartype 4a the logic shall consider a trade as closed winner and shall not assume trade as closed break-even. 610 | //------------------------------------------------------------------------------------------------------- 611 | 612 | Bartype4_a_long = high > TPLevel and low < EntryLevel and low > StopLevel and close > BELevel and Longtradeactive 613 | Bartype4_a_short = high > EntryLevel and high < StopLevel and low < TPLevel and close < BELevel and Shorttradeactive 614 | 615 | 616 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 617 | // Trade resolution: 618 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 619 | 620 | // Breakeven activation 621 | //------------------------------------------------------------------------------------------------------- 622 | shorttradeBElevelactivation = (low < BELevel) and not (low_m1 < TPLevel) 623 | longtradeBElevelactivation = (high > BELevel) and not (high_m1 > TPLevel) 624 | 625 | Breakevenactive = false 626 | Breakevenactive := nz(Breakevenactive[1]) 627 | 628 | if ((Shorttradeactive == true) and (shorttradeBElevelactivation == true)) 629 | Breakevenactive := true 630 | 631 | if ((Longtradeactive == true) and (longtradeBElevelactivation == true)) 632 | Breakevenactive := true 633 | 634 | // loss trades 635 | //------------------------------------------------------------------------------------------------------- 636 | 637 | PlotLossCounter = 0 638 | LossShort = 0 639 | LossLong = 0 640 | 641 | PlotLossCounter := nz(PlotLossCounter[1]) 642 | LossShort := nz(LossShort[1]) 643 | LossLong := nz(LossLong[1]) 644 | 645 | plotlosshort = if ((Shorttradeactive == true) and (high > StopLevel) and (Breakevenactive == false)) 646 | y = 1 // only required to make code work 647 | 648 | plotchar(plotlosshort, char="X", location=location.abovebar, color=color.red, transp=0, offset=0, size=size.small) 649 | 650 | if plotlosshort == true 651 | tradeactive := false 652 | Shorttradeactive := false 653 | Breakevenactive := false 654 | PlotLossCounter := PlotLossCounter + 1 655 | LossShort := LossShort +1 656 | 657 | 658 | //plotlosshort := false 659 | 660 | plotlosslong = if ((Longtradeactive == true) and (low < StopLevel) and (Breakevenactive == false)) 661 | r = 1 // only required to make code work 662 | 663 | plotchar(plotlosslong, char="X", location=location.belowbar, color=color.red, transp=0, offset=0, size=size.small) 664 | 665 | if plotlosslong == true 666 | tradeactive := false 667 | Longtradeactive := false 668 | Breakevenactive := false 669 | PlotLossCounter := PlotLossCounter + 1 670 | LossLong := LossLong + 1 671 | 672 | //plotlosslong := false 673 | 674 | // Breakeven trades 675 | //------------------------------------------------------------------------------------------------------- 676 | 677 | PlotBreakEvenCounter = 0 678 | PlotBreakEvenCounter := nz(PlotBreakEvenCounter[1]) 679 | BELong = 0 680 | BELong := nz(BELong[1]) 681 | BEShort = 0 682 | BEShort := nz(BEShort[1]) 683 | 684 | plotBreakevenshort = if ((Shorttradeactive == true) and (high > EntryLevel) and (Breakevenactive == true) and not Bartype3_a_short and not Bartype4_a_short) 685 | h = 1 // only required to make code work 686 | 687 | plotchar(plotBreakevenshort, char="0", location=location.abovebar, color=color.blue, transp=0, offset=0, size=size.small) 688 | 689 | if plotBreakevenshort == true 690 | tradeactive := false 691 | Shorttradeactive := false 692 | Breakevenactive := false 693 | PlotBreakEvenCounter := PlotBreakEvenCounter + 1 694 | BEShort := BEShort +1 695 | 696 | //plotBreakevenshort := false 697 | 698 | plotBreakevenlong = if ((Longtradeactive == true) and (low < EntryLevel) and (Breakevenactive == true) and not Bartype3_a_long and not Bartype4_a_long) 699 | e = 1 // only required to make code work 700 | 701 | plotchar(plotBreakevenlong, char="0", location=location.belowbar, color=color.blue, transp=0, offset=0, size=size.small) 702 | 703 | if plotBreakevenlong == true 704 | tradeactive := false 705 | Longtradeactive := false 706 | Breakevenactive := false 707 | PlotBreakEvenCounter := PlotBreakEvenCounter + 1 708 | BELong := BELong +1 709 | 710 | //plotBreakevenlong := false 711 | 712 | // Win trades 713 | //------------------------------------------------------------------------------------------------------- 714 | PlotWinCounter = 0 715 | PlotWinCounter := nz(PlotWinCounter[1]) 716 | WinLong = 0 717 | WinLong := nz(WinLong[1]) 718 | WinShort = 0 719 | WinShort := nz(WinShort[1]) 720 | 721 | plotWinshort = if ((Shorttradeactive == true) and (low < TPLevel)) 722 | n = 1 // only required to make code work 723 | 724 | plotchar(plotWinshort, char="✓", location=location.belowbar, color=color.green, transp=0, offset=0, size=size.small) 725 | 726 | if plotWinshort == true 727 | tradeactive := false 728 | Shorttradeactive := false 729 | Breakevenactive := false 730 | PlotWinCounter := PlotWinCounter + 1 731 | WinShort := WinShort +1 732 | 733 | //plotWinshort := false 734 | 735 | plotWinlong = if ((Longtradeactive == true) and (high > TPLevel)) 736 | l = 1 // only required to make code work 737 | 738 | plotchar(plotWinlong, char="✓", location=location.abovebar, color=color.green, transp=0, offset=0, size=size.small) 739 | 740 | if plotWinlong == true 741 | tradeactive := false 742 | Longtradeactive := false 743 | Breakevenactive := false 744 | PlotWinCounter := PlotWinCounter + 1 745 | WinLong := WinLong +1 746 | 747 | //plotWinlong := false 748 | 749 | 750 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 751 | // Trade closing signals 752 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 753 | 754 | // c=position e=bitmex-testnet t=market ro=1 755 | // Original Code Below 756 | // alertcondition(plotlosshort or plotlosslong or plotBreakevenshort or plotBreakevenlong, title='Lemon Close Trade BE or Stop', message='Lemon Close at BE or Stop') 757 | // alertcondition(plotWinshort or plotWinlong, title='Lemon Close Trade Win', message='Lemon Win') 758 | 759 | alertcondition(plotlosshort or plotlosslong or plotBreakevenshort or plotBreakevenlong, title='Lemon Close Trade BE or Stop', message="{{ticker}} Close") 760 | alertcondition(plotWinshort or plotWinlong, title='Lemon Close Trade Win', message="{{ticker}} Take Profit") 761 | 762 | EquityCurve = PlotWinCounter * 2 * USDRiskPerTrade - PlotLossCounter * USDRiskPerTrade - (PlotWinCounter + PlotLossCounter + PlotBreakEvenCounter) * commission 763 | 764 | 765 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 766 | // Statistics 767 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 768 | 769 | //if (plotWinlong or plotWinshort or plotBreakevenlong or plotBreakevenshort or plotlosslong or plotlosshort) and not HideStatistics 770 | // l = label.new(bar_index, high + StatisticsVerticalOffset, style=label.style_none, text="Win : " + tostring(PlotWinCounter) 771 | // + "\nLoss : " + tostring(PlotLossCounter) + "\nBE : " + tostring(PlotBreakEvenCounter),color = color.white, textcolor=color.white) 772 | 773 | winpercent = round((PlotWinCounter/(PlotWinCounter+PlotLossCounter+PlotBreakEvenCounter)*100)) 774 | losspercent = round((PlotLossCounter/(PlotWinCounter+PlotLossCounter+PlotBreakEvenCounter)*100)) 775 | bepercent = round((PlotBreakEvenCounter/(PlotWinCounter+PlotLossCounter+PlotBreakEvenCounter)*100)) 776 | rrpercent = round((PlotWinCounter/(PlotWinCounter+PlotLossCounter))*100) 777 | 778 | //if (plotWinlong or plotWinshort or plotBreakevenlong or plotBreakevenshort or plotlosslong or plotlosshort) and not HideStatistics 779 | // l = label.new(bar_index, high + StatisticsVerticalOffset, style=label.style_none, text="Win : " + tostring(PlotWinCounter) + " ("+ tostring(winpercent)+")% Long: " +tostring(WinLong) +" Short: "+ tostring(WinShort) 780 | // + "\nLoss : " + tostring(PlotLossCounter) +" ("+tostring(losspercent)+")%"+" Long: "+tostring(LossLong)+" Short: "+tostring(LossShort)+"\nBE : " + tostring(PlotBreakEvenCounter)+" ("+ tostring(bepercent)+")% Long: "+tostring(BELong)+" Short: "+tostring(BEShort),color = color.white, textcolor=color.white) 781 | 782 | if (plotWinlong or plotWinshort or plotBreakevenlong or plotBreakevenshort or plotlosslong or plotlosshort) and not HideStatistics 783 | l = label.new(bar_index, high + StatisticsVerticalOffset, style=label.style_none, text="Win : " + tostring(PlotWinCounter) + " ("+ tostring(winpercent)+"%)" 784 | + "\nLoss : " + tostring(PlotLossCounter) +" ("+tostring(losspercent)+"%)" + "\nBE : " + tostring(PlotBreakEvenCounter)+" ("+ tostring(bepercent)+"%)" + "\nRate : " + tostring (rrpercent)+"%)",color = color.white, textcolor=color.white) 785 | 786 | 787 | // The following line is in order to print the equity curve: 788 | //------------------------------------------------------------------------------------------------------- 789 | 790 | plot (DisplayEquityCurve == true ? EquityCurve : na, title = "Profit and Loss", color=color.yellow, linewidth=3, style=plot.style_line) 791 | 792 | // Grimm is the man // 793 | -------------------------------------------------------------------------------- /GitLemon - Simple Edition: -------------------------------------------------------------------------------- 1 | // LOVE JOY PEACE PATIENCE KINDNESS GOODNESS FAITHFULNESS GENTLENESS SELF-CONTROL 2 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ 3 | // Updated by: JoshuaMcGowan 4 | // Adding some checkpoints via global variables to resolve alerts not firing as expected. 5 | // Going to build a simple version just using the followig for the setup: 6 | // Location - Squeeze 7 | // Momo - M/W in Willy and OBV // Can add to this later 8 | // Structure - M/W in Price 9 | // Date: 03022020 10 | 11 | //@version=4 12 | //GitLemon 13 | study(title="GitLemon - Simple Edition", overlay=true, precision=8) 14 | 15 | // updated using git info and update on 2-19-20 for testing. 16 | // https://github.com/grimmolf/LemonTrading/blob/master/GrimmLemon 17 | 18 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 19 | // GLOBAL VARIABLES & INPUTS 20 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 21 | 22 | // GLOBAL VARIABLES 23 | // var longClose = 0 // Might not be needed for simple edition 24 | // var shortClose = 0 25 | 26 | // Global Checkpoint Variable Declarations 27 | // Checkpoint 1 - Squeeze Fires 28 | var cp1 = 0 29 | // Checkpoint 2 - Structure in Willy and OBV 30 | var cp2 = 0 31 | // Checkpoint 3 - Structure in Price 32 | var cp3 = 0 33 | // Checkpoint 4 - Fire Market Order (Future Forward Can Setup Limit or Buy on Break) // Trade State Active 2 or 3 34 | var cp4 = 0 35 | // Checkpoint 5 - Move stop to BE 36 | var cp5 = 0 37 | // Checkpoint 6 - Sell half at target and Trail Remaining 38 | var cp6 = 0 39 | 40 | //Trade State Values. 41 | //0=No orders working and not in active trade. 42 | //1=Orders working. 43 | //2=Active long. 44 | //3=Active short. 45 | var tradeState = 0 // Might not need this for simple edition. // Adding to Checkpoint 3 for testing. 46 | 47 | // INPUTS 48 | src = input(title="Source", type=input.source, defval=close) 49 | 50 | includePrice = input(defval=true, title="Use price") // Set to True 51 | strictPrice = input(defval=false, title="Strict") 52 | rangePrice = input(9, minval=5, title="Max. width of price W/M") // e.g. allow an price W/M to form over 7 bars. 53 | offsetPrice = input(0, minval=0, title="Max. offset of price W/M") // e.g. allow an price W/M to form 1 bar in history. Keep this number low. The goal is to synch the market structure over multiple indicators. 54 | 55 | includeOBV = input(defval=true, title="Use OBV") // Set to True 56 | strictOBV = input(defval=false, title="Strict") 57 | rangeOBV = input(9, minval=5, title="Max. width of OBV W/M") 58 | offsetOBV = input(0, minval=0, title="Max. offset of OBV W/M") 59 | 60 | includeWly = input(defval=true, title="Use Willy") 61 | includeWillyStupid = input(defval=false, title="Use Willy stupid") 62 | strictWly = input(defval=false, title="Strict") 63 | rangeWly = input(9, minval=5, title="Max. width of Willy W/M") 64 | offsetWly = input(0, minval=0, title="Max. offset of Willy W/M") 65 | lengthWly = input(21, minval=1, title="Willy length") 66 | lengthWlyEma = input(13, minval=1, title="Willy length ema") 67 | 68 | Leverage = input(1) 69 | USDRiskPerTrade = input(defval=1, title="Fixed risk amount per trade in USD", type=input.integer) // Changing to $1 from $50 70 | 71 | // commission = input(title="Estimated commission per round-turn in USD", defval=0.1744) 72 | commission = input(title="Estimated commission per round-turn in USD", defval=0.2) 73 | 74 | // FOR TTM SQUEEZE MODULE 75 | strict = input(false, title="Enabled (original) or Disabled (strict)") 76 | length = input(20, minval=1, title="BB Length") 77 | mult = input(2.0, minval=0.001, maxval=50, title="StDev") 78 | 79 | useTrueRange = input(true) 80 | klength = input(20, minval=1, title="Keltner Length") 81 | kmult = input(2, title="Multiplier") 82 | ksrc = input(close, title="Keltner Source") 83 | 84 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 85 | // NON-INPUT VARIABLES 86 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 87 | 88 | Min_Trade_Risk = atr(14) 89 | Max_Trade_Risk = 2*atr(14) 90 | StatisticsVerticalOffset = 3*atr(14) 91 | 92 | low_m1 = security(syminfo.tickerid, "1", low) 93 | high_m1 = security(syminfo.tickerid, "1", high) 94 | 95 | // FOR SQUEEZE MODULE 96 | basis = sma(src, length) // BBands 97 | dev = mult * stdev(src, length) 98 | upper = basis + dev 99 | lower = basis - dev 100 | 101 | ma = ema(src, klength) // Keltner 102 | ranger = useTrueRange ? tr : high - low 103 | rangema = ema(ranger, klength) 104 | kupper = ma + rangema * kmult 105 | klower = ma - rangema * kmult 106 | 107 | bband(length, mult) => 108 | sma(close, length) + mult * stdev(close, length) 109 | keltner(length, mult) => 110 | ema(close, length) + mult * ema(tr, length) 111 | 112 | // Used For Signal For Squeeze On 113 | diff = bband(length, 2) - keltner(length, 1) 114 | 115 | //FOR SQUEEZE MODULE 116 | //============================================================ 117 | e1 = (highest(high, length) + lowest(low, length)) / 2 + sma(close, length) 118 | osc = linreg(close - e1 / 2, length, 0) 119 | osc_color = osc[1] < osc[0] ? osc[0] >= 0 ? #00ffff : #cc00cc : osc[0] >= 0 ? #009b9b : #ff9bff 120 | 121 | SQON = strict and diff < 0 ? true : not strict and kupper > upper and klower < lower ? true : false 122 | mid_color = SQON ? color.red : color.green 123 | 124 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 125 | /// Checkpoint 1 - Squeeze Fires 126 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 127 | 128 | if SQON == true 129 | cp1 := 1 130 | else 131 | cp1 := 0 // Adding the else statement makes this non-persistent (acts like on-off switch) 132 | 133 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 134 | /// Level definitions and Calculations 135 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 136 | 137 | tradeactive = false // After initial testing consider making these Global Variables and updating with the Checkpoints. 138 | tradeactive := nz(tradeactive[1]) 139 | 140 | // STOP Level: 141 | StopLevel = 0.00000 142 | StopLevel := nz(StopLevel[1]) 143 | 144 | // Entry Level: 145 | EntryLevel = 0.00000 146 | EntryLevel := nz(EntryLevel[1]) 147 | 148 | // TP Level: 149 | TPLevel = 0.00000 150 | TPLevel := nz(TPLevel[1]) 151 | 152 | // Breakeven Level: 153 | BELevel = 0.00000 154 | BELevel := nz(BELevel[1]) 155 | 156 | // stopdistance 157 | stopdistance = 0.00000 158 | stopdistance := nz(stopdistance[1]) 159 | 160 | // TradeSizeInXBT 161 | TradeSizeInXBT = 0.00000 162 | TradeSizeInXBT := nz(TradeSizeInXBT[1]) 163 | 164 | // TradeSizeInUSD 165 | TradeSizeInUSD = 0 166 | TradeSizeInUSD := nz(TradeSizeInUSD[1]) 167 | 168 | //PositionMarginXBT 169 | PositionMarginXBT = 0.00000 170 | PositionMarginXBT := nz(PositionMarginXBT[1]) 171 | 172 | //MaxPosMarginXBT 173 | MaxPosMarginXBT = 0.00000 174 | MaxPosMarginXBT := nz(MaxPosMarginXBT[1]) 175 | 176 | // Long and Short trade definitions: 177 | //============================================================= 178 | Longtradeactive = false 179 | Longtradeactive := Longtradeactive[1] 180 | 181 | Shorttradeactive = false 182 | Shorttradeactive := Shorttradeactive[1] 183 | 184 | //CALCULATIONS 185 | 186 | // limit by period option 187 | limitPeriod = input(defval=false, title="Limit period (increases perfomance)") // This might be unneeded for simple edition 188 | lengthPeriod = input(240, minval=1, title="Length of period (hours)") 189 | 190 | hours_in_milliseconds = 1000 * 60 * 60 191 | withinPeriod = not limitPeriod or timenow - time < hours_in_milliseconds * lengthPeriod 192 | 193 | show_order_details = true 194 | entrySource = input(title="Source for stoploss", type=input.source, defval=close) 195 | stopLossSource = input(title="Source for entry", type=input.source, defval=close) 196 | stopLossPercentage = input(defval=0.01, minval=0, maxval=100, step=0.01, title="Stop loss %") 197 | riskRewardRatio = input(defval=5.0, minval=0.0, title="Risk to Reward 1-to-") 198 | 199 | //show = not barstate.isrealtime and (includePrice or includeOBV or includeWly) 200 | show = includePrice or includeOBV or includeWly 201 | 202 | // create a series of obv and willy values 203 | change_1 = change(src) 204 | OBVs = cum(change(src) > 0 ? volume : change_1 < 0 ? -volume : 0 * volume) 205 | 206 | // make willy series 207 | upperWly = highest(lengthWly) 208 | lowerWly = lowest(lengthWly) 209 | WLYs = 100 * (src - upperWly) / (upperWly - lowerWly) 210 | emaWly = ema(WLYs, lengthWlyEma) 211 | 212 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 213 | /// Structure Finder Functions 214 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 215 | 216 | series_a_above_series_b(seriesA, seriesB, aRange) => 217 | result = true 218 | for i = 0 to aRange - 1 by 1 219 | if seriesB[i] > seriesA[i] 220 | result := false 221 | break 222 | result := result 223 | result 224 | 225 | series_a_below_series_b(seriesA, seriesB, aRange) => 226 | result = true 227 | for i = 0 to aRange - 1 by 1 228 | if seriesB[i] < seriesA[i] 229 | result := false 230 | break 231 | result := result 232 | result 233 | 234 | dirmov(len) => 235 | up = change(high) 236 | down = -change(low) 237 | truerange = rma(tr, len) 238 | plus = fixnan(100 * rma(up > down and up > 0 ? up : 0, len) / truerange) 239 | minus = fixnan(100 * rma(down > up and down > 0 ? down : 0, len) / truerange) 240 | [plus, minus] 241 | 242 | data_W(aSeries, aRange, anOffset, strict) => 243 | e = 0 244 | d = 0 245 | c = 0 246 | b = 0 247 | a = 0 248 | valueE = aSeries[0] 249 | valueD = aSeries[0] 250 | valueC = aSeries[0] 251 | valueB = aSeries[0] 252 | valueA = aSeries[0] 253 | found = false 254 | 255 | for offset = 0 to anOffset by 1 256 | if found 257 | break 258 | e := 0 259 | d := 0 260 | c := 0 261 | b := 0 262 | a := 0 263 | valueE := aSeries[0] 264 | valueC := aSeries[0] 265 | valueD := aSeries[0] 266 | valueB := aSeries[0] 267 | valueA := aSeries[0] 268 | 269 | for i = 1 to aRange - 1 by 1 270 | // find d 271 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueC == aSeries[0] 272 | d := i + offset 273 | valueD := aSeries[i + offset] 274 | continue 275 | if d == 0 276 | break 277 | // find c 278 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueB == aSeries[0] 279 | c := i + offset 280 | valueC := aSeries[i + offset] 281 | continue 282 | if c == 0 283 | break 284 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueA == aSeries[0] 285 | b := i + offset 286 | valueB := aSeries[i + offset] 287 | continue 288 | if b == 0 289 | break 290 | if aSeries[i + offset] > aSeries[i + offset - 1] 291 | a := i + offset 292 | valueA := aSeries[i + offset] 293 | continue 294 | if a == 0 295 | break 296 | // W found if we have found point A, and point B has a lower value than point D 297 | found := a > 0 and a != b and c != 0 and d != 0 and aSeries[e] > aSeries[c] and 298 | aSeries[d] < aSeries[e] and aSeries[d] < aSeries[c] and 299 | (aSeries[b] <= aSeries[d] or not strict) and aSeries[b] < aSeries[a] 300 | found 301 | entry = found ? aSeries[c] : na 302 | stopLoss = found ? aSeries[b] * ((100 - stopLossPercentage) / 100) : na 303 | target = found ? entry + (entry - stopLoss) * riskRewardRatio : na 304 | [found, entry, stopLoss, target, a, b, c, d, e] 305 | 306 | data_M(aSeries, aRange, anOffset, strict) => 307 | e = 0 308 | d = 0 309 | c = 0 310 | b = 0 311 | a = 0 312 | valueE = aSeries[0] 313 | valueD = aSeries[0] 314 | valueC = aSeries[0] 315 | valueB = aSeries[0] 316 | valueA = aSeries[0] 317 | found = false 318 | 319 | for offset = 0 to anOffset by 1 320 | if found 321 | break 322 | e := 0 323 | d := 0 324 | c := 0 325 | b := 0 326 | a := 0 327 | valueE := aSeries[0] 328 | valueC := aSeries[0] 329 | valueD := aSeries[0] 330 | valueB := aSeries[0] 331 | valueA := aSeries[0] 332 | 333 | for i = 1 to aRange - 1 by 1 334 | // find d 335 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueC == aSeries[0] 336 | d := i + offset 337 | valueD := aSeries[i + offset] 338 | continue 339 | if d == 0 340 | break 341 | // find c 342 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueB == aSeries[0] 343 | c := i + offset 344 | valueC := aSeries[i + offset] 345 | continue 346 | if c == 0 347 | break 348 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueA == aSeries[0] 349 | b := i + offset 350 | valueB := aSeries[i + offset] 351 | continue 352 | if b == 0 353 | break 354 | if aSeries[i + offset] < aSeries[i + offset - 1] 355 | a := i + offset 356 | valueA := aSeries[i + offset] 357 | continue 358 | if a == 0 359 | break 360 | // M found if we have found point A, and point B has a greater value than point D 361 | found := a > 0 and a != b and c != 0 and d != 0 and aSeries[e] < aSeries[c] and 362 | aSeries[d] > aSeries[e] and aSeries[d] > aSeries[c] and 363 | (aSeries[b] >= aSeries[d] or not strict) and aSeries[b] > aSeries[a] 364 | found 365 | entry = found ? aSeries[c] : na 366 | stopLoss = found ? aSeries[b] * ((100 + stopLossPercentage) / 100) : na 367 | target = found ? entry - (stopLoss - entry) * riskRewardRatio : na 368 | [found, entry, stopLoss, target, a, b, c, d, e] 369 | 370 | find_W(aSeries, aRange, anOffset, strict) => 371 | [found, entry, stopLoss, target, a, b, c, d, e] = data_W(aSeries, aRange, anOffset, strict) 372 | found 373 | 374 | find_M(aSeries, aRange, anOffset, strict) => 375 | [found, entry, stopLoss, target, a, b, c, d, e] = data_M(aSeries, aRange, anOffset, strict) 376 | found 377 | 378 | label_1 = 'davo' 379 | label_entry = 'entry' 380 | 381 | // PLOT DAV-O 382 | [W_found, W_entry, W_stopLoss, W_target, W_pointA, W_pointB, W_pointC, W_pointD, W_pointE] = data_W(src, rangePrice, offsetPrice, strictPrice) 383 | [M_found, M_entry, M_stopLoss, M_target, M_pointA, M_pointB, M_pointC, M_pointD, M_pointE] = data_M(src, rangePrice, offsetPrice, strictPrice) 384 | priceW = includePrice == false or W_found 385 | priceM = includePrice == false or M_found 386 | 387 | OBVw = includeOBV == false or find_W(OBVs, rangeOBV, offsetOBV, strictOBV) 388 | OBVm = includeOBV == false or find_M(OBVs, rangeOBV, offsetOBV, strictOBV) 389 | 390 | Wlyw = includeWly == false or find_W(WLYs, rangeWly, offsetWly, strictWly) 391 | Wlym = includeWly == false or find_M(WLYs, rangeWly, offsetWly, strictWly) 392 | 393 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 394 | /// Checkpoint 2 395 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 396 | 397 | // Checkpoint 2 - Structure in Willy and OBV 398 | // Longs 399 | if (OBVw and Wlyw and withinPeriod and (includeWillyStupid == false or emaWly < -80) and cp1==1) 400 | cp2 := 1 401 | else 402 | cp2 := 0 // Adding the else statement makes this non-persistent 403 | 404 | // Shorts 405 | if (OBVm and Wlym and withinPeriod and (includeWillyStupid == false or emaWly > -20) and cp1==1) 406 | cp2 := 1 407 | else 408 | cp2 := 0 // Adding the else statement makes this non-persistent (acts like on-off switch) 409 | 410 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 411 | /// Checkpoint 3 412 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 413 | 414 | longCondition = false 415 | shortCondition = false 416 | 417 | // Checkpoint 3 - Structure in Price 418 | // Longs 419 | if (priceW and cp2==1) and not (tradeState==2 or tradeState==3) 420 | cp3 := 1 421 | longCondition := true 422 | tradeState := 2 423 | else 424 | cp3 := 0 // Adding the else statement makes this non-persistent 425 | longCondition := false 426 | tradeState := 0 427 | 428 | // Shorts 429 | if (priceM and cp2==1) and not (tradeState==2 or tradeState==3) 430 | cp3 := 1 431 | shortCondition := true 432 | tradeState := 3 433 | else 434 | cp3 := 0 // Adding the else statement makes this non-persistent (acts like on-off switch) 435 | shortCondition := false 436 | tradeState := 0 437 | 438 | // Long and Short Condition // Moved Up. 439 | // longCondition = priceW and OBVw and Wlyw and withinPeriod and (includeWillyStupid == false or emaWly < -80) 440 | // shortCondition = priceM and OBVm and Wlym and withinPeriod and (includeWillyStupid == false or emaWly > -20) 441 | 442 | // calculate entry, stoploss and target 443 | entrySourceLong = entrySource == low ? high : entrySource 444 | entrySourceShort = entrySource == high ? low : entrySource 445 | stopSourceLong = stopLossSource == high ? low : stopLossSource 446 | stopSourceShort = stopLossSource == low ? high : stopLossSource 447 | 448 | long_entry = show and longCondition and not longCondition[1] ? entrySourceLong[W_pointC] : na 449 | lowest_1 = lowest(stopSourceLong, rangePrice) 450 | long_stoploss = show and longCondition and not longCondition[1] ? 451 | lowest_1 * ((100 - stopLossPercentage) / 100) : na 452 | long_target = show and longCondition and not longCondition[1] ? 453 | long_entry + (long_entry - long_stoploss) * riskRewardRatio : na 454 | 455 | short_entry = show and shortCondition and not shortCondition[1] ? entrySourceShort[M_pointC] : 456 | na 457 | highest_1 = highest(stopSourceShort, rangePrice) 458 | short_stoploss = show and shortCondition and not shortCondition[1] ? 459 | highest_1 * ((100 + stopLossPercentage) / 100) : na 460 | short_target = show and shortCondition and not shortCondition[1] ? 461 | short_entry - (short_stoploss - short_entry) * riskRewardRatio : na 462 | 463 | entry = long_entry ? long_entry : short_entry ? short_entry : na 464 | stoploss = long_stoploss ? long_stoploss : short_stoploss ? short_stoploss : na 465 | target = long_target ? long_target : short_target ? short_target : na 466 | 467 | // define plot settings for entry, stoploss and target 468 | transparency = show_order_details ? 0 : 100 469 | clr_entry = show and (longCondition or shortCondition) ? color.white : na 470 | clr_stoploss = show and (longCondition or shortCondition) ? color.red : na 471 | clr_target = show and (longCondition or shortCondition) ? color.lime : na 472 | 473 | //============================================================ 474 | // Alerts for Trade opening 475 | //============================================================ 476 | 477 | alertcondition(show and longCondition and not longCondition[1] and SQON, title='Lemon Entry Trade Sig Long', message="e=bitmex-testnet s=xbtusd b=long q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") // Orig 478 | alertcondition(show and shortCondition and not shortCondition[1] and SQON, title='Lemon Entry Trade Sig Short', message="e=bitmex-testnet s=xbtusd b=short q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") 479 | 480 | //============================================================ 481 | //Plots for trade signal 482 | //============================================================ 483 | 484 | Shorttradetrigger = if (show and shortCondition and not shortCondition[1] and SQON) 485 | StopLevel := highest_1 * ((100 + stopLossPercentage) / 100) 486 | EntryLevel := entrySourceShort[M_pointC] 487 | TPLevel := short_entry - (short_stoploss - short_entry) * riskRewardRatio 488 | BELevel := EntryLevel - (StopLevel - EntryLevel) 489 | stopdistance := StopLevel - EntryLevel 490 | TradeSizeInXBT := USDRiskPerTrade / stopdistance 491 | TradeSizeInUSD := round(EntryLevel * TradeSizeInXBT) //remove factor 1000 for live trading 492 | PositionMarginXBT := (round(100000 * TradeSizeInXBT / Leverage)) / 100000 493 | MaxPosMarginXBT := (round(100000 * USDRiskPerTrade / Min_Trade_Risk / Leverage)) / 100000 494 | tradeactive := true 495 | Shorttradeactive := true 496 | 497 | Longtradetrigger = if (show and longCondition and not longCondition[1] and SQON) 498 | StopLevel := lowest_1 * ((100 - stopLossPercentage) / 100) 499 | EntryLevel := entrySourceLong[W_pointC] 500 | TPLevel := long_entry + (long_entry - long_stoploss) * riskRewardRatio 501 | BELevel := (EntryLevel - StopLevel) + EntryLevel 502 | stopdistance := EntryLevel - StopLevel 503 | TradeSizeInXBT := USDRiskPerTrade / stopdistance 504 | TradeSizeInUSD := round(EntryLevel * TradeSizeInXBT) //remove factor 1000 for live trading 505 | PositionMarginXBT := (round(100000 * TradeSizeInXBT / Leverage)) / 100000 506 | MaxPosMarginXBT := (round(100000 * USDRiskPerTrade / Min_Trade_Risk / Leverage)) / 100000 507 | tradeactive := true 508 | Longtradeactive := true 509 | 510 | // Plot 0 511 | plot(TradeSizeInUSD, title="TradeSizeInUSD", transp=100) // This will be the q= 512 | // Plot 1 513 | plot(EntryLevel, title="EntryLevel", transp=100) // This will be the fp= after testing using market orders 514 | // Plot 2 515 | plot(USDRiskPerTrade, title="USDRiskPerTrade", transp=100) // Shows risk per trade/loss. Multiply by Risk/Reward for Win estimates 516 | // Plot 3 517 | plot(riskRewardRatio, title="riskRewardRatio", transp=100) 518 | 519 | // Debug Plot for SQON 520 | plot(SQON==true ? 1 : 0, title="SQON", transp=100) 521 | 522 | // PLOT LEMON 523 | plotshape(show and longCondition and not longCondition[1] and SQON, title="Lemon long", style=shape.triangleup, location=location.belowbar, color=color.lime, text="Lemon-Long") 524 | plotshape(show and shortCondition and not shortCondition[1] and SQON, title="Lemon short", style=shape.triangledown, location=location.abovebar, color=color.red, text="Lemon-Short") 525 | plotshape(show and longCondition[1], title="Lemon long confirmed", style=shape.cross, location=location.bottom, color=color.lime, text="alert", transp=100) 526 | plotshape(show and shortCondition[1], title="Lemon short confirmed", style=shape.cross, location=location.top, color=color.red, text="alert", transp=100) 527 | 528 | if Shorttradeactive == true 529 | Shorttradetrigger := false 530 | 531 | if Longtradeactive == true 532 | Longtradetrigger := false 533 | 534 | // Plot Levels: 535 | pl1 = plot (StopLevel, title = "stoplevel", color=color.red) 536 | pl2 = plot (EntryLevel, title = "entrylevel", color=color.yellow, transp=50) 537 | pl3 = plot (BELevel, title = "breakevenlevel", color=color.blue) 538 | pl4 = plot (TPLevel, title = "TPlevel", color=color.green) 539 | 540 | fill(pl1, pl2, color=color.red, transp=65) 541 | fill(pl2, pl3, color=color.blue, transp=65) 542 | fill(pl3, pl4, color=color.green, transp=65) 543 | 544 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 545 | // Define and plot conflicting candles: 546 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 547 | 548 | // Subtypes of conflicting bars: 549 | //------------------------------------------------------------------------------------------------------- 550 | 551 | // Bartype 3a is a candle which crosses both BELevel and EntryLevel and has its close above the midline between BELevel and EntryLevel (longs) 552 | // respecively has its close below the midline between BELevel and EntryLevel (shorts) 553 | // In case of a Bartype 3a the logic shall NOT consider a trade as closed as break-even, but shall assume trade continuation with activated break-even-flag. 554 | //------------------------------------------------------------------------------------------------------- 555 | 556 | Bartype3_a_long = high > BELevel and high < TPLevel and low < EntryLevel and low > StopLevel and close > ((BELevel + EntryLevel)/2) and Longtradeactive 557 | Bartype3_a_short = high > EntryLevel and high < StopLevel and low < BELevel and low > TPLevel and close < ((BELevel + EntryLevel)/2) and Shorttradeactive 558 | 559 | // Bartype 4a is a candle which crosses TPLevel, BELevel and EntryLevel and has its close above BELevel (longs) respectively close below BELevel (shorts) 560 | // In case of a Bartype 4a the logic shall consider a trade as closed winner and shall not assume trade as closed break-even. 561 | //------------------------------------------------------------------------------------------------------- 562 | 563 | Bartype4_a_long = high > TPLevel and low < EntryLevel and low > StopLevel and close > BELevel and Longtradeactive 564 | Bartype4_a_short = high > EntryLevel and high < StopLevel and low < TPLevel and close < BELevel and Shorttradeactive 565 | 566 | 567 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 568 | // Trade resolution: 569 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 570 | 571 | // Breakeven activation 572 | //------------------------------------------------------------------------------------------------------- 573 | shorttradeBElevelactivation = (low < BELevel) and not (low_m1 < TPLevel) 574 | longtradeBElevelactivation = (high > BELevel) and not (high_m1 > TPLevel) 575 | 576 | Breakevenactive = false 577 | Breakevenactive := nz(Breakevenactive[1]) 578 | 579 | if ((Shorttradeactive == true) and (shorttradeBElevelactivation == true)) 580 | Breakevenactive := true 581 | 582 | if ((Longtradeactive == true) and (longtradeBElevelactivation == true)) 583 | Breakevenactive := true 584 | 585 | // Loss trades 586 | //------------------------------------------------------------------------------------------------------- 587 | 588 | PlotLossCounter = 0 589 | PlotLossCounter := nz(PlotLossCounter[1]) 590 | 591 | plotlosshort = if ((Shorttradeactive == true) and (high > StopLevel) and (Breakevenactive == false)) 592 | y = 1 // only required to make code work 593 | 594 | plotchar(plotlosshort, char="X", title = "X Short", location=location.abovebar, color=color.fuchsia, transp=0, offset=0, size=size.small) 595 | 596 | if plotlosshort == true 597 | tradeactive := false 598 | Shorttradeactive := false 599 | Breakevenactive := false 600 | PlotLossCounter := PlotLossCounter + 1 601 | 602 | plotlosslong = if ((Longtradeactive == true) and (low < StopLevel) and (Breakevenactive == false)) 603 | r = 1 // only required to make code work 604 | 605 | plotchar(plotlosslong, char="X", title = "X Long", location=location.belowbar, color=color.fuchsia, transp=0, offset=0, size=size.small) 606 | 607 | if plotlosslong == true 608 | tradeactive := false 609 | Longtradeactive := false 610 | Breakevenactive := false 611 | PlotLossCounter := PlotLossCounter + 1 612 | 613 | // Breakeven trades 614 | //------------------------------------------------------------------------------------------------------- 615 | 616 | PlotBreakEvenCounter = 0 617 | PlotBreakEvenCounter := nz(PlotBreakEvenCounter[1]) 618 | 619 | plotBreakevenshort = if ((Shorttradeactive == true) and (high > EntryLevel) and (Breakevenactive == true) and not Bartype3_a_short and not Bartype4_a_short) 620 | h = 1 // only required to make code work 621 | 622 | plotchar(plotBreakevenshort, char="0", title = "0 Short", location=location.abovebar, color=color.blue, transp=0, offset=0, size=size.small) 623 | 624 | if plotBreakevenshort == true 625 | tradeactive := false 626 | Shorttradeactive := false 627 | Breakevenactive := false 628 | PlotBreakEvenCounter := PlotBreakEvenCounter + 1 629 | 630 | plotBreakevenlong = if ((Longtradeactive == true) and (low < EntryLevel) and (Breakevenactive == true) and not Bartype3_a_long and not Bartype4_a_long) 631 | e = 1 // only required to make code work 632 | 633 | plotchar(plotBreakevenlong, char="0", title = "0 Long", location=location.belowbar, color=color.blue, transp=0, offset=0, size=size.small) 634 | 635 | if plotBreakevenlong == true 636 | tradeactive := false 637 | Longtradeactive := false 638 | Breakevenactive := false 639 | PlotBreakEvenCounter := PlotBreakEvenCounter + 1 640 | 641 | // Win trades 642 | //------------------------------------------------------------------------------------------------------- 643 | PlotWinCounter = 0 644 | PlotWinCounter := nz(PlotWinCounter[1]) 645 | 646 | plotWinshort = if ((Shorttradeactive == true) and (low < TPLevel)) 647 | n = 1 // only required to make code work 648 | 649 | plotchar(plotWinshort, char="1", title = "1 Short", location=location.belowbar, color=color.green, transp=0, offset=0, size=size.small) 650 | 651 | if plotWinshort == true 652 | tradeactive := false 653 | Shorttradeactive := false 654 | Breakevenactive := false 655 | PlotWinCounter := PlotWinCounter + 1 656 | 657 | plotWinlong = if ((Longtradeactive == true) and (high > TPLevel)) 658 | l = 1 // only required to make code work 659 | 660 | plotchar(plotWinlong, char="1", title = "1 Long", location=location.abovebar, color=color.green, transp=0, offset=0, size=size.small) 661 | 662 | if plotWinlong == true 663 | tradeactive := false 664 | Longtradeactive := false 665 | Breakevenactive := false 666 | PlotWinCounter := PlotWinCounter + 1 667 | 668 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 669 | // Trade closing signals 670 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 671 | 672 | alertcondition(plotlosshort or plotlosslong or plotBreakevenshort or plotBreakevenlong, title='Lemon Close Trade BE or Stop', message="c=position e=bitmex-testnet t=market ro=1") 673 | alertcondition(plotWinshort or plotWinlong, title='Lemon Close Trade Win', message="c=position e=bitmex-testnet t=market ro=1") 674 | 675 | EquityCurve = PlotWinCounter * 2 * USDRiskPerTrade - PlotLossCounter * USDRiskPerTrade - (PlotWinCounter + PlotLossCounter + PlotBreakEvenCounter) * commission 676 | 677 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 678 | // Statistics 679 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 680 | 681 | if (plotWinlong or plotWinshort or plotBreakevenlong or plotBreakevenshort or plotlosslong or plotlosshort) 682 | l = label.new(bar_index, high + StatisticsVerticalOffset, style=label.style_none, text="Win : " + tostring(PlotWinCounter) 683 | + "\nLoss : " + tostring(PlotLossCounter) + "\nBE : " + tostring(PlotBreakEvenCounter),color = color.white, textcolor=color.white) 684 | 685 | // Debug Plots 686 | 687 | plot(longCondition==true ? 1 : 0, title="longCondition", transp=100) 688 | plot(shortCondition==true ? 1 : 0, title="shortCondition", transp=100) 689 | plot(tradeState, title="tradeState", transp=100) 690 | 691 | plotshape(cp1, "cp1", shape.circle, location.top, color.silver, text = "1", size = size.small) 692 | plotshape(cp2, "cp2", shape.diamond, location.top, color.orange, text = "2", size = size.tiny) 693 | plotshape(cp3, "cp3", shape.circle, location.bottom, color.fuchsia, text = "3", size = size.small) 694 | plotshape(cp4, "cp4", shape.diamond, location.bottom, color.aqua, text = "4", size = size.tiny) 695 | plotshape(cp5, "cp5", shape.triangleup, location.belowbar, color.green, 0, text = "cond5", size = size.tiny) 696 | plotshape(cp6, "cp6", shape.triangledown, location.abovebar, color.maroon, 0, text = "cond6", size = size.tiny) 697 | // Place these markers one bar late so they don't overprint the "plotshape()" triangles. 698 | // plotchar(cond5[1], "cond5", "⮝", location.belowbar, color.lime, 0, size = size.tiny) 699 | // plotchar(cond6[1], "cond6", "⮟", location.abovebar, color.red, 0, size = size.tiny) 700 | 701 | // Grimm is the man // 702 | -------------------------------------------------------------------------------- /Gitlemon - Conservative (enters on E): -------------------------------------------------------------------------------- 1 | //@version=4 2 | //GitLemon 3 | study(title="GitLemon Con", shorttitle="GitLemon Con", overlay=true, precision=8) 4 | 5 | 6 | // INPUTS 7 | src = input(title="Source", type=input.source, defval=close) 8 | 9 | globalwidth = input(9, minval=5, title="Global Max Width of W/M") 10 | globaloffset = input(0, minval=0, title="Global Offset of W/M") 11 | 12 | includePrice = input(defval=true, title="Use price") 13 | strictPrice = input(defval=false, title="Strict") 14 | //rangePrice = input(9, minval=5, title="Max. width of price W/M") // e.g. allow an price W/M to form over 7 bars. 15 | //offsetPrice = input(0, minval=0, title="Max. offset of price W/M") // e.g. allow an price W/M to form 1 bar in history. Keep this number low. The goal is to synch the market structure over multiple indicators. 16 | rangePrice = globalwidth 17 | offsetPrice = globaloffset 18 | 19 | includeOBV = input(defval=true, title="Use OBV") 20 | strictOBV = input(defval=false, title="Strict") 21 | //rangeOBV = input(9, minval=5, title="Max. width of OBV W/M") 22 | //offsetOBV = input(0, minval=0, title="Max. offset of OBV W/M") 23 | rangeOBV = globalwidth 24 | offsetOBV = globaloffset 25 | 26 | includeWly = input(defval=true, title="Use Willy") 27 | includeWillyStupid = input(defval=false, title="Use Willy stupid") 28 | strictWly = input(defval=false, title="Strict") 29 | //rangeWly = input(9, minval=5, title="Max. width of Willy W/M") 30 | //offsetWly = input(0, minval=0, title="Max. offset of Willy W/M") 31 | rangeWly = globalwidth 32 | offsetWly = globaloffset 33 | lengthWly = input(21, minval=1, title="Willy length") 34 | lengthWlyEma = input(13, minval=1, title="Willy length ema") 35 | 36 | 37 | includeMFI = input(defval=false, title="Use MFI") 38 | strictMFI = input(defval=true, title="Strict") 39 | //rangeMFI = input(9, minval=5, title="Max. width of MFI W/M") 40 | //offsetMFI = input(0, minval=0, title="Max. offset of MFI W/M") 41 | rangeMFI = globalwidth 42 | offsetMFI = globaloffset 43 | lengthMFI = input(14, minval=1, title="MFI length") 44 | 45 | includeRSI = input(defval=false, title="Use RSI") 46 | strictRSI = input(defval=true, title="Strict") 47 | //rangeRSI = input(9, minval=5, title="Max. width of RSI W/M") 48 | //offsetRSI = input(0, minval=0, title="Max. offset of RSI W/M") 49 | rangeRSI = globalwidth 50 | offsetRSI = globaloffset 51 | lengthRSI = input(14, minval=1, title="RSI length") 52 | 53 | includeDMI = input(defval=false, title="Use DMI (DI+ & DI-)") 54 | strictDMI = input(defval=true, title="Strict") 55 | //rangeDMI = input(9, minval=5, title="Max. width of DMI W/M") 56 | //offsetDMI = input(0, minval=0, title="Max. offset of DMI W/M") 57 | rangeDMI = globalwidth 58 | offsetDMI = globaloffset 59 | lengthDMI = input(14, minval=1, title="DMI length") 60 | 61 | includeWithinRLZ = input(defval=false, title="Price within RLZ") 62 | includeBelowRLZ = input(defval=false, title="Price above/below RLZ") 63 | upperBoundRLZ = input(defval=61.8, minval=0.0, maxval=100.0, title="Upper bound of RLZ (fib)") 64 | lowerBoundRLZ = input(defval=78.6, minval=0.0, maxval=100.0, title="Lower bound of RLZ (fib)") 65 | lengthPeriodRLZ = input(defval=200, minval=5, title="Lookback period (bars)") 66 | showRLZLong = input(defval=false, title="Draw RLZ long") 67 | showRLZShort = input(defval=false, title="Draw RLZ short") 68 | 69 | ATH = highest(high, lengthPeriodRLZ) 70 | ATL = lowest(low, lengthPeriodRLZ) 71 | 72 | Leverage = input(1) 73 | USDRiskPerTrade = input(defval=1, title="Fixed risk amount per trade in USD", type=input.integer) // Changing to $1 from $50 74 | 75 | HideStatistics = input(false) 76 | DisplayEquityCurve = input(false) 77 | 78 | // commission = input(title="Estimated commission per round-turn in USD", defval=0.1744) 79 | commission = input(title="Estimated commission per round-turn in USD", defval=0.2) 80 | 81 | // FOR TTM SQUEEZE MODULE 82 | strict = input(false, title="Enabled (original) or Disabled (strict)") 83 | length = input(20, minval=1, title="BB Length") 84 | mult = input(2.0, minval=0.001, maxval=50, title="StDev") 85 | 86 | useTrueRange = input(true) 87 | klength = input(20, minval=1, title="Keltner Length") 88 | kmult = input(2.0, title="Multiplier") 89 | ksrc = input(close, title="Keltner Source") 90 | 91 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 92 | // NON-INPUT VARIABLES 93 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 94 | Min_Trade_Risk = 2*atr(14) 95 | Max_Trade_Risk = 4*atr(14) 96 | StatisticsVerticalOffset = 3*atr(14) 97 | 98 | low_m1 = security(syminfo.tickerid, "1", low) 99 | high_m1 = security(syminfo.tickerid, "1", high) 100 | 101 | range = ATH - ATL 102 | 103 | // FOR SQUEEZE MODULE 104 | basis = sma(src, length) 105 | dev = mult * stdev(src, length) 106 | upper = basis + dev 107 | lower = basis - dev 108 | 109 | ma = ema(src, klength) 110 | ranger = useTrueRange ? tr : high - low 111 | rangema = ema(ranger, klength) 112 | kupper = ma + rangema * kmult 113 | klower = ma - rangema * kmult 114 | //c = color.blue 115 | 116 | bband(length, mult) => 117 | sma(close, length) + mult * stdev(close, length) 118 | keltner(length, mult) => 119 | ema(close, length) + mult * ema(tr, length) 120 | 121 | diff = bband(length, 2) - keltner(length, 1) 122 | 123 | 124 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 125 | /// Level definitions: 126 | ///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 127 | 128 | tradeactive = false 129 | tradeactive := nz(tradeactive[1]) 130 | 131 | 132 | // STOP Level: 133 | StopLevel = 0.00000 134 | StopLevel := nz(StopLevel[1]) 135 | 136 | // Entry Level: 137 | EntryLevel = 0.00000 138 | EntryLevel := nz(EntryLevel[1]) 139 | 140 | // TP Level: 141 | TPLevel = 0.00000 142 | TPLevel := nz(TPLevel[1]) 143 | 144 | // Breakeven Level: 145 | BELevel = 0.00000 146 | BELevel := nz(BELevel[1]) 147 | 148 | // stopdistance 149 | stopdistance = 0.00000 150 | stopdistance := nz(stopdistance[1]) 151 | 152 | // TradeSizeInXBT 153 | TradeSizeInXBT = 0.00000 154 | TradeSizeInXBT := nz(TradeSizeInXBT[1]) 155 | 156 | // TradeSizeInUSD 157 | TradeSizeInUSD = 0 158 | TradeSizeInUSD := nz(TradeSizeInUSD[1]) 159 | 160 | //PositionMarginXBT 161 | PositionMarginXBT = 0.00000 162 | PositionMarginXBT := nz(PositionMarginXBT[1]) 163 | 164 | //MaxPosMarginXBT 165 | MaxPosMarginXBT = 0.00000 166 | MaxPosMarginXBT := nz(MaxPosMarginXBT[1]) 167 | 168 | // Long and Short trade definitions: 169 | //============================================================= 170 | Longtradeactive = false 171 | Longtradeactive := Longtradeactive[1] 172 | 173 | Shorttradeactive = false 174 | Shorttradeactive := Shorttradeactive[1] 175 | 176 | //CALCULATIONS 177 | 178 | 179 | is_rlz_long = barssince(highest(high, lengthPeriodRLZ)) >= 180 | barssince(lowest(low, lengthPeriodRLZ)) 181 | is_rlz_short = barssince(highest(high, lengthPeriodRLZ)) < 182 | barssince(lowest(low, lengthPeriodRLZ)) 183 | 184 | longUpperRLZ = showRLZLong ? (1 - upperBoundRLZ / 100) * range + ATL : na 185 | longLowerRLZ = showRLZLong ? (1 - lowerBoundRLZ / 100) * range + ATL : na 186 | longWithinRLZ = longUpperRLZ >= src and src >= longLowerRLZ 187 | longBelowRLZ = longLowerRLZ > src 188 | // Moved below Plot for Trade Size for Autoview Testing 189 | // // Plot 0 190 | // p1 = plot(longUpperRLZ, color=color.green, title="61.8 (long)") 191 | // // Plot 1 192 | // p2 = plot(longLowerRLZ, color=color.green, title="78.6 (long)") 193 | // fill(p1, p2, color=#7DCEA0, transp=90, title="RLZ long") 194 | 195 | shortUpperRLZ = showRLZShort ? ATH - (1 - upperBoundRLZ / 100) * range : na 196 | shortLowerRLZ = showRLZShort ? ATH - (1 - lowerBoundRLZ / 100) * range : na 197 | shortWithinRLZ = shortUpperRLZ <= src and src <= shortLowerRLZ 198 | shortAboveRLZ = shortLowerRLZ < src 199 | // // Plot 2 200 | // p3 = plot(shortUpperRLZ, color=color.red, title="78.6 (short)") 201 | // // Plot 3 202 | // p4 = plot(shortLowerRLZ, color=color.red, title="61.8 (short)") 203 | // fill(p3, p4, color=#cd6155, transp=90, title="RLZ short") 204 | 205 | includeSMA = input(defval=false, title="Price above/below SMA") 206 | lengthSMA = input(20, minval=1, title="SMA length") 207 | 208 | // limit by period option 209 | limitPeriod = input(defval=false, title="Limit period (increases perfomance)") 210 | lengthPeriod = input(245, minval=1, title="Length of period (hours)") 211 | 212 | hours_in_milliseconds = 1000 * 60 * 60 213 | withinPeriod = not limitPeriod or timenow - time < hours_in_milliseconds * lengthPeriod 214 | 215 | // quickLook = input(defval = true, title = "Quick Look") // ignores historic data and will plot a signal on the chart 216 | // show_order_details = input(defval = true, title = "Show entry / stoploss / target") // show entry, stoploss and target (toggling this doesn't work) 217 | show_order_details = true 218 | entrySource = input(title="Entry Source", type=input.source, defval=close) 219 | stopLossSource = input(title="Stop Source", type=input.source, defval=open) 220 | stopLossPercentage = input(defval=0.033, minval=0, maxval=100, step=0.01, title="Stop loss %") 221 | riskRewardRatio = input(defval=3.0, minval=0.0, title="Risk to Reward 1-to-") 222 | 223 | // removed the barstate.isreadltime as it seems to be causing a race condition preventing alerts from firing 224 | //show = not barstate.isrealtime and (includePrice or includeOBV or includeRSI or includeWly or includeMFI or includeDMI) 225 | show = includePrice or includeOBV or includeRSI or includeWly or includeMFI or includeDMI 226 | //showPotential = barstate.isrealtime and (includePrice or includeOBV or includeRSI or includeWly or includeMFI or includeDMI) and option_potential 227 | 228 | // create a series of obv, mfi, rsi, sma and willy values 229 | change_1 = change(src) 230 | OBVs = cum(change(src) > 0 ? volume : change_1 < 0 ? -volume : 0 * volume) 231 | // caclulate mfi series 232 | upper_s = sum(volume * (change(hlc3) <= 0 ? 0 : hlc3), lengthMFI) 233 | lower_s = sum(volume * (change(hlc3) >= 0 ? 0 : hlc3), lengthMFI) 234 | MFIs = rsi(upper_s, lower_s) 235 | RSIs = rsi(src,lengthRSI) 236 | SMAs = sma(src, lengthSMA) 237 | // make willy series 238 | upperWly = highest(lengthWly) 239 | lowerWly = lowest(lengthWly) 240 | WLYs = 100 * (src - upperWly) / (upperWly - lowerWly) 241 | emaWly = ema(WLYs, lengthWlyEma) 242 | 243 | series_a_above_series_b(seriesA, seriesB, aRange) => 244 | result = true 245 | for i = 0 to aRange - 1 by 1 246 | if seriesB[i] > seriesA[i] 247 | result := false 248 | break 249 | result := result 250 | result 251 | 252 | series_a_below_series_b(seriesA, seriesB, aRange) => 253 | result = true 254 | for i = 0 to aRange - 1 by 1 255 | if seriesB[i] < seriesA[i] 256 | result := false 257 | break 258 | result := result 259 | result 260 | 261 | dirmov(len) => 262 | up = change(high) 263 | down = -change(low) 264 | truerange = rma(tr, len) 265 | plus = fixnan(100 * rma(up > down and up > 0 ? up : 0, len) / truerange) 266 | minus = fixnan(100 * rma(down > up and down > 0 ? down : 0, len) / truerange) 267 | [plus, minus] 268 | 269 | data_W(aSeries, aRange, anOffset, strict) => 270 | e = 0 271 | d = 0 272 | c = 0 273 | b = 0 274 | a = 0 275 | valueE = aSeries[0] 276 | valueD = aSeries[0] 277 | valueC = aSeries[0] 278 | valueB = aSeries[0] 279 | valueA = aSeries[0] 280 | found = false 281 | 282 | for offset = 0 to anOffset by 1 283 | if found 284 | break 285 | e := 0 286 | d := 0 287 | c := 0 288 | b := 0 289 | a := 0 290 | valueE := aSeries[0] 291 | valueC := aSeries[0] 292 | valueD := aSeries[0] 293 | valueB := aSeries[0] 294 | valueA := aSeries[0] 295 | 296 | for i = 1 to aRange - 1 by 1 297 | // find d 298 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueC == aSeries[0] 299 | d := i + offset 300 | valueD := aSeries[i + offset] 301 | continue 302 | if d == 0 303 | break 304 | // find c 305 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueB == aSeries[0] 306 | c := i + offset 307 | valueC := aSeries[i + offset] 308 | continue 309 | if c == 0 310 | break 311 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueA == aSeries[0] 312 | b := i + offset 313 | valueB := aSeries[i + offset] 314 | continue 315 | if b == 0 316 | break 317 | if aSeries[i + offset] > aSeries[i + offset - 1] 318 | a := i + offset 319 | valueA := aSeries[i + offset] 320 | continue 321 | if a == 0 322 | break 323 | // W found if we have found point A, and point B has a lower value than point D 324 | found := a > 0 and a != b and c != 0 and d != 0 and aSeries[e] > aSeries[c] and 325 | aSeries[d] < aSeries[e] and aSeries[d] < aSeries[c] and 326 | (aSeries[b] <= aSeries[d] or not strict) and aSeries[b] < aSeries[a] 327 | found 328 | entry = found ? aSeries[e] : na 329 | stopLoss = found ? aSeries[b] * ((100 - stopLossPercentage) / 100) : na 330 | target = found ? entry + (entry - stopLoss) * riskRewardRatio : na 331 | [found, entry, stopLoss, target, a, b, c, d, e] 332 | 333 | data_M(aSeries, aRange, anOffset, strict) => 334 | e = 0 335 | d = 0 336 | c = 0 337 | b = 0 338 | a = 0 339 | valueE = aSeries[0] 340 | valueD = aSeries[0] 341 | valueC = aSeries[0] 342 | valueB = aSeries[0] 343 | valueA = aSeries[0] 344 | found = false 345 | 346 | for offset = 0 to anOffset by 1 347 | if found 348 | break 349 | e := 0 350 | d := 0 351 | c := 0 352 | b := 0 353 | a := 0 354 | valueE := aSeries[0] 355 | valueC := aSeries[0] 356 | valueD := aSeries[0] 357 | valueB := aSeries[0] 358 | valueA := aSeries[0] 359 | 360 | for i = 1 to aRange - 1 by 1 361 | // find d 362 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueC == aSeries[0] 363 | d := i + offset 364 | valueD := aSeries[i + offset] 365 | continue 366 | if d == 0 367 | break 368 | // find c 369 | if aSeries[i + offset] < aSeries[i + offset - 1] and valueB == aSeries[0] 370 | c := i + offset 371 | valueC := aSeries[i + offset] 372 | continue 373 | if c == 0 374 | break 375 | if aSeries[i + offset] > aSeries[i + offset - 1] and valueA == aSeries[0] 376 | b := i + offset 377 | valueB := aSeries[i + offset] 378 | continue 379 | if b == 0 380 | break 381 | if aSeries[i + offset] < aSeries[i + offset - 1] 382 | a := i + offset 383 | valueA := aSeries[i + offset] 384 | continue 385 | if a == 0 386 | break 387 | // M found if we have found point A, and point B has a greater value than point D 388 | found := a > 0 and a != b and c != 0 and d != 0 and aSeries[e] < aSeries[c] and 389 | aSeries[d] > aSeries[e] and aSeries[d] > aSeries[c] and 390 | (aSeries[b] >= aSeries[d] or not strict) and aSeries[b] > aSeries[a] 391 | found 392 | entry = found ? aSeries[e] : na 393 | stopLoss = found ? aSeries[b] * ((100 + stopLossPercentage) / 100) : na 394 | target = found ? entry - (stopLoss - entry) * riskRewardRatio : na 395 | [found, entry, stopLoss, target, a, b, c, d, e] 396 | 397 | 398 | find_W(aSeries, aRange, anOffset, strict) => 399 | [found, entry, stopLoss, target, a, b, c, d, e] = data_W(aSeries, aRange, anOffset, strict) 400 | found 401 | 402 | find_M(aSeries, aRange, anOffset, strict) => 403 | [found, entry, stopLoss, target, a, b, c, d, e] = data_M(aSeries, aRange, anOffset, strict) 404 | found 405 | 406 | // Direction Movement Index 407 | [DIplus, DIminus] = dirmov(lengthDMI) 408 | 409 | // calculate if price is below/above SMA 410 | HighAboveSMA = includeSMA == false or series_a_above_series_b(high, SMAs, rangePrice) 411 | LowBelowSMA = includeSMA == false or series_a_below_series_b(low, SMAs, rangePrice) 412 | 413 | label_1 = 'davo' 414 | label_entry = 'entry' 415 | 416 | // PLOT DAV-O 417 | [W_found, W_entry, W_stopLoss, W_target, W_pointA, W_pointB, W_pointC, W_pointD, W_pointE] = data_W(src, rangePrice, offsetPrice, strictPrice) 418 | [M_found, M_entry, M_stopLoss, M_target, M_pointA, M_pointB, M_pointC, M_pointD, M_pointE] = data_M(src, rangePrice, offsetPrice, strictPrice) 419 | priceW = includePrice == false or W_found 420 | priceM = includePrice == false or M_found 421 | 422 | OBVw = includeOBV == false or find_W(OBVs, rangeOBV, offsetOBV, strictOBV) 423 | OBVm = includeOBV == false or find_M(OBVs, rangeOBV, offsetOBV, strictOBV) 424 | MFIw = includeMFI == false or find_W(MFIs, rangeMFI, offsetMFI, strictMFI) 425 | MFIm = includeMFI == false or find_M(MFIs, rangeMFI, offsetMFI, strictMFI) 426 | RSIw = includeRSI == false or find_M(RSIs, rangeRSI, offsetRSI, strictRSI) // we are searching for M's here to be a bull 427 | RSIm = includeRSI == false or find_W(RSIs, rangeRSI, offsetRSI, strictRSI) // we are searching for W's here to be a bear 428 | Wlyw = includeWly == false or find_W(WLYs, rangeWly, offsetWly, strictWly) 429 | Wlym = includeWly == false or find_M(WLYs, rangeWly, offsetWly, strictWly) 430 | DMIw = includeDMI == false or find_W(DIplus, rangeDMI, offsetDMI, strictDMI) and 431 | find_M(DIminus, rangeDMI, offsetDMI, strictDMI) 432 | DMIm = includeDMI == false or find_M(DIplus, rangeDMI, offsetDMI, strictDMI) and 433 | find_W(DIminus, rangeDMI, offsetDMI, strictDMI) 434 | RLZw = includeWithinRLZ == false and includeBelowRLZ == false or 435 | includeWithinRLZ == true and longWithinRLZ or 436 | includeBelowRLZ == true and longBelowRLZ 437 | RLZm = includeWithinRLZ == false and includeBelowRLZ == false or 438 | includeWithinRLZ == true and shortWithinRLZ or 439 | includeBelowRLZ == true and shortAboveRLZ 440 | 441 | longCondition = LowBelowSMA and priceW and OBVw and MFIw and RSIw and Wlyw and DMIw and 442 | withinPeriod and (includeWillyStupid == false or emaWly < -80) and RLZw 443 | shortCondition = HighAboveSMA and priceM and OBVm and MFIm and RSIm and Wlym and DMIm and 444 | withinPeriod and (includeWillyStupid == false or emaWly > -20) and RLZm 445 | 446 | // calculate entry, stoploss and target 447 | entrySourceLong = entrySource == low ? high : entrySource 448 | entrySourceShort = entrySource == high ? low : entrySource 449 | stopSourceLong = stopLossSource == high ? low : stopLossSource 450 | stopSourceShort = stopLossSource == low ? high : stopLossSource 451 | 452 | long_entry = show and longCondition and not longCondition[1] ? entrySourceLong[W_pointE] : na 453 | lowest_1 = lowest(stopSourceLong, rangePrice) 454 | long_stoploss = show and longCondition and not longCondition[1] ? 455 | lowest_1 * ((100 - stopLossPercentage) / 100) : na 456 | long_target = show and longCondition and not longCondition[1] ? 457 | long_entry + (long_entry - long_stoploss) * riskRewardRatio : na 458 | short_entry = show and shortCondition and not shortCondition[1] ? entrySourceShort[M_pointE] : 459 | na 460 | highest_1 = highest(stopSourceShort, rangePrice) 461 | short_stoploss = show and shortCondition and not shortCondition[1] ? 462 | highest_1 * ((100 + stopLossPercentage) / 100) : na 463 | short_target = show and shortCondition and not shortCondition[1] ? 464 | short_entry - (short_stoploss - short_entry) * riskRewardRatio : na 465 | 466 | entry = long_entry ? long_entry : short_entry ? short_entry : na 467 | stoploss = long_stoploss ? long_stoploss : short_stoploss ? short_stoploss : na 468 | target = long_target ? long_target : short_target ? short_target : na 469 | 470 | // define plot settings for entry, stoploss and target 471 | transparency = show_order_details ? 0 : 100 472 | clr_entry = show and (longCondition or shortCondition) ? color.white : na 473 | clr_stoploss = show and (longCondition or shortCondition) ? color.red : na 474 | clr_target = show and (longCondition or shortCondition) ? color.lime : na 475 | 476 | //FOR SQUEEZE MODULE 477 | //============================================================ 478 | e1 = (highest(high, length) + lowest(low, length)) / 2 + sma(close, length) 479 | osc = linreg(close - e1 / 2, length, 0) 480 | osc_color = osc[1] < osc[0] ? osc[0] >= 0 ? #00ffff : #cc00cc : osc[0] >= 0 ? #009b9b : #ff9bff 481 | 482 | SQON = strict and diff < 0 ? true : not strict and kupper > upper and klower < lower ? true : false 483 | mid_color = SQON ? color.red : color.green 484 | 485 | //============================================================ 486 | // Alerts for Trade opening 487 | //============================================================ 488 | //======================================================= 489 | // Added by Joshua 2-10-20 for Autoview 490 | // plot(entry_buy, title='Entry Buy', transp=100) 491 | // e=bitmex-testnet s=xbtusd b=long q=100 fp={{plot(\"Entry Buy\")}} l=10 t=limit 492 | 493 | // Going to use market orders at first. 494 | // SYNTAX FOR AUTOVIEW // 495 | // b=long e=bitmex-testnet l={{plot("Leverage")}} q={{plot("TradeSizeInUSD")}} t=market // From Peter - Go Long 496 | // b=short e=bitmex-testnet l={{plot("Leverage")}} q={{plot("TradeSizeInUSD")}} t=market // From Peter - Go Short 497 | // c=position e=bitmex-testnet t=market ro=1 // Closes all open positions at market w/ reduce only flag - Closing Signals Alert // Tested Successfully 498 | // message="e=bitmex-testnet s=xbtusd b=long q=100 fp={{plot(\"Entry Buy\")}} l=10 t=limit" 499 | // alertcondition(close > 0, title='Lemon Entry Trade Sig Long', message="e=bitmex-testnet s=xbtusd b=long q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") // added close>0 for testing 500 | alertcondition(show and longCondition and not longCondition[1] and SQON, title='Lemon Entry Trade Sig Long', message='{{ticker}} LONG') // Original Code 501 | // alertcondition(show and longCondition and not longCondition[1] and SQON, title='Lemon Entry Trade Sig Long', message="e=bitmex-testnet s=xbtusd b=long q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") // Orig 502 | 503 | // alertcondition(high > 0, title='Lemon Entry Trade Sig Short', message="e=bitmex-testnet s=xbtusd b=short q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") // added close>0 for testing 504 | alertcondition(show and shortCondition and not shortCondition[1] and SQON, title='Lemon Entry Trade Sig Short', message="{{ticker}} SHORT") // Original Code 505 | // alertcondition(show and shortCondition and not shortCondition[1] and SQON, title='Lemon Entry Trade Sig Short', message="e=bitmex-testnet s=xbtusd b=short q={{plot(\"TradeSizeInUSD\")}} l=1 t=market") 506 | 507 | 508 | //============================================================ 509 | //Plots for trade signal 510 | //============================================================ 511 | 512 | Shorttradetrigger = if (show and shortCondition and not shortCondition[1] and SQON) 513 | StopLevel := highest_1 * ((100 + stopLossPercentage) / 100) 514 | EntryLevel := entrySourceShort[M_pointE] 515 | TPLevel := EntryLevel - (StopLevel - EntryLevel) * riskRewardRatio 516 | BELevel := EntryLevel - (StopLevel - EntryLevel) 517 | stopdistance := StopLevel - EntryLevel 518 | TradeSizeInXBT := USDRiskPerTrade / stopdistance 519 | TradeSizeInUSD := round(EntryLevel * TradeSizeInXBT) //remove factor 1000 for live trading 520 | PositionMarginXBT := (round(100000 * TradeSizeInXBT / Leverage)) / 100000 521 | MaxPosMarginXBT := (round(100000 * USDRiskPerTrade / Min_Trade_Risk / Leverage)) / 100000 522 | tradeactive := true 523 | Shorttradeactive := true 524 | 525 | Longtradetrigger = if (show and longCondition and not longCondition[1] and SQON) 526 | StopLevel := lowest_1 * ((100 - stopLossPercentage) / 100) 527 | EntryLevel := entrySourceLong[W_pointE] 528 | TPLevel := EntryLevel + (EntryLevel - StopLevel) * riskRewardRatio 529 | BELevel := (EntryLevel - StopLevel) + EntryLevel 530 | stopdistance := EntryLevel - StopLevel 531 | TradeSizeInXBT := USDRiskPerTrade / stopdistance 532 | TradeSizeInUSD := round(EntryLevel * TradeSizeInXBT) //remove factor 1000 for live trading 533 | PositionMarginXBT := (round(100000 * TradeSizeInXBT / Leverage)) / 100000 534 | MaxPosMarginXBT := (round(100000 * USDRiskPerTrade / Min_Trade_Risk / Leverage)) / 100000 535 | tradeactive := true 536 | Longtradeactive := true 537 | 538 | 539 | // Plot 0 540 | plot(TradeSizeInUSD, title="TradeSizeInUSD", transp=100) // This will be the q= 541 | // Plot 1 542 | plot(EntryLevel, title="EntryLevel", transp=100) // This will be the fp= after testing using market orders 543 | // Plot 2 544 | plot(USDRiskPerTrade, title="USDRiskPerTrade", transp=100) // Shows risk per trade/loss. Multiply by Risk/Reward for Win estimates 545 | // Plot 3 546 | plot(riskRewardRatio, title="riskRewardRatio", transp=100) 547 | 548 | // PLOT RLZ Moved From Above Section 549 | // Plot 550 | p1 = plot(longUpperRLZ, color=color.green, title="61.8 (long)") 551 | // Plot 552 | p2 = plot(longLowerRLZ, color=color.green, title="78.6 (long)") 553 | fill(p1, p2, color=#7DCEA0, transp=90, title="RLZ long") 554 | // Plot 3 555 | p3 = plot(shortUpperRLZ, color=color.red, title="78.6 (short)") 556 | // Plot 4 557 | p4 = plot(shortLowerRLZ, color=color.red, title="61.8 (short)") 558 | fill(p3, p4, color=#cd6155, transp=90, title="RLZ short") 559 | 560 | 561 | // PLOT LEMON 562 | plotshape(show and longCondition and not longCondition[1] and SQON, title="Lemon long", style=shape.triangleup, location=location.belowbar, color=color.lime, text="LONG") 563 | plotshape(show and shortCondition and not shortCondition[1] and SQON, title="Lemon short", style=shape.triangledown, location=location.abovebar, color=color.red, text="SHORT") 564 | plotshape(show and longCondition[1], title="Lemon long confirmed", style=shape.cross, location=location.bottom, color=color.lime, text="alert", transp=100) 565 | plotshape(show and shortCondition[1], title="Lemon short confirmed", style=shape.cross, location=location.top, color=color.red, text="alert", transp=100) 566 | 567 | 568 | if Shorttradeactive == true 569 | Shorttradetrigger := false 570 | 571 | if Longtradeactive == true 572 | Longtradetrigger := false 573 | 574 | 575 | // Plot Levels: 576 | pl1 = plot (StopLevel, title = "Stop", color=color.red) 577 | pl2 = plot (EntryLevel, title = "Entry", color=color.white) 578 | pl3 = plot (BELevel, title = "BE", color=color.blue) 579 | pl4 = plot (TPLevel, title = "TP", color=color.green) 580 | 581 | fill(pl1, pl2, color=color.red, transp=65) 582 | fill(pl2, pl3, color=color.blue, transp=65) 583 | fill(pl3, pl4, color=color.green, transp=65) 584 | 585 | 586 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 587 | // Define and plot conflicting candles: 588 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 589 | 590 | // Subtypes of conflicting bars: 591 | //------------------------------------------------------------------------------------------------------- 592 | 593 | // Bartype 3a is a candle which crosses both BELevel and EntryLevel and has its close above the midline between BELevel and EntryLevel (longs) 594 | // respecively has its close below the midline between BELevel and EntryLevel (shorts) 595 | // In case of a Bartype 3a the logic shall NOT consider a trade as closed as break-even, but shall assume trade continuation with activated break-even-flag. 596 | //------------------------------------------------------------------------------------------------------- 597 | 598 | Bartype3_a_long = high > BELevel and high < TPLevel and low < EntryLevel and low > StopLevel and close > ((BELevel + EntryLevel)/2) and Longtradeactive 599 | Bartype3_a_short = high > EntryLevel and high < StopLevel and low < BELevel and low > TPLevel and close < ((BELevel + EntryLevel)/2) and Shorttradeactive 600 | //barcolor(Bartype3_a_long or Bartype3_a_short? color.purple : na) 601 | 602 | //Bartype3_a_Counter = 0 603 | //Bartype3_a_Counter := nz(Bartype3_a_Counter[1]) 604 | //if Bartype3_a_long or Bartype3_a_short 605 | // Bartype3_a_Counter := Bartype3_a_Counter + 1 606 | 607 | // Bartype 4a is a candle which crosses TPLevel, BELevel and EntryLevel and has its close above BELevel (longs) respectively close below BELevel (shorts) 608 | // In case of a Bartype 4a the logic shall consider a trade as closed winner and shall not assume trade as closed break-even. 609 | //------------------------------------------------------------------------------------------------------- 610 | 611 | Bartype4_a_long = high > TPLevel and low < EntryLevel and low > StopLevel and close > BELevel and Longtradeactive 612 | Bartype4_a_short = high > EntryLevel and high < StopLevel and low < TPLevel and close < BELevel and Shorttradeactive 613 | 614 | 615 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 616 | // Trade resolution: 617 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 618 | 619 | // Breakeven activation 620 | //------------------------------------------------------------------------------------------------------- 621 | shorttradeBElevelactivation = (low < BELevel) and not (low_m1 < TPLevel) 622 | longtradeBElevelactivation = (high > BELevel) and not (high_m1 > TPLevel) 623 | 624 | Breakevenactive = false 625 | Breakevenactive := nz(Breakevenactive[1]) 626 | 627 | if ((Shorttradeactive == true) and (shorttradeBElevelactivation == true)) 628 | Breakevenactive := true 629 | 630 | if ((Longtradeactive == true) and (longtradeBElevelactivation == true)) 631 | Breakevenactive := true 632 | 633 | // loss trades 634 | //------------------------------------------------------------------------------------------------------- 635 | 636 | PlotLossCounter = 0 637 | LossShort = 0 638 | LossLong = 0 639 | 640 | PlotLossCounter := nz(PlotLossCounter[1]) 641 | LossShort := nz(LossShort[1]) 642 | LossLong := nz(LossLong[1]) 643 | 644 | plotlosshort = if ((Shorttradeactive == true) and (high > StopLevel) and (Breakevenactive == false)) 645 | y = 1 // only required to make code work 646 | 647 | plotchar(plotlosshort, char="X", location=location.abovebar, color=color.red, transp=0, offset=0, size=size.small) 648 | 649 | if plotlosshort == true 650 | tradeactive := false 651 | Shorttradeactive := false 652 | Breakevenactive := false 653 | PlotLossCounter := PlotLossCounter + 1 654 | LossShort := LossShort +1 655 | 656 | 657 | //plotlosshort := false 658 | 659 | plotlosslong = if ((Longtradeactive == true) and (low < StopLevel) and (Breakevenactive == false)) 660 | r = 1 // only required to make code work 661 | 662 | plotchar(plotlosslong, char="X", location=location.belowbar, color=color.red, transp=0, offset=0, size=size.small) 663 | 664 | if plotlosslong == true 665 | tradeactive := false 666 | Longtradeactive := false 667 | Breakevenactive := false 668 | PlotLossCounter := PlotLossCounter + 1 669 | LossLong := LossLong + 1 670 | 671 | //plotlosslong := false 672 | 673 | // Breakeven trades 674 | //------------------------------------------------------------------------------------------------------- 675 | 676 | PlotBreakEvenCounter = 0 677 | PlotBreakEvenCounter := nz(PlotBreakEvenCounter[1]) 678 | BELong = 0 679 | BELong := nz(BELong[1]) 680 | BEShort = 0 681 | BEShort := nz(BEShort[1]) 682 | 683 | plotBreakevenshort = if ((Shorttradeactive == true) and (high > EntryLevel) and (Breakevenactive == true) and not Bartype3_a_short and not Bartype4_a_short) 684 | h = 1 // only required to make code work 685 | 686 | plotchar(plotBreakevenshort, char="0", location=location.abovebar, color=color.blue, transp=0, offset=0, size=size.small) 687 | 688 | if plotBreakevenshort == true 689 | tradeactive := false 690 | Shorttradeactive := false 691 | Breakevenactive := false 692 | PlotBreakEvenCounter := PlotBreakEvenCounter + 1 693 | BEShort := BEShort +1 694 | 695 | //plotBreakevenshort := false 696 | 697 | plotBreakevenlong = if ((Longtradeactive == true) and (low < EntryLevel) and (Breakevenactive == true) and not Bartype3_a_long and not Bartype4_a_long) 698 | e = 1 // only required to make code work 699 | 700 | plotchar(plotBreakevenlong, char="0", location=location.belowbar, color=color.blue, transp=0, offset=0, size=size.small) 701 | 702 | if plotBreakevenlong == true 703 | tradeactive := false 704 | Longtradeactive := false 705 | Breakevenactive := false 706 | PlotBreakEvenCounter := PlotBreakEvenCounter + 1 707 | BELong := BELong +1 708 | 709 | //plotBreakevenlong := false 710 | 711 | // Win trades 712 | //------------------------------------------------------------------------------------------------------- 713 | PlotWinCounter = 0 714 | PlotWinCounter := nz(PlotWinCounter[1]) 715 | WinLong = 0 716 | WinLong := nz(WinLong[1]) 717 | WinShort = 0 718 | WinShort := nz(WinShort[1]) 719 | 720 | plotWinshort = if ((Shorttradeactive == true) and (low < TPLevel)) 721 | n = 1 // only required to make code work 722 | 723 | plotchar(plotWinshort, char="✓", location=location.belowbar, color=color.green, transp=0, offset=0, size=size.small) 724 | 725 | if plotWinshort == true 726 | tradeactive := false 727 | Shorttradeactive := false 728 | Breakevenactive := false 729 | PlotWinCounter := PlotWinCounter + 1 730 | WinShort := WinShort +1 731 | 732 | //plotWinshort := false 733 | 734 | plotWinlong = if ((Longtradeactive == true) and (high > TPLevel)) 735 | l = 1 // only required to make code work 736 | 737 | plotchar(plotWinlong, char="✓", location=location.abovebar, color=color.green, transp=0, offset=0, size=size.small) 738 | 739 | if plotWinlong == true 740 | tradeactive := false 741 | Longtradeactive := false 742 | Breakevenactive := false 743 | PlotWinCounter := PlotWinCounter + 1 744 | WinLong := WinLong +1 745 | 746 | //plotWinlong := false 747 | 748 | 749 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 750 | // Trade closing signals 751 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 752 | 753 | // c=position e=bitmex-testnet t=market ro=1 754 | // Original Code Below 755 | // alertcondition(plotlosshort or plotlosslong or plotBreakevenshort or plotBreakevenlong, title='Lemon Close Trade BE or Stop', message='Lemon Close at BE or Stop') 756 | // alertcondition(plotWinshort or plotWinlong, title='Lemon Close Trade Win', message='Lemon Win') 757 | 758 | alertcondition(plotlosshort or plotlosslong or plotBreakevenshort or plotBreakevenlong, title='Lemon Close Trade BE or Stop', message="{{ticker}} Close") 759 | alertcondition(plotWinshort or plotWinlong, title='Lemon Close Trade Win', message="{{ticker}} Take Profit") 760 | 761 | EquityCurve = PlotWinCounter * 2 * USDRiskPerTrade - PlotLossCounter * USDRiskPerTrade - (PlotWinCounter + PlotLossCounter + PlotBreakEvenCounter) * commission 762 | 763 | 764 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 765 | // Statistics 766 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 767 | 768 | //if (plotWinlong or plotWinshort or plotBreakevenlong or plotBreakevenshort or plotlosslong or plotlosshort) and not HideStatistics 769 | // l = label.new(bar_index, high + StatisticsVerticalOffset, style=label.style_none, text="Win : " + tostring(PlotWinCounter) 770 | // + "\nLoss : " + tostring(PlotLossCounter) + "\nBE : " + tostring(PlotBreakEvenCounter),color = color.white, textcolor=color.white) 771 | 772 | winpercent = round((PlotWinCounter/(PlotWinCounter+PlotLossCounter+PlotBreakEvenCounter)*100)) 773 | losspercent = round((PlotLossCounter/(PlotWinCounter+PlotLossCounter+PlotBreakEvenCounter)*100)) 774 | bepercent = round((PlotBreakEvenCounter/(PlotWinCounter+PlotLossCounter+PlotBreakEvenCounter)*100)) 775 | rrpercent = round((PlotWinCounter/(PlotWinCounter+PlotLossCounter))*100) 776 | 777 | //if (plotWinlong or plotWinshort or plotBreakevenlong or plotBreakevenshort or plotlosslong or plotlosshort) and not HideStatistics 778 | // l = label.new(bar_index, high + StatisticsVerticalOffset, style=label.style_none, text="Win : " + tostring(PlotWinCounter) + " ("+ tostring(winpercent)+")% Long: " +tostring(WinLong) +" Short: "+ tostring(WinShort) 779 | // + "\nLoss : " + tostring(PlotLossCounter) +" ("+tostring(losspercent)+")%"+" Long: "+tostring(LossLong)+" Short: "+tostring(LossShort)+"\nBE : " + tostring(PlotBreakEvenCounter)+" ("+ tostring(bepercent)+")% Long: "+tostring(BELong)+" Short: "+tostring(BEShort),color = color.white, textcolor=color.white) 780 | 781 | if (plotWinlong or plotWinshort or plotBreakevenlong or plotBreakevenshort or plotlosslong or plotlosshort) and not HideStatistics 782 | l = label.new(bar_index, high + StatisticsVerticalOffset, style=label.style_none, text="Win : " + tostring(PlotWinCounter) + " ("+ tostring(winpercent)+"%)" 783 | + "\nLoss : " + tostring(PlotLossCounter) +" ("+tostring(losspercent)+"%)" + "\nBE : " + tostring(PlotBreakEvenCounter)+" ("+ tostring(bepercent)+"%)" + "\nRate : " + tostring (rrpercent)+"%)",color = color.white, textcolor=color.white) 784 | 785 | 786 | // The following line is in order to print the equity curve: 787 | //------------------------------------------------------------------------------------------------------- 788 | 789 | plot (DisplayEquityCurve == true ? EquityCurve : na, title = "Profit and Loss", color=color.yellow, linewidth=3, style=plot.style_line) 790 | 791 | // Grimm is the man // 792 | --------------------------------------------------------------------------------