自由DLL接口规范

来自tradeStar帮助系统
(版本间的差异)
跳转到: 导航, 搜索
(=参数类型)
(返回值类型)
 
(未显示2个用户的16个中间版本)
第1行: 第1行:
 
=简介=
 
=简介=
相比传统DLL接口(飞狐接口),自由DLL接口的特点是放弃了对参数的要求。
+
相比传统DLL接口(飞狐接口),自由DLL接口的特点是参数更加灵活,由用户指定传入的参数,参数类型是c/c++的标准数据类型。
  
传统DLL必须引入一个CalcInfo的结构化参数,通过它来传入行情数据。
+
传统DLL必须引入一个CalcInfo的结构化参数,通过它来传入行情数据,这种设计的好处是用户操心得少一些,因为数据总是有的,不利之处是限制了发挥,难以返回多个序列结果,难以接入没有按接口要求编写的DLL。
  
这种设计的好处是用户操心得少一些,因为数据总是有的,不利之处是限制了发挥,难以返回多个序列结果,难以接入没有按接口要求编写的DLL。
+
自由DLL接口,不再传入CalcInfo参数,取而代之的是,用户必须自己负责传入所有的数据。获得的回报是,
  
自由DLL接口,不再传入CalcInfo参数,取而代之的是,用户必须自己负责传入所有的数据。
 
 
 
获得的回报是,
 
 
1.支持任意多的参数。
 
1.支持任意多的参数。
 +
 
2.支持引用参数,也就是说,可以改变参数的值并返回给公式系统。
 
2.支持引用参数,也就是说,可以改变参数的值并返回给公式系统。
 +
 
3.更灵活的参数传递。例如,可以根据需要传入地址,也可以传入值。
 
3.更灵活的参数传递。例如,可以根据需要传入地址,也可以传入值。
4.支持逐根的计算。每次只计算一根的值并返回单值。
 
  
 +
4.支持逐根的计算。每次只计算一根的值并返回单值。自由DLL只能在逐根模式下运行。
  
 
与传统接口DLL一样,自由接口DLL也必须放置在FmlDLL目录下。
 
与传统接口DLL一样,自由接口DLL也必须放置在FmlDLL目录下。
第22行: 第20行:
 
为了让公式系统知道DLL的参数格式,调用前需要使用extern语句进行声明
 
为了让公式系统知道DLL的参数格式,调用前需要使用extern语句进行声明
  
  extern 返回值类型 函数名(参数类型 参数,...);
+
  extern 返回值类型 函数名(参数类型1, 参数类型2...);
  
参数的个数和名称都没有限制
+
参数的个数没有限制
  
==参数类型=
+
=参数类型=
  
 
传入DLL的参数有类型限制,目前支持的C类型包括
 
传入DLL的参数有类型限制,目前支持的C类型包括
 
float, double, int,BOOL, LONG, DWORD, float*, LPCWSTR等
 
float, double, int,BOOL, LONG, DWORD, float*, LPCWSTR等
暂不支持double *
+
不支持double *
  
公式中,有些类型的名字与C不同。
+
=返回值类型=
其中,float*,有可能是NumericRef,也可能是NumericSeries,还可以是NumericArray 。
+
但打算传入单值,并改变值返回,那么用NumericRef,如果打算传入序列那么用NumericSeries,如果传入数组,那么用NumericArray 。
+
  
// C 代码里的声明
+
函数可以返回 int, float, char, bool 等类型,或无返回。
extern "C" __declspec(dllexport) void WINAPI my_ma2(float* pResultBuffer, float* pDataBuffer, int n, int barpos)
+
公式里面的声明
+
// 公式里面的声明
+
  extern 'MyDll2.dll' void  my_ma2(NumericSeries ResultBuffer, NumericSeries DataBuffer, int n, int barpos);
+
  
=自由DLL调用=
+
若要在DLL内修改一条序列或者修改整个数组,可以通过传序列参数或数组参数的方法,在DLL里面赋值。DLL 里面都使用 float * 来接收参数。
声明过的函数,可以通过函数名直接调用,无需通过"DLLName@FuncName"格式使用。
+
  
