PrescienTrader adds the following AFL functions to AmiBroker. **Most users will only need to use the ****PrescienTrader()**** , PTPlotFLDs() and PTBacktest() functions**.

If you just want to use PrescienTrader as a standalone tool to analyze charts, you can** simply double-click the PrescienTrader AFL formula**, to create a new PrescienTrader chart pane. **You donโt need to read the rest of this article.**

The rest of the functions are for **advanced users** who want to call our algorithms from custom AFL scriPTs, for trading system development.

## PrescienTrader

PrescienTrader ()

- This is the
**main function**that displays a PrescienTrader chart pane , displays all the plots and generates reports in the Interpretation window. - The
- Although itโs possible to plot PrescienTrader on an existing price chart pane, it contains numerous indicators and graphs that may cause too much clutter and may conflict with your existing indicators. Therefore, we recommend creating a separate pane, exclusively for PrescienTrader.
**You must set the API Key in the Parameters window.**If you donโt set the API Key, PrescienTrader will display an*Invalid API Key*message.- To learn how to use each of these parameters, please read the article, PrescienTrader Parameters.

## PTPlotFLDs

PTPlotFLDs()

- This function plots the
*Future Line of Demarcation*(FLD) for each cycle peak identified by PrescienTrader. - The function accepts no parameters, because all parameters are set in the AmiBroker Parameters window.
- Since the FLD is closely related to price and uses the same scale as price,
**we recommend plotting the FLDs on your price chart pane, NOT on the PrescienTrader pane**. - This function uses PrescienTrader as its data source to generate the FLD plots. Therefore,
**it REQUIRES the**.*PrescienTrader()*function to be running in a separate chart pane - You may set the following parameters in the Parameters window:
**FLDs (1-10)**โ This allows you to select which FLD plots to display on the chart. Each cycle peak frequency has an associated FLD plot, but this parameter allows you to avoid chart clutter, by limiting the number of plots.**Sync with PrescienTrader**โ When this is enabled, the function will automatically run once per second, to fetch the latest data from PrescienTrader, ensuring the FLD plots stay synchronized with the cycles analysis generated by PrescienTrader. If you disable sync, you may have to manually refresh the chart each time.

- The function plots past, present and future FLDs. However, to display the
**past**FLD plots, you must enable the static indicators in PrescienTrader. This is because the cycle frequencies change with each new bar. Therefore to plot a past FLD, the function needs access to past cycle analyses, which require the static indicators. If the static indicators are disabled, youโll only see FLD plots for the current bar and future bars. Keep in mind,**the future FLD plots are only an estimate and may change as new bars are added to the chart**.

## PTBarAnalysis

PTBarAnalysis (Data Series, Polarity, PL Basis, Lookback Range, Min Frequency, Max Frequency, Harmonic Filter, Min Fitness, Best X Cycles, Analysis Bar, Plot Start Bar, Plot End Bar, Cache Index)

*PTBarAnalysis* performs a point-in-time cycles analysis on a single bar. It then generates various plots within the specified plot range, going backward and optionally, forward in time. The backward plot can be used to visually verify the accuracy of the cycles analysis, by confirming its shape follows the corresponding price bars. The forward plot is used to **predict future prices** or to view the accuracy of its predictions on past bars. This is the function youโd use for **live trading**.

This function does not return any values directly. Instead, it populates a set of AFL variables, including scalars, arrays and matrices. These arrays can be plotted like any AFL array.

### Parameters

**Data Series**(array)- This parameter expects an
**AmiBroker array**, containing the actual data series you want to analyze. For example, if you want to analyze the closing prices, youโd pass the built-in AmiBroker*Close (C)*variable, which is an array containing the closing prices from your data series.

- This parameter expects an
**Polarity**(integer)- 0 = Positive
- 1 = Negative

**PL Basis**(integer)- 0 = Amplitude
- 1 = Strength

**Lookback Range**(integer)- 1 โ 15

**Min Frequency**(integer)- Typically 10 โ 100

**Max Frequency**(integer)- Typically 150 โ 300

**Harmonic Filter**(integer)- 0 โ 100

**Min Fitness**(integer)- 0 โ 100

**Best X Cycles**(integer)- 1 โ 10

**Analysis Bar**(integer)- This is the bar index for which the analysis will be performed.

