Finally, winning in the past using a trading bot is easy. It is pretty simple to find a winning strategy from three technical indicators and good optimization in a backtest. The problem is we want to win in the future. And here, things are more complicated. In this post, I will present how to make money in the future using a trader bot. I will show you how to find the “fair optimization” giving you the most chance to win in the future with a trader bot working on the Prorealtime platform.

Prorealtime winner tader bot secret

Example of an automated trading strategy

To illustrate this point, I chose the example of a moving average crossing strategy. It is a straightforward trading strategy, but that will help you better understand the concept that I will describe. You will have to run it on the DAX40 with a ’10 minutes’ timeframe.

Description of the trading strategy

The strategy that I chose will open a long entry when the moving average on 100 periods crosses over the moving average on 300 periods.

I generated this trading strategy using the “Cross Finder” algorithm included in the Prorealtime template available in my shop. This algorithm allows to test all the moving average crossings fastly. The results are then sorted in an ascending order depending on their performances.

Source code of the entry openings

The following source code (runnable on the Prorealtime platform) will open a long entry when the moving average on 100 periods crosses over the moving average on 300 periods. It will be active only while the cash market session, that is to say, from 09h00 until 21h30. All the opened entries will be automatically closed at 21h30 anyway.


// Strategy-test for the Dax 40 in a 10 minutes timeframe

DEFPARAM CUMULATEORDERS = false // only one trade in the same time
DEFPARAM FLATBEFORE = 090000 // avoide entry opening before this hour
DEFPARAM FLATAFTER = 213000 // close entry at this hour

//--------------------------------------------------------------------------
// ENTRY POINT
// Strategy of Moving average crossing
// MOVING AVERAGES
MM100 = average[100](close)
MM300 = average[300](close)

// Moving average crossing condition
conditionMovingAverage = MM100 CROSSES OVER MM300

//--------------------------------------------------------------------------
// OPEN A LONG ENTRY
IF NOT LongOnMarket AND conditionMovingAverage THEN

  PSTOPLOSS = //...
  PTARGET = //...

  SET STOP pLOSS PSTOPLOSS
  SET TARGET pPROFIT PTARGET

  BUY 1 CONTRACT AT MARKET

ENDIF

How to optimize an automated trading strategy?

The optimizer of the variables

The Prorealtime platform provides several optimization tools. It is notably the case of the “optimizer of the variables”. This tool will compute all the combinations of the values you want to test about a specific variable. Then, it will sort the obtained results in an ascending order depending on the performance.

Optimization sequence

I divided the test period into two equal samples for this study purpose. The first period will run from November 04, 2020, until July 13, 2021. The second period will run from July 13, 2021, until December 01, 2021. I will optimize the stop loss and the target during the first period. I will call this period “IS”, meaning “In the Sample”. Then I will check this optimization during the second period. I will call this period the “OOS” meaning “Out Of the Sample”.

 Starting dateEnding date
In the Sample11/04/202007/13/2021
Out Of the Sample07/13/202112/01/2021

I created this division to validate the efficiency of an optimization model. To process this validation, I will optimize the strategy on the optimization period, the IS then I will run this strategy on the test period, the OOS. If the performance between the two periods is significantly different, the model is probably inefficient.

Stop-loss and target optimization

Now I will naively run the optimizer of the variables on the stop-loss and the target. First, I will optimize the stop-loss positioning and later the target. I will select the stop-loss and targets values that give the best return during the “In the Sample” period then verify this setting on the “Out Of the sample” period.

Optimization of the stop-loss

To optimize the stop-loss, I need to execute the optimizer of the variables on the “PSTOPLOSS” variable. This variable sets the position of the stop-loss in points. For example, suppose the value of the PSTOPLOSS variable is 20. In that case, the trading system will place all the stop-losses 20 points under the position price immediately after the long entry opening.

Stop-loss optimization preparation

I commented out the code-line allowing the PSTOPLOSS variable assignment because it is precisely the business of the optimizer. The optimizer of the variables will sequentially modify the value of the PSTOPLOSS variable.
I also removed the target code-line from the source code to allow the optimizer quite independently to optimize the stop-loss.
The “FLATAFTER” parameter will close the entries that remain opened at 21h30 anyway.


DEFPARAM CUMULATEORDERS = false // only one trade in the same time
DEFPARAM FLATBEFORE = 090000 // avoide entry opening before this hour
DEFPARAM FLATAFTER = 213000 // close entry at this hour

