futures trading (long/short). i'm trying to calculate historical var for the last 252 days (ie with current position, calculate daily PNL for the last 252 days, sort them, pick the 12th from bottom observation ie 5th percentile, export it as a ticker). but struggling to get it right and my exported var keeps showing zero all the way. any help will be greatly appreciateed.
// === SYSTEM WITH POSITION-BASED VAR COMPUTATION ===
SetBarsRequired(252, 0);
lookback = Param("VARdays", 252, 100, 252, step=1);
confidenceLevel = 0.95;
// Calculate Portfolio Return
portfolioReturn = 0;
symbols = CategoryGetSymbols(categoryWatchlist, Param("Select Watchlist", 4, 1, 252, 1));
numSymbols = StrCount(symbols, ",") + 1;
for (i = 0; i < numSymbols; i++) {
sym = StrExtract(symbols, i);
price = Foreign(sym, "C", 1);
contractSize = Foreign(sym, "PointValue", 1);
marginRequirement = Foreign(sym, "Margin", 1);
contracts = PositionSize / (price * contractSize);
returns = price - Ref(price, -1);
portfolioReturn += returns * contracts * contractSize;
}
// Calculate Historical VaR
// Ensure valid lookback period
firstIndex = max(0, BarCount - lookback);
lastIndex = BarCount - 1;
// Ensure we are only working with `lookback` bars
validReturns = Ref(portfolioReturn, -lookback + 1);
sortedReturns = Sort(validReturns, 0, lookback - 1, False);
// Compute valid VaR index
VaRIndex = max(0, min(lookback - 1, floor(lookback * (1 - confidenceLevel))));
// Ensure sortedReturns has enough data before accessing
historicalVaR = IIf((lookback) > 0, sortedReturns[VaRIndex], 0);
OK, let's try again. I'm trying to get to calculating historical VAR for a futures long/short portfolio but i"m stuck with the output WorstDay returning ZERO. I would really appreciate if someone who has some insights.
My logic (in my mind) goes:
Per BAR, run thru all open positions.
Per OPEN POSITION per BAR, obtain a "lookback" # of days of hypothetical returns by:
calculating the scalar of open contracts
running thru i=0 to i=lookback of price history to determine daily pnl changes.
ADDING these daily price changes into an array called Portfolioreturn
Once i finish running thru the OPEN POSITIONS per BAR, i will get the LOWEST value in the array Portfolioreturn, and export it to an array called WorstDay (also of the same array length as Portfolioreturn)
Then export WorstDay as a ticker.
if (Status("action") == actionPortfolio)
{
bo = GetBacktesterObject();
bo.Backtest(); // Run the backtest
boPosition = bo.GetFirstOpenPos(); // Retrieve first open position
lookback = Param("VARdays", 252, 100, 252, step=1);
SetBarsRequired(lookback, 0);
confidenceLevel = 0.95;
// PortfolioReturn = 0;
// Initialize. This is meant to be an array that stores the last "lookback" days of Portfolio Returns for a given set
// of daily positions. This should be re-written over every bar.
while (boPosition) // Iterate through all open positions
{
symbol = boPosition.Symbol;
dollarNotional = boPosition.GetPositionValue(); // Current position value. I wonder if correct for futures?
dollarPerPoint = boPosition.PointValue;
price = C;
PortfolioReturn = 0;
// Initialize. This is meant to be an array that stores the last "lookback" days of Portfolio Returns for a given set
// of daily positions. This should be re-written over every bar.
// Ensure contract calculation is correct
latestPrice = LastValue(price);
contracts = dollarNotional[BarCount-1] / (latestPrice[BarCount-1] * dollarPerPoint[BarCount-1]);
//this is a SCALAR of current contracts to be applied to past history
// Compute the single-day pnl in the last "lookback" days
for (i = 0; i < lookback; i++)
{
index1 = BarCount - i - 1; // Get bar index `i` days ago
index2 = BarCount - i - 2; // Get bar index `i+1` days ago
// Ensure indices are within valid range
if (index1 < 0 OR index2 < 0)
continue;
pastPrice = price[index1]; // Extract scalar price at specific index
prevPrice = price[index2]; // Extract scalar price at specific index
// **Single-day PNL**
dailyPNL = (pastPrice - prevPrice) * dollarPerPoint * contracts;
// Single-day profit/loss from Scalar of pricechange * Array of dollarperpoint
// * Scalar of current count of contracts
// So dailyPNL should be an array yes?
Portfolioreturn += Portfolioreturn + dailyPNL;
//this array stores sum of [position x price changes] per instrument PER bar (hopefully)
//this array length should be same as lookback
}
// Move to the next open position
boPosition = bo.GetNextOpenPos();
// Extract the lowest value of Portfolioreturn into WorstDay
for (i = 0; i<lookback; i++)
{
WorstDay = LLV(PortfolioReturn, lookback);
}
}
// Export portfolioreturn as a Composite Ticker
AddToComposite (WorstDay,
"~~~WORSTDAY", "X",
atcFlagDeleteValues | atcFlagEnableInPortfolio);
}
Don't do this. use date Range from UI or find the bar index of your range using datetime lookup and iterate through them if you want to do it in AFL.
your whole 0 to BarCount will not mean the same. There is QuickAFL among others things,AB does many calculations, you cannot simply guarantee the number of bars in this way. There could be more bars too. try printing BarCount and check.
SetBarsRequired does NOT affect portfolio backtesting (second phase) run - it is always run with number of bars that are defined by the user in "Range" settings
Portfolio backtest (second phase) is run with EQUITY as selected symbol, but Close array is NOT price in second phase of custom backtester. To access prices of any open trade object use GetPrice member function of any trade object.
Please read this: https://www.amibroker.com/docs/Houston2.pdf
trying something different but still having issues. maybe i just need a clear head (or more brains).
// === SYSTEM WITH POSITION-BASED VAR COMPUTATION ===
// === to simplify code, idea is to obtain WORST DAY of a set of OPEN POSITIONS for a n-lookback days of price history.
// === if lookback days = 100, the worst day approximates 99.9% percentile (or maybe 99% percentile)
// === u can translate to a desired confidence interval using z-score transformation
// === makes very strong assumptions about normality but this is just an exercise
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio)
{
lookback = Param("VARdays", 252, 100, 252, step=1); //# of days to check price history
bo = GetBacktesterObject();
bo.Backtest();
Portfolioreturn = 0; //initialisation. this resets to zero each bar (hopefully)
for(openpos = bo.GetFirstOpenPos(); openpos; openpos = bo.GetNextOpenPos()) //looping thru all open positions
{
symbol = boPosition.Symbol; //??? seems to be in documentation, but doesn't work?
symbolcontracts = boPosition.Shares; //??? seems to be in documentation, but doesn't work?
dollarPerPoint = boPosition.PointValue; //??? seems to be in documentation, but doesn't work?
symbolprice = Foreign (symbol, "C", 1); //??? seems to be in documentation, but doesn't work?
// Compute the single-day pnl in the last "lookback" days
for (i = 0; i < lookback; i++)
{
index1 = BarCount - i - 1; // Get bar index `i` days ago
index2 = BarCount - i - 2; // Get bar index `i+1` days ago
pastPrice = symbolprice[index1]; // Extract scalar price at specific index
prevPrice = symbolprice[index2]; // Extract scalar price at specific index
// **Single-day PNL**
dailyPNL = (pastPrice - prevPrice) * dollarPerPoint * symbolcontracts;
// Single-day profit/loss from Scalar of pricechange *
// Array of dollarperpoint * Scalar of current count of contracts
// So dailyPNL should be an array yes?
Portfolioreturn = Portfolioreturn + dailyPNL;
//this array stores sum of [position x price changes] per instrument PER bar (hopefully)
//this array length should be same as lookback
}
}
// Extract the lowest value of Portfolioreturn into WorstDay
WorstDay = LLV(PortfolioReturn, lookback);
// Export portfolioreturn as a Composite Ticker
AddToComposite (WorstDay,
"~~~WORSTDAY", "X",
atcFlagDeleteValues | atcFlagEnableInPortfolio);
current code: seems logical thru each step but there's a problem somewhere.
SetCustomBacktestProc("");
if (Status("action") == actionPortfolio)
{
lookback = Param("VARdays", 252, 100, 252, step=1); //# of days to check price history
bo = GetBacktesterObject();
bo.Backtest();
Portfolioreturn = 0; //initialisation. this resets to zero each bar (hopefully)
for(openpos = bo.GetFirstOpenPos(); openpos; openpos = bo.GetNextOpenPos()) //looping thru all open positions
{
symbol = openpos.Symbol;
symbolcontracts = openpos.Shares; //i'm assuming a short position will be a negative number?
dollarPerPoint = openpos.PointValue;
symbolprice = Foreign (symbol, "C", 1);
// Compute the single-day pnl in the last "lookback" days
for (i = 0; i < lookback; i++)
{
index1 = BarCount - i - 1; // Get bar index `i` days ago
index2 = BarCount - i - 2; // Get bar index `i+1` days ago
pastPrice = symbolprice[index1]; // Extract scalar price at specific index
prevPrice = symbolprice[index2]; // Extract scalar price at specific index
// **Single-day PNL**
dailyPNL = (pastPrice - prevPrice) * dollarPerPoint * symbolcontracts;
// Single-day profit/loss from Scalar of pricechange *
// Array of dollarperpoint * Array of current count of contracts
// So dailyPNL should be an array of length "lookback" yes?
Portfolioreturn += dailyPNL;
//this array stores sum of [position x price changes] per instrument PER bar (hopefully)
//this array length should be same as lookback
}
}
// Extract the lowest value of Portfolioreturn into WorstDay
WorstDay = LLV(PortfolioReturn, lookback);
// Export portfolioreturn as a Composite Ticker
AddToComposite (WorstDay,
"~~~WORSTDAY", "X",
atcFlagDeleteValues | atcFlagEnableInPortfolio);
}