|
本帖最后由 静夜有思 于 2022-7-24 23:03 编辑
{易得程序化 DLL头文件 Pascal版 静夜思:2022.7 QQ:7998329}
unit YdFunc;
interface
uses windows ,math;
{$A1+} // #pragma pack(1)
{$POINTERMATH ON} //指针可以作为数组使用 delphi2009 last
const
MAX_NUM_DLLPARAM = 32;
YDDLL_HEADTAG = $f32cea12;
type
time_ms = longword;
// K线历史数据
TSTKHISTORY = packed record
m_time: time_ms; // 时间 UCT 1970.1.1开始秒数
m_fOpen: single; // 开盘价
m_fHigh: single; // 最高价
m_fLow: single; // 最低价
m_fClose: single; // 收盘价
m_fVolume: single; // 成交量
m_fAmount: single; // 成交额
m_nBelongDate: integer; // 所属交易日 YYYYMMDD
case Integer of
0: (m_fHold:single; //持仓量,仅期货有效
mfSettlePrice:single); //结算价,仅期货有效
1 m_wAdvance:word; // 涨数,仅大盘有效()
m_wDecline:word; // 跌数,仅大盘有效
m_wEqual:word); // 平盘数,仅大盘有效
2 m_fFixPriceVol:single; // 盘后固定价格成交量,仅科创板有效
m_fFixPriceAmount:single)// 盘后固定价格成交额,仅科创板有效
end;
PSTKHISTORY = ^TSTKHISTORY ;
// 分笔成交数据
TSTKTICK = packed record
m_time: time_ms; // 时间 UCT 1970.1.1开始秒数
m_fPrice: single; // 价格
m_fVolume: single; // 成交量
m_fAmount: single; // 成交额
m_fBuyPrice: single; // 买价
m_fSellPrice: single; // 卖价
m_wMsTime: WORD; // 毫秒
m_wAttrib: WORD; // 保留
m_nBelongDate: integer; // 所属交易日 YYYYMMDD
case integer of
0 m_fHold:single); // 持仓量,仅期货有效
1 m_fStroke:single); // 成交笔数,仅股票有效
end;
PSTKTICK = ^TSTKTICK;
// 基础数据类型枚举
{$Z2}
TENUM_DATATYPE=( SECOND_DATA= 0 ,// 秒线
SEC5_DATA,// 5秒线
TICK_DATA,// 分笔成交
MIN_DATA, // 分时
MIN1_DATA,// 1分钟
MIN5_DATA,// 5分钟
MIN15_DATA,// 15分钟
MIN30_DATA,// 30分钟
MIN60_DATA,// 60分钟
DAY_DATA,// 日线
WEEK_DATA,// 周线
MONTH_DATA,// 周线
SEASON_DATA,// 季线
HALFYEAR_DATA,// 半年线
YEAR_DATA// 年线
);
// 数据类型
TDATA_TYPE = packed record
m_baseType :TENUM_DATATYPE; // 基础数据类型
m_nUnit :WORD ; // 倍数 如:m_baseType=DAY_DATA, m_nUnit=2, 表示2日线; 如:m_baseType=DAY_DATA, m_nUnit<=1, 表示日线
end;
// 公式参数数据
TYDPARAMDATA = packed record
// 入参的数据可以是单值数据,也可以是序列数据,二者选其一
// 也可以通过m_pszText传入字符串
m_dSingleData: double ; // 单值数据
m_pdData : pdouble; // 序列数据(对于单值数据无效,为0) 指针类型: 32位占4字节 64位占8字节
m_nSize: integer; // 序列数据大小(对于单值数据无效,为0)
m_nBegin: integer; // 对于序列数据有效起始位置(对于单值数据无效,为0)
m_nEnd: integer; // 对于序列数据有效结束位置(对于单值数据无效,为0)
m_pszText: pchar; // 也可以传入字符串
function GetData(nN:integer):double; // 获取数据
function IS_VALID_DOUBLE(nN: integer): Boolean; // 是否有效数据
end;
PYDPARAMDATA = ^TYDPARAMDATA ;
(*
32项财务数据
序号 名称
0 总股本
1 人均持股数
2 每股收益
3 每股收益1
4 每股净资产
5 每股净资产1
6 加权净资产收益率
7 营业收入
8 营业收入同比
9 营业利润
10 投资收益
11 利润总额
12 净利润
13 净利润同比
14 未分配利润
15 每股未分配利润
16 销售毛利率
17 总资产
18 流动资产
19 固定资产
20 无形资产
21 总负债
22 流动负债
23 长期负债
24 资产负债比率
25 股东权益
26 股东权益比
27 公积金
28 每股公积金
29 流通A股
30 流通B股
31 H股
*)
//
//
TDLLCALCINFO = packed record
m_dwHeadTag: DWORD; // 头标识 = YDDLL_HEADTAG
m_dwSize: DWORD; // 结构大小
m_dwVersion: DWORD; // 调用软件版本(V2.1.1.1 : 2111)
m_strStkLabel: array [0..Pred(16)] of AnsiChar; // 股票代码
m_bIndex: BOOL; // 指数
m_bRunByBar: BOOL; // 运算模式m_bRunByBar==TRUE表示逐K线运算模式,否则为序列运算模式
m_bOnlyCalcLastBar: BOOL; // 逐K线运算模式下,在盘中实时行情到来时是否只刷新最后一根K线
m_bInstantCalc: BOOL; // 是否是盘中即时行情触发的计算
m_nCurBarPos: integer; // 当前计算位置, 此次调用只执行当前位置的计算
m_dataType: TDATA_TYPE; // 数据类型
m_nPower: integer; // 除权: 0:不除权 1:向前除权 2:向后除权
m_nNumData: integer; // 数据数量(m_pStkHistData或m_pStkTick的数据大小)
m_pStkHistData: pSTKHISTORY; // 历史K线数据, 当m_dataType==DATA_TYPE(TICK_DATA, 0)时为NULL
m_pStkTickData: pSTKTICK; // 分笔成交数据,仅当m_dataType==DATA_TYPE(TICK_DATA, 0)时有效,否则为NULL
m_nNumParam: integer; // 参数个数
m_pParam: array [0..Pred(MAX_NUM_DLLPARAM)] of pYDPARAMDATA; // 参数数据,最大32个参数
m_pResultBuf: pdouble; // 结果缓冲区,也是返回值,大小等于m_nNumData
m_pszResultText: pchar; // 结果也可以返回一个字符串
m_pdFinData: pdouble; // 32项财务数据
end;
//
////////////////////////////////////////////////////////////////////////////////
//(*
//函数输出
//
//__declspec(dllexport) int XXXXXXXXX(CALCINFO* pData);
//
//1. 如果易得软件是64位,DLL也必须编译成64位;如果易得软件是32位,DLL也必须编译成32位。
//2. 函数名称需全部大写.
//3. 对于C++程序需包括在 extern "C" { } 括号中.
//4. 函数入参可以有32个,每个入参都可以是单值数值、或者序列数据、或者字符串。
//5. 函数数据计算结果由pData->m_pResultBuf带回,它是一个序列值。 也可以通过pData->m_pszResultText返回一个字符串。
//6. 编译好的dll必须拷贝到易得客户端的FmlDll目录下.
//7. 建议使用Visual C++编程,当前项目编译环境:Visual studio 2010
//8. 开发者应该了解易得公式序列计算模式和逐K线运算模式的机理。
// 假设一个公式有A、B共2个语句,运算的数据有100根K线。
// 序列运算模式是:A语句先对应每根K线执行100次,全部K线执行完成后再B语句对应每根K线执行100次。 pData->m_nCurBarPos标识了当前执行的K线位置。
// 逐K线运算模式是:为每根K线同时执行AB所有语句;先在第一根K线上执行A语句和B语句,然后在第二根K线上执行A语句和B语句,直到第100根K线。pData->m_nCurBarPos标识了当前执行的K线位置。
//*)
//
//// 示例函数
//__declspec(dllexport);
//
//function TESTCLOSEMA(pData: pDLLCALCINFO): integer; stdcall; external libusb.dll name 'TESTCLOSEMA';
//__declspec(dllexport);
//
//function TESTMA(pData: pDLLCALCINFO): integer; stdcall; external libusb.dll name 'TESTMA';
//__declspec(dllexport);
//
//function DEMO(pData: pDLLCALCINFO): integer; stdcall; external libusb.dll name 'DEMO';
//
//
//{$ifdef __cplusplus}
//end;
//{$endif}
////__cplusplus
implementation
function TYDPARAMDATA.GetData(nN:integer):double; // 获取数据
var
arr:array of double;
begin
if (Self.m_pdData <> nil) then
begin
result:=self.m_pdData[nN];
end;
result:=self.m_dSingleData;
end;
function TYDPARAMDATA.IS_VALID_DOUBLE(nN: integer): Boolean; // 是否有效数据
begin
if (self.m_pdData<>nil) then
begin
Result:=((nN>=self.m_nBegin) and (nN<=m_nEnd) and (nN>=0) and IsNan(self.m_pdData[nN]));
end;
result:=isNan(m_dSingleData);
end;
end.
|
|