The Complete Trade Wizard

A trade is a function that you create to test a given trading strategy. This function is similar to a macro and operates like any other function or "verb" in FDC, in that it can be used in any valid input line in conjunction with any other set of functions and data.When a trade function is applied to a dataset, the output dataset contains data, graphs,and summary information that completely describe the results of the trade.

Our purpose here is to tell you everything you need to know about trade simulations.  Some of this information has been given elsewhere, but we think it advisable to have one document containing everything from A to Z.  So please skip over sections if you feel comfortable in doing so. 

We get more questions about trade simulation than anything else.  The questions arise from the fact that it can be difficult for many intuitive traders to quantitatively describe the market action to be searched for.  It’s like the Supreme Court Justice who said he could not define pornography, but he knew it when he saw it.  Well, computers do not work that way; they need everything defined, and subtle differences in description can result in large differences in performance. 

Some Basic Rules for using the Trade Wizard:

The trade wizard is used to create trade simulation functions, which are then applied to datasets.  When such a function is created, it will contain various trading rules for entering and exiting trades.  You will then apply your newly-created trade function to a dataset.  For it to work properly, there are certain rules regarding how that dataset is constructed.

The fundamental restriction is that all such datasets must have Open, High, Low, and Close prices, in that order, in the first four columns.  We will call any such dataset ‘Tradable'.  If you want to apply a trade simulation function to a price series that has only closing prices (as some funds do), then you must first change this dataset into one with simulated O-H-L-C in the first four columns by using the closing price four times.  To do this for the 1-column dataset rybhx, for example, you would use the expression.

rybhx cols 1 1 1 1

If you have only H-L-C data, then you must add a first column to take the place of the open.  This could be the prior close, or any value of your choice.  Having these four prices, or simulated prices, is necessary in order to compute the statistics and summaries that form the final description of the trades.

Other than the fundamental restriction, the datasets you apply the trade function to can have any number of additional columns.  If the definitions of signals in the trade function compute everything from the O-H-L-C, either directly or by using macros, then any additional columns in the dataset will be ignored.  For example, a formula for a stop price might be

typical #r back 1

Since ‘typical' is a macro that uses only the H-L-C, this expression will make sense for any tradable dataset.

