External Signals Strategy TesterExternal Signals Strategy Tester
This strategy is designed to help you backtest external buy/sell signals coming from another indicator on your chart. It is a flexible and powerful tool that allows you to simulate real trading based on signals generated by any indicator, using input.source connections.
🔧 How It Works
Instead of generating signals internally, this strategy listens to two external input sources:
One for buy signals
One for sell signals
These sources can be connected to the plots from another indicator (for example, custom indicators, signal lines, or logic-based plots).
To use this:
Add your indicator to the chart (it must be visible on the same pane as this strategy).
Open the settings of the strategy.
In the fields Buy Signal and Sell Signal, select the appropriate plot (line, value, etc.) from the indicator that represents the buy/sell logic.
The strategy will open positions when the selected buy signal crosses above 0, and sell signal crosses above 0.
This logic can be easily adapted by modifying the crossover rule inside the script if your signal style is different.
⚙️ Features Included
✅ Configurable trade direction:
You can choose whether to allow long trades, short trades, or both.
✅ Optional close on opposite signal:
When enabled, the strategy will exit the current position if an opposite signal appears.
✅ Optional full position reversal:
When enabled, the strategy will close the current position and immediately open an opposite one on the reverse signal.
✅ Risk Management Tools:
You can define:
Take Profit (TP): Position will be closed once the specified profit (in %) is reached.
Stop Loss (SL): Position will be closed if the price drops to the specified loss level (in %).
BreakEven (BE): Once the specified profit threshold is reached, the strategy will move the stop-loss to the entry price.
📌 If any of these values (TP, SL, BE) are set to 0, the feature is disabled and will not be applied.
🧪 Best Use Cases
Backtesting signals from custom indicators, without rewriting the logic into a strategy.
Comparing the performance of different signal sources.
Testing external indicators with optional position management logic.
Validating strategies using external filters, oscillators, or trend signals.
📌 Final Notes
You can visualize where the strategy detected buy/sell signals using green/red markers on the chart.
All parameters are customizable through the strategy settings panel.
This strategy does not repaint, and it processes signals in real-time only (no lookahead bias).
Testing
Ensemble Alerts█ OVERVIEW 
This indicator creates highly customizable alert conditions and messages by combining several technical conditions into  groups , which users can specify directly from the "Settings/Inputs" tab. It offers a flexible framework for building and testing complex alert conditions without requiring code modifications for each adjustment. 
 █ CONCEPTS 
 Ensemble analysis 
 Ensemble  analysis is a form of data analysis that combines several "weaker" models to produce a potentially more robust model. In a trading context, one of the most prevalent forms of ensemble analysis is the aggregation (grouping) of several indicators to derive market insights and reinforce trading decisions. With this analysis, traders typically inspect multiple indicators, signaling trade actions when specific conditions or groups of conditions align. 
 Simplifying ensemble creation 
Combining indicators into one or more ensembles can be challenging, especially for users without programming knowledge. It usually involves writing custom scripts to aggregate the indicators and trigger trading alerts based on the confluence of specific conditions. Making such scripts customizable via inputs poses an additional challenge, as it often involves complicated input menus and conditional logic.
This indicator addresses these challenges by providing a simple, flexible input menu where users can easily define alert criteria by listing groups of conditions from various technical indicators in simple  text boxes . With this script, you can create complex alert conditions intuitively from the "Settings/Inputs" tab without ever writing or modifying a single line of code. This framework makes advanced alert setups more accessible to non-coders. Additionally, it can help Pine programmers save time and effort when testing various condition combinations.
 █ FEATURES 
 Configurable alert direction 
The "Direction" dropdown at the top of the "Settings/Inputs" tab specifies the allowed direction for the alert conditions. There are four possible options:
 •  Up only : The indicator only evaluates upward conditions. 
 •  Down only : The indicator only evaluates downward conditions. 
 •  Up and down  (default): The indicator evaluates upward and downward conditions, creating alert triggers for both. 
 •  Alternating : The indicator prevents alert triggers for consecutive conditions in the same direction. An upward condition must be the first occurrence after a downward condition to trigger an alert, and vice versa for downward conditions. 
 Flexible condition groups 
This script features six text inputs where users can define distinct condition groups (ensembles) for their alerts. An alert trigger occurs if all the conditions in  at least one  group occur. 
Each input accepts a  comma-separated list  of numbers with optional spaces (e.g., "1, 4, 8"). Each listed number, from 1 to 35, corresponds to a specific individual condition. Below are the conditions that the numbers represent:
 1 — RSI above/below threshold
 2 — RSI below/above threshold
 3 — Stoch above/below threshold
 4 — Stoch below/above threshold
 5 — Stoch K over/under D
 6 — Stoch K under/over D
 7 — AO above/below threshold
 8 — AO below/above threshold
 9 — AO rising/falling
 10 — AO falling/rising
 11 — Supertrend up/down
 12 — Supertrend down/up
 13 — Close above/below MA
 14 — Close below/above MA
 15 — Close above/below open
 16 — Close below/above open
 17 — Close increase/decrease
 18 —  Close decrease/increase
 19 — Close near Donchian top/bottom (Close > (Mid + HH) / 2)
 20 — Close near Donchian bottom/top (Close < (Mid + LL) / 2)
 21 — New Donchian high/low
 22 — New Donchian low/high
 23 — Rising volume
 24 — Falling volume
 25 — Volume above average (Volume > SMA(Volume, 20))
 26 — Volume below average (Volume < SMA(Volume, 20))
 27 — High body to range ratio (Abs(Close - Open) / (High - Low) > 0.5)
 28 — Low body to range ratio (Abs(Close - Open) / (High - Low) < 0.5)
 29 — High relative volatility (ATR(7) > ATR(40))
 30 — Low relative volatility (ATR(7) < ATR(40))
 31 — External condition 1
 32 — External condition 2
 33 — External condition 3
 34 — External condition 4
 35 — External condition 5