使用时必须将DLL放在软件安装目录下的FmlDll子目录下
+
=自由DLL接口的调用=
  
 +
*声明过的函数,可以通过函数名直接调用,无需通过"DLLName@FuncName"格式或RefDLL使用。
  
DLL名称和函数名都是大小写敏感的,代码声明和公式调用时需要匹配。
+
*使用时必须将DLL放在软件安装目录下的FmlDll子目录下
 +
 
 +
*字符串使用单引号,双引号是另一种格式的引用,不能混用
 +
 
 +
*DLL 需要在 .def 文件中 EXPORTS 项添加要调用的函数,否则有可能找不到函数
 +
 
 +
*DLL名称和函数名都是大小写敏感的,代码声明和公式调用时需要匹配。
 +
 
 +
=DLL公式参数传递例子=
 +
 
 +
*无参数时的例子:
 +
 
 +
// 公式里面的声明与调用
 +
extern 'FoxFunc.dll' void test1();
 +
test1();
 +
 
 +
// c++ .h 函数声明
 +
__declspec(dllexport) void __stdcall test1();
 +
 
 +
// c++ .cpp 函数实现
 +
extern "C" __declspec(dllexport) void __stdcall test1()
 +
{
 +
 +
}
 +
 
 +
*传入单值的公式例子:
 +
 
 +
// 公式里面的声明与调用
 +
extern 'FoxFunc.dll' void test2(int, float, bool, char);
 +
Variables:
 +
  NumericSimple var1,
 +
  NumericSeries var2,
 +
  NumericArray var3[10];
 +
 +
var1 := 1;
 +
var2[0] := 2;
 +
var3[0] := 65;
 +
 +
test2(1, 2, 1, 65);
 +
test2(var1, var2[0], var1, var3[0]);
 +
 
 +
// c++ .h 函数声明
 +
__declspec(dllexport) void __stdcall test2(int i, float f, bool b, char c);
 +
 
 +
// c++ .cpp 函数实现
 +
extern "C" __declspec(dllexport) void __stdcall test2(int i, float f, bool b, char c)
 +
{
 +
 +
}
 +
 
 +
*传入字符串的公式例子
 +
 
 +
公式里面的字符串变量是宽字符,编码是GB2312,DLL里面可以使用MultiByteToWideChar/MultiByteToWideChar进行字符转换
 +
 
 +
// 公式里面的声明与调用
 +
extern 'FoxFunc.dll' void test3(LPCWSTR);
 +
Variables:
 +
  String var1;
 +
 +
var1 := 'test string1';
 +
 +
test3(NumToStr(close,3));
 +
test3('aaa');
 +
test3(var1);
 +
 
 +
// c++ .h 函数声明
 +
__declspec(dllexport) void __stdcall test3(const wchar_t* p);
 +
 
 +
// c++ .cpp 函数实现
 +
#include <string>
 +
 +
// 窄字符转宽字符
 +
static std::wstring a2w(LPCSTR lpa)
 +
{
 +
size_t l = MultiByteToWideChar(936, 0, lpa, -1, NULL, 0);
 +
 +
std::wstring s;
 +
s.resize(l - 1);
 +
 +
MultiByteToWideChar(936, 0, lpa, (int)strlen(lpa), (LPWSTR)s.c_str(), (int)s.size());
 +
 +
return s;
 +
}
 +
 +
// 宽字符转窄字符
 +
static std::string w2a(LPCWSTR lpw)
 +
{
 +
size_t l = WideCharToMultiByte(936, 0, lpw, -1, NULL, 0, NULL, NULL);
 +
 +
std::string s;
 +
s.resize(l - 1);
 +
 +
WideCharToMultiByte(936, 0, lpw, (int)wcslen(lpw), (LPSTR)s.c_str(), (int)s.size(), NULL, NULL);
 +
 +
return s;
 +
}
 +
 +
