Strategy · Pine Script v5 · On the chart

Ruckard Squeezed F001

by ruckard

Calculates divergence between price movement and the Squeeze Momentum Indicator transitions to identify entry conditions.

View on GitHub

GitHub stars13on the repository
Pine versionv5runs as is
Lines of code1,313
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago2 Mar 2025

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

1,313 lines of Pine Script v5 from scripts/squeezed/squeezed_f_librarian.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

squeezed_f_librarian.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ruckard

//@version=5

// Current version: v20220815 ( F001 )
// Tradingview Public description - BEGIN
// 
// This strategy checks changes between the different sections of the Squeeze Momentum Indicator.
// Light-Green to Dark-Green change is compared to former Light-Green to Dark-Green change.
// If the squeeze value is smaller and at the same time the price is higher then we short.
// Light-Red to Dark-Red change is compared to former Light-Red to Dark-Red change.
// If the squeeze value is higher and at the same time the price is lower then we long.
//
// This specific strategy also includes Risk Management.
// 
// It was originally tested at BTCUSDT pair and 1h timeframe.
//
// Before using this documentation it's recommended that you:
// [LIST]
// [*] Use default TradingView strategy script or another script and setup its associated alert manually. Just make the alert pop-up in the screen.
// [*] Create a 'Copy-Trader provider' (or Signal Provider) in Zignaly and send signals to it either thanks to your browser or with some basic programming.
// [/LIST]

// [B]SETTINGS[/B]
// [B]__ SETTINGS - Capital[/B]
// [LIST]
// [*] (CAPITAL) Capital quote invested per order in USDT units {100.0}. This setting is only used when '(ZIG) Provider type' is set to 'Signal Provider'.
// [*] (CAPITAL) Capital percentage invested per order (%) {25.0}. This setting is only used when '(ZIG) Provider type' is set to 'Copy Trader Provider'.
// [/LIST]
// [B]__ SETTINGS - Misc[/B]
// [LIST]
// [*] (ZIG) Enable Alert message {True}: Whether to enable alert message or not.
// [*] (ZIG) Service Secret Key {MYSECRETKEY}: Your service secret key. You can find it in your service Edit tab.
// [*] (DEBUG) Enable debug on order comments {False}: Whether to show alerts on order comments or not.
// [*] Number of decimal digits for Prices {2}.
// [*] (DECIMAL) Maximum number of decimal for contracts {3}.
// [/LIST]
// [B]__ SETTINGS - Zignaly[/B]
// [LIST]
// [*] (ZIG) Integration type {TradingView only}: [b]Hybrid[/b]: Both TradingView and Zignaly handle take profit, trailing stops and stop losses. Useful if you are scared about TradingView not firing an alert. It might arise problems if TradingView and Zignaly get out of sync. [b]TradingView only[/b]: TradingView sends entry and exit orders to Zignaly so that Zignaly only buys or sells. Zignaly won't handle stop loss or other settings on its own.
// [*] (ZIG) Zignaly Alert Type {WebHook}: 'Email' or 'WebHook'.
// [*] (ZIG) Provider type {Profit Sharing Provider}: 'Profit Sharing Provider', 'Copy Trader Provider', or 'Signal Provider'. 'Copy Trader Provider' or 'Profit Sharing Provider' sends a percentage to manage. 'Signal Provider' sends a quote to manage.
// [*] (ZIG) Exchange {Zignaly}: 'Zignaly', 'Binance' or 'Kucoin'.
// [*] (ZIG) Exchange Type {Futures}: 'Spot' or 'Futures'.
// [*] (ZIG) Leverage {1}. Set it to '1' when '(ZIG) Exchange Type' is set to 'Spot'.
// [/LIST]
// [B]__ SETTINGS - Strategy[/B]
// [LIST]
// [*] (STRAT) Strategy Type: 'Long and Short', 'Long Only' or 'Short Only'.
// [*] (STRAT) Strategy Start Time {2021-01-01 00:00:00}: When to start the strategy if '(STRAT) Strategy Start Time forced?' setting is set to true.
// [*] (STRAT) Strategy Stop Time {2021-12-31 00:00:00}: When to stop the strategy if '(STRAT) Strategy Stop Time forced?' setting is set to true.
// [*] (STRAT) Strategy Start Time forced? {True}: Whether to start the strategy from a given point in time.
// [*] (STRAT) Strategy Stop Time forced? {False}: Whether to stop the strategy after a given point in time.
// [*] (STOPTAKE) Take Profit? {false}: Whether to enable Take Profit.
// [*] (STOPTAKE) Stop Loss? {True}: Whether to enable Stop Loss.
// [*] (TRAILING) Enable Trailing Take Profit (%) {True}: Whether to enable Trailing Take Profit.
// [*] (STOPTAKE) Take Profit % {3.0}: Take profit percentage. This setting is only used when '(STOPTAKE) Take Profit?' setting is set to true.
// [*] (STRAT) Risk/Reward Ratio % {1.5}. Take Profit is StopLoss times Risk/Reward Ratio set here.
// [*] (STOPTAKE) Stop Loss % {2.0}: Stop loss percentage. This setting is only used when '(STOPTAKE) Stop Loss?' setting is set to true.
// [*] (TRAILING) Trailing Take Profit Trigger (%) {2.5}: Trailing Stop Trigger Percentage. This setting is only used when '(TRAILING) Enable Trailing Take Profit (%)' setting is set to true.
// [*] (TRAILING) Trailing Take Profit as a percentage of Trailing Take Profit Trigger (%) {25.0}: Trailing Stop Distance Percentage. This setting is only used when '(TRAILING) Enable Trailing Take Profit (%)' setting is set to true.
// [*] (RECENT) Number of minutes to wait to open a new order after the previous one has been opened {6}.
// [/LIST]
// [B]____ SETTINGS - Risk Management [/B]
// [list]
// [*] (RISKM) Risk Management Type: 'Safe', 'Somewhat safe compound' or 'None'. '[b]Safe[/b]': Calculations are always done with the initial capital (1000) in mind. The maximum losses per trade/day/week/month are taken into account. '[b]Somewhat safe compound[/b]': Calculations are done with initial capital (1000) or a higher capital if it increases. The maximum losses per trade/day/week/month are taken into account. '[b]None[/b]': In each order all the current capital is gambled and only the default stop loss per order is taken into account. That means that the maximum losses per trade/day/week/month are not taken into account. [b]Default[/b]: 'Somewhat safe compound'.
// [*] (RISKM) Maximum loss per trade % {1.0}.
// [*] (RISKM) Maximum loss per day % {6.0}.
// [*] (RISKM) Maximum loss per week % {8.0}.
// [*] (RISKM) Maximum loss per month % {10.0}.
// [/list]

// [B]DEFAULT SETTINGS[/B]

// By default this strategy has been setup with these beginner settings:
// [LIST]
// [*] '(ZIG) Integration type' : TradingView only
// [*] '(ZIG) Provider type'    : 'Copy Trader Provider'
// [*] '(ZIG) Exchange'         : 'Binance'
// [*] '(ZIG) Exchange Type'    : 'Spot'
// [*] '(STRAT) Strategy Type'  : 'Long Only'
// [*] '(ZIG) Leverage'         : '1' (Or no leverage)
// [/LIST]
// but you can change those settings if needed.


// [B]FIRST STEP[/B]
// [LIST]
// [*] For both future or spot markets you should make sure to change '(ZIG) Zignaly Alert Type' to match either WebHook or Email. If you have a non paid account in TradingView as in October 2020 you would have to use Email which it's free to use.
// [/LIST]

// [B]RECOMMENDED SETTINGS[/B]
// [B]__ RECOMMENDED SETTINGS - Spot markets[/B]
// [LIST]
// [*] '(ZIG) Exchange Type'   setting should be set to 'Spot'
// [*] '(STRAT) Strategy Type' setting should be set to 'Long Only'
// [*] '(ZIG) Leverage'        setting should be set to '1'
// [/LIST]
// [B]__ RECOMMENDED SETTINGS - Future markets[/B]
// [LIST]
// [*] '(ZIG) Exchange Type'   setting should be set to 'Futures'
// [*] '(STRAT) Strategy Type' setting should be set to 'Long and Short'
// [*] '(ZIG) Leverage'        setting might be changed if desired.
// [/LIST]
// [B]__ RECOMMENDED SETTINGS - Signal Providers[/B]
// [LIST]
// [*] '(ZIG) Provider type'   setting should be set to 'Signal Provider'
// [*] '(CAPITAL) Capital quote invested per order in USDT units' setting might be changed if desired.
// [/LIST]
// [B]__ RECOMMENDED SETTINGS - Copy Trader Providers[/B]
// [LIST]
// [*] '(ZIG) Provider type'   setting should be set to 'Copy Trader Provider'
// [*] '(CAPITAL) Capital percentage invested per order (%)' setting might be changed if desired.
// [*] Strategy Properties setting: 'Initial Capital' might be changed if desired.
// [/LIST]

// [B]INTEGRATION TYPE EXPLANATION[/B]
// [LIST]
// [*] 'Hybrid': Both TradingView and Zignaly handle take profit, trailing stops and stop losses. Useful if you are scared about TradingView not firing an alert. It might arise problems if TradingView and Zignaly get out of sync.
// [*] 'TradingView only': TradingView sends entry and exit orders to Zignaly so that Zignaly only buys or sells. Zignaly won't handle stop loss or other settings on its own.
// [/LIST]

// [B]HOW TO USE THIS STRATEGY[/B]
// [LIST]
// [*] Beginner: Copy and paste the strategy and change it to your needs. Turn off '(DEBUG) Enable debug on order comments' setting.
// [*] Medium: Reuse functions and inputs from this strategy into your own as if it was a library.
// [*] Advanced: Check Strategy Tester. List of trades. Copy and paste the different suggested 'alert_message' variable contents to your script and change them to your needs.
// [*] Expert: You needed a way to pass data from TradingView script to the alert. Now you know it's the 'alert_message' variable. You can find several examples in the source code using the variable. You also have seen 'ALERTS SETUP' explanation below. An additional quick look at 'Strategy Tester', 'List of Trades' and you are ready to go.
// [/LIST]


// [B] ALERTS SETUP[/B]
// This is the important piece of information that allows you to connect TradingView to Zignaly in a semi-automatic manner.
// [B] __ ALERTS SETUP - WebHook[/B]
// [LIST]
// [*] Webhook URL: https : // zignaly . com / api / signals.php?key=MYSECRETKEY
// [*] Message: {{strategy.order.alert_message}}
// [/LIST]
// [B] __ ALERTS SETUP - Email[/B]
// [LIST]
// [*] Setup a new Hotmail account
// [*] Add it as an 'SMS email' in TradingView Profile settings page.
// [*] Confirm your own the email address
// [*] Create a rule in your Hotmail account that 'Redirects' (not forwards) emails to 'signals @ zignaly . email' when (1): 'Subject' includes 'Alert', (2): 'Email body' contains string 'MYZIGNALYREDIRECTTRIGGER' and (3): 'From' contains 'noreply @ tradingview . com'.
// [*] In 'More Actions' check: Send Email-to-SMS
// [*] Message: {{strategy.order.alert_message}}
// MYZIGNALYREDIRECTTRIGGER
// [/LIST]