These constituent conditions fall into three distinct categories:
 •  Directional pairs : The numbers 1-22 correspond to  pairs  of opposing upward and downward conditions. For example, if one of the inputs includes "1" in the comma-separated list, that group uses the "RSI above/below threshold" condition pair. In this case, the RSI must be above a high threshold for the group to trigger an upward alert, and the RSI must be below a defined low threshold to trigger a downward alert. 
 •  Non-directional filters : The numbers 23-30 correspond to conditions that  do not  represent directional information. These conditions act as  filters  for both upward  and  downward alerts. Traders often use non-directional conditions to refine trending or mean reversion signals. For instance, if one of the input lists includes "30", that group uses the "Low relative volatility" condition. The group can trigger an upward or downward alert only if the 7-period Average True Range (ATR) is below the 40-period ATR. 
 •  External conditions : The numbers 31-35 correspond to  external  conditions based on the  plots  from other indicators on the chart. To set these conditions, use the source inputs in the "External conditions" section near the bottom of the "Settings/Inputs" tab. The external value can represent an upward, downward, or non-directional condition based on the following logic:
 ▫ Any value above 0 represents an upward condition.
 ▫ Any value below 0 represents a downward condition. 
 ▫ If the checkbox next to the source input is selected, the condition becomes  non-directional . Any group that uses the condition can trigger upward  or  downward alerts only if the source value is not 0. 
To learn more about using plotted values from other indicators, see  this article  in our Help Center and the  Source input  section of our Pine Script™ User Manual.
 Group markers 
Each comma-separated list represents a  distinct group , where all the listed conditions must occur to trigger an alert. This script assigns preset  markers  (names) to each condition group to make the active ensembles easily identifiable in the generated alert messages and labels. The markers assigned to each group use the format "M", where "M" is short for "Marker" and "x" is the group number. The titles of the inputs at the top of the "Settings/Inputs" tab show these markers for convenience. 
For upward conditions, the labels and alert messages show group markers with upward triangles (e.g., "M1▲"). For downward conditions, they show markers with downward triangles (e.g., "M1▼").
NOTE: By default, this script populates the "M1" field with a pre-configured list for a mean reversion group ("2,18,24,28"). The other fields are empty. If any "M*" input does not contain a value, the indicator ignores it in the alert calculations. 
 Custom alert messages 
By default, the indicator's alert message text contains the activated markers and their direction as a comma-separated list. Users can override this message for upward or downward alerts with the two text fields at the bottom of the "Settings/Inputs" tab. When the fields are  not empty , the alerts use that text instead of the default marker list. 
NOTE: This script generates alert triggers,  not  the alerts themselves. To set up an alert based on this script's conditions, open the "Create Alert" dialog box, then select the "Ensemble Alerts" and "Any alert() function call" options in the "Condition" tabs. See the  Alerts FAQ  in our Pine Script™ User Manual for more information. 
 Condition visualization 
This script offers organized visualizations of its conditions, allowing users to inspect the behaviors of each condition alongside the specified groups. The key visual features include:
  1) Conditional plots 
 • The indicator plots the history of each individual condition, excluding the external conditions, as circles at different levels. Opposite conditions appear at positive and negative levels with the  same  absolute value. The plots for each condition show values only on the bars where they occur.
 • Each condition's plot is color-coded based on its type. Aqua and orange plots represent opposing  directional  conditions, and purple plots represent  non-directional  conditions. The titles of the plots also contain the condition numbers to which they apply. 
 • The plots in the separate pane can be turned on or off with the "Show plots in pane" checkbox near the top of the "Settings/Inputs" tab. This input only toggles the color-coded circles, which reduces the graphical load. If you deactivate these visuals, you can still inspect each condition from the script's status line and the Data Window. 
 • As a bonus, the indicator includes "Up alert" and "Down alert" plots in the Data Window, representing the combined upward and downward ensemble alert conditions. These plots are also usable in additional indicator-on-indicator calculations. 
  2) Dynamic labels 
 • The indicator draws a label on the main chart pane displaying the activated group markers (e.g., "M1▲") each time an alert condition occurs. 
 • The labels for upward alerts appear below chart bars. The labels for downward alerts appear above the bars. 
 NOTE: This indicator can display up to 500 labels because that is the maximum allowed for a single Pine script. 
  3) Background highlighting 
 • The indicator can highlight the main chart's background on bars where upward or downward condition groups activate. Use the "Highlight background" inputs in the "Settings/Inputs" tab to enable these highlights and customize their colors. 
 • Unlike the dynamic labels, these background highlights are available for all chart bars, irrespective of the number of condition occurrences.  
 █ NOTES 
• This script uses Pine Script™ v6, the latest version of TradingView's programming language. See the  Release notes  and  Migration guide  to learn what's new in v6 and how to convert your scripts to this version. 
• This script imports our new  Alerts  library, which features functions that provide high-level simplicity for working with complex compound conditions and alerts. We used the library's `compoundAlertMessage()` function in this indicator. It evaluates items from "bool"  arrays  in groups specified by an array of strings containing comma-separated  index lists , returning a  tuple  of "string" values containing the marker of each activated group. 
• The script imports the latest version of the  ta  library to calculate several technical indicators not included in the built-in `ta.*` namespace, including Double Exponential Moving Average (DEMA), Triple Exponential Moving Average (TEMA), Fractal Adaptive Moving Average (FRAMA), Tilson T3, Awesome Oscillator (AO), Full Stochastic (%K and %D), SuperTrend, and Donchian Channels.
• The script uses the `force_overlay` parameter in the  label.new()  and  bgcolor()  calls to display the drawings and background colors in the main chart pane. 
• The plots and hlines use the available `display.*` constants to determine whether the visuals appear in the separate pane. 
 Look first. Then leap. 
