A little while ago I had a heap of constants that I needed to iterate through, and wanted to automatically define them.
The other day, whilst searching the forum for an answer to something else, I find that others have had similar problems, but theirs eventually turned out to be slightly different:
What I was looking for was a readCsv()
sort of function that you get in Python or R, with the following characteristics:
- Only operates on a small number of values – I wanted to avoid the pain of hand-coding them by hand into an AFL variable/s, and potential errors.
- Not enough to values to warrant putting them into a dedicated symbol through
AddToComposite()
- They need to be “portable” between databases. AddToComposite ties them to a single DB, needing them to be load them into each DB.
- Doesn’t need the might and power of a matrix.
The code for numbers and dates:
// ---
function CsvNumsToArr(inpStr, inpValSep)
/*
This function takes a comma-separated list of numerical values, and returns an array with
those values, starting at the 0th element.
Ideally, use it when you want to bulk-load a list of values that you'll use for looping.
Note: only suitable for numerical values, no strings allowed!!
*/
{
if (inpStr != "")
{
cnsNumVals = StrCount(inpStr, inpValSep) + 1 ;
result = Null ;
for (loop = 0; (loop < cnsNumVals) AND (loop < BarCount); loop ++)
{
// Convert each string to a number, and put it into the array
result[loop] = StrToNum(StrExtract(inpStr, loop)) ; // separator = inpValSep)
}
}
else
result = Null ;
// Emit the new array of values
return result ;
}
// ----------
function CsvDatesToArr(inpStr, inpValSep)
/*
This function takes a comma-separated list of dates, and returns an array with
dateTime values, starting at the 0th element.
Ideally, use it when you want to bulk-load a list of dates that you'll use for looping.
Inputs:
- "inpStr": a coma-separated string of dates.
- "inpValSep": a single character used to separate the values, eg a comma ","
Notes:
- only suitable for holding dates as DateTime values, no strings allowed!!
- beware, that the actual values of DateTime variables/ values looks strange, but that's
just because of how they've been bit-set coded into a 32-bit number (the default used by AmiBroker).
*/
{
if (inpStr != "")
{
cnsNumVals = StrCount(inpStr, inpValSep) + 1 ;
result = Null ;
for (loop = 0; (loop < cnsNumVals) AND (loop < BarCount); loop ++)
{
// Convert each string to a number, and put it into the array
//result[loop] = StrToNum(StrExtract(inpStr, loop)) ; // separator = inpValSep)
strPiece = StrExtract(inpStr, loop) ;
strPiece = StrReplace(strPiece, "'", "") ; // Need to remove any quotation marks
result[loop] = StrToDateTime(clcExtract);
}
}
else
result = Null ;
// Emit the new array of values
return result ;
}
Sample data and code to convert it to an array might look like this:
strOfConsts = "0.0001, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100"
arrOfConsts = CsvTextToArr(strOfConsts, ",") ;
It’s not the tightest code, but it works for me. I’ll get around to improving it …