// '(DEBUG) Enable debug on order comments' is turned on by default so that you can see in the Strategy Tester. List of Trades. The different orders alert_message that would have been sent to your alert. You might want to turn it off it some many letters in the screen is problem.

// [B]STRATEGY ADVICE[/B]
// [LIST]
// [*] If you turn on 'Take Profit' then turn off 'Trailing Take Profit'.
// [/LIST]
//
// [B]ZIGNALY SIDE ADVICE[/B]
// [LIST]
// [*] If you are a 'Signal Provider' make sure that 'Allow reusing the same signalId if there isn't any open position using it?' setting in the profile tab is set to true.
// [*] You can find your 'MYSECRETKEY' in your 'Copy Trader/Signal' provider Edit tab at 'Signal URL'.
// [/LIST]
//
// [B]ADDITIONAL ZIGNALY DOCUMENTATION[/B]
// This beginner's guide is quite basic and meant to be an introduction. Please read additional documentation to learn what you actually can do with Zignaly.
// [LIST]
// [*] docs . zignaly . com / signals / how-to -- How to send signals to Zignaly
// [*] help . zignaly . com / hc/en-us/categories/360002703720-Sending-Signals -- Sending zignals
// [/LIST]
//
// [B]FINAL REMARKS[/B]
// [LIST]
// [*] This strategy tries to match the Pine Script Coding Conventions as best as possible.
// [*] You can check my 'Ruckard TradingLatino' strategy for a more complex strategy that it's also integrated with Zignaly. Unfortunatley it does not use Pine Script Coding Conventions as much.
// [/LIST]

// Tradingview Public description - END

strategy('Ruckard Squeezed F001', shorttitle='F001RSqueezed', overlay=true, max_bars_back=5000, calc_on_order_fills=false, calc_on_every_tick=false, pyramiding=0, initial_capital=1000, slippage=1, commission_type=strategy.commission.percent, commission_value=0.04)

import ruckard/RiskManagementBeta/4 as rm
import ruckard/ZignalyBeta/21 as zig

squeezedStrategyHigherTimeframeTrend() =>
    higherTimeframeTrend = getTrend (i_higherTimeframeTrendFastMaType, i_higherTimeframeTrendFastMaLength, i_higherTimeframeTrendFastMaSource, i_higherTimeframeTrendSlowMaType, i_higherTimeframeTrendSlowMaLength, i_higherTimeframeTrendSlowMaSource, i_higherTimeframeTrendMaOffset)

    bool higherTimeframeTrendMaLong = higherTimeframeTrend
    bool higherTimeframeTrendMaShort = (not higherTimeframeTrend)

    [higherTimeframeTrendMaLong, higherTimeframeTrendMaShort]

