I am trying to code the position sizing using the current equity value. I have written the following code in the Mid-Level Interface using Custom Backtesting.
Are you sure you're the AA window is running the same file that is being edited ?
Because even now the two lines are different.
There have been such cases that file name is same but path is different, or the APX is loaded with old code and the AFL being updated isn't the one actually running.
Just like in chart, you insert an indicator and then subsequent changes to file don't reflect because the copy is running.
Try changing this line sig.PosSize = … to something else and see if the New code is being run. sig.PosSize = 2; for example.
Its fairly simple. The line below is yielding an array because the first arg to IIf() is an array. Run as Exploration to see. Any calculations based on it go downhill from there. So, you can't assign an array to sig.PosSize.
I found this code in Amibroker User's Knowledge Base
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio)
{
bo = GetBacktesterObject(); // Get backtester object
bo.PreProcess(); // Do pre-processing
for (i = 0; i < BarCount; i++) // Loop through all bars
{
for (sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i))
{ // Loop through all signals at this bar
if (sig.IsEntry() && sig.IsLong()) // If this signal is a long entry (ie. buy)
{
evol = Foreign("~evol_"+sig.Symbol, "V"); // Get stock's composite volume array
psize = sig.PosSize; // Get position size specified in AFL code
if (psize < 0) // If it's negative (a percentage of equity)
psize = (-psize/100) * bo.Equity; // Convert to dollar value using current equity
scnt = psize / sig.Price; // Calculate number of shares for position size
if (scnt > evol[i] / 10) // If number of shares is > 10% of volume EMA
{
scnt = evol[i] / 10; // Limit number of shares to 10% of EMA value
psize = scnt * sig.Price; // Calculate new position size
}
if (psize < 5000) // If position size is less than $5,000
psize = 0; // Set to zero so buy signal will be ignored
else
{
if (psize > 50000) // If position size is greater than $50,000
psize = 50000; // Limit to $50,000
}
sig.PosSize = psize; // Set modified position size back into object
}
} // End of for loop over signals at this bar
bo.ProcessTradeSignals(i); // Process trades at this bar
} // End of for loop over bars
bo.PostProcess(); // Do post-processing
}
There is an array which is assigned to sig.PosSize
Then most likely you have a Type issue, try and force Array to scalar with LastVaue() as shown.
Permute through each, you'll know which variable is causing it.
I'll get involved but probably shouldn't. Anyway, I'll detail the problem and solutions.
Karan - first, note that the code fragment that you got from the Knowledge Base used "if" statements, not "IIf" functions. If statements are used there to produce scalars. That is why in the example, evol[i] is used because if references the array element in "evol" that the bar counter "i" indexes.
The bottom line is that you have to do one of the following -
Get rid of the "IIf()" statement in the "LotSize = " statement and replace with an "If" statement construct.
Or do the following, which is simple but slightly less efficient with minimal change. Change the following statement -
LotSize = IIf(Datenum()>=1110101 AND DateNum()<=1141031, 50 , IIf( DateNum()>=1141031 AND DateNum()<=1151030 , 25 , 75)) ;
Change it to -
LotSizeArray = IIf(Datenum()>=1110101 AND DateNum()<=1141031, 50 , IIf( DateNum()>=1141031 AND DateNum()<=1151030 , 25 , 75)) ;
LotSize = LotSizeArray[i];
If you are going to write anything more than simple code, it is important to learn debugging techniques. Learn to sprinkle your code with _TRACE() statements. Specifically, after seeing the "Type mismatch" error, you would put a _TRACE() statement before it to output the variable types. This would have led you back to the problem source.