Portfolio level testing, set manual take profit for multiple signals

Hi there,

quite new to Amibroker I do experience some sort of issue while trying to program a manual take profit. I do have a set of rules for Buy and Sell signals which, of course, generate multiple buy and sell signals. Redundant signals should not be removed. Take profit shall only be executed if the Close is above a certain level at the end of the week, therefore I cannot use ApplyStop. Currently I implemented it as follows:

eow = TimeFrameExpand(1, inWeekly, expandPoint);

cnt_array = Null;
bprice_array = Null;
bprice = cnt = 0;

for ( i = 0; i < BarCount-1; i++ ) {

	if ( Buy[ i ] == 1 && bprice == 0 ) {
		bprice = Open[ i+1 ];
	}
	
	if ( bprice > 0 ) {	
		cnt++;
		
		if (eow[i] AND C[i] >= 1.3*bprice) {
			Sell[ i ] = 1;
			bprice = cnt = 0;
		}
		if (C[i] <= 0.85*bprice) {
			Sell[ i ] = 1;
			bprice = cnt = 0;
		}
		cnt_array[ i ] = cnt;
		bprice_array[i] = bprice;
	}	
}

Unfortunately this does not take care of handling multiple signals. Somehow the manual take profit is overwritten as soon as a new Buy Signal occurs, although this Buy signal might not be taken from the Backtester. Any hint on this would be welcome!

Thanks,
Matt

You should read the manual carefully. It explains everything
http://www.amibroker.com/guide/h_portfolio.html

Hi Tomasz,
either I did not fully understand the descriptions given in the page you were referring to or the explanation of my use case is misleading. Please see the following code for my manual stops:

cnt_array = Null;
bprice_array = Null;
bprice = cnt = 0;

for ( i = 0; i < BarCount-1; i++ ) {

	//
	if ( Buy[ i ] == 1 && bprice == 0 ) {
		bprice = Open[ i+1 ];
	}
	
	//
	if ( bprice > 0 ) {	
		cnt++;
		
		if (eow[i] AND C[i] >= 1.3*bprice) {
			Sell[ i ] = 1;
			bprice = cnt = 0;
		}
		if (C[i] <= 0.85*bprice) {
			Sell[ i ] = 1;
			bprice = cnt = 0;
		}
		
		cnt_array[ i ] = cnt;
		bprice_array[i] = bprice;
	}	
}

I want to get out of the trade if it's the end of the week and I'm in profit, 30%, or if I do face a draw down of 15%. However, if I run the backtest the frist trade exits after 9 bars, althoush none of the given requirements is met. This indicates to me, that it must've been a Sell signal of an earlier trade. So question, how can I prevent this and only allow Sell signals, which "fit" to my buy signal?

image

As explained in the document I pointed out backtester, BY ITSELF, matches buy and sell signals. So if it exited, it must be matching.

To get better understanding of what is happening in your code and how functions work, use advice given here: How do I debug my formula?

Hi @Tomasz,

I did some debugging as you suggested. Here's what I've found.
My backtest range start 1st of January 2007. However, the "bprice" which I store and use for comparison for my TP and SL is taken from a trade which is placed on 30th of October, 2006. How can this happen? Is there any command which clears my Buy and Sell signal at the beginning of the loop?

image

Best,
Matt

I didn't see the rest of the code but check if you initialized your Buy and Sell variables to zero, before the loop.

Unfortunately not making any difference. Please find the full code here:

#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"
BarsBeforeDelisted = ( LastValue( ValueWhen( DateTime() == GetFnData( "DelistingDate" ), BarIndex(), 1 ) ) ) - BarIndex();
BarsBeforeDelisted = IIf( IsEmpty( GetFnData( "DelistingDate" ) ), 9999, BarsBeforeDelisted );

_TRACE("!CLEAR!");

PositionsHeld = 5;
SetOption( "MaxOpenPositions", PositionsHeld );
SetOption( "InitialEquity", 100000 );
EquityExportString = "breakout";

AllocationPercent = 100 / PositionsHeld;
SetPositionSize(AllocationPercent, spsPercentOfEquity);
SetOption( "AllowPositionShrinking", True );
SetOption( "AllowSameBarExit", False );
SetOption( "ActivateStopsImmediately", False );
SetTradeDelays( 1, 1, 0, 0 );
SetBacktestMode(backtestRegularRaw);
BuyPrice = SellPrice = Open;
RoundLotSize = 1;

eow = TimeFrameExpand( 1, inWeekly, expandPoint );

// WEEKLY BUY
TimeFrameSet( inWeekly );
WeeklyBuy  =  C > BBandTop( C, 20, 1.5 );
TimeFrameRestore();

BuySignal = eow
            AND TimeFrameExpand( WeeklyBuy, inWeekly, expandPoint )
            AND BarsBeforeDelisted > 2;

PositionScore = Random();

Short = Cover = 0;
Buy = 0;
Sell = 0;

cnt_array = Null;
bprice_array = Null;
bprice = cnt = 0;

for ( i = 0; i < BarCount-1; i++ ) {

	//
	if ( BuySignal[ i ] == 1 && bprice == 0 ) {
		bprice = Open[ i+1 ];
		Buy[i] = 1;
		_TRACE("BUY at barindex: " + i + ", date: " + DateTimeFormat(dtformat, dt[i]) + ", SETTING price to: " + bprice);
	}
	
	//
	if ( bprice > 0 ) {
		cnt++;
		
		if (eow[i] AND C[i] >= 1.3*bprice) {
			_TRACE("SELL at barindex: " + i + ", REASON: TP: Closing price: " + C[i] + ", BUYPRICE: " + bprice);
			Sell[ i ] = 1;
			bprice = cnt = 0;
		}
		if (C[i] <= 0.85*bprice) {
			_TRACE("SELL at barindex: " + i + ", REASON: SL: Closing price: " + C[i] + ", BUYPRICE: " + bprice);
			Sell[ i ] = 1;
			bprice = cnt = 0;
		}
		if (cnt > 63) {
			_TRACE("SELL at barindex: " + i + ", REASON: NBAR: count bars: " + cnt);
			Sell[ i ] = 1;
			bprice = cnt = 0;
		}
		
		cnt_array[ i ] = cnt;
		bprice_array[i] = bprice;
	}
}

@matzbanni, I did not test your code but I see that your loop is going over the ENTIRE bars array.

As a first step, you should include some logic to process only the bars "in range".

Please examine these previous posts by @fxshrat to better understand how to use a function call to Status("BarInRange") to achieve it:

Probably, there will be some other issues to solve about multiple overlapping signals, but at least you will not see the out-of-range ones.

2 Likes

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.