//--------------------------------------------------------------------------
// ENTRY POINT
// Strategy of Moving average crossing
// MOVING AVERAGES
MM100 = average[100](close)
MM300 = average[300](close)

// Moving average crossing condition
conditionMovingAverage = MM100 CROSSES OVER MM300

//--------------------------------------------------------------------------
// OPEN A LONG ENTRY
IF NOT LongOnMarket AND conditionMovingAverage THEN

  // PSTOPLOSS = //...
  // PTARGET = //...

  SET STOP pLOSS PSTOPLOSS
  // SET TARGET pPROFIT PTARGET

  BUY 1 CONTRACT AT MARKET

ENDIF

Configuration of the optimizer for the stop-loss

I set the minimum value at ten points, the maximum value at 500 points, and a step of two points. The optimizer will try the 246 combinations of stop-loss from 10 until 500 by two points. The optimizer will start to place a stop-loss at 10 points, then at 12 points, then at 14 until 500, and it will relaunch the backtest each time.

Prorealtime stoploss optimizer of the variable

Result of the stop-loss optimization

The following graph shows the result of the stop-loss positioning optimization:

Prorealtime stoploss overfitting

The abscissa axis represents the tested values for the stop-loss, and the ordinate axis represents the trading system performance depending on the stop-loss values. According to the previous outcome, a stop-loss at 36 points gives the best performance with a gain of 1400 points during the test period. Thus, I naively set the PSTOPLOSS variable at 36 points in the source code of the trading strategy.


//--------------------------------------------------------------------------
// OPEN A LONG ENTRY
IF NOT LongOnMarket AND conditionMovingAverage THEN

  PSTOPLOSS = 36
  // PTARGET = //...

  SET STOP pLOSS PSTOPLOSS
  // SET TARGET pPROFIT PTARGET

  BUY 1 CONTRACT AT MARKET

ENDIF

Optimization of the target

The optimization of the target is the same process as stop-loss. I need to open the optimizer of the variable again and set the same test for the “PTARGET” variable.

Target optimization preparation

I commented that the code-line allows the “PTARGET” variable because the optimizer will try several values. This time I keep the stop-loss code line with the value I found before, that is to say, 36 points.


DEFPARAM CUMULATEORDERS = false // only one trade in the same time
DEFPARAM FLATBEFORE = 090000 // avoide entry opening before this hour
DEFPARAM FLATAFTER = 213000 // close entry at this hour

//--------------------------------------------------------------------------
// ENTRY POINT
// Strategy of Moving average crossing
// MOVING AVERAGES
MM100 = average[100](close)
MM300 = average[300](close)

// Moving average crossing condition
conditionMovingAverage = MM100 CROSSES OVER MM300

//--------------------------------------------------------------------------
// OPEN A LONG ENTRY
IF NOT LongOnMarket AND conditionMovingAverage THEN

  PSTOPLOSS = 36
  // PTARGET = //...

  SET STOP pLOSS PSTOPLOSS
  SET TARGET pPROFIT PTARGET

  BUY 1 CONTRACT AT MARKET

ENDIF

Configuration of the optimizer for the target

I defined the same configuration as the stop-loss optimization. I set the minimum value at ten points, the maximum value at 500 points, and a step of two points. The optimizer will try the 246 combinations from 10 until 500 by two points.

Prorealtime target Optimizer

Result of the target optimization

The following graph shows the result of the target positioning optimization:

Prorealtime target overfitting

Regarding the result obtained by the optimizer of the variable on the test period, the best value of the target is 360 points. This value gives 1200 points of return. Thus I will naively choose this value for the target in my trading strategy.

Overfitted configuration of the strategy

This is the code source of the trading strategy that I naively optimized the stop-loss and target positioning. This configuration is probably over-optimized. I will run this strategy in the IS period to see the result.


//--------------------------------------------------------------------------
// *** OVERFITTED STRATEGY EXAMPLE – DO NOT RUN ON A REAL ACCOUNT *** //
// * ACADEMICAL PURPOSE * //
// MM100.CROSSES.MM300.DAX.10M
// THIS STRATEGY MUST BE RUN ON THE DAX INDEX WITH A "10-minutes" TIMEFRAME
//--------------------------------------------------------------------------
DEFPARAM CUMULATEORDERS = false // only one trade in the same time
DEFPARAM FLATBEFORE = 090000 // avoide entry opening before this hour
DEFPARAM FLATAFTER = 213000 // close entry at this hour

