Hi, please help i'm trying to create a custom column in the backtest trade list. The column called "HighestPriceSinceBuy" and it should return the highest price that occurs since the buy date untill the sell date. This code is not working and it keeps returning 0 on each trade list.
Buy = C > MA(C, 20);
Sell = C < MA(C, 20);
Buy = ExRem(Buy, Sell);
Sell = ExRem(Sell, Buy);
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio) {
bo = GetBacktesterObject();
bo.Backtest(True);
DateTimeArray = DateTime();
HighArray = H;
for (trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade()) {
BuyDate = trade.EntryDateTime;
SellDate = trade.ExitDateTime;
isopen = trade.IsOpen();
BuyIndex = Null;
SellIndex = Null;
// Find the BuyDateIndex
for (i = 0; i < BarCount; i++) {
if (DateTimeArray[i] == BuyDate) {
BuyIndex = i;
break;
}
}
// Find the SellDateIndex if the trade is closed
if (!isopen) {
for (i = BuyIndex; i < BarCount; i++) {
if (DateTimeArray[i] == SellDate) {
SellIndex = i;
break;
}
}
} else {
SellIndex = BarCount - 1; // If the trade is open, consider until the last bar
}
// Ensure the BuyDateIndex and SellDateIndex are valid
if (BuyIndex == Null || SellIndex == Null) {
continue; // Skip if indices are not valid
}
// Calculate the highest price between BuyDate and SellDate
highestPrice = Null;
for (i = BuyIndex; i <= SellIndex; i++) {
highestPrice = Nz(Max(highestPrice, HighArray[i]));
}
trade.AddCustomMetric("HighestPriceSinceBuy", highestPrice);
}
bo.ListTrades();
}
During Phase 2 of the backtest (aka CBT), OHLC values are used by AmiBroker while generating the equity curve (~~~Equity). Therefore the variable H (High) is not the high price of the trade that you're currently looking at but rather something that AmiBroker uses internally.
There are other ways to retrieve the High price for the trade symbol, but I'm wondering why you don't just use the MAE (Max Adverse Excursion) and MFE (Max Favorable Excursion) columns that AmiBroker already provides? If you really want a price rather than a percentage, you can use the trade.GetMFE() method along with the Buy price to determine the highest price while in the trade.
Whatever you want to access (any array) in custom backtester you need to pass from first backtest phase to second. Knowledge Base has article on that:
Alternatively trade object has GetPrice method that allows to access OHLC of given position, so you can keep track of highest since trade entry on your own by iterating open position list in CBT.
Third alternative is MFE as @mradtke told you as it automatically keeps track of highest high since entry (for long pos)
I am trying using your solution, but i think i'm not quite getting it right.
Lets try based on AAPL stock and the backtest it.
my problems are:
On the OpenLong position the highestPriceSinceBuy returning blank. Although its not sell yet, but i need it to return the highest price until the current date which is on this case it happens in 6/12 at 220.2
The most recent long position is on 4/29 and exits on 5/1. The highestPriceSinceBuy returning 174.96 but i think it suppose to be 176.03 (this is the highest price that occurs between 4/29 to 5/1)
below is my code:
Buy = C > MA(C, 20);
Sell = C < MA(C, 20);
Buy = ExRem(Buy, Sell);
Sell = ExRem(Sell, Buy);
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio) {
bo = GetBacktesterObject();
bo.Backtest(True);
for (trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade()) {
BuyDate = trade.EntryDateTime;
SellDate = trade.ExitDateTime;
isopen = trade.IsOpen();
// Use GetMFE() method to get the highest price since buy
if (isopen) {
highestPriceSinceBuy = trade.GetMFE(); // Max Favorable Excursion
} else {
highestPriceSinceBuy = trade.GetMFE() + trade.EntryPrice; // Calculate highest price since buy
}
trade.AddCustomMetric("HighestPriceSinceBuy", highestPriceSinceBuy);
}
bo.ListTrades();
}
Plot(C, "Close", colorDefault, styleCandle);
GetFirstTrade/GetNextTrade gives list of closed trades only. MFE is PERCENTAGE movement, not price. You have to convert percent movement to price (1+0.01*MFE)*entry