Alerts█  OVERVIEW 
This library is a Pine Script™ programmers tool that provides functions to simplify the creation of compound conditions and alert messages. With these functions, scripts can use comma-separated "string" lists to specify condition groups from arbitrarily large "bool"  arrays , offering a convenient way to provide highly flexible alert creation to script users without requiring numerous inputs in the "Settings/Inputs" menu. 
 █  CONCEPTS 
 Compound conditions 
 Compound conditions  are essentially groups of two or more conditions, where each required condition must occur to produce a `true` result. Traders often combine conditions, including signals from various indicators, to drive and reinforce trade decisions. Similarly, programmers use compound conditions in logical operations to create scripts that respond dynamically to groups of events. 
 Condition conundrum 
Providing flexible condition combinations to script users for signals and alerts often poses a significant challenge:  input complexity . Conventionally, such flexibility comes at the cost of an extensive list of separate inputs for toggling individual conditions and customizing their properties, often resulting in complicated input menus that are difficult for users to navigate effectively. Furthermore, managing all those inputs usually entails tediously handling many extra variables and logical expressions, making such projects more complex for programmers. 
 Condensing complexity 
This library introduces a technique using parsed strings to reference groups of elements from "bool"  arrays , helping to simplify and streamline the construction of compound conditions and alert messages. With this approach, programmers can provide one or more "string" inputs in their scripts where users can  list numbers  corresponding to the conditions they want to combine. 
For example, suppose you have a script that creates alert triggers based on a combination of up to 20 individual conditions, and you want to make inputs for users to choose which conditions to combine. Instead of creating 20 separate checkboxes in the "Settings/Inputs" tab and manually adding associated logic for each one, you can store the conditional values in arrays, make one or more "string" inputs that accept values listing the array item locations (e.g., "1,4,8,11"), and then pass the inputs to these functions to determine the compound conditions formed by the specified groups. 
This approach condenses the input space, improving navigability and utility. Additionally, it helps provide high-level simplicity to complex conditional code, making it easier to maintain and expand over time. 
 █  CALCULATIONS AND USE 
This library contains three functions for evaluating compound conditions: `getCompoundConditon()`, `getCompoundConditionsArray()`, and `compoundAlertMessage()`. Each function has two overloads that evaluate compound conditions based on groups of items from one or two "bool"  arrays . The sections below explain the functions' calculations and how to use them. 
 Referencing conditions using "string" index lists 
Each function processes "string" values containing comma-separated lists of  numerals  representing the  indices  of the "bool" array items to use in its calculations (e.g., "4, 8, 12"). The functions split each supplied "string" list by its commas, then iterate over those specified indices in the "bool" arrays to determine each group's combined `true` or `false` state. 
For convenience, the numbers in the "string" lists can represent  zero-based  indices (where the first item is at index 0) or  one-based  indices (where the first item is at index 1), depending on the function's `zeroIndex` parameter. For example, an index list of "0, 2, 4" with a `zeroIndex` value of `true` specifies that the condition group uses the  first ,  third , and  fifth  "bool" values in the array, ignoring all others. If the `zeroIndex` value is `false`, the list "1, 3, 5" also refers to those same elements.
Zero-based indexing is convenient for programmers because Pine arrays always use this index format. However, one-based indexing is often more convenient and familiar for script users, especially non-programmers.
 Evaluating one or many condition groups 
The `getCompoundCondition()` function evaluates  singular  condition groups determined by its `indexList` parameter, returning `true` values whenever the specified array elements are `true`. This function is helpful when a script has to evaluate specific groups of conditions and does not require many combinations. 
In contrast, the `getCompoundConditionsArray()` function can evaluate  numerous  condition groups, one for each "string" included in its `indexLists` argument. It returns arrays containing `true` or `false` states for each listed group. This function is helpful when a script requires multiple condition combinations in additional calculations or logic. 
The `compoundAlertMessage()` function is similar to the `getCompoundConditionsArray()` function. It also evaluates a separate compound condition group for each "string" in its `indexLists` array, but it returns "string" values containing the  marker (name)  of each group with a `true` result. You can use these returned values as the `message` argument in  alert()  calls, display them in  labels  and other drawing objects, or even use them in additional calculations and logic.  
 Directional condition pairs 
The first overload of each function operates on a single `conditions` array, returning values representing one or more compound conditions from groups in that array. These functions are ideal for general-purpose condition groups that may or may not represent direction information. 
The second overloads accept  two  arrays representing upward and downward conditions separately: `upConditions` and `downConditions`. These overloads evaluate opposing directional conditions in  pairs  (e.g., RSI is above/below a level) and return upward and downward condition information separately in a  tuple . 
When using the directional overloads, ensure the `upConditions` and `downConditions` arrays are the same size, with the intended condition pairs at the  same indices . For instance, if you have a specific upward RSI condition's value at the first index in the `upConditions` array, include the opposing downward RSI condition's value at that same index in the `downConditions` array. If a condition can apply to  both  directions (e.g., rising volume), include its value at the same index in both arrays. 
 Group markers 
To simplify the generation of informative alert messages, the `compoundAlertMessage()` function assigns "string"  markers  to each condition group, where "marker" refers to the group's name. The `groupMarkers` parameter allows you to assign custom markers to each listed group. If not specified, the function generates default group markers in the format "M", where "M" is short for "Marker" and "" represents the  group number  starting from 1. For example, the default marker for the first group specified in the `indexLists` array is "M1". 
The function's returned "string" values contain a comma-separated list with markers for each activated condition group (e.g., "M1, M4"). The function's second overload, which processes directional pairs of conditions, also appends  extra  characters to the markers to signify the direction. The default for upward groups is "▲" (e.g., "M1▲") and the default for downward ones is "▼" (e.g., "M1▼"). You can customize these appended characters with the `upChar` and `downChar` parameters. 
 Designing customizable alerts 