//--------------------------------------------------------------------------
// ENTRY POINT
// Strategy of Moving average crossing
// MOVING AVERAGES
MM100=average[100](close)
MM300=average[300](close)

// Moving average crossing condition
conditionMovingAverage = MM100 CROSSES OVER MM300

//--------------------------------------------------------------------------
// OPEN A LONG ENTRY
IF NOT LongOnMarket AND conditionMovingAverage THEN

  // Overfitted setting
  PSTOPLOSS = 36
  PTARGET = 360

  SET STOP pLOSS PSTOPLOSS
  SET TARGET pPROFIT PTARGET

  BUY 1 CONTRACT AT MARKET

ENDIF

Result of the overfitted backtest

The optimization of the stop-loss and target that I proceeded gives me a performance of 14.86% during the test period. The success rate of this strategy is 47.5%, the drawdown is four times lower than the runup, and the risk/reward ratio is 1.8. In other words, the result of this backtest does not show any lack or problem. It even looks perfectly acceptable!

Over-fitted backtest Prorealtime

Equity curve of the overfitted backtest

The equity curve is quasi-perfect, and it does not show an eventual overfitting problem. In short, this strategy is quite acceptable and looks ready to be launched on a real trading account. [IRONY]

Prorealtime over-fitted equity curve backtest

Now I will compare the performance of this strategy ran on the IS period with the result on the OOS period.

Win in the past but lose in the future

I will run this fantastic trading strategy on the OOS period, that is to say, from July 13, 2021, until December 01, 2021, to validate its efficiency.

Out of the sample validation

Here is the result of the strategy applied on the OOS period:

Prorealtime over-fitted equity curve OOS

This wonderful trading system takes a trashing during the OOS period to no one’s surprise. Unfortunately, it is the tragic fate of many trading systems.

How to find the fair optimization of a trading system?

When I started automatic trading, I optimized my trading system a bit randomly, incrementally correcting losses after losses. I had fallen into the overfitting trap: I always won in the past but never in the future. It took a lot of time and many tests to understand how to win in the future with a trading system. The method I have found is counterintuitive, and you may find it difficult to accept.

I will explain to you how to process to find the fair optimization of a trading strategy. That is to say, finding an optimization that will be winning in the future.

Deteriorate the equity curve of the backtest

Over the many optimization tests of trading systems that I made, I realized an amazing phenomenon: the more a backtest is wining in the past, the more it will be losing in the future.

Out of curiosity, I have had fun deteriorating the equity curve of a backtest, modifying the configuration of the strategy. What a surprise! This poor strategy in the past had become winning in the future. At this time, I realized the underfitting principle. I understood that it is better to voluntarily under-optimize a trading system instead of reaching the correct optimization. (The correct optimization is supposed to be a point at the center between under-fitting and over-fitting)

Under-optimize the stop-loss and the target

Now, I will voluntarily under-optimize the stop-loss and target positioning in my automated trading system. Later, I will compare the behavior of this trading bot between the IS and the OOS. As a reminder, at the beginning of this study, I have chosen the stop-loss and target positioning that gave the best performance during the IS period. And this configuration has been loosing during the OOS period.

To under-optimize the stop-loss and the target, I will choose the value for which the performance is two times lower than the best possible choice. The best performance of the stop-loss position gave a return of 1400 points. Thus, I will select the value for which the performance is nearest 700 points. The best performance of the target position gave a return of 1200 points. Thus, I will select the value for which the performance is nearest 600 points.

Under-optimize the stop-loss position

The following graph shows the optimizer result executed on the stop-loss variable. The over-optimized values are circled in red (at the top of the chart). They give the best performance during the IS period, but they lose the OOS period.
The under-optimized values are circled in green (at the bottom of the chart). Their performance during the IS backtest are two times lower than the over-optimized values.

Prorealtime stoploss overfitting underfitting

I will choose one of the green circled values and restart an OOS backtest to see the performance of this trading system. However, I will also under-optimize the target before launching the backtest.

Under-optimize the target position

The following graph shows the optimizer result executed on the target variable. The over-optimized values are circled in red (at the top of the chart). They give the best performance during the IS period, but they lose the OOS period.
The under-optimized values are circled in green (at the bottom of the chart). Their performance during the IS backtest are two times lower than the over-optimized values.

Prorealtime over-fitting under-fitting target