extern "C" __declspec(dllexport) void __stdcall test3(const wchar_t *p)
 +
{
 +
std::wstring sw = p;
 +
std::string sa = w2a(sw.c_str());
 +
}
 +
 
 +
*传入序列的公式例子
 +
 
 +
// 公式声明与调用
 +
extern 'FoxFunc.dll' void test4(NumericSeries, int, NumericArray, int);
 +
Variables:
 +
  NumericSeries var1,
 +
  NumericArray var2[5];
 +
 +
var1 := close;
 +
var2[1] := 1;
 +
var2[2] := 2;
 +
var2[3] := 3;
 +
var2[4] := 4;
 +
var2[5] := 5;
 +
 +
//var2 数组实际大小是5+1
 +
test4(var1, BarsCount(close), var2, 6);
 +
 
 +
// c++ .h 声明
 +
__declspec(dllexport) void __stdcall test4(float *pf1, int n1, float *pf2, int n2);
 +
 
 +
// c++ .cpp 函数实现
 +
extern "C" __declspec(dllexport) void __stdcall test4(float *pf1, int n1, float *pf2, int n2)
 +
{
 +
 +
}
 +
 
 +
*传入引用的公式例子
 +
 
 +
// 公式声明与调用
 +
extern 'FoxFunc.dll' void test5(NumericRef);
 +
Variables:
 +
  NumericSimple var1;
 +
 +
var1 := 3;
 +
test5(var1);
 +
comment(var1);
 +
 
 +
// c++ .h 声明
 +
__declspec(dllexport) void __stdcall test5(float *pf);
 +
 
 +
// c++ .cpp 实现
 +
extern "C" __declspec(dllexport) void __stdcall test5(float *pf)
 +
{
 +
*pf = 9;
 +
}
  
 
=DLL的返回值=
 
=DLL的返回值=
 +
 
新格式DLL可返回单值,序列和数组。单值类型大致分为两种:数值类型和字符串类型,可以通过函数返回值直接返回。
 
新格式DLL可返回单值,序列和数组。单值类型大致分为两种:数值类型和字符串类型,可以通过函数返回值直接返回。
 +
 
*返回单值类型的c语言例子
 
*返回单值类型的c语言例子
  //返回整数
+
 
  extern "C" __declspec(dllexport) int WINAPI my_test1()
+
// 公式声明与调用例子
 +
extern 'FoxFunc.dll' int test6();
 +
extern 'FoxFunc.dll' float test7();
 +
extern 'FoxFunc.dll' LPCWSTR test8();
 +
 +
k1: test6(),OwnerScale;
 +
k2: test7(),OwnerScale;
 +
comment(test8);
 +
 
 +
// c++ .h 声明
 +
__declspec(dllexport) int __stdcall test6();
 +
__declspec(dllexport) float __stdcall test7();
 +
__declspec(dllexport) wchar_t* __stdcall test8();
 +
 
 +
  // c++ .cpp 实现
 +
  extern "C" __declspec(dllexport) int __stdcall test6()
 
  {
 
  {
 
  return 1;
 
  return 1;
 
  }
 
  }
//返回浮点
+
  extern "C" __declspec(dllexport) float __stdcall test7()
  extern "C" __declspec(dllexport) float WINAPI my_test2()
+
 
  {
 
  {
  return 2.0f;
+
  return 0.5f;
 
  }
 
  }
//返回字符串
+
  extern "C" __declspec(dllexport) wchar_t* __stdcall test8()
  extern "C" __declspec(dllexport) LPCWSTR WINAPI my_test3()
+
 
  {
 
  {
  return L"TEST STRING";
+
  return L"test string 1";
 
  }
 
  }
相应的公式调用例子
+
 