We recommend following these primary steps when using this library to design flexible alerts for script users:
 1. Create text inputs for users to specify comma-separated lists of conditions with the  input.string()  or  input.text_area()  functions, and then collect all the input values in a "string"  array . Note that each separate "string" in the array will represent a  distinct  condition group. 
 2. Create arrays of "bool" values representing the possible conditions to choose from. If your script will process  pairs  of upward and downward conditions, ensure the related elements in the arrays align at the same indices. 
 3. Call `compoundAlertMessage()` using the arrays from steps 1 and 2 as arguments to get the alert message text. If your script will use the text for alerts only,  not  historical display or calculation purposes, the call is necessary only on  realtime bars .
 4. Pass the calculated "string" values as the `message` argument in  alert()  calls. We recommend calling the function only when the "string" is  not empty  (i.e., `messageText != ""`). To avoid repainting alerts on open bars, use  barstate.isconfirmed  in the condition to allow alert triggers only on each bar's  close .  
 5. Test the alerts. Open the "Create Alert" dialog box and select  "Any alert() function call"  in the "Condition" field. It is also helpful to inspect the strings with  Pine Logs .
NOTE: Because the techniques in this library use lists of numbers to specify conditions, we recommend including a  tooltip  for the "string" inputs that lists the available numbers and the conditions they represent. This tooltip provides a  legend  for script users, making it simple to understand and utilize. To create the tooltip, declare a "const string" listing the options and pass it to the `input.*()` call's `tooltip` parameter. See the library's example code for a simple demonstration. 
 █  EXAMPLE CODE 
This library's example code demonstrates one possible way to offer a selection of compound conditions with "string" inputs and these functions. It uses three  input.string()  calls, each accepting a comma-separated list representing a distinct condition group. The title of each input represents the default  group marker  that appears in the label and alert text. The code collects these three input values in a `conditionGroups` array for use with the `compoundAlertMessage()` function.
In this code, we created two "bool" arrays to store six arbitrary condition pairs for demonstration:
 1.  Bar up/down:  The bar's  close  price must be above the  open  price for upward conditions, and vice versa for downward conditions. 
 2.  Fast EMA above/below slow EMA : The 9-period Exponential Moving Average of  close  prices must be above the 21-period EMA for upward conditions, and vice versa for downward conditions. 
 3.  Volume above average : The bar's  volume  must exceed its 20-bar average to activate an upward or downward condition. 
 4.  Volume rising : The  volume  must exceed that of the previous bar to activate an upward or downward condition. 
 5.  RSI trending up/down : The 14-period Relative Strength Index of  close  prices must be between 50 and 70 for upward conditions, and between 30 and 50 for downward conditions. 
 6.  High volatility : The 7-period Average True Range (ATR) must be above the 40-period ATR to activate an upward or downward condition.  
We included a `tooltip` argument for the third  input.string()  call that displays the condition numbers and titles, where 1 is the first condition number. 
The `bullConditions` array contains the `true` or `false` states of all individual upward conditions, and the `bearConditions` array contains all downward condition states. For the conditions that filter either direction because they are non-directional, such as "High volatility", both arrays contain the condition's `true` or `false` value at the same index. If you use these conditions alone, they activate upward and downward alert conditions simultaneously. 
The example code calls `compoundAlertMessage()` using the `bullConditions`, `bearConditions`, and `conditionGroups` arrays to create a  tuple  of strings containing the directional markers for each activated group. On  confirmed  bars, it displays non-empty strings in  labels  and uses them in  alert()  calls. For the text shown in the labels, we used  str.replace_all()  to replace commas with newline characters, aligning the markers vertically in the display.  
 Look first. Then leap. 
 █  FUNCTIONS 
