User error, calling Weighted Moving Average (WMA) Function from DLL incorrectly

Hello. I have been implementing AFL scripts in C++ for a while now with great success. I have lately been having a problem where I am unable to get a function call to the WMA function to properly work.

C++ code:

AmiVar Sym1Wwma_Arg[2];
Sym1Wwma_Arg[0] = Sym1; // Sym1 is result of a call to foreign
Sym1Wwma_Arg[1].type = VAR_FLOAT;
Sym1Wwma_Arg[1].val = ###; // hiding this number for IP reasons

AmiVar Sym1Wwma = gSite.AllocArrayResult();
Sym1Wwma_Pent = gSite.CallFunction("WMA", 2, Sym1Wwma_Arg);

This function call results in an exception being thrown when I call the DLL from AmiBroker telling me the operation is not allowed/invalid operand or operator. I am unsure what I might be doing wrong. Does my second parameter need to be an array for some reason, even though the function reference doesn't say it needs to be?

Any help would be greatly appreciated.

Type coercion (upsizing float to array) works automatically in AFL only.
If you write in C/C++ it does NOT. C/C++ is not AFL.
If you write in C/C++, second argument needs to be array, because WMA is a variable period function http://www.amibroker.com/guide/a_varperiods.html

It is advised NOT to use DLLs. Use AFL instead. C/C++ is way too to error prone.

I don’t see the reason why you would want to do that in DLL. It will be slower than AFL. Excess usage of DLLs slows down the system because functions in DLLs are serialized.

DLL is not magical recipe for speed. Just the opposite. Properly written AFL is as fast as machine code: http://www.amibroker.com/kb/2008/08/12/afl-execution-speed/

2 Likes

Thanks for the answer. Does the array need to be of size 1 containing the range value, or of size range containing 1-range?

I am not implementing DLLs for performance reasons so I am not worried about performance, thanks for the heads up though.

The size of ANY AFL array is dynamic (may change between executions) and needs to be equal to what is returned by Site.GetArraySize().

2 Likes

anyway you cant call WMA, DEMA, ... with gSite.CallFunction, just MA and EMA

That is obviously FALSE statement.

You can call ANY function.

The fact that you do not have knowledge how to do something does not mean that it can't be done. It just means that you do not know.
And if you do NOT know it is better to remain silent than to make false statements.

As I wrote in previous reply it is perfectly doable and actually provided description how to do that. Those who understand will know what to do, but copy-paste artists won't get free code to copy without any effort.

For your own benefit, you should NOT write DLLs if you don't know how.

1 Like

sorry Tomasz, that my statement is incorrect, i just means in CodySigvartson' example code, he cant use gSite.CallFunction for any average function using variable period with his code, except EMA and MA do not use variable period. To call WMA:


Sym1Wwma_Arg[1].type = VAR_ARRAY;
Sym1Wwma_Arg[1] = gSite.AllocArrayResult();
int nSize = gSite.GetArraySize();
for (int i=0; i < nSize; i++)
	Sym1Wwma_Arg[1].array[i] = ###; // float value, i.e = ArgsTable[1].val

AmiVar Sym1Wwma = gSite.AllocArrayResult();
Sym1Wwma_Pent = gSite.CallFunction("WMA", 2, Sym1Wwma_Arg);

Moderator comment: yes that is correct code. If function needs array, then array should be supplied. If value is constant, the array should be filled with constant. It is quite obvious and if somebody does not understand that, it means that he/she should not be writing DLLs.

2 Likes

Wilders func does not use variable period too.

Moderator comment: How about just reading the manual instead of guessing. It is all documented in the guide http://www.amibroker.com/guide/a_varperiods.html