#MAINCHART
+
*返回序列或数组
#Run_By_Bar
+
extern 'MyDll2.dll' int my_test1();
+
extern 'MyDll2.dll' float my_test2();
+
extern 'MyDll2.dll' LPCWSTR my_test3();
+
k1: my_test1;
+
k2: my_test2;
+
comment(my_test3);
+
  
 
若要返回序列或数组,则把需要返回的序列赋值目标当作参数传递给DLL,在DLL内部直接修改已达到赋值。
 
若要返回序列或数组,则把需要返回的序列赋值目标当作参数传递给DLL,在DLL内部直接修改已达到赋值。
 
注意逐根运行模式下,每一根K线都会调用dll,所以通常每次调用只需要赋值比上一根K线新增加的类型,
 
注意逐根运行模式下,每一根K线都会调用dll,所以通常每次调用只需要赋值比上一根K线新增加的类型,
 
例如计算收盘价均值时,每次在BarPos位置填入当根K线的均值即可。由此可见,这种应用下通常需要把
 
例如计算收盘价均值时,每次在BarPos位置填入当根K线的均值即可。由此可见,这种应用下通常需要把
BarPos(当前是第几根K线)作为参数传入Dll中。
+
BarPos(当前是第几根K线)作为参数传入Dll中。返回序列和数组可以参考上面传入序列的公式例子。
*返回序列和数组的例子
+
 
  extern "C" __declspec(dllexport) void WINAPI my_test4(float*pReturn, int nIndex)
+
下面一个例子是在图形上输出当前是第几根K线的例子:
{
+
 
pReturn[nIndex-1] = 123;
+
// 公式中的声明与调用
}
+
  extern 'FoxFunc.dll' void test9(NumericSeries, int);
 
   
 
   
  extern "C" __declspec(dllexport) void WINAPI my_test5(float*pReturn, int nLen)
+
MyIndi:0;
 +
test9(MyIndi, BarPos);
 +
 
 +
// c++ .h 声明文件
 +
__declspec(dllexport) void __stdcall test9(float *pf, int n);
 +
 
 +
// c+= .cpp 实现
 +
  extern "C" __declspec(dllexport) void __stdcall test9(float *pf, int n)
 
  {
 
  {
  for(int i=0;i<nLen;i++)
+
  // 每根都会调用一次,所以每次只需赋值当前根
pReturn[i] = 0;
+
pf[n - 1] = n;
 
  }
 
  }
相应的公式调用例子
 
#MAINCHART
 
#Run_By_Bar
 
variable:
 
  NumericSeries mySequence(0);
 
array:
 
  myArray[100](1);
 
 
extern 'MyDll2.dll' void my_test4(NumericSeries mySequence, int nIndex);
 
extern 'MyDll2.dll' void my_test5(NumericArray myArray, int nLen);
 
my_test4(mySequence, BarPos);
 
my_test5(myArray, 100);
 
  
=DLL的参数类型=
+
=DLL的参数类型参考=
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
!    - !!  单值 !!  序列 !!  数组 !!  引用
+
!-   类型  !!  公式 !!  DLL
 +
|-
 +
| 数值 || NumericSimple || float, int, char, bool
 +
|-
 +
| 字符串 || LPCWSTR || wchar_t*
 +
|-
 +
| 数值引用 || NumericRef || float*
 
|-
 
|-
| 数值 || NumericSimple || NumericSeries || NumericArray || NumericRef
+
| 序列 || NumericSeries || float*
 
|-
 
|-
| 字符串 || String || - || StringArray || StringRef
+
| 数组 || NumericArray || float*
 
|}
 
|}
  
第125行: 第274行:
 
  k1:Invalid;
 
  k1:Invalid;
 
则k1指标线不会输出
 
则k1指标线不会输出
 +
  
 
=编写调用公式=
 
=编写调用公式=
第142行: 第292行:
 
  extern 'kernel32.dll' int GetTickCount();
 
  extern 'kernel32.dll' int GetTickCount();
 
  tickcount:GetTickCount();
 
  tickcount:GetTickCount();
 
同样地,这种用法只能工作于逐根模式下。
 
 
  
 
=调用.Net DLL=
 