- When performing an analysis for live trading, youโd set the analysis bar equal to the bar index of the last bar on the chart.
- AmiBroker displays the first bar on the chart as bar number 1. However, the internal index used by AFL starts at bar 0. Therefore, if you want to analyze a specific bar, you need to subtract 1 from the bar number displayed in AmiBroker to get the correct bar number. If there are 5,000 bars on a chart, the last bar number would be 4,999, not 5,000.
- You can specify a past bar index to perform a point-in-time analysis for that bar. For example, if you specified a bar index of 1,000, you could then compare the Prescient Line from bars 1,001 to the last bar on the chart, with the actual price bars for that bar range to see how accurate the forecast was
**at that point in time**. When generating the cycle plots, the function ignores any price data to the right of the specified bar number.

**Plot Start Bar**(integer)- Specifies the bar index where the plot should start.
- Itโs usually not necessary to calculate plots for the entire series. For example, if your chart view displays 100 bars, you only need plots for those 100 bars, not the entire series.

**Plot End Bar**(integer)- Specifies the bar index where the plot should end.
- You can project the plots into the future by specifying a Plot End Bar greater than the number of bars on the chart.

**Cache Index**(integer)- The function contains an internal caching mechanism intended to prevent sending multiple consecutive API requests for the same data. The cache stores the data series, parameters and results for each API request. If it receives the exact same data series and parameters twice in a row, it skips the API request and immediately returns the cached result.
- If youโre just analyzing a single data series on a chart, you should set the Cache Index to 0.
- If youโre analyzing multiple data series on a chart, you should specify a unique cache index for each data series. For example, if youโre analyzing the base period, plus two higher time periods, youโd specify Cache Index 0 for the base period, Cache Index 1 for HTP 1 and Cache Index 2 for HTP 2. This would create a separate cache for each time period.

### Response

#### AFL Arrays:

Each element in these arrays represents a bar, starting with bar zero.

If you set *Plot End Bar* to a number greater than *LastValue(BarIndex())*, it will automatically **shift the arrays backward** by the difference. You can then project the plots into the future using the *Plot *functionโs *XShift* parameter.

For example, suppose your chart contains 5,000 bars, meaning the last bar index is 4,999. If you set *Plot End Bar* to 5,009, the array would be shifted to the left by 10 bars. Youโd then set XShift to 10, to plot 10 bars into the future. Since the array was shifted to the left by 10 bars, the XShifted plot will be correctly aligned with the chart.

**PTPL**โ the*Prescient Line*plot**PTPLSlope**โ the**slope**of the Prescient Line. A positive value means itโs sloping upward and a negative value means itโs sloping downward.**PTTrendBar**โ the**relative bar number**within the current Prescient Line trend. The first bar number in each trend is bar 0 and all subsequent bar numbers are relative to the first bar of the trend.**PTTrendBars**โ the**total number of bars**in the current Prescient Line trend.**PTTrendPct**โ the**percentage completed**of the current Prescient Line trend. The percentage will never reach 100, because that would mean a new trend has started with a zero percent completion. So, 100% of the old trend is equivalent to 0% of the new trend.

#### AFL Matrices:

**PTCycles**โ contains one row for each individual cycle frequency, in the range specified by the*minFrequency*and*maxFrequency*parameters. Each row contains eight columns, with the column numbers identified by AFL variables. When reading the values from the matrix,**you should always reference the column numbers using their associated AFL variables,**rather than hard coding the column numbers. That way, if the column numbers change in the future, your code will still work,**Frequency**(PTColFrequency) โ the cycle frequency.

**Amplitude**(PTColAmplitude) โ the cycle amplitude.**Strength**(PTColStrength) โ the cycle strength, which is amplitude divided by frequency.**Start Bar**(PTColStartBar) โ the bar index where the cycle plot starts. This is used to set the correct phase for the cycle plot, but itโs generally not necessary, as the function provides the plots for you in the PTPlots matrix discussed below.**Fitness**(PTColFitness) โ a statistical measure of how reliable the cycle has been, from 0% to 100%.**Peak**(PTColPeak) โ indicates whether or not the cycle is a peak and if so, whether or not it was filtered by one of the filters specified in the parameter settings:- 0 = Not a peak
- 1 = Valid peak
- -1 = Peak filtered by
*Min Fitness*filter - -2 = Peak filtered by
*Harmonic Filter* - -3 = Peak filtered by
*Best X Cycles*filter

**Slope**(PTColSlope) โ indicates whether the cycle is sloping up or down. Slope will only be calculated on cycles that are valid peaks (Peak = 1):- 1 = Sloping
**up** - -1 = Sloping
**down**

