Using Three Special Types of Read-Only Time Series In Quagensia® N Edition Strategies (Quagensia N Edition Only)
You cannot create a read-only time series variable in a Quagensia N Edition strategy, nor is there a need to do so, because all of the read-only time series that NinjaTrader® makes available to your NinjaScript® trading strategy are available as certain specific types of time series data in Quagensia N Edition. These special types of read-only time series include the following:
- NinjaTrader® indicators, which are represented in Quagensia N Edition using the “Indicator Time Series” data type.
- Primary data series, i.e. primary price bar time series, which are built into the Quagensia N Edition application (as opposed to being made available via Quagensia N Edition functions) and are accessible via context menu items in the “Set/Replace Item >> Price Data” context menu folder that is available in context menus that open when you click on locations where both market data is allowed and either decimal or date and time data, or time series of decimal or date and time data, are allowed.
- Secondary data series, i.e. secondary price bar time series, which are represented in Quagensia N Edition using the “Secondary Price Bars” data type.
Using Read-Only Time Series In Quagensia T Edition Strategies (Quagensia T Edition Only)
Quagensia T Edition doesn’t have special data types for different kinds of read-only time series. It has only two types of time series: “Read-Only Time Series” and “Editable Time Series”. You can create a read-only time series variable in a Quagensia T Edition strategy to hold the return values from Quagensia T Edition functions that call TradeStation® EasyLanguage® functions and reserved words that represent indicators, primary data series, and secondary data series.
How To Use Best Practices For Using EasyLanguage® Functions (e.g. Indicators) By Using Read-Only Time Series Internal Variables (Quagensia T Edition Only)
Much has been written by many EasyLanguage® programmers and TradeStation® support staff with slightly differing advice about how to avoid incorrect results in EasyLanguage® code that uses EasyLanguage® simple functions and EasyLanguage® series functions that return time series or otherwise involve a bar history, such as those that represent indicators. The TradeStation® discussion forums have many threads with slightly different advice on best practices regarding the usage of both EasyLanguage® series functions and EasyLanguage® simple functions, and the forums are full of examples of problems that can occur when specific best practices are not followed in certain scenarios.
Because there is no official documentation with agreed upon rules, the Quagensia T Edition application takes an approach that both protects the vast majority of all Quagensia T Edition users who are not EasyLanguage® programming experts but at the same time makes it possible for an EasyLanguage® programming expert to decide to not follow these rules when they are confident that the Quagensia T Edition validation rules regarding these best practices are overkill, i.e. the validation rules that Quagensia T Edition enforces by default are too restrictive and not necessary, for the EasyLanguage® programming expert’s specific algo logic.
Quagensia T Edition’s balanced approach to ensure that all users follow best practices regarding the usage of EasyLanguage® functions except for those advanced users who opt out of the protection is as follows:
- There is a check box titled “I Want to Use Best Practices When Using EasyLanguage® Functions (e.g. Indicators)” in the “Strategy Details” section of strategies and in the “Function Details” sections of functions.
- This check box is checked by default when you create a new Quagensia T Edition Strategy or Function.
- When this check box is checked, only Quagensia T Edition functions that are believed to not violate best practices will be shown in the “Set/Replace Item” context menus that appear when you click on locations that expect an expression, and attempting to generate the EasyLanguage® code for your Quagensia T Edition Algo will fail if the Quagensia T Edition validation engine identifies that a best practice was violated. One or more validation errors will be displayed with detailed descriptions of what rule or rules were violated, with advice on how to rectify the problem. Once you’ve rectified the problem or problems, you will be able to successfully generate the code, assuming that your algo has no other validation errors.
- When this check box is unchecked, even the Quagensia T Edition functions that are believed to violate best practices will be shown in the “Set/Replace Item” context menus that appear when you click on locations that expect an expression, and attempting to generate the EasyLanguage® code for your Quagensia T Edition algo will not fail even if the Quagensia T Edition validation engine identifies that a best practice was violated.
When the “I Want to Use Best Practices When Using EasyLanguage® Functions (e.g. Indicators)” check box is checked, the Quagensia T Edition validation engine finds all of the places in both the Quagensia T Edition Algo being validated as well as all of the places in all of the Quagensia T Edition Functions that the Quagensia T Edition Algo being validated calls, either directly or indirectly via another Quagensia T Edition Function, where a Quagensia T Edition function that is “best-practice limited” is called.
A “best-practice limited” Quagensia T Edition Function is one whose “May Call an Indicator or Any Other EasyLanguage® Function That May Involve a Bar History” check box is checked in the Quagensia T Edition Function’s “Function Details” section.
The reason why this entire discussion is on the “Using Read-Only Time Series” help page is because the best way to avoid a breach of best practices regarding the usage of EasyLanguage® functions almost always involves creating or modifying a “Read-Only Time Series” internal variable.
When the “I Want to Use Best Practices When Using EasyLanguage® Functions (e.g. Indicators)” check box is checked, the Quagensia T Edition validation engine attempts to stop you from the following breaches of best practices:
- Best-practice limited EasyLanguage® functions such as those that represent indicators should not be called twice with the same input parameters in the same EasyLanguage® strategy. The best way to fix this problem in a Quagensia T Edition Algo is to create an internal variable, usually with a data type of Read-Only Time Series, and set its value to the return value of the Quagensia Function call that is causing the validation error, then use that internal variable in all the places that are calling this function with the same input parameters. For instance, if you need to use a 10-bar exponential moving average in five places, create an internal variable of type Read-Only Time Series, set its value to the return value of a properly configured “Exponential Moving Average” Quagensia Function call, then use that internal variable in the five places where you need to use a 10-bar exponential moving average.
- Best-practice limited EasyLanguage® functions such as those that represent indicators should only be called at locations that are guaranteed to be called exactly once per bar update of the hosting strategy, at the location in which the function call appears on the Quagensia T Edition Algo and in the code output. Locations that are not guaranteed to be called exactly once per bar update at the location at which they appear include the following: 1) inside of loop conditions or loop statement blocks, 2) inside of “If” or “Else If” conditions or “If”, “Else If”, or “Else” statement blocks, 3) inside of “Do Once If” conditions or “Do Once If” statement blocks, 4) expressions that are part of Boolean conditions that are joined with “and” or “or” Boolean operators, 5) inside of a comparison expression of type “Is (or Is Not) Between”, “Is (or Is Not) Within X Units Of Y”, or the more advanced “Crossed Above (or Below) A Time Series” comparison types that add another criterion such as “Crossed Above A Time Series (Both Going Up)”, 6) inside of the definition of an internal variable of any data type other than “Read-Only Time Series”, and 7) as an input parameter of another Quagensia Function, since the expressions passed into many input parameters of many Quagensia Functions are passed as input parameters to EasyLanguage® functions or parameter-accepting EasyLanguage® “keywords”, and these EasyLanguage® code constructs may either not execute the expressions that are passed into them, or may execute the expressions passed into them more than once. If a Quagensia T Edition function is called in any of the prohibited locations mentioned above, there is no guarantee that the function will be called at the location in which one would expect it to be called based on its location in the Quagensia T Edition Algo, and instead could be called either zero times, called more than once, or in the case of series functions, called by the platform after all the lines of your generated code, making this algorithm behave in a way that is different than one might expect after inspecting the Quagensia T Edition Algo or the code output. The best way to fix this problem in a Quagensia T Edition Algo is to create an internal variable, usually with a data type of Read-Only Time Series, and set its value to the return value of the Quagensia Function call that is causing the validation error, then use that internal variable at the location where the Quagensia Function is prohibited from being called directly.
- Best-practice limited EasyLanguage® functions such as those that represent indicators should not be passed into input parameters of other best-practice limited EasyLanguage® functions. Best practices regarding EasyLanguage® functions dictate that they should not be “chained together” by passing one EasyLanguage® function into the input parameter of another EasyLanguage® function. Instead, “chaining” or “nesting” of EasyLanguage® functions should be achieved by setting a variable to the return value of a function, then passing that variable into the input parameter of another function. The best way to fix this problem in a Quagensia T Edition Algo is to “chain” Quagensia T Edition Functions together using two separate internal variables. To do this, first create an internal variable with a data type of “Read-Only Time Series” and set its “Value:” field to a Quagensia T Edition Function such as an indicator. Then, repeat this process by creating another internal variable beneath it whose data type is also Read-Only Time Series and set its “Value:” field to a Quagensia T Edition Function such as an indicator, but set an input parameter of the Quagensia T Edition Function to which the second internal variable is set to the previous internal variable. A practical example of when you should do this would be to create an exponential moving average of a simple moving average of the close price. The first internal variable described above would be a simple moving average of the close price, and the second internal variable described above would be an exponential moving average whose input parameter named “Input Data Series” should be set to the first internal variable, thereby creating an exponential moving average of a simple moving average of the close price.
The List of Quagensia T Edition Functions that are marked as Best-Practice Limited:
- All Quagensia Functions in the folder “Expressions >> Indicators”.
- All Quagensia Functions in the folder “Expressions >> Chart Patterns”.
- All Quagensia Functions in the folder “Expressions >> Price Data >> Higher Time Frame Price Data”.
- All Quagensia Functions in the folder “Expressions >> Price Data >> Bid/Ask”.
- The Quagensia Function “Expressions >> Price Data >> Price Bar Metadata >> Bar Number Of Historical Bar”.
- The Quagensia Functions in the “Expressions >> Price Data” folder named “Median Price ((H+L)/2)”, “Typical Price ((H+L+C)/3)”, “Weighted Close ((H+L+2*C)/4)”, “Average Price ((O+H+L+C)/4 Or (H+L+C)/3)”, “Range”, “True Range”, “True High”, and “True Low”.
Final notes for those advanced users who are considering unchecking the “I Want to Use Best Practices When Using EasyLanguage® Functions (e.g. Indicators)” check box:
Most, but not all, EasyLanguage® strategies will still work as expected even if these best practices are not followed, but Quagensia does its best to protect you from those instances where failing to follow these best practices would lead to a logic error that is very hard to spot, even for a highly experienced programmer that wasn’t aware of best practices regarding the usage of EasyLanguage® functions.
If strictly adhering to best practices is not possible, for instance if the location where a violation is occurring is in a Quagensia Function rather than a Quagensia Strategy, or if you simply need to take this risk in order to create certain functionality, uncheck the “I Want to Use Best Practices When Using EasyLanguage® Functions (e.g. Indicators)” check box to enable the ability to stray from best practices.
One scenario in which you will need to uncheck this checkbox is if you need to use an EasyLanguage® “simple function” (but never an EasyLanguage® “series function”) in a “While Loop” or “Do While Loop” where you pass the EasyLanguage® “simple function” different parameters for each loop iteration.
Another scenario in which you will need to uncheck this checkbox is that of a multi-data series strategy, i.e. a strategy that uses multiple instruments or multiple time frames in the same strategy, whose logic requires that two time series internal variables both be set to the return value of the same Quagensia Function with the same input parameters but whose time series internal variables differ in their need to each use the price bars of a different data series in the logic that counts bars back for each of the time series by counting backward over a specific data series’ price bars.
Note that your choice for the checked state of this check box will override the choice of the checked states for the “I Want to Use Best Practices When Using EasyLanguage® Functions (e.g. Indicators)” check boxes in all the Quagensia Functions that the Quagensia Algo calls.
Using Read-Only Time Series As Quagensia Function Input Parameters (All Quagensia Editions)
Quagensia Functions in all editions of Quagensia use read-only time series input parameters to make them useful in more scenarios.
When a Quagensia Function has an input parameter that is a read-only time series, the Quagensia Function can accept any kind of time series so long as the data type of the individual time series items are the same.
A read-only time series can be of any time series type, including primary or secondary price bar series, indicator time series, or editable time series.
Examples of using read-only time series as input parameters of Quagensia Functions are all of the Quagensia Functions that represent indicators. Whenever you use a Quagensia Function that represents an indicator such as a “Simple Moving Average”, you can use that same Quagensia Function to calculate the simple moving average of price bar series, your own custom editable time series, other indicators, or even nested indicators like “the 10-period simple moving average of the 20-period exponential moving average of the 30-period double exponential moving average of the primary price bar high prices” all with the same Quagensia Function, even though price bar series, editable time series, and indicator time series are different Quagensia data types in Quagensia N Edition and read-only time series and editable time series are different data types in Quagensia T Edition.