This library exports the following functions:
 getCompoundCondition(conditions, indexList, minRequired, zeroIndex) 
  (Overload 1 of 2) Determines a compound condition based on selected elements from a `conditions` array.
  Parameters:
     conditions (array) : (array) An array containing the possible "bool" values to use in the compound condition.
     indexList (string) : (series string) A "string" containing a comma-separated list of whole numbers representing the group of `conditions` elements to use in the compound condition. For example, if the value is `"0, 2, 4"`, and `minRequired` is `na`, the function returns `true` only if the `conditions` elements at index 0, 2, and 4 are all `true`. If the value is an empty "string", the function returns `false`.
     minRequired (int) : (series int) Optional. Determines the minimum number of selected conditions required to activate the compound condition. For example, if the value is 2, the function returns `true` if at least two of the specified `conditions` elements are `true`. If the value is `na`, the function returns `true` only if all specified elements are `true`. The default is `na`.
     zeroIndex (bool) : (series bool) Optional. Specifies whether the `indexList` represents zero-based array indices. If `true`, a value of "0" in the list represents the first array index. If `false`, a `value` of "1" represents the first index. The default is `true`.
  Returns: (bool) `true` if `conditions` elements in the group specified by the `indexList` are `true`, `false` otherwise.
 getCompoundCondition(upConditions, downConditions, indexList, minRequired, allowUp, allowDown, zeroIndex) 
  (Overload 2 of 2) Determines upward and downward compound conditions based on selected elements from `upConditions` and `downConditions` arrays.
  Parameters:
     upConditions (array) : (array) An array containing the possible "bool" values to use in the upward compound condition.
     downConditions (array) : (array) An array containing the possible "bool" values to use in the downward compound condition.
     indexList (string) : (series string) A "string" containing a comma-separated list of whole numbers representing the `upConditions` and `downConditions` elements to use in the compound conditions. For example, if the value is `"0, 2, 4"` and `minRequired` is `na`, the function returns `true` for the first value only if the `upConditions` elements at index 0, 2, and 4 are all `true`. If the value is an empty "string", the function returns ` `.
     minRequired (int) : (series int) Optional. Determines the minimum number of selected conditions required to activate either compound condition. For example, if the value is 2, the function returns `true` for its first value if at least two of the specified `upConditions` elements are `true`. If the value is `na`, the function returns `true` only if all specified elements are `true`. The default is `na`.
     allowUp (bool) : (series bool) Optional. Controls whether the function considers upward compound conditions. If `false`, the function ignores the `upConditions` array, and the first item in the returned tuple is `false`. The default is `true`.
     allowDown (bool) : (series bool) Optional. Controls whether the function considers downward compound conditions. If `false`, the function ignores the `downConditions` array, and the second item in the returned tuple is `false`. The default is `true`.
     zeroIndex (bool) : (series bool) Optional. Specifies whether the `indexList` represents zero-based array indices. If `true`, a value of "0" in the list represents the first array index. If `false`, a value of "1" represents the first index. The default is `true`.
  Returns: ( ) A tuple containing two "bool" values representing the upward and downward compound condition states, respectively.
 getCompoundConditionsArray(conditions, indexLists, zeroIndex) 
  (Overload 1 of 2) Creates an array of "bool" values representing compound conditions formed by selected elements from a `conditions` array.
  Parameters:
     conditions (array) : (array) An array containing the possible "bool" values to use in each compound condition.
     indexLists (array) : (array) An array of strings containing comma-separated lists of whole numbers representing the `conditions` elements to use in each compound condition. For example, if an item is `"0, 2, 4"`, the corresponding item in the returned array is `true` only if the `conditions` elements at index 0, 2, and 4 are all `true`. If an item is an empty "string", the item in the returned array is `false`.
     zeroIndex (bool) : (series bool) Optional. Specifies whether the "string" lists in the `indexLists` represent zero-based array indices. If `true`, a value of "0" in a list represents the first array index. If `false`, a value of "1" represents the first index. The default is `true`.
  Returns: (array) An array of "bool" values representing compound condition states for each condition group. An item in the array is `true` only if all the `conditions` elements specified by the corresponding `indexLists` item are `true`. Otherwise, the item is `false`.
 getCompoundConditionsArray(upConditions, downConditions, indexLists, allowUp, allowDown, zeroIndex) 
  (Overload 2 of 2) Creates two arrays of "bool" values representing compound upward and
downward conditions formed by selected elements from `upConditions` and `downConditions` arrays.
  Parameters:
     upConditions (array) : (array) An array containing the possible "bool" values to use in each upward compound condition.
     downConditions (array) : (array) An array containing the possible "bool" values to use in each downward compound condition.
     indexLists (array) : (array) An array of strings containing comma-separated lists of whole numbers representing the `upConditions` and `downConditions` elements to use in each compound condition. For example, if an item is `"0, 2, 4"`, the corresponding item in the first returned array is `true` only if the `upConditions` elements at index 0, 2, and 4 are all `true`. If an item is an empty "string", the items in both returned arrays are `false`.
     allowUp (bool) : (series bool) Optional. Controls whether the function considers upward compound conditions. If `false`, the function ignores the `upConditions` array, and all elements in the first returned array are `false`. The default is `true`.
     allowDown (bool) : (series bool) Optional. Controls whether the function considers downward compound conditions. If `false`, the function ignores the `downConditions` array, and all elements in the second returned array are `false`. The default is `true`.
     zeroIndex (bool) : (series bool) Optional. Specifies whether the "string" lists in the `indexLists` represent zero-based array indices. If `true`, a value of "0" in a list represents the first array index. If `false`, a value of "1" represents the first index. The default is `true`.
  Returns: ( ) A tuple containing two "bool" arrays:
- The first array contains values representing upward compound condition states determined using the `upConditions`.
- The second array contains values representing downward compound condition states determined using the `downConditions`.
 compoundAlertMessage(conditions, indexLists, zeroIndex, groupMarkers) 
  (Overload 1 of 2) Creates a "string" message containing a comma-separated list of markers representing active compound conditions formed by specified element groups from a `conditions` array.
  Parameters:
     conditions (array) : (array) An array containing the possible "bool" values to use in each compound condition.
     indexLists (array) : (array) An array of strings containing comma-separated lists of whole numbers representing the `conditions` elements to use in each compound condition. For example, if an item is `"0, 2, 4"`, the corresponding marker for that item appears in the returned "string" only if the `conditions` elements at index 0, 2, and 4 are all `true`.
     zeroIndex (bool) : (series bool) Optional. Specifies whether the "string" lists in the `indexLists` represent zero-based array indices. If `true`, a value of "0" in a list represents the first array index. If `false`, a value of "1" represents the first index. The default is `true`.
     groupMarkers (array) : (array) Optional. If specified, sets the marker (name) for each condition group specified in the `indexLists` array. If `na`, the function uses the format `"M"` for each group, where "M" is short for "Marker" and `` represents the one-based index for the group (e.g., the marker for the first listed group is "M1"). The default is `na`.
  Returns: (string) A "string" containing a list of markers corresponding to each active compound condition.
 compoundAlertMessage(upConditions, downConditions, indexLists, allowUp, allowDown, zeroIndex, groupMarkers, upChar, downChar) 
  (Overload 2 of 2) Creates two "string" messages containing comma-separated lists of markers representing active upward and downward compound conditions formed by specified element groups from `upConditions` and `downConditions` arrays. 
  Parameters:
     upConditions (array)  An array containing the possible "bool" values to use in each upward compound condition.
     downConditions (array)  An array containing the possible "bool" values to use in each downward compound condition.
     indexLists (array)  An array of strings containing comma-separated lists of whole numbers representing the `upConditions` and `downConditions` element groups to use in each compound condition. For example, if an item is `"0, 2, 4"`, the corresponding group marker for that item appears in the first returned "string" only if the `upConditions` elements at index 0, 2, and 4 are all `true`.
     allowUp (bool)  Optional. Controls whether the function considers upward compound conditions. If `false`, the function ignores the `upConditions` array and returns an empty "string" for the first tuple element. The default is `true`.
     allowDown (bool)  Optional. Controls whether the function considers downward compound conditions. If `false`, the function ignores the `downConditions` array and returns an empty "string" for the second tuple element. The default is `true`.
     zeroIndex (bool)  Optional. Specifies whether the "string" lists in the `indexLists` represent zero-based array indices. If `true`, a value of "0" in a list represents the first array index. If `false`, a value of "1" represents the first index. The default is `true`.
     groupMarkers (array)  Optional. If specified, sets the name (marker) of each condition group specified in the `indexLists` array. If `na`, the function uses the format `"M"` for each group, where "M" is short for "Marker" and `` represents the one-based index for the group (e.g., the marker for the first listed group is "M1"). The default is `na`.
     upChar (string)  Optional. A "string" appended to all group markers for upward conditions to signify direction. The default is "▲".
     downChar (string)  Optional. A "string" appended to all group markers for downward conditions to signify direction. The default is "▼".
  Returns: ( ): A tuple of "string" values containing lists of markers corresponding to active upward and downward compound conditions, respectively. 