- 1 = Sloping
**FLD Price**(PTColFLDPrice) โ indicates the price of the cycleโs FLD. This will only be calculated on cycles that are valid peaks (Peak = 1).

**PTPeaks**โ the*PTPeaks*matrix contains the same information in the same format as the*PTCycles*matrix, except it only includes cycles that are valid peaks (Peak = 1). The cycles will be sorted by frequency.**PTPlots**โ the*PTPlots*matrix contains the plots for each cycle thatโs a valid peak (Peak = 1), sorted by cycle frequency. Each row represents a**peak cycle frequency**and each column represents a**bar**. As with the arrays, if you specify a*Plot End Bar*beyond the last bar on the chart, the matrix rows will be shifted to the left by the difference. You may use the*MxGetBlock*function to convert the matrix rows to AFL arrays.**PTFLDPrices**โ The PTFLDPrices matrix contains the FLD prices for each cycle thatโs a valid peak (Peak = 1), sorted by cycle frequency. Each row represents a peak cycle frequency and each column represents a bar. This matrix will only contains FLD prices for the current bar and future bars. Use the*PTRangeAnalysis*function to obtain past FLD data. As with the arrays, if you specify a Plot End Bar beyond the last bar on the chart, the matrix rows will be shifted to the left by the difference. You may use the MxGetBlock function to convert the matrix rows to AFL arrays.

#### AFL Scalars

**PTFLDScore**โ The*FLD Score*is a powerful indicator that can help to confirm or reject trades proposed by the Prescient Line and the other cycle indicators.- The FLD Score is calculated by multiplying the strength or amplitude (depending on the
*PL Basis*setting) of each peak cycle frequency by either 1 or -1, depending on whether the series price is above or below the FLD price, and summing them all together. - If the FLD Score is
**positive**, it indicates the market is in a cyclical**uptrend**. - If the FLD Score is
**negative**, it indicates the market is in a cyclical**downtrend**.