=调用.Net DLL=
只能在逐根模式中使用.net DLL
+
 
  
 
跟一般DLL不同的是,.net DLL在声明时,除了函数名信息,还要提供命名空间、类名的信息,例如:
 
跟一般DLL不同的是,.net DLL在声明时,除了函数名信息,还要提供命名空间、类名的信息,例如:
第154行: 第301行:
  
 
这里的RzRq就是命名空间,而Grabber则是类的名称,GetFinance是函数名
 
这里的RzRq就是命名空间,而Grabber则是类的名称,GetFinance是函数名
 +
 +
另外,在.net DLL中,除了可以用参数来传递数据,还可以使用GetVarData, SetVarData这两个函数在.net和公式引擎间交换数据。
 +
 +
.net DLL开发过程如下:<br>
 +
1. visual studio 新建一个类库 工程,用C#或者VB.net,Managed C++都可以,这里以C#为例<br>
 +
[[image:dotnet1.png]]<br>
 +
<br>
 +
2.添加 金魔方 .net api dll 引用,位置位于金魔方安装目录下 DotNetBridge.dll<br>
 +
[[文件:dotnet2.png]]<br>
 +
[[文件:dotnet3.png]]<br>
 +
<br>
 +
3.新建或者修改 从 Formula 继承 一个类,Formula 是金魔方.net api的类,从此类继承可以访问 GetVarData等接口函数,需要用 fox.api 命名空间<br>
 +
[[文件:dotnet4.png]]<br>

2016年11月14日 (一) 14:54的最后版本

目录

[编辑] 简介

相比传统DLL接口(飞狐接口),自由DLL接口的特点是参数更加灵活,由用户指定传入的参数,参数类型是c/c++的标准数据类型。

传统DLL必须引入一个CalcInfo的结构化参数,通过它来传入行情数据,这种设计的好处是用户操心得少一些,因为数据总是有的,不利之处是限制了发挥,难以返回多个序列结果,难以接入没有按接口要求编写的DLL。

自由DLL接口,不再传入CalcInfo参数,取而代之的是,用户必须自己负责传入所有的数据。获得的回报是,

1.支持任意多的参数。

2.支持引用参数,也就是说,可以改变参数的值并返回给公式系统。

3.更灵活的参数传递。例如,可以根据需要传入地址,也可以传入值。

4.支持逐根的计算。每次只计算一根的值并返回单值。自由DLL只能在逐根模式下运行。

与传统接口DLL一样,自由接口DLL也必须放置在FmlDLL目录下。

[编辑] 自由DLL声明

为了让公式系统知道DLL的参数格式,调用前需要使用extern语句进行声明

extern 返回值类型 函数名(参数类型1, 参数类型2...);

参数的个数没有限制

[编辑] 参数类型

传入DLL的参数有类型限制,目前支持的C类型包括 float, double, int,BOOL, LONG, DWORD, float*, LPCWSTR等 不支持double *

[编辑] 返回值类型

函数可以返回 int, float, char, bool 等类型,或无返回。

若要在DLL内修改一条序列或者修改整个数组,可以通过传序列参数或数组参数的方法,在DLL里面赋值。DLL 里面都使用 float * 来接收参数。

[编辑] 自由DLL接口的调用

  • 声明过的函数,可以通过函数名直接调用,无需通过"DLLName@FuncName"格式或RefDLL使用。
  • 使用时必须将DLL放在软件安装目录下的FmlDll子目录下
  • 字符串使用单引号,双引号是另一种格式的引用,不能混用
  • DLL 需要在 .def 文件中 EXPORTS 项添加要调用的函数,否则有可能找不到函数
  • DLL名称和函数名都是大小写敏感的,代码声明和公式调用时需要匹配。

[编辑] DLL公式参数传递例子

  • 无参数时的例子:
// 公式里面的声明与调用
extern 'FoxFunc.dll' void test1();
test1();
// c++ .h 函数声明
__declspec(dllexport) void __stdcall test1();
// c++ .cpp 函数实现
extern "C" __declspec(dllexport) void __stdcall test1()
{

}
  • 传入单值的公式例子:
// 公式里面的声明与调用
extern 'FoxFunc.dll' void test2(int, float, bool, char);
Variables:
 NumericSimple var1,
 NumericSeries var2,
 NumericArray var3[10];

var1 := 1;
var2[0] := 2;
var3[0] := 65;

test2(1, 2, 1, 65);
test2(var1, var2[0], var1, var3[0]);
// c++ .h 函数声明
__declspec(dllexport) void __stdcall test2(int i, float f, bool b, char c);
// c++ .cpp 函数实现
extern "C" __declspec(dllexport) void __stdcall test2(int i, float f, bool b, char c)
{

}
  • 传入字符串的公式例子

公式里面的字符串变量是宽字符,编码是GB2312,DLL里面可以使用MultiByteToWideChar/MultiByteToWideChar进行字符转换

// 公式里面的声明与调用
extern 'FoxFunc.dll' void test3(LPCWSTR);
Variables:
  String var1;

var1 := 'test string1';

test3(NumToStr(close,3));
test3('aaa');
test3(var1);
// c++ .h 函数声明
__declspec(dllexport) void __stdcall test3(const wchar_t* p);
// c++ .cpp 函数实现
#include <string>

// 窄字符转宽字符
static std::wstring a2w(LPCSTR lpa)
{
	size_t l = MultiByteToWideChar(936, 0, lpa, -1, NULL, 0);

	std::wstring s;
	s.resize(l - 1);

	MultiByteToWideChar(936, 0, lpa, (int)strlen(lpa), (LPWSTR)s.c_str(), (int)s.size());

	return s;
}

// 宽字符转窄字符
static std::string w2a(LPCWSTR lpw)
{
	size_t l = WideCharToMultiByte(936, 0, lpw, -1, NULL, 0, NULL, NULL);

	std::string s;
	s.resize(l - 1);

	WideCharToMultiByte(936, 0, lpw, (int)wcslen(lpw), (LPSTR)s.c_str(), (int)s.size(), NULL, NULL);

	return s;
}

extern "C" __declspec(dllexport) void __stdcall test3(const wchar_t *p)
{
	std::wstring sw = p; 
	std::string sa = w2a(sw.c_str());
}
  • 传入序列的公式例子
// 公式声明与调用
extern 'FoxFunc.dll' void test4(NumericSeries, int, NumericArray, int);
Variables:
  NumericSeries var1,
  NumericArray var2[5];

var1 := close;
var2[1] := 1;
var2[2] := 2;
var2[3] := 3;
var2[4] := 4;
var2[5] := 5;

//var2 数组实际大小是5+1
test4(var1, BarsCount(close), var2, 6);
// c++ .h 声明
__declspec(dllexport) void __stdcall test4(float *pf1, int n1, float *pf2, int n2);
// c++ .cpp 函数实现
extern "C" __declspec(dllexport) void __stdcall test4(float *pf1, int n1, float *pf2, int n2)
{
	
}
  • 传入引用的公式例子
// 公式声明与调用
extern 'FoxFunc.dll' void test5(NumericRef);
Variables:
  NumericSimple var1;

var1 := 3;
test5(var1);
comment(var1);
// c++ .h 声明
__declspec(dllexport) void __stdcall test5(float *pf);
// c++ .cpp 实现
extern "C" __declspec(dllexport) void __stdcall test5(float *pf)
{
	*pf = 9;
}

[编辑] DLL的返回值

新格式DLL可返回单值,序列和数组。单值类型大致分为两种:数值类型和字符串类型,可以通过函数返回值直接返回。

  • 返回单值类型的c语言例子
// 公式声明与调用例子
extern 'FoxFunc.dll' int test6();
extern 'FoxFunc.dll' float test7();
extern 'FoxFunc.dll' LPCWSTR test8();