PineUnitPineUnit by Guardian667 
A comprehensive testing framework for Pine Script on TradingView. Built with well-known testing paradigms like Assertions, Units and Suites. It offers the ability to log test results in TradingView's built-in Pine Protocol view, as well as displaying them in a compact table directly on your chart, ensuring your scripts are both robust and reliable.
Unit testing Pine Script indicators, libraries, and strategies becomes seamless, ensuring the precision and dependability of your TradingView scripts. Beyond standard function testing based on predefined input values, PineUnit supports series value testing. This means a test can run on every bar, taking into account its specific values. Moreover, you can specify the exact conditions under which a test should execute, allowing for series-based testing only on bars fitting a designated scenario.
 Detailed Guide & Source Code 
 Quick Start 
To get started swiftly with PineUnit, follow this minimalistic example.
 
import Guardian667/PineUnit/1 as PineUnit
var testSession = PineUnit.createTestSession()
var trueTest = testSession.createSimpleTest("True is always True")
trueTest.assertTrue(true)
testSession.report()
 
After running your script, you'll notice a table on your chart displaying the test results. For a detailed log output, you can also utilize the Pine Protocol view in TradingView.
 
--------------------------------------------------------------
T E S T S
--------------------------------------------------------------
Running Default Unit
Tests run: 1, Failures: 0, Not executed: 0, Skipped: 0
 
To further illustrate, let's introduce a test that's destined to fail:
 
var bullTest = testSession.createSeriesTest("It's allways Bull Market")
bullTest.assertTrue(close > open, "Uhoh... it's not always bullish")
 
After executing, the test results will reflect this intentional discrepancy:
 
--------------------------------------------------------------
T E S T S
--------------------------------------------------------------
Running Default Unit
Tests run: 2, Failures: 1, Not executed: 0, Skipped: 0 <<< FAILURE! - in
It's allways Bull Market
Uhoh... it's not always bullish ==> expected: , but was 
 
This shows how PineUnit efficiently captures and reports discrepancies in test expectations.
It's important to recognise the difference between `createSimpleTest()` and `createSeriesTest()`. In contrast to a simple test, a series-based test is executed on each bar, making assertions on series values.
 License 
This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
@ Guardian667
 A Personal Note 
As a software developer experienced in OO-based languages, diving into Pine Script is a unique journey. While many aspects of it are smooth and efficient, there are also notable gaps, particularly in the realm of testing. We've all been there: using `plotchar()` for debugging, trying to pinpoint those elusive issues in our scripts. I've come to appreciate the value of writing tests, which often obviates the need for such debugging. My hope is that this Testing Framework serves you well and saves you a significant amount of time, more that I invested into developing this "baby."
ANTEYA ProfilingThis script allows to compare which code is more efficient by running it inside a loop for a certain time or a certain number of iterations.
Just paste your pieces of code as Option 1 and Option 2 inside the loop (see comments in the script).
Parabolic SAR Heikin Ashi MTF Candle ScalperThis is scalper strategy designed around parabolic sar indicator, where as an input candle value it uses the heikinashi from a higher timeframe.
This example has been adapted to SPY/SPX chart
In this case ,we are using a 5 min chart, but the calculations are made on a 15 min heikin ashi chart for the PSAR and then on 5 min chart we plot the results.
At the same time we are conditioning the entry to be base on a time/session for daytrading/scalper mentality
In this case we only enter within the first 30 min of SPY opening session , and then we exit after 3-4 hours of staying in the position ( unless we hit a reverse condition).
For long condition we enter when the mtf ha candle close is above the mtf psar and for short condition we enter when the mtf ha candle close is below the mtf psar
This script is made with an educational purpose to show the power of multiple time frame approach compared to a single chart.
If you have any questions, let me know !
matrixautotableLibrary   "matrixautotable" 
Automatic Table from Matrixes with pseudo correction for na values and default color override for missing values. uses overloads in cases of cheap float only, with additional addon for strings next, then cell colors, then text colors, and tooltips last..  basic size and location are auto, include the template to speed this up...
 TODO  : make bools version
 