- The FLD Score is calculated by multiplying the strength or amplitude (depending on the

## PTRangeAnalysis

PTRangeAnalysis (Data Series, Polarity, PL Basis, Lookback Range, Min Frequency, Max Frequency, Harmonic Filter, Min Fitness, Best X Cycles, Start Bar, End Bar, Process Arrays)

*PTRangeAnalysis* analyzes an **entire range of bars**, returning the **point-in-time** values for each bar in the analyzed range. Calling *PTRangeAnalysis* for a range of 1,000 bars is equivalent to calling *PTBarAnalysis* 1,000 times, once for each bar in the range. This is the function to use for **backtesting** and **optimization**, **NOT** for live trading.

This function does not return any values directly. Instead, it populates a set of AFL arrays and matrices. These arrays can be plotted like any AFL array.

### Parameters

**Data Series**(array)- This parameter expects an
**AmiBroker array**, containing the actual data series you want to analyze. For example, if you want to analyze the closing prices, youโd pass the built-in AmiBroker*Close (C)*variable, which is an array containing the closing prices from your data series.

- This parameter expects an
**Polarity**(integer or array- 0 = Positive
- 1 = Negative

**PL Basis**(integer or array)- 0 = Amplitude
- 1 = Strength

**Lookback Range**(integer or array)- 1 โ 15

**Min Frequency**(integer or array)- Typically 10 โ 100

**Max Frequency**(integer or array)- Typically 150 โ 300

**Harmonic Filter**(integer or array)- 10 โ 100

**Min Fitness**(integer or array)- 0 โ 95

**Best X Cycles**(integer or array)- 1 โ 10

**Start / End Bar**(integer)- The
*Start Bar*and*End Bar*parameters specify the bar range to analyze. Unlike*PTBarAnalysis*, End Bar may**NOT**exceed the bar index of the last value on the chart. This function is used for**backtesting**, not live trading, thus it would make no sense to project the plots into the future.

- The
**Process Arrays**(integer)- This parameter determines whether the function processes the parameters as integers or arrays. This only applies to parameters that can be either integers or arrays, which include Polarity, PL Basis, Lookback Range, Min Frequency, Max Frequency, Harmonic Filter, Min Fitness and Best X Cycles.
- Normally, these parameters are integers, which means the same parameter setting would be applied to the entire range of analyzed bars. This is the default setting and most users should leave this alone. However, if youโre an advanced user, this gives you the incredibly powerful capability to vary the parameter settings on a bar-by-bar basis by passing the values as arrays.
- If you do use arrays, you must set the Process Arrays parameter to 1, so PrescienTrader knows to process them as arrays.
**Enabling this feature greatly increases the file size of each API request, which consumes bandwidth and slows processing time**, so only enable it if you know what youโre doing and have a good reason for doing it.- 0 = Off

- 1 = On

### Response

#### AFL Arrays

Each element in these arrays represents a bar, starting with bar zero.

**PTStaticPL**โ the static*Prescient Line*. This contains the Prescient Line plot values calculated at the**point-in-time of each bar in the specified range**. This is**very different**from the standard Prescient Line analysis returned by*PTBarAnalysis*, which calculates the Prescient Line at a**single**point-in-time, then projects the plot backward and forward in time.**PTStaticPLSlope**โ the slope of the**static**Prescient Line. A positive value means itโs sloping upward and a negative value means itโs sloping downward.**PTStaticPLSlopeCum**โ the**cumulative**slope of the static Prescient Line. This is what youโd use to**plot**the static Prescient Line.**PTStaticTrendBar**โ**the relative bar number**within the current static Prescient Line trend. The first bar number in each trend is bar 0 and all subsequent bar numbers are relative to the first bar of the trend.**PTStaticTrendBars**โ the**total number of bars**in the current static Prescient Line trend.**PTStaticTrendPct**โ the**percentage completed**of the current static Prescient Line trend. The percentage will never reach 100, because that would mean a new trend has started with a zero percent completion. So, 100% of the old trend is equivalent to 0% of the new trend.**PTStaticFLDScore**โ see the description in the*PTBarAnalysis*section for an explanation of FLD Score.

#### AFL Matrices

These matrices return a list of values pertaining to the **peak cycle frequencies** of each bar. Each matrix represents a different indicator, but theyโre all sorted by frequency. So, for example, row 3, column 999 corresponds to the **same** peak cycle frequency at bar 1,000, in all the matrices. The matrices contain the number of rows needed to list all the peak cycle frequencies for all bars.

**PTStaticFrequencies**โ each row in this matrix corresponds to a**peak cycle frequency**.**PTStaticSlopes**โ each row in this matrix corresponds to the slope of the frequency found in the*PTStaticFrequencies*matrix, at the same row and column.**PTStaticFLDPrices**โ each row in this matrix corresponds to the FLD price of the frequency found in the PTStaticFrequencies matrix, at the same row and column.

### PTBacktest

PTBacktest ()

This function is used to **run** a **single-thread** analysis for an exploration, backtest or optimization. It takes no parameters because you configure all the parameters in the *Parameters* window. When it runs, it calls *PTRangeAnalysis* and generates the AFL arrays and matrices described in the PTRangeAnalysis function.

Unlike the PrescienTrader function, which supports two higher time periods, the *PTBacktest* function supports **unlimited** higher time periods.

Read the Exploration, Backtesting and OPTimization article, for a detailed explanation of how to use this function.

### PTBacktestMultiPrepare

PTBacktestMultiPrepare ()

This function is used to **prepare** a **multi-threaded** analysis for an exploration, backtest or optimization. It uses the parameters defined in the Parameters window to generate the data in the proper format for an API request.

Read the Exploration, Backtesting and OPTimization article, for a detailed explanation of how to use this function.

### PTBacktestMultiExecute

PrescientAnalysisExecute ()

This function is used to **execute** a **multi-threaded** analysis for an exploration, backtest or optimization. It parses the data, outputs the results to the exploration columns and generates AFL arrays containing the results.

Read the Exploration, Backtesting and OPTimization article, for a detailed explanation of how to use this function.

## PTLogToFile

PTLogToFile (Message)

You can use *PTLogToFile* to write messages to the log file defined in the backtest Parameters window.

## PTWait

PTWait (Seconds)

You can use *PTWait* to suspend execution for the specified number of seconds. Normally, this is used when making API requests. If an API request fails due to a down Internet connection, you can use PTWait to wait a certain number of seconds before retrying.

### PTPositionSize

PTPositionSize (Points Risked, Percent of Equity Risked, Account Base Currency)

This function automates Van Tharp-style, volatility-based position sizing in AmiBroker. We think this is the best approach to position sizing, because it automatically manages risk based on volatility and portfolio equity.

AmiBrokerโs built-in *SetPositionSize* function includes an option to specify position size as a percent of equity, but it considers position size to be the **margin** amount required to open the position. The problem is, **margin is only loosely associated with risk**. While its true that riskier instruments **generally** have higher margin requirements, we think itโs best to calculate position size based on the exact risk of each trade, not by relying on your broker to manage your risk for you. Therefore, we need to use the **cash** value of the position, not the margin value. For instance, if you buy a futures contract and its price drops by 2%, youโve lost 2% of the **cash value** of that contract, not 2% of your margin deposit!

**This function sets the position size AmiBroker uses to execute trades; it does NOT return a value. Itโs intended to replace the built-in SetPositionSize function.**

- The
*Points Risked*argument should be an array, specifying the number of points youโre willing to risk on each trade. Typically, this would be the same number of points youโre using for your stop. If youโre not using stops, estimate the maximum number of points your trading system typically loses before it exits from or reverses a position. We recommend using a formula that considers the typical price range of the current instrument. For example,*ATR(20) * 2*would specify a maximum risk of twice the Average True Range. Itโs particularly important to use a formula, not a static value, when backtesting multiple instruments (portfolio backtesting), so Points Risked automatically adapts to the price range and volatility of each instrument. *Percent of Equity Risked*is the percentage of your current equity youโre willing to risk on each trade. We normally use 2%, but you may use a higher or lower value, depending on your risk tolerance.*Account Base Currency*is a string containing the base currency of your trading account. For example, โUSDโ.

The function uses the following fields from the AmiBroker Information window:

- Margin Deposit
- Point Value
- Currency

Additionally, the function supports **multi-currency position sizing**, which is necessary when the base currency of an instrument differs from the base currency of your account. Most commonly, this happens with Forex pairs denominated in currencies other than US Dollars. To perform multi-currency position sizing, the function looks up the price of the Forex pair thatโs a combination of your accountโs base currency and the base currency of the Forex pair being backtested. For example, if youโre backtesting CHFJPY, the base currency would be JPY. If your account base currency is USD, the function would look up the price of USDJPY, to calculate the price of JPY in US Dollars, which then allows it to calculate the position size for CHFJPY in US Dollars. Therefore, the following data is required for multi-currency position sizing to work:

- You must enter the correct
*Point Value*for each instrument youโre backtesting. Consult the AmiBroker documentation for an explanation of Point Value. - You must enter the
*Margin Deposit*for each instrument youโre backtesting. You can enter a fixed margin deposit as a positive number, or as a percentage of the contractโs cash value, by entering the percentage as a negative number. For example, if your broker offers 20:1 leverage, the margin deposit would be 5%. So youโd enter -5 as the margin deposit. - For any instrument
**NOT**denominated in your account base currency, you must enter the base currency in the*Currency*field. Using the example of CHFJPY, youโd enter JPY in the Currency field for that instrument. - You must have quotes in your AmiBroker database for the ticker symbol XXXOOO or OOOXXX, where XXX represents your
**account**base currency and OOO represents the**instrument**base currency.**If your account base currency appears first in the symbol (XXXOOO), the function will automatically invert the price of the currency pair.**Again, using the example of CHFJPY, if your account base currency is USD, youโd need to have quotes for USDJPY in your database. The symbol must be formatted exactly as XXXOOO or OOOXXXX, NOT XXX-OOO or some other variation.**If your data provider uses a non-standard ticker symbol format**, you can map the standard format to the non-standard format in your database by creating a variable named after the standard format and assigning the non-standard format as the value. Again, using the above example, if your database contained the symbol USD-JPY, you could map USDJPY to USD-JPY using the following code:

USDJPY = "USD-JPY";

Alternatively, you may set a fixed conversion value by setting the variable equal to a numerical value. For instance:

USDJPY = 108.68;

- Setting a fixed conversion value overrides any values in your database. This is mostly useful when you donโt have quotes in your database for the conversion currency.
- You must create variables for all your symbol maps
**before**calling the PrescientPositionSize function. - The PrescientPositionSize function ignores AmiBrokerโs built-in currency conversion settings. Thus, when using this function, you can disregard the settings in the
*Preferences->Currencies*screen. We actually recommend that you**disable AmiBrokerโs dynamic currency conversion functions**by removing the symbols from the*Dynamic Rate Symbol*column in this screen. This is because AmiBrokerโs built-in dynamic currency conversion creates a problem when the conversion currency has a shorter quote history than the instrument being analyzed. In this instance, the position size will be set to zero for any dates outside the range of the conversion currencyโs quote history. Removing the symbols from the Dynamic Rate Symbol column disables dynamic currency conversion, which fixes this problem. If your conversion currencyโs quote history is shorter than the the quote history of the instrument being analyzed, the PresicentPositionSize function will use the price from the**last bar**of the conversion currency, for any bars outside the range of the conversion currencyโs quote history.