Position score issue i cannot resolve

// Strategy: RSI Selective
// Program control variables
fPort = 1;  					// 1 = Portfolio, 0 = All Trades 
fSameBarExit = 1;				// 1 = allow same bar exit (day trades), 0 = disallow
						
nEntryTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Avg Price 
nExitTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Avg Price 

nMaxPos = 2; MaxPos = nMaxPos;
acctMargin = 100;
//pctPosSize = 100/nMaxPos * 100/acctMargin;	

////////////////////////////////////////////////////*************************************************************
// Back Test Parameters
minVolume = 250*1000;
nDays = 2;
pctLimit = 1;//FS 4


// SetOption("usecustombacktestproc", True);
// SETUP // 
#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"
xMember = NorgateIndexConstituentTimeSeries("$SPX");
//SetBacktestMode(backtestRegularRawMulti); FS
//SetBacktestMode(backtestRegular); FS
SetOption("InitialEquity",IIf(fPort,10000,10000));                   
SetOption("CommissionMode",3);              
SetOption("CommissionAmount",IIf(fPort, 0.01, 0)); 
SetOption("InterestRate",0);
SetOption("AllowSameBarExit", fSameBarExit);
SetOption("MaxOpenPositions",IIf(fPort,nMaxPos,2500));                
SetOption("AccountMargin",IIf(fPort,acctMargin,100));                   
SetOption("UsePrevBarEquityForPosSizing",IIf(nEntryTiming==0,False,True)); 
SetOption("AllowPositionShrinking", True);   
SetTradeDelays(nEntryTiming,nExitTiming,nEntryTiming,nExitTiming);                             
SetOption("ActivateStopsImmediately", IIf(nExitTiming==0,False,True)); 
SetOption("PriceBoundChecking", False); // - if set to False - disables checking and adjusting buyprice/sellprice/coverprice/shortprice arrays to current symbol High-Low range. Bij F, dan ab doet Low
SetOption( "Initialequity", 100000 );
SetOption( "MaxOpenPositions", MaxPos );
SetPositionSize( 100000/nMaxPos, spsValue );


////////////////////////////////////////////////////
// Initialize all arrays so the backtest will always run
Buy = Sell = Short = Cover = 0;
AvgPrice = (O+H+L+C)/4;
BuyPrice = ShortPrice = IIf(nEntryTiming==0,C,AvgPrice);
SellPrice = CoverPrice = IIf(nExitTiming==0,C,AvgPrice);

// Find the last bar where the price actually changed
BarsSinceLastChange = BarsSince(C != Ref(C,-1));
LastGoodBar = IIf(IsEmpty(BarsSinceLastChange), 0, BarCount - LastValue(BarsSinceLastChange) - 1);
fDelisted = LastGoodBar < BarCount -1;
inRange = Status("BarInRange") AND IIf(fDelisted, (LastGoodBar - BarIndex()) >= 3, True);
isLastBar = Status("LastBarInRange");

// Rank trade candidates by lowest RSI
PositionScore = 100 - RSI(2);


fLiquid =	C > 5 AND
			MA(V, 21) > minVolume;

BuySetup = 	xMember AND
			fLiquid AND
			RSI(2)<40 AND 
			RSI(2) == LLV(RSI(2),2) AND 
			C > MA(C,200) AND
			inRange;

// Determine the limit price now, but allow the CBT to determine whether to enter the trade
pLimit = Ref(C,-1) * (1 - pctLimit/100);
BuyPrice = min(pLimit, O);	

Buy = 	Ref(BuySetup,-1)  ;
Sell = 	RSI(2)>70 OR
		BarIndex() == LastGoodBar;

Filter =  NorgateIndexConstituentTimeSeries("$SPX") AND BuySetUp ;
AddColumn(BuySetup, "BSetUP");
AddColumn(PositionScore, "PosScore");
AddColumn( (C - Ref(L,1))/C*100>pctLimit  ,"hit");
AddColumn( (C - Ref(L,1))/C*100  ,"L.1 % lower than C"); 

//*
// Basic limit test with limit enforced in CBT
// Limit price should be assigned to the BuyPrice/ShortPrice array
SetBacktestMode(backtestRegularRaw);
SetCustomBacktestProc("");