I will choose one of the green circled values and restart an OOS backtest to see the performance of this trading system.

Result of the under-optimized backtest

I will run a backtest with under-optimized values for the stop-loss and target. First, I will run the backtest on the IS period, and later I will run the backtest on the IS period.

Source code of the under-fitted trading system


//--------------------------------------------------------------------------
// *** UNDER-OPTIMIZED STRATEGY *** //
// * ACADEMICAL PURPOSE * //
// MM100.CROSSES.MM300.DAX.10M
// AUTOR: Vivien Schmitt
// https://artificall.com
// DATE : 2021/12/01
// THIS STRATEGY MUST BE RUN ON THE DAX INDEX WITH A "10-minutes" TIMEFRAME
//--------------------------------------------------------------------------
DEFPARAM CUMULATEORDERS = false // only one trade in the same time
DEFPARAM FLATBEFORE = 090000 // avoide entry opening before this hour
DEFPARAM FLATAFTER = 213000 // close entry at this hour

//--------------------------------------------------------------------------
// ENTRY POINT
// Strategy of Moving average crossing
// MOVING AVERAGES
MM100=average[100](close)
MM300=average[300](close)

// Moving average crossing condition
conditionMovingAverage = MM100 CROSSES OVER MM300

//--------------------------------------------------------------------------
// OPEN A LONG ENTRY
IF NOT LongOnMarket AND conditionMovingAverage THEN

  // Overfitted setting
  PSTOPLOSS = 125
  PTARGET = 50

  SET STOP pLOSS PSTOPLOSS
  SET TARGET pPROFIT PTARGET

  BUY 1 CONTRACT AT MARKET

ENDIF

Performance of the under-optimized trading system

Here is the result of the trading system having under-fitted stop-loss and target:

Prorealtime under-fitted equity curve backtest

Validation of the optimization in the future

I will compare the performance of this trader robot between the IS and the OOS. I will run a backtest on the IS period and another on the OOS period on the same chart to process this comparison.

IS and OOS performance comparison

The following chart compares the performance between the IS and the OOS backtest. The IS backtest result is on the top of the chart, and the OOS result is below.

Prorealtime unfitted comparison IS OOS

This time, the performance of the OOS backtest is positive. This under-optimized configuration is winning in the future. That confirms that an under-optimized trading system has more chance to succeed in the future.

The limitations of the under-optimization model

As with all financial studies and all mathematical models, there are some lacks and limitations. I will present to you the most important.

Risk management accordance

An under-optimized setting is always in keeping with your personal risk management rules. In this example, the final under-fitted values do not correspond with my risk management rules. The “target/stop-loss” ratio is lower than one (50/125<1), and I do not accept it. I respect the risk management rule saying that the target must be greater than the stop-loss. Thus I can validate the previous trading system nether run it on my real account.

Definition of an “under-optimized” value

The choice of under-optimized values is not perfectly established. In this example, I choose the values for which their returns were two times lower than the most performance during the IS backtest. This choice is relatively arbitrary, and it may not be the best choice.

What parameters need to be under-optimized?

To support my arguments about the duty of under-optimization, I choose to apply this model on the stop-loss and the target. I cannot guarantee that it would be possible to under-fit all the trading system parameters. And I don’t know if the under-optimization of all the features would be profitable in the future.

Optimization models

Several mathematical models allow trading system optimization like the WalkFarward or the Gradient Descent. As I write this, I have not found a perfect model that works each time. Each model has possibilities and limitations.

Under-optimization key points

  1. The more a trading system wins in the past, the more it risks losing in the future.
  2. An under-optimized trading systems have more chances to win in the future. they provide a relatively poor performance during the “In the Sample” period, but they give a positive return during the “Out Of the Sample” period.
  3. The definition of under-optimization is subjective. And sometimes, the choice can be difficult because of missing values.
  4. Unfortunately, perfect mathematical or machine learning models do not exist. They give only a probability of success.

credit image: https://www.maxpixel.net/Mystery-Youth-Magic-Girl-The-Silence-Beauty-Ruda-4716922

Download for free the “SEVEN PILLARS TO BUILD A WINNER PROREALTIME BOT”

The “SEVEN PILLARS TO BUILD A WINNER PROREALTIME BOT” is a PDF containing 63 pages allowing you to improve the success of your automated trading system.

Spread the love

This Post Has One Comment

  1. patrick

    Great content! Keep up the good work!

Leave a Reply