On the other hand, you may wish to calculate some ‘signals' ahead of time, and store the results as additional columns of the target dataset.  The trade function can then access these signals, without having to compute them at the time of simulation.  For example, you could specify a Buy Entry by saying

            (#r col 8) = 1        or         (#r col 15) crossup 0

This can be a time saver, but note that it puts restrictions on target datasets.  Any dataset that is to be trade simulated with this trade function must not only be tradable, but must have appropriate data in column 8 or column 15.  Thus, such target data must be ‘preprocessed' to have the correct form.  Even so, it is sometimes useful to preprocess a list of target datasets (say by running a command loop), and then apply the trading function to every dataset in the list.

We encourage you to familiarize yourself with defining entry and exit conditions in the Trade Wizard, as when you do so you can use trade variables defined by the trading experience (for example: number of days in the trade, maximum profit excursion, etc.)  You can also use the trade function on other datasets.  One test of a robust system is one that works on different datasets.

Simple Trades

When you open up the Trade Wizard by clicking on the icon, you will be presented with a template listing all of the trades that have been programmed.  A number of trades have been included in your trades folder, and you should look through them at your convenience.  However, let’s start off by creating a new trade.

The first thing to do is to click on , which will then provide you with two additional buttons to either process or cancel the new trade. 

Let’s define the trade.  You may start anywhere, but the logical beginning is to define the Buy Entry.  Are you going to affect the Buy Entry on today’s close, tomorrow’s opening, on a stop, or at a limit?  For this example, pick MARKET NEXT OPEN.  Then we must define our conditions. 

For this example, let’s assume that you wish to buy when the 3-day moving average of the close crosses above the 20-day moving average of the close.  This is a very simple trend following system.  That definition is:

(3 movave close #R) crossup (20 movave close #R)

That’s all there is to defining this simple Buy Entry.  The #R refers to the “right argument”, or the dataset to be named to the right of the trade command. 

Now click on the  tab, choose MARKET NEXT OPEN and enter the following definition, which is simply the reverse of your Buy Entry:

(3 movave close #R) crossdown (20 movave close #R)

Note that there are 3 lines for Additional Conditions.  However you may have as many conditions as you wish.  You may certainly put more than one condition on each line, or you may construct a macro defining all of your conditions, and then put the macro name in the condition box.  Additionally there are 3 tabs for each entry and exit.  In short, there are no practical limits. 

This trade which you have just saved has very few instructions.  It puts you long when the 3-day moving average of the close crosses above the 20-day, and liquidates and goes short when the reverse happens.  Your position will always be “in the market” and there will never be any conflicts.  That is, there is no possibility for you to get conflicting BUY and SELL signals.  If there were potential conflicts, you would be wise to click on the  tab and provide FDC with rules to resolve any conflicts.  

Then click .  You will be presented with the trades folder, and asked for a name under which you will save the trade instructions.  We suggest the name “reverse320”.  Then click .  That’s it.

Now, let’s actually trade this “system”.  Click on  (in the upper left corner of the template), close out   the Trade Wizard, and paste   the name into a command line.  [We created the “Copy Trade Name” button to encourage users to pick descriptive names, without regard to their length or complexity.] 

Finally, just enter the name of a dataset to be traded, such that your command line reads:

The trade uses natural units to keep track of the trade - that is it assumes that one unit of the input price represents 1 dollar of profit. It also assumes no starting equity, no commission and no slippage. We will show you later how to override these defaults.

Your output will be a dataset with multiple columns and tabs. 

If you click on the  tab, you will see the most-watched selection of trade statistics.  Additional tabs will appear that enable you to retrieve more statistics.

If you click on the  tab you will get the “picture worth a thousand words”:

Clicking on the summary tab shows the following summary variables for all trades. 

There are similar tabs for long trades only and short trade only summaries, and for a trade by trade summary, as shown below:

This trade simulation has produced a temporary dataset, which FDC has named “temp1”.  It will not be saved unless you choose to do so.  

Simple Trades with Left Parameters

Suppose you wish to create a somewhat generic trade function, where certain critical parameters fall into the category “to be determined”.  That is, you want to create a trade function where the inputs will be determined when you decide to run the trade (as opposed to when you create the trade function). This is similar to the situation of macros with left parameters.  

The first example illustrated the creation of the trade function reverse320, obviously using the 3- and 20-day moving averages.  If you then wanted to test the 4-day versus the 22-day moving average as a trade, you would have to create another trade function.  After a while all of these trade functions clutter up your trades folder. 

We have a better way.  Create the trade with the shorter-term and longer-term moving averages defined only as “short” and “long”.  That is, your Buy Entry and Sell Entry Conditions should be as follows:

(short movave cl #r) crossup (long movave cl #r)     [Buy Entry]

(short movave cl #r) crossdown (long movave cl #r)     [Sell Entry]

Then at the bottom of the Trade Wizard template, enter “short” and “long” as left inputs, as illustrated.

This trade has been created for users and is saved under the name “revtrade”.  To operate it, simply enter commands such as the following:

3 20 revtrade euro last 200

13 52 revtrade wkbars djia

Note in the above examples, the datasets are the expressions “euro last 200” and “wkbars djia”.

How to Specify Slippage, Commissions, etc. (i.e. Right Parameters)

The trade function uses natural units to keep track of the trade - that is, it assumes that one unit of the input price represents 1 dollar of profit.  It also assumes no starting equity, no commission and no slippage.  For most traders/investors dealing in stocks, a successful trading strategy can be designed without getting too particular about other details.  However for futures, each market has its own point value, and if you want your result in dollars, you must use the right parameters.

The syntax is as follows:            [tradefunction]  [dataset]  a  b  c  d 

in which:           a = unit value of a 1-integer change in price

                        b = starting value equity in dollars

                        c = value in dollars of a round-turn commission

                        d = price slippage you wish to assume for each side of the transaction in                                                dataset (i.e. chart) units.

IMPORTANT:  If you need to use any of the parameters, you must use them all.  That is, FDC is looking for either 1 or 5 parameters to the right of the trade function.  The first is the dataset.  If you use more than one parameter, you must use all 5, separated by spaces.

Here’s two sample trade simulation requests:

reverse320 msft 100 0 7 .10

5 20 revtrade (euro last 200) 12.5 10000 15 1

Accessing Summary Numbers from the Command Line and Sorting

After you have run a trade simulation and saved the resulting dataset (or kept the temporary dataset open) you can access any of the trade summary parameters directly from a command line.  Let us suppose that our first example is visible as the dataset temp1.

Then we enter the command  temp1 summary ‘netpla  and get the result shown below:

Here the ‘a’ in netpla’  refers to the summary of all trades, and shows that we want to see the net profit or loss for all trades.  This appears in the numerical value field.  Using ‘l’ or ‘s’ instead of ‘a’ (as in ‘netpll’ or ‘netpls’) would access the netpl parameter for all long or all short trades respectively.

Trades run on large datasets may take a while to compute and display.  If the data is too long, the display may overrun the graphics buffer.  This is a limitation of individual graphics cards, and not an FDC limitation.  The best way to access trade results is to run the simulations in hidden mode, and look at the results in the FDC List Viewer.

The following command set, when run using the play button, produces 9 outputs corresponding to 9 different moving average reversal trading plans. The results are hidden, because the boxes are unchecked.

Then if you open the graphics wizard and choose the play list, you will see a list of these 9 trade simulations. You can view them by choosing the listviewer, but you can also manipulate them without seeing them.

If you choose 'Sort List' you can sort the results using any FDC expression that produces a numerical output. You use #r to stand for the general trade simulation. Thus if you choose the expression "#r summary 'netpla'" as the sorting computation, that portion of the list wizard will look as follows:

Then when you press that 'Sort List' button, you will get the following display (this new list is saved in 'templist' for convenience).

In this way you can sort any number of trades for profitablility according to any criterion. All of this can also be done automatically from a command set. For a large number of trades, that command set can be run automatically overnight.

Running Multiple Trades Without Display; Combining Summaries

When you execute a trade simulation you are provided with output that includes the price data, trading data, three summaries, and two types of plots.  For some people, that’s more information than they need, and the extra information takes time to compute and uses valuable graphics memory to display.  If you wish you may simply “cut to the chase” and eliminate all but the summaries.  In FDC you may run trade simulations on lists of either parameters or datasets (or both), and then combine the summaries into a single Excel® document using the function 'mergesummaries'.

The syntax is:  

'excelfilename' mergesummaries 'listname’ 

Here 'excelfilename'  is a name of your choosing. It can be a fully qualified path name to any location, or just a simple name, in which case it will be saved in the 'Excel' subfolder of the FDC folder. On the right, listname (also in quotes) is the name of a list containing the names of the trade simulation datasets.


For a relatively few datasets, the list name on the right can be replaced by the names of the datasets in the list, separated by semicolons.  Thus

'excelfile1' mergesummaries 'trdlist'

and

'excelfile1' mergesummaries 'trddata1;trddata2;trddata3'

will produce the same result if the list 'trdlist' contains the names 'trddata1' 'trddata2' and 'trddata3'.

EXCEPTION:  If you substitute playlist instead of the list of saved datasets on the right, do not surround it with ‘quotes’.  This may seem inconsistent, but it is not:  playlist is actually a function that calls up the list of recently played items.  The only items in FDC that need quotes are list names and computer paths. 

There are other uses for the function mergesummaries.  With this function you may produce trading results for a collection of assets or trading programs, and then use mergesummaries to see the portfolio effect. 

You may also use mergesummaries to test a multi-year trading strategy for futures without dealing with “continuous contracts”.  Much research on the futures markets has been done with “continuous contracts”.  Because futures contracts have a relatively short liquid life, market researchers have looked for a way to create one long dataset for each market.  To do this they have devised at least 6 methods for splicing the expiring datasets together.  Each continuous contract method has some flaw, which generally stems from the fact that the assembled dataset is simply not tradable.  However the individual expiring options are tradable, and in FDC you can trade each, glue together their summaries and output the final as an Excel® document. 

WARNING: In order to facilitate the combining of summaries, any trades left open in a summary will be considered closed out for purposes of the function mergesummaries. This means that combined summaries may list more trades, wins or losses, etc. than would be found by adding up the corresponding quantities in all summaries, where open trades appear separately.

Portfolios: 

Here’s something else you may try.  Suppose you want to simulate the effect of a portfolio consisting of say 10 units of one asset (asset “A”), 5 units of another (asset “B”) and 3 units of a third (asset “C”).  Run hidden trade simulations on each asset (1 unit of each), and create a composite of their equity curves.  This is easily done, as the dataset output of each trade simulation consists of 10 columns, and column 10 is the equity curve.  Then just do the algebra:

(10* (tradeA col 10)) + (5* (tradeB col 10)) + (3* (tradeC col 10))

You could also create a list of portfolio weights, apply them in varying amounts to each trade, and sort their results in the List Wizard according to whatever criteria.

Caveats:  Be Careful About Your Definitions

FDC permits you to specify and simulate trades that are technically not possible.  Since you are simulating trades in a dataset already completed, the future values of the data and studies computed from that data are improperly available on any day. You could, for example, ask FDC to execute a stop on today's high. It would correctly do this, but the trade is impossible to perform in real time, and therefore useless.

In the case of internal or 'trade variables', described below, FDC makes that data available only when it properly exists, and not before. Thus, for example, the variable #hihi, representing the highest high achieved during the life of the trade, will be updated only at the end of each trading day. If you reference this variable in a buy, sell, or exit condition used during the day, you will be using the highest high as of yesterday, since that is the latest value available at the time. On the other hand, the variable #hiop (highest open of the trade) will be updated on the day's opening, and so will be current during the day. When you read the definition of a trade variable, be sure to note when it is updated.

FDC includes a lot of flexibility, and that flexibility permits you to make silly mistakes, so exercise care at all times to make sure that your result is reasonable and ac curate. 

Using internal Variables in a Trade.

When forming signals for a trade, you may uses any valid FDC expressions, including macros. You may also use temporary variables that exist only during a trade simulation. We call these 'internal variables'. When you use them in a trade definition, you should add a '#' to the name, as in '#numbars'. There are five types of internal variables, which we now list and describe.

Overall simulation constants. These numbers are parameters of the simulation. They may be specified by the user, but if not, they will be given default values. They are always available to use in buy, sell, or exit conditions.

#startequity - - - - -equity at beginning of simulation
#commission - - - - -commission charged once per trade
#slippage - - - - - applied to each entry and exit in the most adverse way
#dolsperpt - - - - - the dollar value of a single unit of the dataset being traded

Overall simulation vectors. These are lists of numbers, each reflecting the state of the overall simulation on any given date. New numbers are added at the end of each day. These variables are always available to use in buy, sell, or exit conditions. When you use one in such a condition, you will always get the latest value, that is the value at the end of that last completed day. Because these variables are lists containing one number for each day from the beginning of the simulation to the current day, you may also apply moving functions (movave etc.) cumulative functions or total functions to them, as well as most other FDC functions. For example, 4 movave #equity, when used in a daily condition, will give the four day moving average of the value of equity on the last 4 closed out days.

#equity - - - - - equity on each date
#totgrpl - - - - - total gross profit (loss) of the simulation up to any given date.

#totlgrpl - - - - - same as above, but only for long trades
#totsgrpl - - - - - same as above, but only for short trades
#totmaxdrawdn - - - - - maximum drawdown of equity from the first date until the current date

Completed trade numbers. These numbers reflect the state of the simulation regarding all closed out trades, and are always available. If updated, they will be updated at the end of a trading day on which a trade is completed.

#numtrades - - - - - total number of closed out trades
#numwins - - - - - total number of closed out wins
#numlosses - - - - - total number of closed out losses
#percentprof - - - - - percent of closed out trades that were profitable
#maxwin - - - - - maximum closed out profit
#maxloss - - - - - maximum closed out loss
#avewin - - - - - minimum closed out profit
#aveloss - - - - - minimum closed out loss
#wlratio - - - - - ratio of winning closed out trades to losing closed out trades
#avegrpl - - - - - average gross profit of closed out trades
#avenetpl - - - - - average net profit of closed out trades
#avempx - - - - - average maximum positive excursion of closed out trades
#avemnx - - - - - average maximum negative excursion of closed out trades
#consecwin - - - - - consecutive wins leading up to the current trade (if any)
#consecloss - - - - - consecutive losses leading up to the current trade (if any)
#avewinbars - - - - - average number of bars for closed out winning trades
#avelossbars - - - - - average number of bars for closed out losing trades
#avebars - - - - - average number of bars for closed out trades
#maxconsecwin - - - - - maximum consecutive win of all closed out trades
#maxconsecloss - - - - - maximum consecutive loss of all closed out trades

The following represent similar variables, but apply to closed out long trades only.

#lavemnx, #lavempx, #lnumtrades, #lnumwins, #lnumlosses, #lpercentprof, #lmaxwin, #lmaxloss, #lavewin, #laveloss, #lwlratio, #lavegrpl, #lavenetpl, #lavewinbars, #lavelossbars, #lavebars, #lmaxconsecwin, #lconsecwin, #lconsecloss, #lmaxconsecloss

The following represent similar variables, but apply to closed out short trades only.

#savemnx, #savempx, #snumtrades, #snumwins, #snumlosses, #spercentprof, #smaxwin, #smaxloss, #savewin, #saveloss, #swlratio, #savegrpl, #savenetpl, #savewinbars, #savelossbars, #savebars, #smaxconsecwin, #sconsecwin, #sconsecloss, #smaxconsecloss

Completed trade vectors. These are lists of numbers, each reflecting the state of all completed trades. New numbers are added at the end of any day on which a trade is completed. These variables all begin with #c, for ease of identification, and are available at any time. Because these variables are lists containing one number for each completed trade, you can apply moving, cumulative or total functions to them, as well as most other FDC functions. Many (almost all) of the completed trade numbers are actually computed from these vectors, and you can customize your own.

#centrydate- - - - - list of entry dates of closed out trades
#centry- - - - - list of entry prices of closed out trades
#cexit- - - - - list of exit dates of closed out trades
#cexitdate- - - - - list of exit prices of closed out trades
#cgrpl - - - - - list of gross closed out profits (in order)
#cmaxdrawdn - - - - - list of maximum trade drawdown numbers
#cmnx - - - - - list of maximum trade negative excursions
#cmpx - - - - - list of maximum trade positive excursions
#cnetp - - - - - list of net closed out profits (in order)
#cnumbars - - - - - list of number of bars of closed out trades
#cposition - - - - - list of position numbers (1 = long, -1 = short) of closed out trades.

The following represent similar variables, but apply to closed out long trades only. They begin with '#cl'

#clentrydate, #clentry, #clexit, #clexitdate, #clgrpl, #clmaxdrawdn, #clmnx, #clmpx, #clnetpl, #clnumbars

The following represent similar variables, but apply to closed out short trades only. They begin with '#cs'

#csentrydate, #csentry, #csexit, #csexitdate, #csgrpl, #csmaxdrawdn, #csmnx, #csmpx, #csnetpl, #csnumbars

Intrade numbers. These are numbers that reflect the state of a current trade(if any) in the simulation. They are reset to zero when a trade is closed out, and are zero whenever there is no current trade.

#entrydate - - - - - entry date for current trade
#entry - - - - - entry price for current trade
#position - - - - - position of current trade (1 = long, -1 = short)
#numdays - - - - - number of bars and partial days on which the trade has been active. This number is updated at the beginning of each trading day, rather than at the end, and so has been updated at the time that buy, sell, or exit signals are evaluated during a trading day.
#numbars - - - - - same as #numdays, but could be used when each bar represents a period other than one day.

Intrade vectors. These are number lists that reflect the state of a current trade (if any) in the simulation. They are reset to zero when a trade is closed out, and are zero whenever there is no current trade. During a trade, they have one entry for each trade day from first completed day to the most recent completed day. Because these variables are lists containing one number for each completed trading day, you can apply moving, cumulative or total functions to them, as well as most other FDC functions. They are updated at the close of each trading day, with the exception of #op, #loop, and #hiop, which are updated at the beginning of a trading day (and therefore before signals are evaluated)

#op - - - - - list of opens on each full and partial day of the trade
#hi - - - - - list of highs on each full day of the trade
#lo - - - - - list of lows on each full day of the trade
#cl - - - - - list of closes on each full day of the trade
#grpl - - - - - list of gross profits at the end of each full day of the trade
#mpx - - - - - list of maximum positive excursions at the end of each full day of the trade
#mnx - - - - - list of maximum negative excursions at the end of each full day of the trade
#hiop - - - - - list of highest opens on each full and partial day from the beginning of the trade until current
#hihi - - - - - list of highest highs on each full day from the beginning of the trade until current
#hilo - - - - - list of highest lows on each full day from the beginning of the trade until current
#hicl - - - - - list of highest closes on each full day from the beginning of the trade until current
#loop - - - - - list of lowest opens on each full and partial day from the beginning of the trade until current
#lohi - - - - - list of lowest highs on each full day from the beginning of the trade until current
#lolo - - - - - list of lowest lows on each full day from the beginning of the trade until current
#locl - - - - - list of lowest closes on each full day from the beginning of the trade until current
#maxdrawdn - - - - - list of maximum drawdowns on each full day from the beginning of the trade until current