virtualAPI:CTP期货的最小系统

宏源和SIMNOW CTP穿透式监管下单撤单Demo程序和源代码
// 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));
}

发表评论