k1: test6(),OwnerScale;
k2: test7(),OwnerScale;
comment(test8);
// c++ .h 声明
__declspec(dllexport) int __stdcall test6();
__declspec(dllexport) float __stdcall test7();
__declspec(dllexport) wchar_t* __stdcall test8();
// c++ .cpp 实现
extern "C" __declspec(dllexport) int __stdcall test6()
{
	return 1;
}
extern "C" __declspec(dllexport) float __stdcall test7()
{
	return 0.5f;
}
extern "C" __declspec(dllexport) wchar_t* __stdcall test8()
{
	return L"test string 1";
}
  • 返回序列或数组

若要返回序列或数组,则把需要返回的序列赋值目标当作参数传递给DLL,在DLL内部直接修改已达到赋值。 注意逐根运行模式下,每一根K线都会调用dll,所以通常每次调用只需要赋值比上一根K线新增加的类型, 例如计算收盘价均值时,每次在BarPos位置填入当根K线的均值即可。由此可见,这种应用下通常需要把 BarPos(当前是第几根K线)作为参数传入Dll中。返回序列和数组可以参考上面传入序列的公式例子。

下面一个例子是在图形上输出当前是第几根K线的例子:

// 公式中的声明与调用
extern 'FoxFunc.dll' void test9(NumericSeries, int);

MyIndi:0;
test9(MyIndi, BarPos);
// c++ .h 声明文件
__declspec(dllexport) void __stdcall test9(float *pf, int n);
// c+= .cpp 实现
extern "C" __declspec(dllexport) void __stdcall test9(float *pf, int n)
{
	// 每根都会调用一次,所以每次只需赋值当前根
	pf[n - 1] = n;
}

[编辑] DLL的参数类型参考

- 类型 公式 DLL
数值 NumericSimple float, int, char, bool
字符串 LPCWSTR wchar_t*
数值引用 NumericRef float*
序列 NumericSeries float*
数组 NumericArray float*

[编辑] 无效数据表示

公式系统使用std的无效浮点数表示无效值,浮点无效值的一个重要特征是 f != f 为真,可作为判断依据, 其它运算皆输出无效值,其它比较皆输出假。当序列作为指标输出时,开始和结束两段的无效值自动截除,不作为指标输出。 例如要输出5日均线,序列的前4个值可填充无效值(填充0时会使指标线变形)

#include <limits>
#define INVALID_NUMERIC std::numeric_limits<float>::quiet_NaN()

无效值在公式里可以用 Invalid 关键字指定,例如

k1:Invalid;

则k1指标线不会输出


[编辑] 编写调用公式

[编辑] 开发DLL的详细例子

[编辑] 实例下载


[编辑] 调用Windows系统DLL

调用win32提供的系统DLL,与调用自己编写的DLL是一样的。

只要知道windows系统函数所属的DLL和函数名,参数等信息就可以直接使用,例如

extern 'kernel32.dll' int GetTickCount();
tickcount:GetTickCount();

[编辑] 调用.Net DLL

跟一般DLL不同的是,.net DLL在声明时,除了函数名信息,还要提供命名空间、类名的信息,例如:

 extern 'RzRq.dll' void RzRq.Grabber.GetFinance( LPCWSTR stockCode);

这里的RzRq就是命名空间,而Grabber则是类的名称,GetFinance是函数名

另外,在.net DLL中,除了可以用参数来传递数据,还可以使用GetVarData, SetVarData这两个函数在.net和公式引擎间交换数据。

.net DLL开发过程如下:
1. visual studio 新建一个类库 工程,用C#或者VB.net,Managed C++都可以,这里以C#为例
Dotnet1.png

2.添加 金魔方 .net api dll 引用,位置位于金魔方安装目录下 DotNetBridge.dll
Dotnet2.png
Dotnet3.png

3.新建或者修改 从 Formula 继承 一个类,Formula 是金魔方.net api的类,从此类继承可以访问 GetVarData等接口函数,需要用 fox.api 命名空间
Dotnet4.png

个人工具
名字空间

变换
操作
导航
工具箱