if (Status("action") == actionPortfolio)
{
	// Get backtester object
	bo = GetBacktesterObject(); 
	bo.PreProcess();	
	
	dn = DateNum();

	if (fPort)
	{
		
		dailyRiskFreeRtn	=	Nz((1+(0)/100)^(1/365)-1); //zero interest
		nElapsedDays		=	DaysSince1900()-Ref(DaysSince1900(),-1);
	}

	rptEquity = 0;
	rptExposure = 0;

	for (bar=0; bar < BarCount; ++bar)
	{
		bo.HandleStops(bar);
		bo.UpdateStats(bar,1);
			
		if (!fSameBarExit)
		{
			for (sig = bo.GetFirstSignal(bar); sig; sig = bo.GetNextSignal(bar))
			{
				if (sig.IsExit())
				{
					bo.ExitTrade(bar, sig.Symbol, sig.Price, sig.Reason);
				}	// end if Is Exit signal
			}
			
			bo.UpdateStats(bar,1);
			
		}	
				

		nPos = 0;
		for (openPos=bo.GetFirstOpenPos(); openPos; openPos=bo.GetNextOpenPos())
		{
			++nPos;		
		}
		
		
 		for (sig = bo.GetFirstSignal(bar); sig; sig = bo.GetNextSignal(bar))
		{
			
			if (fPort)
				fAvailSlots = nPos < nMaxPos;
			else 
				fAvailSlots = True;

			if(sig.IsEntry() AND fAvailSlots)
			{
				
				trade = bo.FindOpenPos(sig.Symbol);
				if (IsNull(trade))
				{
					
					++nPos;

					SetForeign(sig.Symbol);
						pOpen = O;
						pHigh = H;
						pLow = L;
					RestorePriceArrays();
					
					if (sig.IsLong())
						fLimit = pLow[bar] < sig.Price;
					else
						fLimit = pHigh[bar] > sig.Price;
							

					if (fLimit)
					{
						
						bo.EnterTrade(bar, sig.Symbol, sig.IsLong(), sig.Price, sig.PosSize, 0, sig.RoundLotSize);
					}
				} 
			}	
		}	
		bo.UpdateStats(bar,1);

		
		if (fSameBarExit)
		{
			for (sig = bo.GetFirstSignal(bar); sig; sig = bo.GetNextSignal(bar))
			{
				if (sig.IsExit())
				{
					bo.ExitTrade(bar, sig.Symbol, sig.Price, sig.Reason);
				}	
			}
		}

		
		bo.UpdateStats(bar,1);
		bo.UpdateStats(bar,2);
		
		
		if (fPort)
		{
			bo.cash	*=	((1 + dailyRiskFreeRtn[bar]) ^ Nz(nElapsedDays[bar]));	
		}
	}
	
	bo.PostProcess();
	StaticVarRemove("*");
	
	


			
	bo.AddCustomMetric("Max Postions", nMaxPos);

}
//*/

I bought an AB course at trading markets. I understood everything, but by checking results i found wrong results with AB.
Probably I do something wrong, but I donot understand what.
I rebuild the RSI-Selective-Limit-Port met CBT FS201022, code, with a simple RSI, just to test.

When i tested the period 2020.08.01 – 2020.10.01 with
#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"
xMember = NorgateIndexConstituentTimeSeries("$SPX");
maxpos = 2; // not to many symbols, so I can easily understand the portfolio.
pctLimit = 1; // to get more trades

I noticed that AB does not always take the top of the positon score.
Here are the trades of AB 2020.08.01 – 2020.10.01 :
afbeelding
for example, on 2020.09.17 AB bought HSY, while HSY is nr 4 on the positonscore at date 2020.09.16, it
should have tested for KR, this was not hit, so there should not be bought any stock at 2020.09.17 :
afbeelding
for example, on 2020.09.21 AB bought LKQ, while LKQ is nr 17 on the positonscore at date 2020.09.20,

it should have bought BF.B, which is nr 1 and is hit
afbeelding

would someone be so kind to help me and say what i am doing wrong? tanks a lot ! Frans

Your user account isn't marked with License verified badge. Did you purchase AmiBroker license?

Only users with License verified badge are allowed to post on this forum.

So before posting, make sure you verify your license as explained here.

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?

@tdsfransschreiber, I had not the opportunity to test your code, but I wonder if you are using the correct position score values in your reports/explorations.

Looking at your formula, I see that you'll buy the next day.

Is the position score reported the one calculated in the day when you are getting the signals, or is the one of the (next) day in which you'll execute the buy orders?

you're right, but - while i program a lot pascal/lazarus/delphi - it takes for me some time to understand the logic of AB and how to debug AB. tx

you re right Beppe. I had also that possibility in my mind,but could not reproduce it. But after your remarkt, I tested again and trade by trade - took some hours - but the actual Buy did use the pos.score of today, which is very wrong of course.
I use now for the Buy the pos.score one day ago, and placed that after the Filter. see code.

PositionScore = 100 - RSI(2);

fLiquid =	 MA(V, 21) > minVolume;
BuySetup = 	NorgateIndexConstituentTimeSeries("$SPX") AND
			fLiquid AND
			RSI(2)<40 AND 
			RSI(2) == LLV(RSI(2),2) AND 
			C > MA(C,200) AND	inRange;

pLimit = Ref(C,-1) * (1 - pctLimit/100);
BuyPrice = min(pLimit, O);	

Buy = 	Ref(BuySetup,-1)  AND NorgateIndexConstituentTimeSeries("$SPX");

Sell =	RSI(2)>70 OR	BarIndex() == LastGoodBar;

Filter =  NorgateIndexConstituentTimeSeries("$SPX") AND BuySetUp ;
AddColumn(BuySetup, "BSetUP");
AddColumn(PositionScore, "PScore");
AddColumn( (C - Ref(L,1))/C*100>pctLimit  ,"hit");
AddColumn( RSI(2) ,"RSI.0");
AddColumn( C  ,"C.0");
AddColumn( Ref(L,1)  ,"L +1");
AddColumn( (C - Ref(L,1))/C*100  ,"L.1 % lower than C");  
PositionScore = Ref(PositionScore,-1);// Now the right POS SC voor exploration en for the buy

Thanks for your suggestion !

1 Like

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