|
Navigation: Introduction > Developing Study Formulas > Calling DLLs Calling DLLs |
Top Previous Next |
DLL-defined functions can be called from within ScanExpert study formulas. We have provided an example study formula that uses a DLL function to calculate a simple moving average. The source file for this study formula is dsSMAStudyUsingDLL.pas and it can be found in the ScanExpert Studies folder. The actual compiled DLL is called SMADLL.dll and can be found in the ScanExpert Application folder.
The example DLL (i.e., SMADLL.dll) was written in Delphi:

In a nutshell, we pass the period (length) of the desired moving average as well as a static array containing the data to be averaged. Here we have defined this array of double with 501 elements as type TDataArray. It is critical that you pass an array of exactly the same type and size from your ScanExpert script. Note that all ScanExpert series (even Volume) are stored internally as Double values so, when passing ScanExpert data to a DLL function you should always use an Array type of Double.
This is a very simple example. If needed, you can pass multiple arrays (i.e., you might want to pass an array for Open, High, Low, and Close to your DLL function) and you can pass multiple parameters. In general, the return value should always be a Double. Be sure to perform any and all necessary error-checking from within your DLL to make it as bullet-proof as possible. Also, any DLLs that you create MUST be thread-safe.
Here is the source code from our example study formula that calls the DLL function outlined above:
//======================================================================
//+--------------------------------------------------------------------+
//| dsSMAStudyUsingDLL.pas +
//+--------------------------------------------------------------------+
//| simple moving average formula that calls external DLL +
//| input parameters: 1 +
//| input streams: 1 +
//======================================================================
//-- specify the number of input parameters and input
//-- streams that are expected. this information is
//-- critical and is used by the ScanExpert program.
{params: 1}
{streams: 1}
//-- This is an example study formula that demonstrates how to call a DLL
//-- function from within a ScanExpert formula study. The DLL that works in
//-- conjunction with this example is called SMADLL.dll and is located in the
//-- ScanExpert program folder. See the Scripting User Guide for the source
//-- code to this DLL.
//-- declare the array type. note that the array type you declare here must
//-- exactly match the array type that you declare in your DLL. In this case
//-- it is an array of Double with 501 elements.
type
TDataArray = Array[0..500] of Double;
//-- declare the DLL function (note that the DLL itself should always be placed
//-- in the ScanExpert Program folder). This particular DLL function will calculate
//-- a simple moving average. We pass the period as well as an array of data to
//-- this DLL function.
function calcSMA( _period: integer; _data: TDataArray ) : Double; external 'SMADLL.dll';
var
x: integer;
v: Double;
period: Integer;
source: TEStream;
bars: Integer;
bInit: Boolean;
data: TDataArray;
begin
if (bInit = false) then
begin
//== get the period being used for this particular sma study
period := ThisStudy.getInputParameter(0);
//== always check to be sure that the period is in the
//== expected range
if (period < 1) then
exit;
//== get the input source
source := ThisStudy.getInputStream(0);
//-- initialize the array that will hold our data that will
//-- be passed to the DLL function
for x:=0 to high(data) do
begin
data[x] := 0.0;
end;
//== ALWAYS check for a nil source
if (source = nil) then
exit;
bInit := true;
end;
//== get the number of bars we currently have available in our input source
bars := source.getNumBars;
//== if we have enough bars, calculate the SMA
if (bars > period) then
begin
//-- on each new bar, shift our storage array (i.e., shift the data
//-- back by one element)
if ( source.getBarState = BARSTATE_NEWBAR ) then
begin
for x:=high(data) downto 1 do
begin
data[x] := data[x-1];
end;
data[0] := 0.0;
end;
//-- pass the current value into array element 0
data[0] := source.getValue(0);
//-- call the DLL function which in this case returns the
//-- simple moving average
v := calcSMA( period, data );
//== if this is a new bar then add a new element to our
//== custom study object. Othewise just update the current
//== value of our study object
if (source.getBarState = BARSTATE_NEWBAR) then
ThisStudy.addValue(v)
else
ThisStudy.setValue(v);
end;
end.