var string  group_table    = ' Table'
var int     _tblssizedemo  = input.int    ( 10 )
string      tableYpos      = input.string ( 'middle'    , '↕'               , inline = 'place' , group = group_table, options= )
string      tableXpos      = input.string ( 'center'    , '↔'               , inline = 'place' , group = group_table, options= , tooltip='Position on the chart.')
int         _textSize      = input.int    ( 1           , 'Table Text Size' , inline = 'place' , group = group_table)
var matrix  _floatmatrix     = matrix.new  (_tblssizedemo, _tblssizedemo,  0            ) 
var matrix _stringmatrix     = matrix.new (_tblssizedemo, _tblssizedemo,  'test'       ) 
var matrix  _bgcolormatrix    = matrix.new  (_tblssizedemo, _tblssizedemo,  color.white  ) 
var matrix  _textcolormatrix  = matrix.new  (_tblssizedemo, _tblssizedemo,  color.black  ) 
var matrix _tooltipmatrix    = matrix.new (_tblssizedemo, _tblssizedemo,  'tool'       ) 
// basic table ready to go with the aboec matrixes (replace in your code)
//   for demo purpose, random colors, random nums, random na vals
if barstate.islast
    varip _xsize = matrix.rows    (_floatmatrix) -1
    varip _ysize = matrix.columns (_floatmatrix) -1
    for _xis = 0  to _xsize  -1  by 1
        for _yis  = 0 to _ysize  -1 by 1
            _randomr = int(math.random(50,250))
            _randomg = int(math.random(50,250))
            _randomb = int(math.random(50,250))
            _randomt = int(math.random(10,90 ))
            bgcolor  = color.rgb(250 - _randomr, 250 - _randomg, 250 - _randomb, 100 - _randomt )
            txtcolor = color.rgb(_randomr, _randomg, _randomb, _randomt                         )
            matrix.set(_bgcolormatrix    ,_yis,_xis, bgcolor )
            matrix.set(_textcolormatrix  ,_yis,_xis, txtcolor)
            matrix.set(_floatmatrix      ,_yis,_xis, _randomr)
            
            // random na
            _ymiss = math.floor(math.random(0, _yis))
            _xmiss = math.floor(math.random(0, _xis))
            matrix.set( _floatmatrix     ,_ymiss,  _xis, na)
            matrix.set( _stringmatrix    ,_ymiss,  _xis, na)
            matrix.set( _bgcolormatrix   ,_ymiss,  _xis, na)
            matrix.set( _textcolormatrix ,_ymiss,  _xis, na)
            matrix.set( _tooltipmatrix   ,_ymiss,  _xis, na)
// import here
import kaigouthro/matrixautotable/1 as mtxtbl
// and render table.. 
mtxtbl.matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _textcolormatrix, _tooltipmatrix, _textSize   ,tableYpos   ,tableXpos)
 
 matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _textcolormatrix, _tooltipmatrix, _textSize, tableYpos, tableXpos)  matrixtable
  Parameters:
     _floatmatrix :  float vals
     _stringmatrix :  string
     _bgcolormatrix :  color
     _textcolormatrix : color
     _tooltipmatrix :  string
     _textSize : int
     tableYpos : string
     tableXpos : string
 matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _textcolormatrix, _textSize, tableYpos, tableXpos)  matrixtable
  Parameters:
     _floatmatrix :  float vals
     _stringmatrix :  string
     _bgcolormatrix :  color
     _textcolormatrix : color
     _textSize : int
     tableYpos : string
     tableXpos : string
 matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _txtdefcol, _textSize, tableYpos, tableXpos)  matrixtable
  Parameters:
     _floatmatrix :  float vals
     _stringmatrix :  string
     _bgcolormatrix :  color
     _txtdefcol : color
     _textSize : int
     tableYpos : string
     tableXpos : string
 matrixtable(_floatmatrix, _stringmatrix, _txtdefcol, _bgdefcol, _textSize, tableYpos, tableXpos)  matrixtable
  Parameters:
     _floatmatrix :  float vals
     _stringmatrix :  string
     _txtdefcol : color
     _bgdefcol : color
     _textSize : int
     tableYpos : string
     tableXpos : string
 matrixtable(_floatmatrix, _txtdefcol, _bgdefcol, _textSize, tableYpos, tableXpos)  matrixtable
  Parameters:
     _floatmatrix :  float vals
     _txtdefcol : color
     _bgdefcol : color
     _textSize : int
     tableYpos : string
     tableXpos : string
debuggerDEBUGGER is a library to help print debug messages to a console.
This library provides an easy-to-use interface to print your debugging messages to a console in the chart. Special attention has been given to printing series and arrays easily.
A debugger is a valuable tool when working on scripts and getting into trouble.  Unfortunately, TradingView does not provide an interactive debugger, and does not provide a console to use the oldest trick in the debugging book: print statements.  This library provides you with the latter tool, print statements.
As a bonus, the library also provides a way to show labels in the chart next to the pricing action.
For more information and examples of usage, check the description in the header comments.
[UTILS] Unit Testing FrameworkTL;DR 
 
  This script doesn't provide any buy/sell signals.
  This script won't make you profitable implicitly.
  This script is intended for utility function testing, library testing, custom assertions.
  It is free and open-source.
 
 Introduction 
About the idea: is not exclusive, programmers tend to use this method a lot and for a long time.
The point is to ensure that parts of a software, "units" (i.e modules, functions, procedures, class methods etc), work as they should, meet they design and behave as intended. That's why we use the term "Unit testing".
In PineScript we don't have a lot of entities mentioned above yet. What we have are functions. For example, a function that sums numbers should return a number, a particular sum. Or a professor wrote a function that calculates something or whatever. He and you want to be sure that the function works as expected and further code changes (refactoring) won't break its behaviour. What the professor needs to do is to write unit tests for his function/library of functions. And what you need to do is to check if the professor wrote tests or not.
 No tests = No code 
 - Total test-driven development 