squeezedStrategyMain() =>

    // INPUTS - BEGIN

    // Strategy - Inputs
    i_enableZignalyAlert = input(true, '(ZIG) Enable Alert message {True}')
    i_zignalyServiceSecretKey = input.string('MYSECRETKEY', '(ZIG) Service Secret Key {MYSECRETKEY}')
    _ZIGHYBRIDINTEGRATION_ = 'Hybrid', _ZIGTVONLYINTEGRATION_ = 'TradingView only'
    i_zignalyIntegrationTypePre = input.string(_ZIGHYBRIDINTEGRATION_, '(ZIG) Integration type', options=[_ZIGTVONLYINTEGRATION_, _ZIGHYBRIDINTEGRATION_])
    i_zignalyIntegrationType = (i_zignalyIntegrationTypePre == _ZIGHYBRIDINTEGRATION_) ? 'hybrid' : 'nonhybrid'
    _ZIGSIGNALPROVIDER_ = 'Signal Provider', _ZIGCOPYTRADERPROVIDER_ = 'Profit Sharing/Copy Trader Provider'
    i_zignalyProviderTypePre = input.string(_ZIGCOPYTRADERPROVIDER_, '(ZIG) Provider type', options=[_ZIGSIGNALPROVIDER_, _ZIGCOPYTRADERPROVIDER_])
    i_zignalyProviderType = (i_zignalyProviderTypePre == _ZIGCOPYTRADERPROVIDER_) ? 'copytrader' : 'signalprovider'
    L_S = 'Long and Short', _L_ = 'Long Only', _S_ = 'Short Only', _REVERSE_ = 'Reverse'
    i_strategyType = input.string(_REVERSE_, '(STRAT) Strategy Type', options=[L_S, _L_, _S_, _REVERSE_])
    i_strategyStartTime = input.time(timestamp('01 Jan 2021'), '(STRAT) Strategy Start Time {2021-01-01 00:00:00}')
    i_strategyStopTime = input.time(timestamp('31 Dec 2021'), '(STRAT) Strategy Stop Time {2021-12-31 00:00:00}')
    i_strategyStartTimeOn = input.bool(true, '(STRAT) Strategy Start Time forced? {True}')
    i_strategyStopTimeOn = input.bool(false, '(STRAT) Strategy Stop Time forced? {False}')

    i_highClosingMaType = input.string(defval = 'SMA', options = ['SMA', 'EMA', 'VWMA', 'RMA'], title = '(STRAT) High Closing MA Type [SMA]')
    i_highClosingMaLength = input.int(13, minval = 1,  title = '(STRAT) High Closing MA Length [13]')
    i_highClosingMaSource = input.source(ohlc4, title = '(STRAT) High Closing MA Source [ohlc4]')
    i_highestClosingMaLength = input.int(22, minval = 1,  title = '(STRAT) Highest Closing MA Length [22]')

    i_lowClosingMaType = input.string(defval = 'SMA', options = ['SMA', 'EMA', 'VWMA', 'RMA'], title = '(STRAT) Low Closing MA Type [SMA]')
    i_lowClosingMaLength = input.int(6, minval = 1,  title = '(STRAT) Low Closing MA Length [6]')
    i_lowClosingMaSource = input.source(ohlc4, title = '(STRAT) Low Closing MA Source [ohlc4]')
    i_lowestClosingMaLength = input.int(18, minval = 1,  title = '(STRAT) Lowest Closing MA Length [18]')

    i_signalSource = input.source(ohlc4, title = '(STRAT) Signal Source [ohlc4]')
    i_showRibbon = input.bool(true, title = 'Show ribbon [true]')

    // Order comments based debug
    i_enableOrderCommentDebug = input.bool(false, title='(DEBUG) Enable debug on order comments {False}')
    i_enableTakeProfit = input.bool(false, '(STOPTAKE) Take Profit? {False}')
    i_enableStopLoss = input.bool(false, '(STOPTAKE) Stop Loss? {False}')
    i_enableTrailingTakeProfit = input.bool(false, title='(TRAILING) Enable Trailing Take Profit (%) {False}')
    i_enableBreakEven = input.bool(false, title='(BREAKEVEN) Enable Break Even (%) {False}')
    i_enableCustomBreakEven = input.bool(false, title='(BREAKEVEN) Enable Custom Break Even (%) {False}')
    i_enableRiskRewardRatio = input.bool(false, title='(STOPTAKE) Calculate Take Profit from R/R Ratio (%) {False}')
    i_takeProfit = input.float(1.1, title='(STOPTAKE) Take Profit % {3.0}')
    i_takeProfitPerOne = i_takeProfit / 100
    i_positionRatio = input.float(1.5, title='(STRAT) Risk/Reward Ratio % {1.5}', minval=0.01)
    i_stopLoss = input.float(7.0, title='(STOPTAKE) Stop Loss % {7.0}', minval=0.01) / 100
    _SLConstant_ = 'Constant', _SLATR_ = 'ATR'
    i_stopLossTypePre = input.string(_SLATR_, '(STOPTAKE) Stop Loss type', options=[_SLConstant_, _SLATR_])
    i_stopLossType = (i_stopLossTypePre == _SLConstant_) ? 'constant' : (i_stopLossTypePre == _SLATR_) ? 'atr' : ''
    i_atrStopLossLength = input.int(14, minval = 1,  title = '(STOPTAKE) ATR Stop Loss Length [14]')
    i_atrStopLossSource = input.source(close, title = '(STOPTAKE) ATR Stop Loss Source [close]')
    i_atrStopLossMultiplier = input.float(1.5, title='(STOPTAKE) ATR Stop Loss Multiplier % {1.5}', minval=0.01)

    i_sqzmomLength = input.int(20, title='(SQZMOM) BB Length {20}')
    i_sqzmomMult = input.float(2.0,title='(SQZMOM) BB MultFactor {2.0}')
    i_sqzmomLengthKC=input.int(20, title='(SQZMOM) KC Length {20}')
    i_sqzmomMultKC = input.float(1.5, title='(SQZMOM) KC MultFactor {1.5}')
    i_sqzmomUseTrueRange = input.bool(true, title='(SQZMOM) Use TrueRange (KC) {True}')

    i_higherTimeframeTrendMaTimeframe = input.timeframe("60",title='(STRAT) Higher Timeframe Trend MA Timeframe {1 hour}')

    i_higherTimeframeTrendMaOffset = input.int(12,title='(STRAT) Higher Timeframe Trend MA Bars Offset {12 bars}')

    i_higherTimeframeTrendFastMaType = input.string(defval = 'EMA', options = ['SMA', 'EMA', 'VWMA', 'RMA', 'WMA'], title = '(STRAT) Higher Timeframe Trend Fast MA Type {EMA}')
    i_higherTimeframeTrendFastMaLength = input.int(1, minval = 1,  title = '(STRAT) Higher Timeframe Trend Fast MA Length {1}')
    i_higherTimeframeTrendFastMaSource = input.source(close, title = '(STRAT) Higher Timeframe Trend Fast MA Source {close}')

    i_higherTimeframeTrendSlowMaType = input.string(defval = 'EMA', options = ['SMA', 'EMA', 'VWMA', 'RMA', 'WMA'], title = '(STRAT) Higher Timeframe Trend Slow MA Type {EMA}')
    i_higherTimeframeTrendSlowMaLength = input.int(12, minval = 1,  title = '(STRAT) Higher Timeframe Trend Slow MA Length {12}')
    i_higherTimeframeTrendSlowMaSource = input.source(close, title = '(STRAT) Higher Timeframe Trend Slow MA Source {close}')

    i_higherTimeframeTrendMaEnforce = input.bool(true, title='(STRAT) Enforce Higher Timeframe Trend {True}')

    // Too old order - Inputs
    i_tooOldLongBarsNumber = input.int(6, '(OLD) Number of bars to consider a Long order to be old {6}', minval=1, maxval=100, step=1)
    i_tooOldShortBarsNumber = input.int(6, '(OLD) Number of bars to consider a Short order to be old {6}', minval=1, maxval=100, step=1)
    i_tooOldLongStopLoss = input.float(1.20, '(OLD) Too Old Long order Stop Loss (%) {1.20}', minval=0, step=0.01)
    i_tooOldLongStopLossPerOne = i_tooOldLongStopLoss * 0.01
    i_tooOldShortStopLoss = input.float(0.60, '(OLD) Too Old Short order Stop Loss (%) {0.60}', minval=0, step=0.01)
    i_tooOldShortStopLossPerOne = i_tooOldShortStopLoss * 0.01

    i_subStrategiesLookback = input.int(1, title='(STRAT) Substrategies Lookback [1]')
    i_subStrategiesMinimum = input.int(1, title='(STRAT) Substrategies minimum [1]')

    i_enableVolatilityProtection = input.bool(true, '(STRAT) Enable Volatility Protection? {True}')

    i_atrVolatilityLength = input.int(14, minval = 1,  title = '(STRAT) ATR Volatility Length [14]')
    i_atrVolatilitySource = input.source(close, title = '(STRAT) ATR Volatility Source [close]')
    i_atrVolatilityMultiplier = input.float(1.10, title='(STRAT) ATR Volatility Multiplier % {1.10}', minval=0.01)

    i_showAtrVolatilityMultiplier = input.bool(false, title='(STRAT) Show ATR Volatility Multiplier Level {False}')

    i_enableLongEdgeProtection = input.bool(false, '(STRAT) Enable Long Edge Protection? {False}')
    i_longEdgeLength = input.int(100, minval = 1,  title = '(STRAT) Long Edge Length [100]')
    i_longEdgeSource = input.source(high, title = '(STRAT) Long Edge Source [high]')
    i_longEdgeMinimumDistance = input.float(3.50, title='(STRAT) Long Edge Minimum Distance % {3.50}', minval=0.01)
    i_enableLongEdgeTakeProfitProtection = input.bool(false, '(STRAT) Enable Long Edge TakeProfit Protection? {False}')

    i_enableShortEdgeProtection = input.bool(false, '(STRAT) Enable Short Edge Protection? {False}')
    i_shortEdgeLength = input.int(100, minval = 1,  title = '(STRAT) Short Edge Length [100]')
    i_shortEdgeSource = input.source(low, title = '(STRAT) Short Edge Source [low]')
    i_shortEdgeMinimumDistance = input.float(1.00, title='(STRAT) Short Edge Minimum Distance % {1.00}', minval=0.01)
    i_enableShortEdgeTakeProfitProtection = input.bool(false, '(STRAT) Enable Short Edge TakeProfit Protection? {False}')

    i_showEdges = input.bool(false, title='(STRAT) Show Edge Minimum and Maximum {False}')

    // Trailing Take Profit - Inputs
    i_trailingTakeProfitPercentageTrigger = input.float(1.2, '(TRAILING) Trailing Take Profit Trigger (%) {2.5}', minval=0, step=0.01)
    i_trailingTakeProfitPercentageTriggerPerOne = i_trailingTakeProfitPercentageTrigger * 0.01
    i_trailingTakeProfitPercentageOffset = input.float(25.0, '(TRAILING) Trailing Take Profit as a percentage of Trailing Take Profit Trigger (%) {25.0}', minval=0, step=0.01)
    i_trailingTakeProfitPercentageOffsetPerOne = i_trailingTakeProfitPercentageOffset * 0.01
    // Break Even - Inputs
    i_breakEvenTrigger = input.float(1.0, '(BREAKEVEN) Break Even Trigger (%) {1.0}', minval=0, step=0.01)
    i_breakEvenTriggerPerOne = i_breakEvenTrigger * 0.01
    i_breakEven = input.float(0.20, '(BREAKEVEN) Break Even Stop Loss (%) {0.20}', minval=0, step=0.01)
    i_breakEvenPerOne = i_breakEven * 0.01
    // Zignaly - Email (zignalye)
    _ZIGNALYE_ = 'Email', _ZIGNALYW_ = 'WebHook'
    i_zignalyAlertTypePre = input.string(_ZIGNALYW_, '(ZIG) Zignaly Alert Type {WebHook}', options=[_ZIGNALYW_, _ZIGNALYE_])
    i_zignalyAlertType = (i_zignalyAlertTypePre == _ZIGNALYW_) ? 'webhook' : 'email'
    _ZIGEXZIGNALY_ = 'Zignaly', _ZIGEXBINANCE_ = 'Binance', _ZIGEXKUCOIN_ = 'Kucoin'
    i_zignalyExchange = input.string(_ZIGEXZIGNALY_, '(ZIG) Exchange {Zignaly}', options=[_ZIGEXZIGNALY_, _ZIGEXBINANCE_, _ZIGEXKUCOIN_])
    _ZIGEXTYPESPOT_ = 'spot', _ZIGEXFUTURES_ = 'futures'
    i_zignalyExchangeType = input.string(_ZIGEXFUTURES_, '(ZIG) Exchange Type {Futures}', options=[_ZIGEXFUTURES_, _ZIGEXTYPESPOT_])
    i_zignalyLeverage = input.int(1, '(ZIG) Leverage {1}', minval=1, step=1, maxval=125)
    var i_zignalyLeverage_str = str.tostring(i_zignalyLeverage)  // It needs to run only once
    i_priceDecimalDigits = input.int(2, 'Number of decimal digits for Prices {2}', minval=0, maxval=10, step=1)
    // Decimal - Inputs
    i_contractMaximumDecimalNumber = input.int(3, title='(DECIMAL) Maximum number of decimal for contracts {3}', minval=0)
    i_tooRecentMinutesNumber = input.int(0, '(RECENT) Number of minutes to wait to open a new order after the previous one has been opened {0}', minval=0, maxval=100, step=1)
    i_CapitalQuote = input.float(100.0, title='(CAPITAL) Capital quote invested per order in USDT units {100.0}')
    i_CapitalPercentage = input.float(25.0, title='(CAPITAL) Capital percentage invested per order (%) {25.0}', minval=0, step=0.01) * 0.01
    // Risk Management - Inputs
    _SAFE_ = 'Safe', _SCOMPOUND_ = 'Somewhat safe compound', _NONE_ = 'None', _CUSTOM_ = 'Custom', _FORCED_ = 'Forced'
    i_riskManagementTypePre = input.string(_SCOMPOUND_, '(RISKM) Risk Management Type', options=[_SAFE_, _SCOMPOUND_, _NONE_, _CUSTOM_, _FORCED_])
    i_riskManagementType = (i_riskManagementTypePre == _SAFE_) ? 'SAFE' : (i_riskManagementTypePre == _SCOMPOUND_) ? 'SCOMPOUND' : (i_riskManagementTypePre == _NONE_) ? 'NONE' : (i_riskManagementTypePre == _CUSTOM_) ? 'CUSTOM' : 'FORCED'
    i_riskManagementMaximumLossPerTrade = input.float(1.0, title='(RISKM) Maximum loss per trade % {1.0}') / 100
    i_riskManagementMaximumLossPerDay = input.float(6.0, title='(RISKM) Maximum loss per day % {6.0}') / 100
    i_riskManagementMaximumLossPerWeek = input.float(8.0, title='(RISKM) Maximum loss per week % {8.0}') / 100
    i_riskManagementMaximumLossPerMonth = input.float(10.0, title='(RISKM) Maximum loss per month % {10.0}') / 100

    // INPUTS - END



    // Strategy - INIT - BEGIN

    string stringNA = na

    onStartTimeInterval = (not i_strategyStartTimeOn) or (time >= i_strategyStartTime)
    offStopTimeInterval = (i_strategyStopTimeOn) and (time > i_strategyStopTime)

    // order Stop Loss
    float orderStopLossPerOne = na
    float orderStopLoss = orderStopLossPerOne

    float customBreakEvenPerOne = na
    float customBreakEven = customBreakEvenPerOne

    // Dynamic Trailing Take Profit - Variables

    var int buyOrderOpenBarIndex = na
    var int sellOrderOpenBarIndex = na

    // Breakeven accounting - Variables
    var bool breakEvenTriggered = false
    var bool breakEvenNeedsTrigger = false
    var bool customBreakEvenNeedsTrigger = false

    // Handle to avoid two long and short orders being too next to each other
    var bool insideABuyOrder = false
    var bool insideASellOrder = false

    var int lastOrderOpenBarTime = na

    // Handle recalculate after Stop Loss / Take Profit order
    if (strategy.position_size == 0.0)
        insideABuyOrder := false
        insideASellOrder := false
    else
        lastOrderOpenBarTime := time_close

    if (strategy.position_size > 0.0)
        insideABuyOrder := true
        insideASellOrder := false
    if (strategy.position_size < 0.0)
        insideABuyOrder := false
        insideASellOrder := true

    // Zignaly
    exchangeTickerID = syminfo.ticker

    var string tmpOrderComment = na
    var string tmpOrderAlertMessage = na

    var int i_tooRecentMinutesNumber_ms = i_tooRecentMinutesNumber * 60 * 1000 // Convert minutes into milliseconds only once

    // Strategy - INIT - END

    // FUNCTIONS - BEGIN

    // Decimals - Functions
    f_getContractMultiplier(_contractMaximumDecimalNumber) =>
        _contractMultiplier = 1
        if (_contractMaximumDecimalNumber == 0)
            _contractMultiplier // Return 1
        else
            for _counter = 1 to _contractMaximumDecimalNumber
                _contractMultiplier:= _contractMultiplier * 10
            _contractMultiplier

    // Order comment - Functions - BEGIN

    f_getOrderComment(_typeOrder, _side, _alertMessage) =>
        // Dependencies: i_enableOrderCommentDebug (initialized in inputs).

        // TODO: Add descriptive comments
        // _typeOrder="entry" or _typeOrder="close"
        // _side: true means long ; false means short ; We can use strategy.long or strategy.short as true and false aliases
        // _alertMessage
        var string _orderComment = ""
        
        if (i_enableOrderCommentDebug)
            _orderComment := _alertMessage
        else
            // TODO: Use human explanations instead of default order comment value (na)
            _orderComment := na
            
        _orderComment

    // Order comment - Functions - END

    // Too recent orders functions

    f_getTooRecentOrderNotOpenAdvice (_lastOrderOpenBarTime) =>
        // Dependencies: i_tooRecentMinutesNumber_ms

        // Condition 1: The order was open
        // Condition 2: The order was long or short
        // Condition 3: Time since order was last open is smaller than minimum between orders
        // Returns boolean
        bool _isTooRecent =  ((time_close) <= (_lastOrderOpenBarTime + i_tooRecentMinutesNumber_ms))

        bool _tooRecentOrderBuyNotOpenAdvice = na
        if (na(_lastOrderOpenBarTime))
            _tooRecentOrderBuyNotOpenAdvice := false
        else
            _tooRecentOrderBuyNotOpenAdvice := _isTooRecent
        _tooRecentOrderBuyNotOpenAdvice

    // SMILB functions - BEGIN
    sqzmom(length, mult, lengthKC, multKC, useTrueRange) =>
        // Calculate BB
        source = close
        basis = ta.sma(source, length)
        dev = mult * ta.stdev(source, length)
        upperBB = basis + dev
        lowerBB = basis - dev

        // Calculate KC
        ma = ta.sma(source, lengthKC)
        _range = useTrueRange ? ta.tr : (high - low)
        rangema = ta.sma(_range, lengthKC)
        upperKC = ma + rangema * multKC
        lowerKC = ma - rangema * multKC

        sqzOn  = (lowerBB > lowerKC) and (upperBB < upperKC)
        sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC)
        noSqz  = (sqzOn == false) and (sqzOff == false)

        val = ta.linreg(source - math.avg(math.avg(ta.highest(high, lengthKC), ta.lowest(low, lengthKC)),ta.sma(close,lengthKC)), lengthKC,0)

        bcolor = val > 0 ? ( val > nz(val[1]) ? color.lime : color.green ) : ( val < nz(val[1]) ? color.red : color.maroon )
        // TODO: Use string variables for colours so that final user can change the actual colour if he wants to.
        scolor = noSqz ? color.blue : sqzOn ? color.black : color.gray

        sqzon_percentage = (((upperKC-upperBB)/upperKC)*100)*(0.5) + (((lowerBB-lowerKC)/lowerBB)*100)*(0.5)
        sqzoff_percentage = (((upperBB-upperKC)/upperBB)*100)*(0.5) + (((lowerKC-lowerBB)/lowerKC)*100)*(0.5)
        float sqz_percentage = na
        if sqzOn
            sqz_percentage := sqzon_percentage
        else if sqzOff
            sqz_percentage := - sqzoff_percentage

        [val, bcolor, scolor, sqz_percentage]

    // MA - Functions - BEGIN
    f_Ma (_maType, _maSource, _maLength) =>
        _maType == "SMA" ? ta.sma(_maSource, _maLength) : _maType == "EMA" ? ta.ema(_maSource, _maLength) : _maType == "VWMA" ? ta.vwma(_maSource, _maLength) : _maType == "RMA" ? ta.rma(_maSource, _maLength) : _maType == "WMA" ? ta.wma(_maSource, _maLength) : _maType == "HMA" ? ta.hma(_maSource, _maLength) : _maSource
    // MA - Functions - END

    // Too old orders functions

    getTooOldOrderLongCloseAdvice () =>
        // Condition 1: The order is open
        // Condition 2: The order is long
        // Condition 3: Order age is bigger than the maximum setting
        // Returns boolean
        bool isValidOpenLongOrder = (strategy.position_size > 0)
        bool isTooOld =  (bar_index >= (buyOrderOpenBarIndex + i_tooOldLongBarsNumber))
        tooOldStopLoss = strategy.position_avg_price * (1 - i_tooOldLongStopLossPerOne)

        bool isALosingOrder = close < tooOldStopLoss
        tooOldOrderLongCloseAdvice = isValidOpenLongOrder and isTooOld and isALosingOrder
        tooOldOrderLongCloseAdvice

    getTooOldOrderShortCloseAdvice () =>
        // Condition 1: The order is open
        // Condition 2: The order is short
        // Condition 3: Order age is bigger than the maximum setting
        // Returns boolean
        bool is_valid_open_sell_order = (strategy.position_size < 0)
        bool isTooOld =  (bar_index >= (sellOrderOpenBarIndex + i_tooOldShortBarsNumber))
        tooOldStopLoss = strategy.position_avg_price * (1 + i_tooOldShortStopLossPerOne)

        bool isALosingOrder = close > tooOldStopLoss
        tooOldOrderShortCloseAdvice = is_valid_open_sell_order and isTooOld and isALosingOrder
        tooOldOrderShortCloseAdvice

    getTrend (_fastMaType, _fastMaLength, _fastMaSource, _slowMaType, _slowMaLength, _slowMaSource, _offset) =>
        _fastMa = f_Ma (_fastMaType, _fastMaSource, _fastMaLength)
        _slowMa = f_Ma (_slowMaType, _slowMaSource, _slowMaLength)
        _trend = _fastMa >= _slowMa

        _trendOffset = _trend[_offset]
        _trendOffset

    // FUNCTIONS - END


    // Strategy Body - BEGIN

    // SQMMOMDivergence SubStrategy
    // Short divergence means that next top height is smaller than previous top height and at the same time price is bigger than in the previous top height.
    // Long divergence means that next bottom height is higher than previous bottom height and at the same time price is smaller than in the previous bottom height.

    // Needed variables
    var int sqzmom_top_changes = 0
    var float sqzmom_top_val_a = na
    var float sqzmom_top_price_a = na
    var float sqzmom_top_val_b = na
    var float sqzmom_top_price_b = na

    var int sqzmom_bottom_changes = 0
    var float sqzmom_bottom_val_a = na
    var float sqzmom_bottom_price_a = na
    var float sqzmom_bottom_val_b = na
    var float sqzmom_bottom_price_b = na

    [sqzmom_val, sqzmom_bcolor, sqzmom_scolor, sqz_percentage] = sqzmom(i_sqzmomLength, i_sqzmomMult, i_sqzmomLengthKC, i_sqzmomMultKC, i_sqzmomUseTrueRange)

    // Gather data

    bool sqzmom_top_change = ( sqzmom_bcolor[1] == color.lime )  and ( sqzmom_bcolor[0] == color.green )
    bool sqzmom_bottom_change = ( sqzmom_bcolor[1] == color.red )  and ( sqzmom_bcolor[0] == color.maroon )

    if (sqzmom_top_change)
        sqzmom_top_changes := sqzmom_top_changes + 1

    if (sqzmom_bottom_change)
        sqzmom_bottom_changes := sqzmom_bottom_changes + 1

    bool sqzmom_top_is_a = (sqzmom_top_changes % 2) == 0
    bool sqzmom_top_is_b = (sqzmom_top_changes % 2) == 1

    bool sqzmom_bottom_is_a = (sqzmom_bottom_changes % 2) == 0
    bool sqzmom_bottom_is_b = (sqzmom_bottom_changes % 2) == 1

    if (sqzmom_top_change and sqzmom_top_is_a)
        sqzmom_top_val_a := sqzmom_val[1]
        sqzmom_top_price_a := close[1]

    if (sqzmom_top_change and sqzmom_top_is_b)
        sqzmom_top_val_b := sqzmom_val[1]
        sqzmom_top_price_b := close[1]

    if (sqzmom_bottom_change and sqzmom_bottom_is_a)
        sqzmom_bottom_val_a := sqzmom_val[1]
        sqzmom_bottom_price_a := close[1]

    if (sqzmom_bottom_change and sqzmom_bottom_is_b)
        sqzmom_bottom_val_b := sqzmom_val[1]
        sqzmom_bottom_price_b := close[1]

    // Implement logic

    bool sqzmomDivergenceLong = false
    bool sqzmomDivergenceShort = false

    // Short divergence - Section A
    if (sqzmom_top_change and sqzmom_top_is_a and (sqzmom_top_val_a < sqzmom_top_val_b) and (sqzmom_top_price_a > sqzmom_top_price_b))
        sqzmomDivergenceShort := true
    // Short divergence - Section B
    if (sqzmom_top_change and sqzmom_top_is_b and (sqzmom_top_val_b < sqzmom_top_val_a) and (sqzmom_top_price_b > sqzmom_top_price_a))
        sqzmomDivergenceShort := true
    // Long divergence - Section A
    if (sqzmom_bottom_change and sqzmom_bottom_is_a and (sqzmom_bottom_val_a > sqzmom_bottom_val_b) and (sqzmom_bottom_price_a < sqzmom_bottom_price_b))
        sqzmomDivergenceLong := true
    // Long divergence - Section B
    if (sqzmom_bottom_change and sqzmom_bottom_is_b and (sqzmom_bottom_val_b > sqzmom_bottom_val_a) and (sqzmom_bottom_price_b < sqzmom_bottom_price_a))
        sqzmomDivergenceLong := true

    // Higher Timeframe Trend substrategy


    higherTimeframeTrend = request.security(syminfo.tickerid, i_higherTimeframeTrendMaTimeframe, getTrend (i_higherTimeframeTrendFastMaType, i_higherTimeframeTrendFastMaLength, i_higherTimeframeTrendFastMaSource, i_higherTimeframeTrendSlowMaType, i_higherTimeframeTrendSlowMaLength, i_higherTimeframeTrendSlowMaSource, i_higherTimeframeTrendMaOffset))

    int higherTimeframeTrendMaBarIndex = request.security (syminfo.tickerid, i_higherTimeframeTrendMaTimeframe, bar_index)
    bool newHigherTimeframeTrendMaBar = higherTimeframeTrendMaBarIndex[1] != higherTimeframeTrendMaBarIndex[0]

    var higherTimeframeTrendMaLong = higherTimeframeTrend
    var higherTimeframeTrendMaShort = (not higherTimeframeTrend)

    if newHigherTimeframeTrendMaBar
        higherTimeframeTrendMaLong := higherTimeframeTrend
        higherTimeframeTrendMaShort := (not higherTimeframeTrend)

    // Noro TrendRibbon substrategy
    highClosingMa = f_Ma (i_highClosingMaType, i_highClosingMaSource, i_highClosingMaLength)
    lowClosingMa = f_Ma (i_lowClosingMaType, i_lowClosingMaSource, i_lowClosingMaLength)

    highestClosingMA = ta.highest(highClosingMa, i_highestClosingMaLength)
    lowestClosingMA = ta.lowest(lowClosingMa, i_lowestClosingMaLength)

    // Too old logic

    tooOldOrderLongCloseAdvice = getTooOldOrderLongCloseAdvice ()
    tooOldOrderShortCloseAdvice = getTooOldOrderShortCloseAdvice ()

    // Volatility substrategy

    volatilityLongCondition = true
    volatilityShortCondition = true

    atrLongVolatilityPrice = i_atrVolatilitySource + (ta.atr(i_atrVolatilityLength) * i_atrVolatilityMultiplier)
    barIsVolatileLong = (close[0] >= open[0]) and (close[0] >= atrLongVolatilityPrice[1])

    if barIsVolatileLong or barIsVolatileLong[1]
        volatilityLongCondition := false

    atrShortVolatilityPrice = i_atrVolatilitySource - (ta.atr(i_atrVolatilityLength) * i_atrVolatilityMultiplier)
    barIsVolatileShort = (close[0] <= open[0]) and (close[0] <= atrShortVolatilityPrice[1])

    if barIsVolatileShort or barIsVolatileShort[1]
        volatilityShortCondition := false

    // Edge substrategy

    edgeLongCondition = true
    edgeShortCondition = true

    edgeShortPrice = ta.lowest(i_shortEdgeSource, i_shortEdgeLength)
    edgeShortMinimumPrice = edgeShortPrice + (edgeShortPrice * i_shortEdgeMinimumDistance * 0.01)

    edgeLongPrice = ta.highest(i_longEdgeSource, i_longEdgeLength)
    edgeLongMaximumPrice = edgeLongPrice - (edgeLongPrice * i_longEdgeMinimumDistance * 0.01)

    if not (close <= edgeLongMaximumPrice)
        edgeLongCondition := false

    if not (close >= edgeShortMinimumPrice)
        edgeShortCondition := false

    // Final logic
    bool longCondition1 = sqzmomDivergenceLong
    bool longCondition2 = false
    bool longCondition3 = false
    bool longCondition4 = false
    bool longCondition5 = false

    bool longCondition1Found = false
    bool longCondition2Found = false
    bool longCondition3Found = false
    bool longCondition4Found = false
    bool longCondition5Found = false

    bool shortCondition1 = sqzmomDivergenceShort
    bool shortCondition2 = false
    bool shortCondition3 = false
    bool shortCondition4 = false
    bool shortCondition5 = false

    bool shortCondition1Found = false
    bool shortCondition2Found = false
    bool shortCondition3Found = false
    bool shortCondition4Found = false
    bool shortCondition5Found = false


    longConditions = 0
    shortConditions = 0
    for i = (i_subStrategiesLookback - 1) to 0
        if longCondition1[i]
            longCondition1Found := true
        if longCondition2[i]
            longCondition2Found := true
        if longCondition3[i]
            longCondition3Found := true
        if longCondition4[i]
            longCondition4Found := true
        if longCondition5[i]
            longCondition5Found := true
        if shortCondition1[i]
            shortCondition1Found := true
        if shortCondition2[i]
            shortCondition2Found := true
        if shortCondition3[i]
            shortCondition3Found := true
        if shortCondition4[i]
            shortCondition4Found := true
        if shortCondition5[i]
            shortCondition5Found := true

    if longCondition1Found
        longConditions := longConditions + 1
    if longCondition2Found
        longConditions := longConditions + 1
    if longCondition3Found
        longConditions := longConditions + 1
    if longCondition4Found
        longConditions := longConditions + 1
    if longCondition5Found
        longConditions := longConditions + 1
    if shortCondition1Found
        shortConditions := shortConditions + 1
    if shortCondition2Found
        shortConditions := shortConditions + 1
    if shortCondition3Found
        shortConditions := shortConditions + 1
    if shortCondition4Found
        shortConditions := shortConditions + 1
    if shortCondition5Found
        shortConditions := shortConditions + 1

    bool longCondition = na
    bool shortCondition = na

    longCondition := (longConditions >= i_subStrategiesMinimum)
    shortCondition := (shortConditions >= i_subStrategiesMinimum)

    if i_enableVolatilityProtection
        longCondition := longCondition and volatilityLongCondition
        shortCondition := shortCondition and volatilityShortCondition

    if i_enableLongEdgeProtection
        longCondition := longCondition and edgeLongCondition

    if i_enableShortEdgeProtection
        shortCondition := shortCondition and edgeShortCondition

    if (i_higherTimeframeTrendMaEnforce)
        longCondition := longCondition and higherTimeframeTrendMaLong
        shortCondition := shortCondition and higherTimeframeTrendMaShort

    // TrendRibbon - Plot - BEGIN
    highestClosingLowestColor = i_showRibbon ? color.yellow : na
    highestClosingMAPlot = plot(highestClosingMA, color = highestClosingLowestColor, title = "Upper Closing line")
    lowestClosingMAPlot = plot(lowestClosingMA, color = highestClosingLowestColor, title = "Lower Closing Line")
    // TrendRibbon - Plot - END

    atrVolatilityColor = i_showAtrVolatilityMultiplier ? color.maroon : na
    atrLongVolatilityPricePlot = plot(atrLongVolatilityPrice, color = atrVolatilityColor, title = "Long Volatility Price")
    atrShortVolatilityPricePlot = plot(atrShortVolatilityPrice, color = atrVolatilityColor, title = "Short Volatility Price")

    edgeColor = i_showEdges ? color.purple : na
    edgeLongPricePlot = plot(edgeLongMaximumPrice, color = edgeColor, style=plot.style_stepline, title = "Long Edge Price")
    edgeShortPricePlot = plot(edgeShortMinimumPrice, color = edgeColor, style=plot.style_stepline, title = "Short Edge Price")

    plotshape(higherTimeframeTrendMaLong, title="SideMA Up", style=shape.arrowup, color=color.new(#00c3ff, transp=0), location=location.top)
    plotshape(higherTimeframeTrendMaShort, title="SideMA Down", style=shape.arrowdown, color=color.new(#ff0062, transp=0), location=location.top)

    plotshape(sqzmomDivergenceLong, text="D", title="Divergence Up", style=shape.labelup, color=color.new(#00c3ff, transp=0), location=location.bottom)
    plotshape(sqzmomDivergenceShort, text="D", title="Divergence Down", style=shape.labeldown, color=color.new(#ff0062, transp=0), location=location.bottom)

    // Position price calculation - BEGIN
    float positionPrice = na
    if (insideASellOrder or insideABuyOrder)
        positionPrice := strategy.position_avg_price
    else
        positionPrice := close
        // Make sure to reset breakeven triggered if we are not in an order
        breakEvenTriggered := false
        breakEvenNeedsTrigger := false
        customBreakEvenNeedsTrigger := false
        
    // Position price calculation - END

    tooRecentOrderNotOpenAdvice = f_getTooRecentOrderNotOpenAdvice (lastOrderOpenBarTime)

    // Decide if we are going to LONG/Go LONG - BEGIN
    PRE_LONG = false
    if (i_tooRecentMinutesNumber == 0)
        PRE_LONG := onStartTimeInterval and longCondition
    else
        PRE_LONG := onStartTimeInterval and longCondition and (not tooRecentOrderNotOpenAdvice)

    // LONG = PRE_LONG[1] and PRE_LONG // Wait for confirmation
    LONG = PRE_LONG // Do not wait for confirmation

    // Decide if we are going to LONG/Go LONG - END

    // Decide if we are going to SHORT/Go SHORT - BEGIN
    PRE_SHORT = false
    if (i_tooRecentMinutesNumber == 0)
        PRE_SHORT := onStartTimeInterval and shortCondition
    else
        PRE_SHORT := onStartTimeInterval and shortCondition and (not tooRecentOrderNotOpenAdvice)

    // SHORT = PRE_SHORT[1] and PRE_SHORT // Wait for confirmation
    SHORT = PRE_SHORT // Do not wait for confirmation

    // Decide if we are going to SHORT/Go SHORT - END

    // Decide if a LONG/LONG entry should be closed - BEGIN
    LONG_CLOSE = true
    LONG_CLOSE := offStopTimeInterval or shortCondition or ( ta.crossunder(i_signalSource, highestClosingMA) and (close >= (positionPrice * (1 + i_breakEvenPerOne))) ) or tooOldOrderLongCloseAdvice

    if i_enableLongEdgeTakeProfitProtection
        LONG_CLOSE := LONG_CLOSE or (not edgeLongCondition)

    // Let's make sure LONG does not trigger if LONG_CLOSE would tell us to close the LONG
    if LONG_CLOSE
        LONG := false
    // Decide if a LONG/LONG entry should be closed - END

    // Decide if a SHORT/SHORT entry should be closed - BEGIN
    SHORT_CLOSE = true
    SHORT_CLOSE := offStopTimeInterval or longCondition or ( ta.crossover(i_signalSource, lowestClosingMA) and (close <= (positionPrice * (1 - i_breakEvenPerOne))) ) or tooOldOrderShortCloseAdvice

    if i_enableShortEdgeTakeProfitProtection
        SHORT_CLOSE := SHORT_CLOSE or (not edgeShortCondition)

    // Let's make sure SHORT does not trigger if SHORT_CLOSE would tell us to close the SHORT
    if SHORT_CLOSE
        SHORT := false
    // Decide if a SHORT/SHORT entry should be closed - END

    // orderStopLoss is just here just in case
    // we implement i_longStopLoss and i_shortStopLoss
    // in the future
    atrLongStopLossPrice = i_atrStopLossSource - (ta.atr(i_atrStopLossLength) * i_atrStopLossMultiplier)
    atrShortStopLossPrice = i_atrStopLossSource + (ta.atr(i_atrStopLossLength) * i_atrStopLossMultiplier)
    if LONG
        if ( i_stopLossType == 'constant' )
            orderStopLossPerOne := i_stopLoss
        else if ( i_stopLossType == 'atr' )
            orderStopLossPerOne := (close - atrLongStopLossPrice) / close

        orderStopLoss := orderStopLossPerOne * 100
    else
        if ( i_stopLossType == 'constant' )
            orderStopLossPerOne := i_stopLoss
        else if ( i_stopLossType == 'atr' )
            orderStopLossPerOne := (atrShortStopLossPrice - close) / atrShortStopLossPrice

        orderStopLoss := orderStopLossPerOne * 100

    var float LongBreakEvenTrigger = na
    var float ShortBreakEvenTrigger = na

    if ((not insideABuyOrder[1]) and insideABuyOrder)
        LongBreakEvenTrigger := positionPrice * (1 + i_breakEvenTriggerPerOne)
    if ((not insideASellOrder[1]) and insideASellOrder)
        ShortBreakEvenTrigger := positionPrice * (1 - i_breakEvenTriggerPerOne)

    if (insideABuyOrder and insideABuyOrder[1])
        if ( false )
            customBreakEvenNeedsTrigger := true
    if (insideASellOrder and insideASellOrder[1])
        if ( false )
            customBreakEvenNeedsTrigger := true

    if insideABuyOrder
        if (high >= LongBreakEvenTrigger)
            breakEvenNeedsTrigger := true
    if insideASellOrder
        if (low <= ShortBreakEvenTrigger)
            breakEvenNeedsTrigger := true

    if (insideABuyOrder and LONG_CLOSE)
        breakEvenTriggered := false
        breakEvenNeedsTrigger := false
        customBreakEvenNeedsTrigger := false
    if (insideASellOrder and SHORT_CLOSE)
        breakEvenTriggered := false
        breakEvenNeedsTrigger := false
        customBreakEvenNeedsTrigger := false

    // How much to LONG/GO LONG/SHORT/GO SHORT - BEGIN

    // Custom take profit and stop loss
    var float LongStopLoss = na
    var float ShortStopLoss = na

    // Initial StopLoss value based on last closed candle
    if (i_enableStopLoss and (not insideABuyOrder))
        LongStopLoss := close * (1 - orderStopLossPerOne)
    if (i_enableStopLoss and (not insideASellOrder))
        ShortStopLoss := close * (1 + orderStopLossPerOne)

    // Final StopLoss value based on actual position price
    if (i_enableStopLoss and ((not insideABuyOrder[1]) and (insideABuyOrder)))
        LongStopLoss := positionPrice * (1 - orderStopLossPerOne)
    if (i_enableStopLoss and ((not insideASellOrder[1]) and (insideASellOrder)))
        ShortStopLoss := positionPrice * (1 + orderStopLossPerOne)

    // Make sure LongStopLoss and ShortStopLoss are undefined
    // by default when i_enableStopLoss is set to false
    if (not i_enableStopLoss)
        LongStopLoss := na
        ShortStopLoss := na

    // Override StopLoss with BreakEven if needed
    if ( i_enableBreakEven and insideABuyOrder and (not breakEvenTriggered) and breakEvenNeedsTrigger )
        LongStopLoss := positionPrice * (1 + i_breakEvenPerOne)
    if ( i_enableBreakEven and insideASellOrder and (not breakEvenTriggered) and breakEvenNeedsTrigger )
        ShortStopLoss := positionPrice * (1 - i_breakEvenPerOne)

    if ( i_enableCustomBreakEven and insideABuyOrder and customBreakEvenNeedsTrigger )
        LongStopLoss := positionPrice * (1 + i_breakEvenPerOne)
        customBreakEvenPerOne := (LongStopLoss - close) / close
        customBreakEven := customBreakEvenPerOne * 100
    if ( i_enableCustomBreakEven and insideASellOrder and customBreakEvenNeedsTrigger )
        ShortStopLoss := positionPrice * (1 - i_breakEvenPerOne)
        customBreakEvenPerOne := (close - ShortStopLoss) / ShortStopLoss
        customBreakEven := customBreakEvenPerOne * 100

    var float takeProfit = na
    var float takeProfitPerOne = na

    if i_enableRiskRewardRatio
        takeProfit := orderStopLoss * i_positionRatio
        takeProfitPerOne := takeProfit / 100
    else
        takeProfit := i_takeProfit
        takeProfitPerOne := i_takeProfitPerOne

    var float LongTakeProfit = na
    var float ShortTakeProfit = na

    // Initial TakeProfit value based on last closed candle
    if (not insideABuyOrder)
        LongTakeProfit := close * (1 + takeProfitPerOne)
    if (not insideASellOrder)
        ShortTakeProfit := close * (1 - takeProfitPerOne)

    // Final TakeProfit value based on actual position price
    if ((not insideABuyOrder[1]) and (insideABuyOrder))
        LongTakeProfit := positionPrice * (1 + takeProfitPerOne)
    if ((not insideASellOrder[1]) and (insideASellOrder))
        ShortTakeProfit := positionPrice * (1 - takeProfitPerOne)

    float entryQuantity = na
    float currentCapital = strategy.initial_capital + strategy.netprofit

    var float customQuantity = na


    if (i_zignalyProviderType == 'copytrader')
        entryQuantity := i_CapitalPercentage * currentCapital
    else // _ZIGSIGNALPROVIDER_
        entryQuantity := i_CapitalQuote

    if ( (i_riskManagementType == 'CUSTOM') or (i_riskManagementType == 'FORCED') )
        customQuantity := entryQuantity
    else
        customQuantity := na

    if (i_zignalyProviderType == 'copytrader') // Risk management is only implemented for CopyTrader Providers
        var currentDayCapital = 0.0
        var currentDay = 0
        var currentWeekCapital = 0.0
        var currentWeek = 0
        var currentMonthCapital = 0.0
        var currentMonth = 0

        currentDay := rm.getCurrentDay ()
        currentWeek := rm.getCurrentWeek ()
        currentMonth := rm.getCurrentMonth ()

        [__entryQuantity, __currentDay, __currentDayCapital, __currentWeek, __currentWeekCapital, __currentMonth, __currentMonthCapital] = rm.advisedEntryQuantity (currentCapital, currentDay, currentDayCapital, currentWeek, currentWeekCapital, currentMonth, currentMonthCapital, i_riskManagementMaximumLossPerDay, i_riskManagementMaximumLossPerWeek, i_riskManagementMaximumLossPerMonth, i_riskManagementMaximumLossPerTrade, orderStopLossPerOne, i_riskManagementType, customQuantity)

        entryQuantity := __entryQuantity
        currentDayCapital := __currentDayCapital
        currentWeekCapital := __currentWeekCapital
        currentMonthCapital := __currentMonthCapital

    float entryQuantityContractsReducer = 0.99

    contractMultiplier = f_getContractMultiplier(i_contractMaximumDecimalNumber)

    // We assume the current price is current bar close

    entryQuantityContracts = (math.floor(((entryQuantity / close) * entryQuantityContractsReducer) * contractMultiplier) / contractMultiplier)
    entryQuantityContractsUSDT = entryQuantityContracts * (close)

    // How much to LONG/GO LONG/SHORT/GO SHORT - END


    // GO LONG only logic - BEGIN

    var float tmpPositionBeforeOpeningOrder = na

    if (i_strategyType == _L_)
        if LONG
            tmpPositionBeforeOpeningOrder := strategy.position_avg_price
            if (not insideABuyOrder) // Entry
                tmpOrderAlertMessage := zig.longEntry(key=i_zignalyServiceSecretKey,positionSizeQuote=entryQuantityContractsUSDT, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, integration=i_zignalyIntegrationType, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                strategy.entry("[L]", strategy.long, qty=entryQuantityContracts, alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            if (na(tmpPositionBeforeOpeningOrder)) // bar_index should only be saved when there is no order opened
                buyOrderOpenBarIndex := bar_index + 1
            0 // Workaround for making every if branch to return the same type of value
        else if LONG_CLOSE
            tmpOrderAlertMessage := zig.longExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
            tmpOrderComment := f_getOrderComment("close", strategy.long, tmpOrderAlertMessage)
            strategy.close("[L]", alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            0 // Workaround for making every if branch to return the same type of value
        if ((insideABuyOrder) and (not LONG_CLOSE))
            if ( i_enableCustomBreakEven and customBreakEvenNeedsTrigger ) // Update Custom Breakeven
                tmpOrderAlertMessage := zig.updateLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableCustomBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = customBreakEven, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
            else if (i_enableBreakEven and breakEvenNeedsTrigger and (not(breakEvenTriggered))) // Update Breakeven
                tmpOrderAlertMessage := zig.updateLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = i_breakEvenTrigger, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
                breakEvenTriggered := true
            else // Update StopLoss
                tmpOrderAlertMessage := zig.updateLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
    // GO LONG only logic - END

    // GO SHORT only logic - BEGIN
    if (i_strategyType == _S_)
        if SHORT
            tmpPositionBeforeOpeningOrder := strategy.position_avg_price
            if (not insideASellOrder) // Entry
                tmpOrderAlertMessage := zig.shortEntry(key=i_zignalyServiceSecretKey,positionSizeQuote=entryQuantityContractsUSDT, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, integration=i_zignalyIntegrationType, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                strategy.entry("[S]", strategy.short, qty=entryQuantityContracts, alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            if (na(tmpPositionBeforeOpeningOrder)) // bar_index should only be saved when there is no order opened
                sellOrderOpenBarIndex := bar_index + 1
            0 // Workaround for making every if branch to return the same type of value
        else if SHORT_CLOSE
            tmpOrderAlertMessage := zig.shortExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
            tmpOrderComment := f_getOrderComment("close", strategy.short, tmpOrderAlertMessage)
            strategy.close("[S]", alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            0 // Workaround for making every if branch to return the same type of value
        if ((insideASellOrder) and (not SHORT_CLOSE))
            if ( i_enableCustomBreakEven and customBreakEvenNeedsTrigger ) // Update Custom Breakeven
                tmpOrderAlertMessage := zig.updateShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableCustomBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = customBreakEven, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
            else if (i_enableBreakEven and breakEvenNeedsTrigger and (not(breakEvenTriggered))) // Update Breakeven
                tmpOrderAlertMessage := zig.updateShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = i_breakEvenTrigger, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
                breakEvenTriggered := true
            else // Update StopLoss
                tmpOrderAlertMessage := zig.updateShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
    // GO SHORT only logic - END

    // GO LONG and SHORT logic - BEGIN
    if (i_strategyType == L_S)
    // Asumption: Above we have:
    // if LONG_CLOSE
    //    LONG := false
    // if SHORT_CLOSE
    //    SHORT := false

        // LONG and SHORT cannot be true at the same time
        // Anyways we will take it into account
        if (LONG == true) and (SHORT == true)
            LONG := true
            SHORT := false
            SHORT_CLOSE := true

        if LONG
            tmpPositionBeforeOpeningOrder := strategy.position_avg_price
            if (not insideABuyOrder) // Entry
                tmpOrderAlertMessage := zig.longEntry(key=i_zignalyServiceSecretKey,positionSizeQuote=entryQuantityContractsUSDT, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, integration=i_zignalyIntegrationType, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                strategy.entry("[L]", strategy.long, qty=entryQuantityContracts, alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            if (na(tmpPositionBeforeOpeningOrder)) // bar_index should only be saved when there is no order opened
                buyOrderOpenBarIndex := bar_index + 1
        if LONG_CLOSE
            tmpOrderAlertMessage := zig.longExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
            tmpOrderComment := f_getOrderComment("close", strategy.long, tmpOrderAlertMessage)
            strategy.close("[L]", alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
        if ((insideABuyOrder) and (not LONG_CLOSE))
            if ( i_enableCustomBreakEven and customBreakEvenNeedsTrigger ) // Update Custom Breakeven
                tmpOrderAlertMessage := zig.updateLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableCustomBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = customBreakEven, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
            else if (i_enableBreakEven and breakEvenNeedsTrigger and (not(breakEvenTriggered))) // Update Breakeven
                tmpOrderAlertMessage := zig.updateLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = i_breakEvenTrigger, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
                breakEvenTriggered := true
            else // Update StopLoss
                tmpOrderAlertMessage := zig.updateLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
        if SHORT
            tmpPositionBeforeOpeningOrder := strategy.position_avg_price
            if (not insideASellOrder) // Entry
                tmpOrderAlertMessage := zig.shortEntry(key=i_zignalyServiceSecretKey,positionSizeQuote=entryQuantityContractsUSDT, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, integration=i_zignalyIntegrationType, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                strategy.entry("[S]", strategy.short, qty=entryQuantityContracts, alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            if (na(tmpPositionBeforeOpeningOrder)) // bar_index should only be saved when there is no order opened
                sellOrderOpenBarIndex := bar_index + 1
        if SHORT_CLOSE
            tmpOrderAlertMessage := zig.shortExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
            tmpOrderComment := f_getOrderComment("close", strategy.short, tmpOrderAlertMessage)
            strategy.close("[S]", alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
        if ((insideASellOrder) and (not SHORT_CLOSE))
            if ( i_enableCustomBreakEven and customBreakEvenNeedsTrigger ) // Update Custom Breakeven
                tmpOrderAlertMessage := zig.updateShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableCustomBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = customBreakEven, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
            else if (i_enableBreakEven and breakEvenNeedsTrigger and (not(breakEvenTriggered))) // Update Breakeven
                tmpOrderAlertMessage := zig.updateShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = i_breakEvenTrigger, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
                breakEvenTriggered := true
            else // Update StopLoss
                tmpOrderAlertMessage := zig.updateShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
    // GO LONG and SHORT logic - END

    // Reverse logic - BEGIN
    if (i_strategyType == _REVERSE_)
    // Asumption: Above we have:
    // if LONG_CLOSE
    //    LONG := false
    // if SHORT_CLOSE
    //    SHORT := false

        // LONG and SHORT cannot be true at the same time
        // Anyways we will take it into account
        if (LONG == true) and (SHORT == true)
            LONG := true
            SHORT := false

        if (LONG and (not LONG_CLOSE))
            tmpPositionBeforeOpeningOrder := strategy.position_avg_price
            if (not insideABuyOrder) // Entry
                tmpOrderAlertMessage := zig.reverseLongEntry(key=i_zignalyServiceSecretKey,positionSizeQuote=entryQuantityContractsUSDT, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, integration=i_zignalyIntegrationType, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                strategy.entry("[L]", strategy.long, qty=entryQuantityContracts, alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            if (na(tmpPositionBeforeOpeningOrder)) // bar_index should only be saved when there is no order opened
                buyOrderOpenBarIndex := bar_index + 1
        if (LONG_CLOSE and (not ((SHORT and (not SHORT_CLOSE)))))
            tmpOrderAlertMessage := zig.reverseLongExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
            tmpOrderComment := f_getOrderComment("close", strategy.long, tmpOrderAlertMessage)
            strategy.close("[L]", alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
        if ((insideABuyOrder) and (not LONG_CLOSE))
            if ( i_enableCustomBreakEven and customBreakEvenNeedsTrigger ) // Update Custom Breakeven
                tmpOrderAlertMessage := zig.updateReverseLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableCustomBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = customBreakEven, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
            else if (i_enableBreakEven and breakEvenNeedsTrigger and (not(breakEvenTriggered))) // Update Breakeven
                tmpOrderAlertMessage := zig.updateReverseLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = i_breakEvenTrigger, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
                breakEvenTriggered := true
            else // Update StopLoss
                tmpOrderAlertMessage := zig.updateReverseLongEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.long, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
        if (SHORT and (not SHORT_CLOSE))
            tmpPositionBeforeOpeningOrder := strategy.position_avg_price
            if (not insideASellOrder) // Entry
                tmpOrderAlertMessage := zig.reverseShortEntry(key=i_zignalyServiceSecretKey,positionSizeQuote=entryQuantityContractsUSDT, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, integration=i_zignalyIntegrationType, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                strategy.entry("[S]", strategy.short, qty=entryQuantityContracts, alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
            if (na(tmpPositionBeforeOpeningOrder)) // bar_index should only be saved when there is no order opened
                sellOrderOpenBarIndex := bar_index + 1
        if (SHORT_CLOSE and (not (LONG and (not LONG_CLOSE))))
            tmpOrderAlertMessage := zig.reverseShortExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
            tmpOrderComment := f_getOrderComment("close", strategy.short, tmpOrderAlertMessage)
            strategy.close("[S]", alert_message=i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)
        if ((insideASellOrder) and (not SHORT_CLOSE))
            if ( i_enableCustomBreakEven and customBreakEvenNeedsTrigger ) // Update Custom Breakeven
                tmpOrderAlertMessage := zig.updateReverseShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableCustomBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = customBreakEven, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
            else if (i_enableBreakEven and breakEvenNeedsTrigger and (not(breakEvenTriggered))) // Update Breakeven
                tmpOrderAlertMessage := zig.updateReverseShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableBreakEven, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, breakEvenPercentage = i_breakEvenTrigger, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
                breakEvenTriggered := true
            else // Update StopLoss
                tmpOrderAlertMessage := zig.updateReverseShortEntry(key=i_zignalyServiceSecretKey, currentCapital=currentCapital, alertType=i_zignalyAlertType, stopLoss=i_enableStopLoss, takeProfit=i_enableTakeProfit, takeProfitPercentage1=takeProfit, trailingStopLoss=i_enableTrailingTakeProfit, trailingStopTriggerPercentage=i_trailingTakeProfitPercentageTrigger, trailingStopDistancePercentage=i_trailingTakeProfitPercentageOffset, priceDecimalDigits=i_priceDecimalDigits, exchange=i_zignalyExchange, exchangeAccountType=i_zignalyExchangeType, pair=exchangeTickerID, leverage=i_zignalyLeverage, providerType=i_zignalyProviderType, stopLossPercentage=orderStopLoss, signalId=stringNA, partial=false)
                // tmpOrderComment := f_getOrderComment("entry", strategy.short, tmpOrderAlertMessage)
                alert(message=( i_enableZignalyAlert and (i_zignalyIntegrationType == 'hybrid') ) ? tmpOrderAlertMessage : na)
    // Reverse logic - END

    // Handle STOP LOSS (and similar) order exits - BEGIN

    // Quick Paste - BEGIN
    float longTrailingTakeProfitPrice = na
    float longTrailingTakeProfitPoints = na
    float longTrailingTakeProfitOffset = na
    float shortTrailingTakeProfitPrice = na
    float shortTrailingTakeProfitPoints = na
    float shortTrailingTakeProfitOffset = na

    // Calculate trailing_take_profit_offset based on tick units
    longTmpTtpBaseValue = positionPrice * (1 + i_trailingTakeProfitPercentageTriggerPerOne)
    longTmpTtpTop_value = longTmpTtpBaseValue * (1 + i_trailingTakeProfitPercentageOffsetPerOne)
    longTrailingTakeProfitOffsetFloat = longTmpTtpTop_value - longTmpTtpBaseValue
    float longTrailingTakeProfitOffsetTick = math.floor (longTrailingTakeProfitOffsetFloat / syminfo.mintick)

    shortTmpTtpBaseValue = positionPrice * (1 - i_trailingTakeProfitPercentageTriggerPerOne)
    shortTmpTtpBottomValue = shortTmpTtpBaseValue * (1 - i_trailingTakeProfitPercentageOffsetPerOne)
    shortTrailingTakeProfitOffsetFloat = shortTmpTtpBaseValue - shortTmpTtpBottomValue
    float shortTrailingTakeProfitOffsetTick = math.floor (shortTrailingTakeProfitOffsetFloat / syminfo.mintick)

    if i_enableTrailingTakeProfit
        longTrailingTakeProfitPrice := positionPrice * (1 + i_trailingTakeProfitPercentageTriggerPerOne)
        longTrailingTakeProfitOffset := longTrailingTakeProfitOffsetTick
        shortTrailingTakeProfitPrice := positionPrice * (1 - i_trailingTakeProfitPercentageTriggerPerOne)
        shortTrailingTakeProfitOffset := shortTrailingTakeProfitOffsetTick
    else
        longTrailingTakeProfitPrice := na
        longTrailingTakeProfitOffset := na
        shortTrailingTakeProfitPrice := na
        shortTrailingTakeProfitOffset := na
    // Quick Paste - END

    // This might trigger additional close orders than needed in zignaly
    // Better close an existing order twice than regreting zignaly not having closed it.

    if (not (i_strategyType == _REVERSE_))
        tmpOrderAlertMessage := zig.longExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
    else // REVERSE
        tmpOrderAlertMessage := zig.reverseLongExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
    tmpOrderComment := f_getOrderComment("close", strategy.long, tmpOrderAlertMessage)

    bool i_enableAnyStopLoss = i_enableStopLoss or i_enableBreakEven or i_enableCustomBreakEven

    // Exit the signal if
    // * We are not in reverse mode
    // * We are in Long reverse mode and there is not a new Short reverse entry that would have closed it.
    if (
        (not (i_strategyType == _REVERSE_))
        or
        ((i_strategyType == _REVERSE_) and (not (SHORT and (not SHORT_CLOSE))))
    )
        strategy.exit("[L]-[SL/TP]", "[L]", stop= i_enableAnyStopLoss ? LongStopLoss : na, limit= i_enableTakeProfit ? LongTakeProfit : na, trail_price= i_enableTrailingTakeProfit ? longTrailingTakeProfitPrice : na, trail_offset = i_enableTrailingTakeProfit ? longTrailingTakeProfitOffset : na, alert_message= i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)

    if (not (i_strategyType == _REVERSE_))
        tmpOrderAlertMessage := zig.shortExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
    else // REVERSE
        tmpOrderAlertMessage := zig.reverseShortExit(key=i_zignalyServiceSecretKey,exchange=i_zignalyExchange,exchangeAccountType=i_zignalyExchangeType,pair=exchangeTickerID,leverage=i_zignalyLeverage,alertType=i_zignalyAlertType, signalId=stringNA, partial=false)
    tmpOrderComment := f_getOrderComment("close", strategy.short, tmpOrderAlertMessage)

    // Exit the signal if
    // * We are not in reverse mode
    // * We are in Short reverse mode and there is not a new Long reverse entry that would have closed it.
    if (
        (not (i_strategyType == _REVERSE_))
        or
        ((i_strategyType == _REVERSE_) and (not (LONG and (not LONG_CLOSE))))
    )
        strategy.exit("[S]-[SL/TP]", "[S]", stop= i_enableAnyStopLoss ? ShortStopLoss : na, limit= i_enableTakeProfit ? ShortTakeProfit : na, trail_price= i_enableTrailingTakeProfit ? shortTrailingTakeProfitPrice : na, trail_offset = i_enableTrailingTakeProfit ? shortTrailingTakeProfitOffset : na, alert_message= i_enableZignalyAlert ? tmpOrderAlertMessage : na, comment=tmpOrderComment)

    // Handle STOP LOSS (and similar) order exits - END

    // Strategy Body - END
    // TODO: Return 'i_enableAnyStopLoss ? ShortStopLoss : n' as ShortStopLoss.

    [LONG, SHORT, LONG_CLOSE, SHORT_CLOSE, alertMessage]

[squeezeStrategyHigherTimeframeTrendMaLong, squeezeStrategyHigherTimeframeTrendMaShort] = request.security('BTCUSDTPERP', i_higherTimeframeTrendMaTimeframe, squeezedStrategyHigherTimeframeTrend())

[squeezedStrategyLong, squeezedStrategyShort, squeezedStrategyLongClose, squeezedStrategyShortClose, squeezedStrategyAlertMessage, squeezedStrategyEntryQuantityContracts, squeezedStrategyLongExit, squeezedStrategyShortExit, squeezedStrategyLongStopLoss, squeezedStrategyLongTakeProfit, squeezedStrategyLongTrailingTakeProfitPrice, squeezedStrategyLongTrailingTakeProfitOffset, squeezedStrategyShortStopLoss, squeezedStrategyShortTakeProfit, squeezedStrategyShortTrailingTakeProfitPrice, squeezedStrategyShortTrailingTakeProfitOffset, squeezedStrategyLongStopLossAlertMessage, squeezedStrategyShortStopLossAlertMessage] = request.security('BTCUSDTPERP', '1h', squeezedStrategyMain())

string mainStrategyAlertMessage = squeezedStrategyAlertMessage
string mainStrategyLongStopLossAlertMessage = squeezedStrategyLongStopLossAlertMessage
string mainStrategyShortStopLossAlertMessage = squeezedStrategyShortStopLossAlertMessage
bool mainStrategyLong = squeezedStrategyLong
bool mainStrategyShort = squeezedStrategyShort
float mainStrategyEntryQuantityContracts = squeezedStrategyEntryQuantityContracts
bool mainStrategyLongClose = squeezedStrategyLongClose
bool mainStrategyShortClose = squeezedStrategyShortClose
bool mainStrategyLongExit = squeezedStrategyLongExit
bool mainStrategyShortExit = squeezedStrategyShortExit

bool mainStrategyLongStopLoss = squeezedStrategyLongStopLoss
bool mainStrategyLongTakeProfit = squeezedStrategyLongTakeProfit
bool mainStrategyLongTrailingTakeProfitPrice = squeezedStrategyLongTrailingTakeProfitPrice
bool mainStrategyLongTrailingTakeProfitOffset = squeezedStrategyLongTrailingTakeProfitOffset
bool mainStrategyShortStopLoss = squeezedStrategyShortStopLoss
bool mainStrategyShortTakeProfit = squeezedStrategyShortTakeProfit
bool mainStrategyShortTrailingTakeProfitPrice = squeezedStrategyShortTrailingTakeProfitPrice
bool mainStrategyShortTrailingTakeProfitOffset = squeezedStrategyShortTrailingTakeProfitOffset

// TODO: Do not send alert here for the main strategy
// when either of mainStrategyLong, mainStrategyShort, mainStrategyLongClose or mainStrategyShortClose
// is true
alert(message= i_enableZignalyAlert  ? squeezedStrategyAlertMessage : na)

// If main pair
if mainStrategyLong
    strategy.entry("[L]", strategy.long, qty=mainStrategyEntryQuantityContracts, alert_message=i_enableZignalyAlert ? mainStrategyAlertMessage : na, comment=mainStrategyAlertMessage)
if mainStrategyShort
    strategy.entry("[S]", strategy.short, qty=mainStrategyEntryQuantityContracts, alert_message=i_enableZignalyAlert ? mainStrategyAlertMessage : na, comment=mainStrategyAlertMessage)
if mainStrategyLongClose
    strategy.close("[L]", alert_message=i_enableZignalyAlert ? mainStrategyAlertMessage : na, comment=mainStrategyAlertMessage)
if mainStrategyShortClose
    strategy.close("[S]", alert_message=i_enableZignalyAlert ? mainStrategyAlertMessage : na, comment=mainStrategyAlertMessage)
if mainStrategyLongExit
    strategy.exit("[L]-[SL/TP]", "[L]", stop= mainStrategyLongStopLoss, limit= mainStrategyLongTakeProfit, trail_price= mainStrategyLongTrailingTakeProfitPrice, trail_offset = mainStrategyLongTrailingTakeProfitOffset, alert_message= i_enableZignalyAlert ? mainStrategyLongStopLossAlertMessage : na, comment=mainStrategyLongStopLossAlertMessage)
if mainStrategyShortExit
    strategy.exit("[S]-[SL/TP]", "[S]", stop= mainStrategyShortStopLoss, limit= mainStrategyShortTakeProfit, trail_price= mainStrategyShortTrailingTakeProfitPrice, trail_offset = mainStrategyLongTrailingTakeProfitOffset, alert_message= i_enableZignalyAlert ? mainStrategyShortStopLossAlertMessage : na, comment=mainStrategyShortStopLossAlertMessage)

Overview

A short position is opened when the squeeze value decreases while price makes a higher high during bullish momentum decay. A long position is triggered when the squeeze value increases while price makes a lower low during bearish momentum decay. Features extensive Zignaly webhook alert formatting and configurable risk management settings. Stop loss and take profit protection are disabled by default.

Details

Published by

ruckard on GitHub

Type

Strategy, Pine Script v5

Draws

On the price chart

Category

Oscillators & momentum, Divergence

Markets

Crypto

Timeframes

M15-H1

Risk Notes

  • The strategy enters trades without a stop loss

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
(ZIG) Enable Alert message {True}booltruei_enableZignalyAlert
(ZIG) Service Secret Key {MYSECRETKEY}stringMYSECRETKEYi_zignalyServiceSecretKey
(ZIG) Integration typestring_ZIGHYBRIDINTEGRATION_i_zignalyIntegrationTypePre
(ZIG) Provider typestring_ZIGCOPYTRADERPROVIDER_i_zignalyProviderTypePre
(STRAT) Strategy Typestring_REVERSE_i_strategyType
(STRAT) Strategy Start Time {2021-01-01 00:00:00}timetimestamp('01 Jan 2021')i_strategyStartTime
(STRAT) Strategy Stop Time {2021-12-31 00:00:00}timetimestamp('31 Dec 2021')i_strategyStopTime
(STRAT) Strategy Start Time forced? {True}booltruei_strategyStartTimeOn
(STRAT) Strategy Stop Time forced? {False}boolfalsei_strategyStopTimeOn
(STRAT) High Closing MA Type [SMA]stringSMAi_highClosingMaType
(STRAT) High Closing MA Length [13]int13i_highClosingMaLength
(STRAT) High Closing MA Source [ohlc4]sourceohlc4i_highClosingMaSource
Show all 40 settings
SettingTypeDefaultVariable
(STRAT) Highest Closing MA Length [22]int22i_highestClosingMaLength
(STRAT) Low Closing MA Type [SMA]stringSMAi_lowClosingMaType
(STRAT) Low Closing MA Length [6]int6i_lowClosingMaLength
(STRAT) Low Closing MA Source [ohlc4]sourceohlc4i_lowClosingMaSource
(STRAT) Lowest Closing MA Length [18]int18i_lowestClosingMaLength
(STRAT) Signal Source [ohlc4]sourceohlc4i_signalSource
Show ribbon [true]booltruei_showRibbon
(DEBUG) Enable debug on order comments {False}boolfalsei_enableOrderCommentDebug
(STOPTAKE) Take Profit? {False}boolfalsei_enableTakeProfit
(STOPTAKE) Stop Loss? {False}boolfalsei_enableStopLoss
(TRAILING) Enable Trailing Take Profit (%) {False}boolfalsei_enableTrailingTakeProfit
(BREAKEVEN) Enable Break Even (%) {False}boolfalsei_enableBreakEven
(BREAKEVEN) Enable Custom Break Even (%) {False}boolfalsei_enableCustomBreakEven
(STOPTAKE) Calculate Take Profit from R/R Ratio (%) {False}boolfalsei_enableRiskRewardRatio
(STOPTAKE) Take Profit % {3.0}float1.1i_takeProfit
(STRAT) Risk/Reward Ratio % {1.5}float1.5i_positionRatio
(STOPTAKE) Stop Loss % {7.0}float7.0i_stopLoss
(STOPTAKE) Stop Loss typestring_SLATR_i_stopLossTypePre
(STOPTAKE) ATR Stop Loss Length [14]int14i_atrStopLossLength
(STOPTAKE) ATR Stop Loss Source [close]sourceclosei_atrStopLossSource
(STOPTAKE) ATR Stop Loss Multiplier % {1.5}float1.5i_atrStopLossMultiplier
(SQZMOM) BB Length {20}int20i_sqzmomLength
(SQZMOM) BB MultFactor {2.0}float2.0i_sqzmomMult
(SQZMOM) KC Length {20}int20i_sqzmomLengthKC
(SQZMOM) KC MultFactor {1.5}float1.5i_sqzmomMultKC
(SQZMOM) Use TrueRange (KC) {True}booltruei_sqzmomUseTrueRange
(STRAT) Higher Timeframe Trend MA Timeframe {1 hour}timeframe60i_higherTimeframeTrendMaTimeframe
(STRAT) Higher Timeframe Trend MA Bars Offset {12 bars}int12i_higherTimeframeTrendMaOffset
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

ETH_buy_3commas

by hasnocool
106 stars

This strategy overlays a Cipher B style WaveTrend study on the price chart and is titled for Ethereum buy alerts aimed at 3Commas. It calculates a WaveTrend channel and a short moving average, and can mark buy, sell, gold, and divergence dots. Settings change

Strategy v4 Oscillators & momentumDivergence
Updated 2 years ago · GPL-3.0 GitHub repository of ETH_buy_3commas
24 stars

This overlay strategy combines a Cipher B WaveTrend oscillator with two optional moving averages on the price chart. It exposes WaveTrend channel and average lengths, overbought and oversold levels, buy, sell and gold dots, and regular or hidden divergence mar

Strategy v5 Oscillators & momentumMoving averages
Updated 4 years ago · MPL-2.0 GitHub repository of Cipher B + EMAs Strategy

RSI Divergence

by muammeryldrm42
7 stars

This strategy detects bullish and bearish RSI divergences using price and RSI pivot points. A bullish divergence triggers a long entry when price forms a lower low while RSI forms a higher low below 40. A bearish divergence triggers a short entry when price fo

Strategy v5 Oscillators & momentumDivergence
Updated 3 months ago · MIT GitHub repository of RSI Divergence

This strategy executes long positions by combining a 200-period EMA trend filter, Stochastic RSI oversold crosses, and Williams Alligator retracements, supplemented by RSI divergence detection. It triggers long entries when the price trades above the 200 EMA w

Strategy v4 TrendOscillators & momentum
Updated 3 years ago · Apache-2.0 GitHub repository of 200 EMA + Alligator + Stochastic Long Strategy
330 stars

MACD + Divergences [Alorse] is a momentum strategy that calculates the MACD oscillator and identifies regular and hidden divergences using pivot high and low points. It filters trade signals with dual Exponential Moving Averages (EMA 150 and 600) to ensure tra

Strategy v4 Oscillators & momentumDivergence Repaints
Updated 2 months ago · None stated GitHub repository of MACD + Divergences [Alorse]
11 stars

The Stochastic Divergence Strategy calculates the Stochastic oscillator (%K and %D) to identify regular bullish and bearish divergence patterns against price pivots. It plots the oscillator and divergence lines in a separate indicator pane. Entries trigger on

Strategy v6 Oscillators & momentumDivergence
Updated 5 months ago · Apache-2.0 GitHub repository of Stochastic Divergence Strategy

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers