(NOT) Basic Next Day System Backtesting

Hello!

I would like to test a very basic system that:

  1. Places a BUY order for each of several limit prices I establish (calculated as of the prior day close). So for example, using daily data for Aug 18, 2022, calculate several limit prices, which are now valid for August 19, 2022. These orders should be filled if the low of Aug 19, 2022 is less than the limit price calculated on the close of Aug 18, 2022.

  2. Places a Short order for each of several limit prices I establish. These orders should be filled if the high price of the next day is higher than the limit prices I establish.

For example, I have BLP1 (Buylimitprice1) through BLPn and SLP1 through SLPn.

I would like to buy and short at every BLP1…BLPn and every SLP1…SLPn on the next bar. Even if I have 100 BLP triggered, I would want each signal to be filled.

For a basic test, I do NOT want to have sell or cover rules. Later I can add sell and cover rules.

In sum, how could I achieve this basic system in the backtester:

Buying/shorting at ALL predefined levels using limit prices if those limit prices are triggered on the next trading day.

IMPORTANT: Since I do not have sell or cover rules, I will need the AmiBroker report to show open trades with open profit and loss. How do I achieve this feature?

Thank you very much!

After consulting the Knowledge Base:

I attempted this code, but get no trades generated even when I know there should be.

/// I have these Buy and Sell signals, which I think are odd, because of AB’s requirement to have a Buy “rule”. I do not have a “rule” per se. What I have are levels where I would like to buy or sell. What is the AB recommended way to code a Buy or Sell “rule” for such a scenario, where the rule is merely buy/sell at **several** limit prices if triggered the next day?

//my hope is that this rule will allow the buy/sell orders to be filled on the next bar, if the next day’s low is below the buylimitprice (BLP1……..BLPn) or if the next day’s high is above the selllimitprice (SLP1…..SLPn)

//Below I show only three BLP and SLPs but I would like the formula to allow for as many BLPs or SLPS as I want.

.

BuySIGNAL1= IIf(Ref (L, 1) < BLP1,1,0);

ShortSIGNAL1 = IIf(Ref(H,1) > SLP1 > 0,1,0);

BuySIGNAL2= IIf(Ref (L, 1) < BLP2,1,0);

ShortSIGNAL2 = IIf(Ref(H,1) > SLP2 > 0,1,0);

BuySIGNAL3= IIf(Ref (L, 1) < BLP3, 1,0);

ShortSIGNAL3 = IIf(Ref(H,1) > SLP3 > 0,1,0);

// buy on the next bar

Buy = Ref(BUYSIGNAL1, -1);

BUYLIMITPRICE1 = Ref(BLP1,-1);

Buy = Ref(BUYSIGNAL,2 -1);

BUYLIMITPRICE2 = Ref(BLP2,-1);

//Can I have multiple buyprice and Buy values as below to match my multiple buy signals?

Buy = Buy AND L < BUYLIMITPRICE1;

BuyPrice = Min (Ref(Open,1), BUYLIMITPRICE1);

Buy = Buy AND L < BUYLIMITPRICE2;

BuyPrice = Min (Ref(Open,1), BUYLIMITPRICE2);

// SHORT on the next bar

Short = Ref(SHORTSIGNAL, -1);

SHORTLIMITPRICE = Ref(SLP1, -1);

SHORT = SHORT AND H > SHORTLIMITPRICE;

SHORTPrice = MAX (Ref(Open,1), SHORTLIMITPRICE);

This is definitely not "basic" system. This system is PYRAMIDING system (you scale IN already opened positions).
You are adding to position more and more depending on level. More about pyramiding is in the Guide: https://www.amibroker.com/guide/h_pyramid.html

It is actually much more complex than you think.

You need to keep track of what limit you already entered etc.

The following is NOT complete code but a starting point. It just shows entries (pyramiding), as nothing in your description talks about exits. So the code below as it is would just pyramid on 3 separate levels and stay there (stay open position)


LimitPrice1 = ....
LimitPrice2 = ....
LimitPrice3 = ...

CurPosSize = 0;
PosSizeIncrement = 1000;

Buy = 0;
PositionSize = 0;

Limit1Entered = False;
Limit2Entered = False;
Limit3Entered = False
                        
for( i = 0; i < BarCount; i++ )
{
	OldPosSize = CurPosSize;

		
	if( L[ i ] < LimitPrice1[ i ] AND NOT Limit1Entered )
	{
		Limit1Entered = True;
		CurPosSize += PosSizeIncrement;
	}
	if( L[ i ] < LimitPrice2[ i ] AND NOT Limit2Entered )
	{
		Limit2Entered = True;
		CurPosSize += PosSizeIncrement;
	}
	if( L[ i ] < LimitPrice3[ i ] AND NOT Limit3Entered )
	{
		Limit3Entered = True;
		CurPosSize += PosSizeIncrement;
	}

	if( CurPosSize > OldPosSize )
	{
		Buy[ i ] = sigScaleIn;
		PositionSize = CurPosSize - OldPosSize;
	}

}

Dear Tomasz,

Thank you much for the response.

I think we are seeing things differently, does not mean incorrectly, just different perspectives.

I do not see this style of trading as pyramiding per se. I also do not see all the trades as ONE trade, which is how Amibroker sees it, as detailed in the pyramiding notes. The notes specifically, state that all such “pyramided” trades appear only as ONE trade entry.

Can we not use Amibroker where trades are approached on a FIFO (First In First Out basis).

In this case ,each buy or sell entry is a unique “trade” offset by the first occurring trade on the opposing side.

Consider the following system

It buys on the open for the next ten days (Day 1 through Day 10)

It then sells on the open for the next five days. Day 11 through Day 15)

The backtesting report should then show

Trade 1: Day 1 Buy offset by Day 11 Sell

Trade 2 Day 2 Buy offset by Day 12 Sell

…and so on

With the backtest report showing five open long positions

Open Trade 1: Day 6 Buy

Open Trade 2: Day 7 Buy

,….and so on

How does one create a backtest of this form?

Put differently,

How can one get Amibroker just to list all buy and sell trades offset on a FIFO basis, with any non-offset entries showing as open positions; and generate the backtest report on this basis?

You can do whatever you want including FIFO/lifo/random whatever using custom back tester. There are also other backtest modes available via SetBacktestMode function that you can use instead of pyramiding

1 Like