Choice数据量化接口 Windows平台C#库、文档及实例
using System;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using EmQuantApiCSharp_x64;
namespace EmQuantApiCSharpSample
{
/*
* 编码注意事项:
* 1、保持lib文件夹中文件的版本与EmQuantApiCSharp(_x64).dll文件的一致性及完整性;
* 2、项目生成的平台类型必须和被引用的工程文件保持一致;
* 3、在回调函数的内部编码及使用时,要注意参数的声明、内部解析过程的锁定等;
* 4、多个实时行情订阅或跳价订阅时,应保存每个订阅的序列号,便于取消订阅。
*/
class Program
{
static bool isUseOld = true;
static Dictionary<string, string> dicCommand = new Dictionary<string, string>();
static Structs.ILogCallback callbackLog;
static Structs.IDataCallback callbackMain;
static Structs.IDataCallback callbackCsq;
static Structs.IDataCallback callbackCst;
static Structs.IDataCallback callbackCnq;
static Structs.IDataCallback callbackChq;
static void Main(string[] args)
{
CreateCommand();
callbackLog = CallbackStart;
callbackMain = CallbackMain;
try
{
string str = Console.ReadLine().ToUpper();
while (str != "EXIT")
{
if (str == "START") EmStart();
if (str == "STOP") EmStop();
if (str == "MA") ManualActivate();
if (str == "CSD") if (isUseOld) EmCsd(); else EmCsd2();
if (str == "CSS") if (isUseOld) EmCss(); else EmCss2();
if (str == "CSES") if (isUseOld) EmCses(); else EmCses2();
if (str == "TD") if (isUseOld) EmTreadedate(); else EmTreadedate2();
if (str == "GD") if (isUseOld) EmGetdate(); else EmGetdate2();
if (str == "SEC") if (isUseOld) EmSector(); else EmSector2();
if (str == "CSQ") if (isUseOld) EmCsq(); else EmCsq2();
if (str == "CHQ") if (isUseOld) EmChq(); else EmChq2();
if (str == "CC") EmCsqcancel();
if (str == "CHQC") EmChqcancel();
if (str == "CMC") EmCmc();
if (str == "CSC") if (isUseOld) EmCsc(); else EmCsc2();
if (str == "CST") if (isUseOld) EmCst(); else EmCst2();
if (str == "CTR") if (isUseOld) EmCtr(); else EmCtr2();
if (str == "CFC") if (isUseOld) EmCfc(); else EmCfc2();
if (str == "CEC") if (isUseOld) EmCec(); else EmCec2();
if (str == "CT") if (isUseOld) EmCsqsnapshot(); else EmCsqsnapshot2();
if (str == "CHQS") if (isUseOld) EmChqsnapshot(); else EmChqsnapshot2();
if (str == "CPS") if (isUseOld) EmCps(); else EmCps2();
if (str == "PQ") EmPQuery();
if (str == "PO") EmPOrder();
if (str == "EDB") EmEdb();
if (str == "EDBQ") EmEdbQuery();
if (str == "PC") EmPCreate();
if (str == "PD") EmPDelete();
if (str == "PR1") EmPReport(1);
if (str == "PR2") EmPReport(2);
if (str == "TDN") EmTradeNum();
if (str == "CFN") EmCfn();
if (str == "CFNQ") EmCfnQuery();
if (str == "CNQ") EmCnq();
if (str == "CNQC") EmCnqCancel();
if (str == "PCT") EmPCTransfer();
Console.WriteLine("\r\n请输入命令:");
str = Console.ReadLine().ToUpper();
}
}
catch (Exception ex)
{
WriteToConsole(ex.ToString());
}
}
static void CreateCommand()
{
if (dicCommand == null)
dicCommand = new Dictionary<string, string>();
dicCommand["START"] = "登录";
dicCommand["STOP"] = "登出";
dicCommand["MA"] = "激活账户";
dicCommand["CSD"] = "获取序列数据";
dicCommand["CSS"] = "获取截面数据";
dicCommand["CSES"] = "获取板块截面数据";
dicCommand["TD"] = "获取交易日数据";
dicCommand["GD"] = "推算交易日";
dicCommand["SEC"] = "获取板块数据";
dicCommand["CSQ"] = "订阅实时行情数据";
dicCommand["CHQ"] = "专项订阅(异步) ";
dicCommand["CC"] = "取消订阅";
dicCommand["CHQC"] = "取消专项订阅";
dicCommand["CMC"] = "获取历史分钟K线数据";
dicCommand["CST"] = "获取跳价数据";
dicCommand["CTR"] = "获取专题报表数据";
dicCommand["CT"] = "获取行情快照数据";
dicCommand["CHQS"] = "专项快照(同步请求)";
dicCommand["CPS"] = "获取条件选股数据";
dicCommand["PQ"] = "获取组合账户关系数据";
dicCommand["PO"] = "批量下单";
dicCommand["EDB"] = "宏观指标服务";
dicCommand["EDBQ"] = "宏观指标ID详情查询";
dicCommand["PC"] = "新建组合";
dicCommand["PD"] = "删除组合";
dicCommand["PR1"] = "组合报表查询1";
dicCommand["PR2"] = "组合报表查询2";
dicCommand["TDN"] = "获取交易日总量";
dicCommand["CFN"] = "资讯数据查询";
dicCommand["CFNQ"] = "资讯板块查询";
dicCommand["CNQ"] = "资讯订阅";
dicCommand["CNQC"] = "取消资讯订阅";
dicCommand["PCT"] = "组合资金调配";
if (dicCommand != null)
{
foreach (KeyValuePair<string, string> cmd in dicCommand)
{
Console.WriteLine("\t" cmd.Key "\t" cmd.Value);
}
}
Console.WriteLine("\r\n请输入命令:");
}
static void WriteToConsole(string strLog)
{
Console.WriteLine(strLog);
}
static void WriteToConsole(Exception ex)
{
Console.WriteLine(ex.ToString());
}
static void EmStart()
{
WriteToConsole("登录函数:正在登录中......");
// 1.设置主回调函数以及配置文件路径:
// 对于第二个参数,若不设定,将使用默认路径(C#接口文件所在目录的lib文件夹);若设定,其值可为相对路径,也可为绝对路径;(Windows服务类型应用尽量使用绝对路径)
OptionEnums.EQErr code = EmQuantAPI.setcallback(callbackMain, "lib"); // 等同于 OptionEnums.EQErr code = EmQuantAPI.setcallback(callbackMain);
WriteToConsole("设置主回调函数:" code);
// 2.登陆
code = EmQuantAPI.start("TestLatency =" (int)OptionEnums.TestLatency.YES ",ForceLogin=" (int)OptionEnums.ForceLogin.YES, callbackLog);
WriteToConsole("登录函数:" code);
if (code == OptionEnums.EQErr.EQERR_SECUSS)
{
callbackCsq = CallbackCsq;
callbackCst = CallbackCst;
callbackCnq = CallbackCnq;
callbackChq = CallbackChq;
}
WriteToConsole("\n============================================================\n");
}
static void EmStop()
{
OptionEnums.EQErr code = EmQuantAPI.stop();
WriteToConsole("登出函数:" code);
WriteToConsole("\n============================================================\n");
}
static void EmCsqcancel()
{
if (csqSerialID != -1)
{
WriteToConsole("CSQ取消实时行情:" csqSerialID);
OptionEnums.EQErr code = EmQuantAPI.csqcancel(csqSerialID);
WriteToConsole("CSQ取消结果:" code);
csqSerialID = -1;
}
}
static void EmChqcancel()
{
if (chqSerialID != -1)
{
WriteToConsole("CHQ取消实时行情:" chqSerialID);
OptionEnums.EQErr code = EmQuantAPI.chqcancel(chqSerialID);
WriteToConsole("CHQ取消结果:" code);
chqSerialID = -1;
}
}
static void CallbackStart(string strLog)
{
Console.WriteLine(strLog);
}
/// <summary>
/// 主回调函数
/// </summary>
/// <param name="pMsg"></param>
/// <param name="pfnCallback"></param>
/// <returns></returns>
static void CallbackMain(IntPtr pMsg, IntPtr pfnCallback)
{
object objData = Marshal.PtrToStructure(pMsg, typeof(Structs.EQMSG));
Structs.EQMSG msgData = (Structs.EQMSG)objData;
// 检测到登陆掉线或者登录被踢处理逻辑
if (msgData.MsgType == OptionEnums.EQMsgType.Type_Err)
{
if (msgData.Err == OptionEnums.EQErr.EQERR_LOGIN_DISCONNECT || msgData.Err == OptionEnums.EQErr.EQERR_LOGIN_COUNT_LIMIT)
{
WriteToConsole(string.Format("主回调函数:Your account is disconnect。Error={0} {1}", msgData.Err, EmQuantAPI.geterrstring(msgData.Err)));
// 您可以在此:1、通知主线程账号掉线让主线程重新登陆和后续处理事宜,2、在此处重新登陆也可。
// 推荐第一种。
// ...do something
}
// 行情登录验证失败(每次连接行情服务器时需要登录验证),或者行情浏览验证失败时,动态库内部会取消所有订阅,用户需根据具体情况处理
if (msgData.Err == OptionEnums.EQErr.EQERR_QUOTE_LOGIN_FAIL || msgData.Err == OptionEnums.EQErr.EQERR_QUOTE_FLOW_FAIL)
{
WriteToConsole(string.Format("主回调函数:Your all csq subscribe have stopped。Error={0} {1}", msgData.Err, EmQuantAPI.geterrstring(msgData.Err)));
}
// 行情服务器断线自动重连,连续6次失败(1分钟左右)不过重连尝试还会继续进行直到成功为止,遇到这种情况需要确认两边的网络状况
else if (msgData.Err == OptionEnums.EQErr.EQERR_QUOTE_RECONNECT_FAIL)
{
WriteToConsole(string.Format("主回调函数:Error={0} {1}", msgData.Err, EmQuantAPI.geterrstring(msgData.Err)));
}
//行情订阅遇到一些错误(这些错误会导致重连,错误原因通过日志输出,统一转换成EQERR_QUOTE_RECONNECT在这里通知),正自动重连并重新订阅,可以做个监控
else if (msgData.Err == OptionEnums.EQErr.EQERR_QUOTE_RECONNECT)
{
WriteToConsole(string.Format("主回调函数:Error={0} {1}", msgData.Err, EmQuantAPI.geterrstring(msgData.Err)));
}
//资讯服务器断线自动重连连续6次失败(1分钟左右)不过重连尝试还会继续进行直到成功为止,遇到这种情况需要确认两边的网络状况
else if (msgData.Err == OptionEnums.EQErr.EQERR_INFO_RECONNECT_FAIL)
{
WriteToConsole(string.Format("主回调函数:Error={0} {1}", msgData.Err, EmQuantAPI.geterrstring(msgData.Err)));
}
//资讯订阅遇到一些错误(这些错误会导致重连,错误原因通过日志输出,统一转换成EQERR_QUOTE_RECONNECT在这里通知),正自动重连并重新订阅,可以做个监控
else if (msgData.Err == OptionEnums.EQErr.EQERR_INFO_RECONNECT)
{
WriteToConsole(string.Format("主回调函数:Error={0} {1}", msgData.Err, EmQuantAPI.geterrstring(msgData.Err)));
}
//资讯订阅登录验证失败(每次连接资讯服务器时需要登录验证)或者资讯流量验证失败时,动态库内部会取消所有订阅,用户需根据具体情况处理
else if (msgData.Err == OptionEnums.EQErr.EQERR_INFOSUB_LOGIN_FAIL || msgData.Err == OptionEnums.EQErr.EQERR_INFO_FLOW_FAIL)
{
WriteToConsole(string.Format("Your all cnq subscribe have stopped.Error={0} {1}", msgData.Err, EmQuantAPI.geterrstring(msgData.Err)));
}
}
else
{
WriteToConsole("主回调函数:" EmQuantAPI.geterrstring(msgData.Err));
}
}
......................................
评论