Ok, it is not so serious, but very important in software development. And I created a tool for that.
I tried to follow the APIs of testing tools/libs/frameworks I worked or work with: Jasmine (Javascript), Mocha/Chai (Javascript), Jest (Javascript), RSpec (Ruby), unittest (Python), pytest (Python) and others. Got something workable but it would be much easier to implement (and it would look much better) if PineScript had a higher-order functions feature.
 API 
 _describe(suiteName: string) 
A function to declare a test suite. Each suite with tests may have 2 statuses:
 
  ✔️ Passed
  ❌ Failed
 
A suite is considered to be failed if at least one of the specs in it has failed.
 _it(specName: string, actual: any, expected: any) 
A function to run a test. Each test may have 3 statuses:
 
  ✔️ Passed
  ❌ Failed
  ⛔ Skipped
 
Some examples:
 
  _it("is a falsey value", 1 != 2, true)
  _it("is not a number", na(something), true)
  _it("should sum two integers", _sum(1, 2), 1)
  _it("arrays are equal", _isEqual(array.from(1, 2), array.from(1, 2)), true)
 
Remember that both the 'actual' and 'expected' arguments must be of the same type.
And a group of  _it()  functions must be preceded by a  _describe()  declaration (see in the code).
 _test(specName: string, actual: any, expected: any) 
An alias for  _it . Does the same thing.
 _xit(specName: string, actual: any, expected: any) 
A function to skip a particular test for a while. Doesn't make any comparisons, but the test will appear in the results as skipped.
This feature is unstable and may be removed in the future releases.
 _xtest(specName: string, actual: any, expected: any) 
An alias for  _xit . Does the same thing.
 _isEqual(id_1: array, id_2: array) 
A function to compare two arrays for equality. Both arrays must be of the same type.
This function doesn't take into account the order of elements in each array. So arrays like (1, 2, 3) and (3, 2, 1) will be equal.
 _isStrictEqual(id_1: array, id_2: array) 
A function to compare two arrays for equality. Both arrays must be of the same type.
This function is a stricter version of  _isEqual  because it takes into account the order of elements in each array. So arrays like (1, 2, 3) and (3, 2, 1) won't be equal.
 Usage 
To use this script to test your library you need to do the following steps:
1) Copy all the code you see between line #5 and #282 (Unit Testing Framework Core)
2) Place the copied code at the very beginning of your script (but below study())
3) Start to write suites and tests where your code ends. That's it.
 NOTE 
The current version is 0.0.1 which means that a lot of things may be changed on the way to 1.0.0 - the first stable version.
Cosmic BB SRThis script is based on Bollinger Bands/Bandwidth data and displays support and resistance levels (thick horizontal lines), the direction/volatility of the levels (thin dynamic lines), and the testing of the levels (cross markers).
Supertrend V1.0 - Buy or Sell SignalTesting a concept to get a TP and SL based on the ATR at the time of the position entry. 
Manual Back Test LinesI created this indicator to primarily manually test other indicators in replay mode.
To use this indicator generally you will:
 
 Select trade type: long or short
 Enter your ATR (enter the actual ATR). The indicator will then calculate and plot your SL and targets based on your values
 Default Stop Loss is ATR * 1.5
 Default Target 1 is ATR * 1.5
 Default Target 2 is ATR * 3
 
Using this indicator on Replay mode is great. What you do is go back in time. Hit play and as the indicator(s) you use provide signals pause.
Pull up options:
 
 Select trade type
 Update ATR value
 Change date to entry date. Typically if you are trading off the daily timeframe you are going to wait for your current day candle to close to provide signal. That would mean your entry would be on the next day.
 Click play and watch, track and record how trade unfolds.
 
Future updates:
I'd like to be able to have some way to click one button and have it fire that enter trade right now on chart. Also I'm working on figuring out how to calculate the ATR on the entry date so that isn't required to be entered.
Finally, I'd like to have some auto calculation on when targets and SL are hit. I have this partially done but it's more important that I use this indicator than spend time or funds to update it to do that. But I do plan on updating.
ACM22 not repaintedДелал данный скрипт для FORTS.Идеально подойдет тем,кто использует трейлинг стопы.В основе стратегии лежит RSI.Как по мне,хорошая вещь для проверки стратегии и ее оптимизиации.На скрине 50 контрактов,так что не сильно радуйтесь,а просто делите на 50 и получите показатели на 1 контракт.
 
Script make for futures on MICEX.U can change paramets of RSI,traling stop and stop loss .On a ps 50 futures USDollar-russian ruble.Use for testing and optimisation.
C320up Strategy Tester Start TimeC320up Strategy Tester Start Time 
This is a little snippet you can paste into your Strategy to set the testing start date and time.
It is not a Strategy per se, though is an example with the timestamp script included.
Instructions are fairly straight forward, and are listed in the script.
If for some reason you also wanted an end date, that too is possible. Just leave a note in the comments.
Disclaimer: We searched for a similar script on TV, and could not find anything at this point in time.
You can set your preferred date and time in the input section of the settings.
Enjoy!
Binary Options Strategy Testing ScriptThis is a script for testing binary options trading strategies.  To test a strategy, modify the 'go_down' or 'go_up' booleans. These SHOULD NOT access any current values (for example, 'ohlc4' or 'close '), or the backtesting will not be an accurate representation of the forward values.
Modify the fraction_return input to be the return rate of the option on success.  This is assumed to be a true 100 or 0 option- i.e. if the choice is not correct, there is a 100% loss.
The strategy in place is merely an example, and as you can see, has a very negative rate of return when implemented as a strategy.
Please comment in your code if you use this in any future posts. Thanks!














