// AutoTrader.cpp : 单合约版本,输入经纪公司代码,实盘帐号,密码即可下单。
//自动保存订阅合约TICK数据到\Bin\TickData下,文件名合约名称_日期.txt
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <time.h>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#include ".\ThostTraderApi\ThostFtdcTraderApi.h"
#include ".\ThostTraderApi\ThostFtdcMdApi.h"
#include "TraderSpi.h"
#include "MdSpi.h"
#include "Common.h"
#include "DataSniffer.h"
#include "MyTrader.h"
#include "IniFile.h"
#pragma warning(disable : 4996)
// UserApi对象
CThostFtdcTraderApi *pUserApi;
// MdApi对象
CThostFtdcMdApi *pMdApi;
// 配置参数
char FRONT_ADDR_TD[] = "tcp://180.168.146.187:10101"; // 前置地址1交易:实盘
char FRONT_ADDR_MD[] = "tcp://180.168.146.187:10111"; // 前置地址1交易:盘后
TThostFtdcBrokerIDType BROKER_ID = "9999"; // 实盘:经纪公司代码
TThostFtdcInvestorIDType INVESTOR_ID = "000000"; // 实盘:投资者代码
TThostFtdcPasswordType PASSWORD = "000000"; // 实盘:用户密码
TThostFtdcAuthCodeType AuthCode = "000000"; //期货公司提供的认证码,SINNOW为 0000000000000000
TThostFtdcAppIDType AppID = "000000"; //appid
TThostFtdcInstrumentIDType INSTRUMENT_ID = "rb1911"; // 交易合约代码,必须和CSV数据文件中合约字段代码一致
TThostFtdcDirectionType DIRECTION; // 交易买卖方向
TThostFtdcOffsetFlagType MARKETState; // 开平仓
TThostFtdcPriceType LIMIT_PRICE; // 交易价格
//char *ppInstrumentID[] = {"IF1910", "rb1910","ag1910", "ru1910", "cu1910", "j1910", "SR1910", "m1910", "y1910", "p1910"}; // 行情订阅列表
//int iInstrumentID = 10; // 行情订阅数量
char *ppInstrumentID[] = { "rb1911"}; // 行情订阅列表,交易合约代码,必须和CSV数据文件中合约字段代码一致,目前只支持1个合约同时回测,不支持订阅多个合约回测
int iInstrumentID = 1; // 行情订阅数量
bool ReceiveTick = false;
// 请求编号
int iRequestID = 0;
// 交易时间
bool JustRun = false; //正在启动标志
TThostFtdcDateExprType TradingDay;
// User行情数据
extern char *InstrumentID_name; //
extern string Q_BarTime_s; //时间字符串
extern int Q_BarTime_1; //时间采用秒计
extern double Q_BarTime_2; //时间格式0.145100
extern double Q_UpperLimit; //
extern double Q_LowerLimit; //
extern double NewPrice; //
extern int FirstVolume; //前一次成交量数据
extern double Mn_open[3]; //
extern double Mn_high[3]; //
extern double Mn_low[3]; //
extern double Mn_close[3]; //
extern double BuyPrice; //开仓价
extern double SellPrice; //开仓价
extern int BNum; //开仓次数
extern int SNum; //开仓次数
extern bool BuySignal; //
extern bool SellSignal; //
extern double BSVolume; //开仓量
extern int TickABS;
extern double TickAPrice[4]; //
extern int TickBNum;
extern double TickBPrice[4]; //
extern char LogFilePaths[80]; //
// 会话参数
extern TThostFtdcFrontIDType FRONT_ID; //前置编号
extern TThostFtdcSessionIDType SESSION_ID; //会话编号
extern TThostFtdcOrderRefType ORDER_REF; //报单引用
void main(void)
{
CIniFile cfgfile(_T("./settini.ini"));
//char brokeidchar[31] = { 0 };
//char investorchar[31] = { 0 };
//char passwordchar[31] = { 0 };
//char appidchar[31] = { 0 };
//char tdserverchar[31] = { 0 };
GetPrivateProfileStringA("setting", "Brokeid", "9999", BROKER_ID, sizeof(BROKER_ID), ("./setting.ini"));
GetPrivateProfileStringA("setting", "Investor", "", INVESTOR_ID, sizeof(INVESTOR_ID), ("./setting.ini"));
GetPrivateProfileStringA("setting", "Password", "", PASSWORD, sizeof(PASSWORD), ("./setting.ini"));
GetPrivateProfileStringA("setting", "TDServer", "", FRONT_ADDR_TD, sizeof(FRONT_ADDR_TD), ("./setting.ini"));
GetPrivateProfileStringA("setting", "MDServer", "", FRONT_ADDR_MD, sizeof(FRONT_ADDR_MD), ("./setting.ini"));
GetPrivateProfileStringA("setting", "AuthCode", "0000000000000000", AuthCode, sizeof(AuthCode), ("./setting.ini"));
GetPrivateProfileStringA("setting", "AppID", "20", AppID, sizeof(AppID), ("./setting.ini"));
GetPrivateProfileStringA("setting", "InstrumentID", "rb1910", INSTRUMENT_ID, sizeof(INSTRUMENT_ID), ("./setting.ini"));
printf("Brokeid:%s Investor:%s AuthCode:%s AppID:%s\n", BROKER_ID, INVESTOR_ID, AuthCode, AppID);
Sleep(5000);
//非穿透式(老API)
void Erasefiles();
void Sniffer();
void Trading();
bool ReadConfiguration(char *filepaths);
void WriteConfiguration(char *filepaths);
Erasefiles();
Sleep(2000);
cerr << "--->>> " << "Welcom MyAutoTrader System!" << endl;
cerr << "--->>> " << "Version 1.0.0!" << endl;
// 初始化MdApi
pMdApi = CThostFtdcMdApi::CreateFtdcMdApi();
CThostFtdcMdSpi* pMdSpi = new CMdSpi();
pMdApi->RegisterSpi(pMdSpi); // 注册事件类
pMdApi->RegisterFront(FRONT_ADDR_MD); // connect 优先行情地址
//cout << pMdApi->GetApiVersion() << endl;
pMdApi->Init();
cout << "--->>> " << "Initialing MdApi" << endl;
// 初始化UserApi
pUserApi = CThostFtdcTraderApi::CreateFtdcTraderApi();
CTraderSpi* pUserSpi = new CTraderSpi();
pUserApi->RegisterSpi((CThostFtdcTraderSpi*)pUserSpi); // 注册事件类
pUserApi->SubscribePublicTopic(THOST_TERT_RESTART); // 注册公有流
pUserApi->SubscribePrivateTopic(THOST_TERT_RESTART); // 注册私有流
pUserApi->RegisterFront(FRONT_ADDR_TD); // connect
pUserApi->Init();
//cout << pUserApi->GetApiVersion() << endl;
cout << "--->>> " << "Initialing TradeApi" << endl;
Sleep(6000);
ReadConfiguration("./AutoTrader.dat"); //自定义数据,如持仓数据等均可
cout << "--->>> " << "初始化完成!" << endl;
while(1)
{
//指标计算,下面只是个简单例子
//可自建函数,进行复杂处理 见DataSniffer.h
Sleep(5000);
}
}
//MdSpi.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <time.h>
using namespace std;
#include "TraderSpi.h"
#include "MdSpi.h"
#pragma warning(disable : 4996)
// USER_API参数
extern CThostFtdcMdApi* pMdApi;
// 配置参数
extern char FRONT_ADDR[];
extern TThostFtdcBrokerIDType BROKER_ID;
extern TThostFtdcInvestorIDType INVESTOR_ID;
extern TThostFtdcPasswordType PASSWORD;
extern char* ppInstrumentID[];
extern int iInstrumentID;
extern TThostFtdcInstrumentIDType INSTRUMENT_ID;
// 请求编号
extern int iRequestID;
// User行情数据
extern TThostFtdcDateExprType TradingDay;
extern bool ReceiveTick;
bool CloseAll= false; //收盘标志
char *InstrumentID_name; //
double Q_Dayopen=0; //
double Q_UpperLimit = 0; //
double Q_LowerLimit = 0; //
string Q_BarTime_s; //
int Q_BarTime_1; //
double Q_BarTime_2; //
int FirstVolume; //前一次成交量数据
int BNum = 0; //开仓次数
int SNum = 0; //开仓次数
bool MnKlinesig=false; //
double Mn_open[3] = {0,0,0}; //
double Mn_high[3] = {0,0,0}; //
double Mn_low[3] = {0,0,0}; //
double Mn_close[3] = {0,0,0}; //
double NewPrice = 0; //
double Mn_bbreak = 0; //
double Mn_sbreak = 0; //
double Mn_UpperBand = 100000; //
double Mn_LowerBand = 0; //
double M4 = 1.0; //
double M5 = 1.0; //
double BuyPrice = 0; //开仓价
double SellPrice = 0; //开仓价
double BuyPrice1 = 0; //买一价
double SellPrice1 = 0; //卖一价
double BuyVol1 = 0; //买一量
double SellVol1 = 0; //卖一量
double BuyVol10 = 0; //上一次买一量
double SellVol10 = 0; //上一次卖一量
double TodayVolume = 0; //成交量
double OpenInt = 0; //持仓量
double BuyStopline = 0; //开仓止损价
double SellStopline = 0; //开仓止损价
double BSVolume = 1; //开仓量
bool BuySignal = false; //
bool SellSignal = false; //
int TickABS = 0;
double TickAPrice[4]; //
int TickBNum = 0;
double TickBPrice[4]; //
char TickFileWritepaths[80]=""; //
char LogFilePaths[80]=""; //
void CMdSpi::OnRspError(CThostFtdcRspInfoField *pRspInfo,
int nRequestID, bool bIsLast)
{
cerr << "--->>> "<< __FUNCTION__ << endl;
IsErrorRspInfo(pRspInfo);
}
void CMdSpi::OnFrontDisconnected(int nReason)
{
cerr << "--->>> " << __FUNCTION__ << endl;
cerr << "--->>> Reason = " << nReason << endl;
}
void CMdSpi::OnHeartBeatWarning(int nTimeLapse)
{
cerr << "--->>> " << __FUNCTION__ << endl;
cerr << "--->>> nTimerLapse = " << nTimeLapse << endl;
}
void CMdSpi::OnFrontConnected()
{
cerr << "--->>> " << __FUNCTION__ << endl;
//cerr << "--->>> " << "CMdSpi::OnFrontConnected" << endl;
///用户登录请求
ReqUserLogin();
}
void CMdSpi::ReqUserLogin()
{
CThostFtdcReqUserLoginField req;
memset(&req, 0, sizeof(req));
strcpy(req.BrokerID, BROKER_ID);
strcpy(req.UserID, INVESTOR_ID);
strcpy(req.Password, PASSWORD);
int iResult = pMdApi->ReqUserLogin(&req, ++iRequestID);
cerr << "--->>> 发送行情用户登录请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
}
void CMdSpi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin,
CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
if (bIsLast && !IsErrorRspInfo(pRspInfo))
{
///获取当前交易日
cerr << "--->>> 获取当前交易日 = " << pMdApi->GetTradingDay() << endl;
// 请求订阅行情
SubscribeMarketData();
}
}
void CMdSpi::SubscribeMarketData()
{
int iResult0 = pMdApi->UnSubscribeMarketData(ppInstrumentID, iInstrumentID);
cerr << "--->>> 取消行情订阅请求: " << ((iResult0 == 0) ? "成功" : "失败") << endl;
Sleep(1000);
int iResult = pMdApi->SubscribeMarketData(ppInstrumentID, iInstrumentID);
cerr << "--->>> 发送行情订阅请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
//文件命名,“OrderInfo_date.txt”
char perf[100];
char tmp[20];
int tmp1 = 20140424;
strcpy(perf,"./AutoTrade/");
strcpy(perf,"TraderInfo_");
sprintf(tmp,"%d",tmp1);
strcat(perf,tmp);
strcat(perf,".txt");
cerr << "--->>> " << perf << endl;
//检查文件是否存在,是否需要新建文本文件
ifstream inf;
ofstream ouf;
inf.open(perf,ios::out);
}
void CMdSpi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> 成功订阅合约:" <<"_"<<pSpecificInstrument->InstrumentID<< endl;
}
void CMdSpi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
}
extern void Sniffer();//监听Tick数据已经指标计算 实盘用
extern void Trading(); //下单以及订单管理
bool openstate = false;
bool closestate = false;
extern void SendOrder(TThostFtdcInstrumentIDType FuturesId, int BuySell, int OpenClose);
extern bool tdloginstate;
int dealytick = 0;
void CMdSpi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData)
{
printf("%s %f\n",pDepthMarketData->InstrumentID, pDepthMarketData->LastPrice);
if (tdloginstate)
{
if (!openstate)
{
openstate = true;
NewPrice = pDepthMarketData->UpperLimitPrice;
SendOrder(INSTRUMENT_ID, 0, 0);
NewPrice = pDepthMarketData->LowerLimitPrice;
SendOrder(INSTRUMENT_ID, 0, 0);
}
if (openstate)
{
dealytick++;
}
if (!closestate && dealytick>=8)
{
closestate = true;
NewPrice = pDepthMarketData->LowerLimitPrice;
SendOrder(INSTRUMENT_ID, 1, 3);
}
}
}
bool CMdSpi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo)
{
// 如果ErrorID != 0, 说明收到了错误的响应
bool bResult = ((pRspInfo) && (pRspInfo->ErrorID != 0));
if (bResult)
cerr << "--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << endl;
return bResult;
}
//stdafx.cpp
// stdafx.cpp : 只包括标准包含文件的源文件
// testTraderApi.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用
//TraderSpi.cpp
#include <iostream>
#include <fstream>
#include <cstring>
#include <windows.h>
using namespace std;
#include ".\ThostTraderApi\ThostFtdcTraderApi.h"
#include ".\ThostTraderApi\ThostFtdcMdApi.h"
#include "TraderSpi.h"
#include "MdSpi.h"
#pragma warning(disable : 4996)
// USER_API参数
extern CThostFtdcTraderApi* pUserApi;
// 配置参数
extern char FRONT_ADDR[]; // 前置地址
extern char BROKER_ID[]; // 经纪公司代码
extern char INVESTOR_ID[]; // 投资者代码
extern char PASSWORD[]; // 用户密码
extern char AuthCode[] ; //期货公司提供的认证码,SINNOW为 0000000000000000
extern char AppID[] ; //appid
extern char* ppInstrumentID[];
extern int iInstrumentID;
extern char INSTRUMENT_ID[]; // 合约代码
extern TThostFtdcDirectionType DIRECTION; // 买卖方向
extern TThostFtdcOffsetFlagType MARKETState;//开平仓
extern TThostFtdcPriceType LIMIT_PRICE; // 价格
// 请求编号
extern int iRequestID;
extern TThostFtdcDateExprType TradingDay;
extern double Q_UpperLimit; //
extern double Q_LowerLimit; //
extern bool JustRun; //正在启动标志
// 会话参数
TThostFtdcFrontIDType FRONT_ID; //前置编号
TThostFtdcSessionIDType SESSION_ID; //会话编号
TThostFtdcOrderRefType ORDER_REF; //报单引用
void CTraderSpi::OnFrontConnected()
{
Sleep(3000);
cerr << "--->>> " << __FUNCTION__ << endl;
cerr << "--->>> " << "CTraderSpi::Delay 3s!" << endl;
///用户登录请求
CThostFtdcReqAuthenticateField req;
memset(&req, 0, sizeof(CThostFtdcReqAuthenticateField));
strcpy(req.BrokerID, BROKER_ID);
strcpy(req.UserID, INVESTOR_ID);
strcpy(req.AuthCode, AuthCode);
strcpy(req.AppID, AppID);
int iResult = pUserApi->ReqAuthenticate(&req, ++iRequestID);
}
void CTraderSpi::OnRspAuthenticate(CThostFtdcRspAuthenticateField *pRspAuthenticateField, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
ReqUserLogin();
}
void CTraderSpi::ReqUserLogin()
{
CThostFtdcReqUserLoginField req;
memset(&req, 0, sizeof(CThostFtdcReqUserLoginField));
strcpy(req.BrokerID, BROKER_ID);
strcpy(req.UserID, INVESTOR_ID);
strcpy(req.Password, PASSWORD);
int iResult = pUserApi->ReqUserLogin(&req, ++iRequestID);
cerr << "--->>> 发送交易用户登录请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
}
bool tdloginstate = false;
void CTraderSpi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin,
CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
if (bIsLast && !IsErrorRspInfo(pRspInfo))
{
// 保存会话参数
FRONT_ID = pRspUserLogin->FrontID;
SESSION_ID = pRspUserLogin->SessionID;
int iNextOrderRef = atoi(pRspUserLogin->MaxOrderRef);
iNextOrderRef++;
sprintf(ORDER_REF, "%d", iNextOrderRef);
//cerr << "--->>> 报单引用 = " << ORDER_REF << endl;
///获取当前交易日
strcpy(TradingDay,pUserApi->GetTradingDay());
cerr << "--->>> 获取当前交易日 = " << pUserApi->GetTradingDay() << endl;
///投资者结算结果确认
ReqSettlementInfoConfirm();
}
}
void CTraderSpi::ReqSettlementInfoConfirm()
{
CThostFtdcSettlementInfoConfirmField req;
memset(&req, 0, sizeof(CThostFtdcSettlementInfoConfirmField));
strcpy(req.BrokerID, BROKER_ID);
strcpy(req.InvestorID, INVESTOR_ID);
int iResult = pUserApi->ReqSettlementInfoConfirm(&req, ++iRequestID);
cerr << "--->>> 投资者结算结果确认: " << ((iResult == 0) ? "成功" : "失败") << endl;
}
void CTraderSpi::OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
if (bIsLast && !IsErrorRspInfo(pRspInfo))
{
///请求查询合约
ReqQryInstrument();
tdloginstate = true;
}
}
void CTraderSpi::ReqQryInstrument()
{
CThostFtdcQryInstrumentField req;
memset(&req, 0, sizeof(CThostFtdcQryInstrumentField));
strcpy(req.InstrumentID, INSTRUMENT_ID);
int iResult = pUserApi->ReqQryInstrument(&req, ++iRequestID);
cerr << "--->>> 请求查询合约: " << ((iResult == 0) ? "成功" : "失败") << endl;
}
void CTraderSpi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
if (bIsLast && !IsErrorRspInfo(pRspInfo))
{
///请求查询合约
ReqQryTradingAccount();
}
}
void CTraderSpi::ReqQryTradingAccount()
{
CThostFtdcQryTradingAccountField req;
memset(&req, 0, sizeof(CThostFtdcQryTradingAccountField));
strcpy(req.BrokerID, BROKER_ID);
strcpy(req.InvestorID, INVESTOR_ID);
int iResult = pUserApi->ReqQryTradingAccount(&req, ++iRequestID);
cerr << "--->>> 请求查询资金账户: " << ((iResult == 0) ? "成功" : "失败") << endl;
}
void CTraderSpi::OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
if (bIsLast && !IsErrorRspInfo(pRspInfo))
{
///请求查询投资者持仓
ReqQryInvestorPosition();
}
}
void CTraderSpi::ReqQryInvestorPosition()
{
CThostFtdcQryInvestorPositionField req;
memset(&req, 0, sizeof(CThostFtdcQryInvestorPositionField));
strcpy(req.BrokerID, BROKER_ID);
strcpy(req.InvestorID, INVESTOR_ID);
strcpy(req.InstrumentID, INSTRUMENT_ID);
int iResult = pUserApi->ReqQryInvestorPosition(&req, ++iRequestID);
cerr << "--->>> 请求查询投资者持仓: " << ((iResult == 0) ? "成功" : "失败") << endl;
}
void CTraderSpi::OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
if (bIsLast && !IsErrorRspInfo(pRspInfo))
{
///报单录入请求
//ReqOrderInsert(); //--调试状态,不下单
}
}
void CTraderSpi::ReqOrderInsert()
{
//const char bsstat;
//char bsopenstat;
CThostFtdcInputOrderField req;
memset(&req, 0, sizeof(CThostFtdcInputOrderField));
///经纪公司代码
strcpy(req.BrokerID, BROKER_ID);
///投资者代码
strcpy(req.InvestorID, INVESTOR_ID);
///合约代码
strcpy(req.InstrumentID, INSTRUMENT_ID);
///报单引用
strcpy(req.OrderRef, ORDER_REF);
///用户代码
// TThostFtdcUserIDType UserID;
///报单价格条件: 限价
req.OrderPriceType = THOST_FTDC_OPT_LimitPrice;
///买卖方向:
req.Direction = DIRECTION;
///组合开平标志: 开仓
req.CombOffsetFlag[0] = MARKETState;
///组合投机套保标志
req.CombHedgeFlag[0] = THOST_FTDC_HF_Speculation;
///价格
req.LimitPrice = LIMIT_PRICE;
///数量: 1
req.VolumeTotalOriginal = 1;
///有效期类型: 当日有效
req.TimeCondition = THOST_FTDC_TC_GFD;
///GTD日期
// TThostFtdcDateType GTDDate;
///成交量类型: 任何数量
req.VolumeCondition = THOST_FTDC_VC_AV;
///最小成交量: 1
req.MinVolume = 1;
///触发条件: 立即
req.ContingentCondition = THOST_FTDC_CC_Immediately;
///止损价
// TThostFtdcPriceType StopPrice;
///强平原因: 非强平
req.ForceCloseReason = THOST_FTDC_FCC_NotForceClose;
///自动挂起标志: 否
req.IsAutoSuspend = 0;
///业务单元
// TThostFtdcBusinessUnitType BusinessUnit;
///请求编号
// TThostFtdcRequestIDType RequestID;
///用户强评标志: 否
req.UserForceClose = 0;
int iResult = pUserApi->ReqOrderInsert(&req, ++iRequestID);
cerr << "--->>> 报单录入请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
}
void CTraderSpi::OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
SYSTEMTIME sys_time;
GetLocalTime(&sys_time);
double system_times;
system_times=(double)((sys_time.wHour)/10e1)+(double)((sys_time.wMinute)/10e3)+(double)((sys_time.wSecond)/10e5); //格式时间0.145100
cerr << "--->>> 报单: " <<TradingDay << "_" <<system_times<< "_" << INSTRUMENT_ID <<"_"<< ((DIRECTION == '0') ? "买" : "卖") <<"_"<< ((MARKETState == '0') ? "开仓" : "平仓")<< "_" << LIMIT_PRICE << endl;
IsErrorRspInfo(pRspInfo);
}
void CTraderSpi::ReqOrderAction(CThostFtdcOrderField *pOrder)
{
static bool ORDER_ACTION_SENT = false; //是否发送了报单
if (ORDER_ACTION_SENT)
return;
CThostFtdcInputOrderActionField req;
memset(&req, 0, sizeof(CThostFtdcInputOrderActionField));
strcpy(req.ExchangeID, "SHFE");
///经纪公司代码
strcpy(req.BrokerID, pOrder->BrokerID);
///投资者代码
strcpy(req.InvestorID, pOrder->InvestorID);
///报单操作引用
// TThostFtdcOrderActionRefType OrderActionRef;
///报单引用
strcpy(req.OrderRef, pOrder->OrderRef);
///请求编号
// TThostFtdcRequestIDType RequestID;
///前置编号
req.FrontID = FRONT_ID;
///会话编号
req.SessionID = SESSION_ID;
///交易所代码
// TThostFtdcExchangeIDType ExchangeID;
///报单编号
// TThostFtdcOrderSysIDType OrderSysID;
///操作标志
req.ActionFlag = THOST_FTDC_AF_Delete;
///价格
// TThostFtdcPriceType LimitPrice;
///数量变化
// TThostFtdcVolumeType VolumeChange;
///用户代码
// TThostFtdcUserIDType UserID;
///合约代码
strcpy(req.InstrumentID, pOrder->InstrumentID);
int iResult = pUserApi->ReqOrderAction(&req, ++iRequestID);
cerr << "--->>> 报单操作请求: " << ((iResult == 0) ? "成功" : "失败") << endl;
ORDER_ACTION_SENT = true;
}
void CTraderSpi::OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << __FUNCTION__ << endl;
IsErrorRspInfo(pRspInfo);
}
///报单通知
void CTraderSpi::OnRtnOrder(CThostFtdcOrderField *pOrder)
{
cerr << "--->>> " << __FUNCTION__ << endl;
if (IsMyOrder(pOrder))
{
if (IsTradingOrder(pOrder))
ReqOrderAction(pOrder);
else if (pOrder->OrderStatus == THOST_FTDC_OST_Canceled)
cout << "--->>> 撤单成功" << endl;
}
}
///成交通知
void CTraderSpi::OnRtnTrade(CThostFtdcTradeField *pTrade)
{
cerr << "--->>> " << "OnRtnTrade" << endl;
}
void CTraderSpi:: OnFrontDisconnected(int nReason)
{
cerr << "--->>> " << "OnFrontDisconnected" << endl;
cerr << "--->>> Reason = " << nReason << endl;
}
void CTraderSpi::OnHeartBeatWarning(int nTimeLapse)
{
cerr << "--->>> " << "OnHeartBeatWarning" << endl;
cerr << "--->>> nTimerLapse = " << nTimeLapse << endl;
}
void CTraderSpi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
cerr << "--->>> " << "OnRspError" << endl;
IsErrorRspInfo(pRspInfo);
}
bool CTraderSpi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo)
{
// 如果ErrorID != 0, 说明收到了错误的响应
bool bResult = ((pRspInfo) && (pRspInfo->ErrorID != 0));
if (bResult)
cerr << "--->>> ErrorID=" << pRspInfo->ErrorID << ", ErrorMsg=" << pRspInfo->ErrorMsg << endl;
return bResult;
}
bool CTraderSpi::IsMyOrder(CThostFtdcOrderField *pOrder)
{
return ((pOrder->FrontID == FRONT_ID) &&
(pOrder->SessionID == SESSION_ID) &&
(strcmp(pOrder->OrderRef, ORDER_REF) == 0));
}
bool CTraderSpi::IsTradingOrder(CThostFtdcOrderField *pOrder)
{
return ((pOrder->OrderStatus != THOST_FTDC_OST_PartTradedNotQueueing) &&
(pOrder->OrderStatus != THOST_FTDC_OST_Canceled) &&
(pOrder->OrderStatus != THOST_FTDC_OST_AllTraded));
}