
// TestWrapperAPIDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TestWrapperAPI.h"
#include "TestWrapperAPIDlg.h"
#include "afxdialogex.h"
#include "CqdStock.h"
#include "CqdFuture.h"
#include "CqdOption.h"
#include "CqdTimeAndSales.h"
#include "CqdiTimeAndSalesItem.h"
#include "CqdTechanicalAnalysis.h"
#include "CqdiTechanicalAnalysisItem.h"
#include "CqdPriceByVolume.h"
#include "CqdiPriceByVolumeItem.h"
#include "CadiAccountItem.h"
#include "CrptReportItems.h"
#include "CrptExecutionReportItem.h"
#include "CrptFilledOrderItem.h"
#include "CadiMarginItem.h"
#include "CadiPositionItem.h"
#include "SymbolSelectDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define QUOTEREALTIME_TEXT _T("商品报价")
#define QUOTEMATCHLIST_TEXT _T("分时")
#define QUOTEPRICELIST_TEXT _T("分价")
#define QUOTETECH1K_TEXT _T("分K")
#define QUOTETECHDAYK_TEXT _T("日K")

#define TRADECOMBOTEXT1	_T("部位")
#define TRADECOMBOTEXT2 _T("资金")

#define PRICEFORMAT 10000000000

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CTestWrapperAPIDlg dialog




CTestWrapperAPIDlg::CTestWrapperAPIDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CTestWrapperAPIDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTestWrapperAPIDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO_DataType, m_ComboDataType);
	DDX_Control(pDX, IDC_COMBO_TradeQuery, m_ComboTradeQueryType);
	DDX_Control(pDX, IDC_COMBO_Account, m_cmbAccount);
	DDX_Control(pDX, IDC_EDT_OrderType, m_edtOrderType);
	DDX_Control(pDX, IDC_EDT_BS, m_edtBS);
	DDX_Control(pDX, IDC_EDT_TimeInForce, m_edtTimeInForce);
	DDX_Control(pDX, IDC_EDT_PositionEffect, m_edtPositionEffect);
	DDX_Control(pDX, IDC_EDT_Price, m_edtPrice);
	DDX_Control(pDX, IDC_EDT_Qty, m_edtQty);
	DDX_Control(pDX, IDC_EDT_TradeSymbol, m_edtTradeSymbol);
}

BEGIN_MESSAGE_MAP(CTestWrapperAPIDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_Connect, &CTestWrapperAPIDlg::OnBnClickedBtnConnect)
	ON_BN_CLICKED(IDC_BTN_Disconnect, &CTestWrapperAPIDlg::OnBnClickedBtnDisconnect)
	ON_BN_CLICKED(IDC_BTN_Sub, &CTestWrapperAPIDlg::OnBnClickedBtnSub)
	ON_BN_CLICKED(IDC_BTN_UnSub, &CTestWrapperAPIDlg::OnBnClickedBtnUnsub)
	ON_BN_CLICKED(IDC_BTN_Clear, &CTestWrapperAPIDlg::OnBnClickedBtnClear)
	ON_BN_CLICKED(IDC_BTN_Connect2, &CTestWrapperAPIDlg::OnBnClickedBtnConnect2)
	ON_BN_CLICKED(IDC_BTN_Disconnect2, &CTestWrapperAPIDlg::OnBnClickedBtnDisconnect2)
	ON_BN_CLICKED(IDC_BTN_DoOrder, &CTestWrapperAPIDlg::OnBnClickedBtnDoorder)
	ON_BN_CLICKED(IDC_BTN_Query, &CTestWrapperAPIDlg::OnBnClickedBtnQuery)
	ON_BN_CLICKED(IDC_BTN_SymbolSelect, &CTestWrapperAPIDlg::OnBnClickedBtnSymbolselect)
	ON_BN_CLICKED(IDC_BTN_SymbolSelect2, &CTestWrapperAPIDlg::OnBnClickedBtnSymbolselect2)
END_MESSAGE_MAP()


// CTestWrapperAPIDlg message handlers

BOOL CTestWrapperAPIDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	m_blClassificationsUpdate = false;
	m_nLogstatus = 0;
	int n  = m_QuoteAPI.Init(this);
	int n2 = m_TradeAPI.Init(this);

	m_ComboDataType.ResetContent();
	m_ComboDataType.AddString(QUOTEREALTIME_TEXT);
	m_ComboDataType.AddString(QUOTEMATCHLIST_TEXT);
	m_ComboDataType.AddString(QUOTEPRICELIST_TEXT);
	m_ComboDataType.AddString(QUOTETECH1K_TEXT);
	m_ComboDataType.AddString(QUOTETECHDAYK_TEXT);
	m_ComboDataType.SetCurSel(0);

	m_ComboTradeQueryType.ResetContent();
	m_ComboTradeQueryType.AddString(TRADECOMBOTEXT1);
	m_ComboTradeQueryType.AddString(TRADECOMBOTEXT2);
	m_ComboTradeQueryType.SetCurSel(0);

	GetDlgItem(IDC_EDT_Symbol)->SetWindowText(_T("TC.F.CME.6J.HOT"));
	GetDlgItem(IDC_EDT_BeginDateTime)->SetWindowText(_T("2018110709"));
	GetDlgItem(IDC_EDT_EndDateTime)->SetWindowText(_T("2018110712"));

	GetDlgItem(IDC_EDT_TradeSymbol)->SetWindowText(_T("TC.F.CME.6J.201811"));
	m_edtBS.SetWindowText(_T("1")); // 1:买 2:卖
	m_edtTimeInForce.SetWindowText(_T("1")); //1:rod 2:ioc 3:fok
	m_edtOrderType.SetWindowText(_T("2"));  // 1:市价  2:限价
	m_edtPositionEffect.SetWindowText(_T("4")); // 0:开仓 1:平仓 4:自动
	m_edtPrice.SetWindowText(_T("8800"));
	m_edtQty.SetWindowText(_T("1")); 

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTestWrapperAPIDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTestWrapperAPIDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTestWrapperAPIDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CTestWrapperAPIDlg::WriteLog(CString strLog)
{
	SYSTEMTIME st;
	GetLocalTime(&st);
	CString str;
	str.Format(_T("Time=[%02d:%02d:%02d:%03d] Data=[%s]\r\n"), st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, strLog);
	m_strLog += str;
	if(m_strLog.GetLength()>65535 && m_nLogstatus < 1)
	{
		m_nLogstatus = 1;
		AfxMessageBox(_T("资料有点长 建议清除一下"));
	}
	else if (m_strLog.GetLength()>65535*3 && m_nLogstatus < 2)
	{
		m_nLogstatus = 2;
		AfxMessageBox(_T("资料长长的 建议清除"));
	}
	else if (m_strLog.GetLength()>65535*5 && m_nLogstatus < 3)
	{
		m_nLogstatus = 3;
		AfxMessageBox(_T("资料真的很长 清一下吧"));
	}
	else if (m_strLog.GetLength()>65535*10 && m_nLogstatus < 4)
	{
		m_nLogstatus = 4;
		AfxMessageBox(_T("你不清我清"));
		m_strLog = str;
		GetDlgItem(IDC_EDT_Result)->SetWindowText(m_strLog);
	}
	GetDlgItem(IDC_EDT_Result)->SetWindowText(m_strLog);
}

//连线状态
void CTestWrapperAPIDlg::OnQuoteCommandMsg(long lMsgType, long lMsgCode, LPCTSTR strMsg)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	CString strLog;
	strLog.Format(_T("QuoteAPI OnCommandMsg lMsgType=[%d], lMsgCode=[%d] strMsg=[%s]"), lMsgType, lMsgCode,CString(strMsg));
	WriteLog(strLog);

	if (lMsgType == COMMAND_MSG_SYSTEM_STATUS)
	{
		switch (lMsgCode)
		{
			case CONNECTION_STATUS_RECONNECT_FAIL:	//-5		//重连失败
			case CONNECTION_STATUS_DISCONNECTED:	//-4		//已结束连线
			case CONNECTION_STATUS_CONNECT_LOST:	//-3		//连线中断
			case CONNECTION_STATUS_LOGIN_FAIL:		//-2		//登入失败
			case CONNECTION_STATUS_CONNECT_FAIL:	//-1		//连线失败
				break;
			case CONNECTION_STATUS_RECONNECTING:	//3		//断线重连中
			case CONNECTION_STATUS_CONNECTING:		//0		//连线中
				break;
			case CONNECTION_STATUS_CONNECT_OK:		//1		//连线完成
				break;
			case CONNECTION_STATUS_EXCHANGE_CLEAR://	4		//交易所清盘
			case CONNECTION_STATUS_SUBSECURITY_CLEAR://	5		//订阅中品种清盘
				break;
		}
	}

}

//报价资料
void CTestWrapperAPIDlg::OnQuoteData(long lSymbolType, long lDataType, LPDISPATCH lpDispData)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	CString strLog;
	strLog.Format(_T("OnQuoteData lSymbolType=%d, lDataType=%d"), lSymbolType, lDataType);
	WriteLog(strLog);

	if(!lpDispData)
		return;

	switch(lDataType)
	{
	case DATA_TYPE_REALTIME:
		ProcessRealtimeQuoteData(lSymbolType,lpDispData);
		break;
	case DATA_TYPE_MATCH_LIST:
		ProcessMatchListQuoteData(lSymbolType,lpDispData);
		break;
	case DATA_TYPE_PRICE_LIST:
		ProcessPriceListQuoteData(lSymbolType,lpDispData);
		break;
	case DATA_TYPE_1K:
	case DATA_TYPE_DK:
		ProcessTechanicalQuoteData(lSymbolType,lpDispData);
		break;
	}
}

//报价资料(不并tick)
void CTestWrapperAPIDlg::OnQuoteDataSyn(long lSymbolType, long lDataType, LPDISPATCH lpDispData, LPCTSTR lpModifiedFields)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

}

void CTestWrapperAPIDlg::OnBnClickedBtnConnect()
{
	// TODO: Add your control notification handler code here
	int nRtn = m_QuoteAPI.Connect(_T("."), _T("AlgoUAT"), _T("XXXXXXXXXXX"), 1);
	//m_QuoteAPI.SetSubscriptionLevel(1);  //不并tick
}


void CTestWrapperAPIDlg::OnBnClickedBtnDisconnect()
{
	// TODO: Add your control notification handler code here
	m_QuoteAPI.Disconnect();
}


void CTestWrapperAPIDlg::OnBnClickedBtnSub()
{
	// TODO: Add your control notification handler code here
	int nSel=m_ComboDataType.GetCurSel();
	if(nSel==CB_ERR)
		return;
	CString strType;
	m_ComboDataType.GetLBText(nSel, strType);

	int nDataType=DATA_TYPE_REALTIME;
	if(strType==QUOTEMATCHLIST_TEXT)
		nDataType=DATA_TYPE_MATCH_LIST;
	else if(strType==QUOTEPRICELIST_TEXT)
		nDataType=DATA_TYPE_PRICE_LIST;
	else if(strType==QUOTETECH1K_TEXT)
		nDataType=DATA_TYPE_1K;
	else if(strType==QUOTETECHDAYK_TEXT)
		nDataType=DATA_TYPE_DK;
	
	CString strSymbol = _T(""), strBeginTime=_T(""), strEndTime=_T("");
	GetDlgItem(IDC_EDT_Symbol)->GetWindowText(strSymbol);
	GetDlgItem(IDC_EDT_BeginDateTime)->GetWindowText(strBeginTime);
	GetDlgItem(IDC_EDT_EndDateTime)->GetWindowText(strEndTime);
	int nBeginTime =0,nEndTime=0;
	nBeginTime = _ttoi(strBeginTime);
	nEndTime = _ttoi(strEndTime);

	stcSubQuote SubData;
	SubData.strSymbol = strSymbol;
	SubData.nStartTime = nBeginTime;
	SubData.nEndTime = nEndTime;

	m_QuoteAPI.DoSub(SubData,nDataType);
}


void CTestWrapperAPIDlg::OnBnClickedBtnUnsub()
{
	// TODO: Add your control notification handler code here
	int nSel=m_ComboDataType.GetCurSel();
	if(nSel==CB_ERR)
		return;
	CString strType;
	m_ComboDataType.GetLBText(nSel, strType);

	int nDataType=DATA_TYPE_REALTIME;
	if(strType==QUOTEMATCHLIST_TEXT)
		nDataType=DATA_TYPE_MATCH_LIST;
	else if(strType==QUOTEPRICELIST_TEXT)
		nDataType=DATA_TYPE_PRICE_LIST;
	else if(strType==QUOTETECH1K_TEXT)
		nDataType=DATA_TYPE_1K;
	else if(strType==QUOTETECHDAYK_TEXT)
		nDataType=DATA_TYPE_DK;

	CString strSymbol = _T(""), strBeginTime=_T(""), strEndTime=_T("");
	GetDlgItem(IDC_EDT_Symbol)->GetWindowText(strSymbol);
	GetDlgItem(IDC_EDT_BeginDateTime)->GetWindowText(strBeginTime);
	GetDlgItem(IDC_EDT_EndDateTime)->GetWindowText(strEndTime);
	int nBeginTime =0,nEndTime=0;
	nBeginTime = _ttoi(strBeginTime);
	nEndTime = _ttoi(strEndTime);

	stcSubQuote SubData;
	SubData.strSymbol = strSymbol;
	SubData.nStartTime = nBeginTime;
	SubData.nEndTime = nEndTime;

	m_QuoteAPI.DoUnSub(SubData,nDataType);
}

//即时报价
void CTestWrapperAPIDlg::ProcessRealtimeQuoteData(LONG lSecurityType, LPDISPATCH lpDispQuoteData)
{
	switch(lSecurityType)
	{
	case SECURITY_TYPE_STOCK:
		{
			CqdStock pStockData;
			pStockData.AttachDispatch(lpDispQuoteData);
			CString strSymbol = pStockData.get_Symbol();
			LONGLONG llSymbolType = pStockData.get_SecurityType();
			LONGLONG llDate = pStockData.get_TradeDate();	

			//时间为格林威治需要转换到目前时区
			LONGLONG llTradeTime = pStockData.get_FilledTime(); //更新时间
			LONG lYear = (LONG)llDate/10000;
			LONG lMonth = (LONG)llDate%10000/100;
			LONG lDay = (LONG)llDate%100;
			LONG lHour = (LONG)llTradeTime/10000;
			LONG lMinute = (LONG)llTradeTime%10000/100;
			LONG lSecond = (LONG)llTradeTime%100;
			CTime timeTrade(lYear, lMonth, lDay, lHour, lMinute, lSecond);
			CTimeSpan tmSpan(0, 8, 0, 0); 
			timeTrade += tmSpan;
			llDate = timeTrade.GetYear()*10000+timeTrade.GetMonth()*100+timeTrade.GetDay();
			llTradeTime = timeTrade.GetHour()*10000+timeTrade.GetMinute()*100+timeTrade.GetSecond();

			LONGLONG llLastPrice = pStockData.get_TradingPrice();	//成交价
			LONGLONG llLastQty = pStockData.get_TradeQuantity();	//成交量

			//用index取字串
			CString s13 = pStockData.GetStringFromIndex(13);
			//用index取数字
			LONGLONG ll125 = pStockData.GetValueFromIndex(125);
			CString str;
			str.Format(_T("[ProcessRealtimeQuoteData] Stock Symbol=[%s] SymbolType[%I64d] TradeDate=[%I64d] filledTime=[%I64d] llLastPrice=[%I64d] llLastQty=[%I64d] s13=[%s] ll125=[%I64d]"),
				strSymbol,llSymbolType,llDate,llTradeTime,llLastPrice,llLastQty,s13,ll125);
			WriteLog(str);
		}
		break;
	case SECURITY_TYPE_FUTURE:
		{
			CqdFuture pFutureData;
			pFutureData.AttachDispatch(lpDispQuoteData);
			CString strSymbol = pFutureData.get_Symbol();
			LONGLONG llSymbolType = pFutureData.get_SecurityType();
			LONGLONG llDate = pFutureData.get_TradeDate();	

			//时间为格林威治需要转换到目前时区
			LONGLONG llTradeTime = pFutureData.get_FilledTime(); //更新时间
			LONG lYear = (LONG)llDate/10000;
			LONG lMonth = (LONG)llDate%10000/100;
			LONG lDay = (LONG)llDate%100;
			LONG lHour = (LONG)llTradeTime/10000;
			LONG lMinute = (LONG)llTradeTime%10000/100;
			LONG lSecond = (LONG)llTradeTime%100;
			if (lYear <= 1900 || lMonth <= 0 || lDay <= 0)
			{//不合法的时间,改为本机时间
				CTime tmLocal = CTime::GetCurrentTime();
				lYear = tmLocal.GetYear();
				lMonth = tmLocal.GetMonth();
				lDay = tmLocal.GetDay();
			}
			CTime timeTrade(lYear, lMonth, lDay, lHour, lMinute, lSecond);
			CTimeSpan tmSpan(0, 8, 0, 0); 
			timeTrade += tmSpan;
			llDate = timeTrade.GetYear()*10000+timeTrade.GetMonth()*100+timeTrade.GetDay();
			llTradeTime = timeTrade.GetHour()*10000+timeTrade.GetMinute()*100+timeTrade.GetSecond();

			LONGLONG llLastPrice = pFutureData.get_TradingPrice();	//成交价
			LONGLONG llLastQty = pFutureData.get_TradeQuantity();	//成交量

			//用index取字串
			CString s13 = pFutureData.GetStringFromIndex(13);
			//用index取数字
			LONGLONG ll125 = pFutureData.GetValueFromIndex(125);
			CString str;
			str.Format(_T("[ProcessRealtimeQuoteData] Future Symbol=[%s] SymbolType[%I64d] TradeDate=[%I64d] filledTime=[%I64d] llLastPrice=[%I64d] llLastQty=[%I64d] s13=[%s] ll125=[%I64d]"),
				strSymbol,llSymbolType,llDate,llTradeTime,llLastPrice,llLastQty,s13,ll125);
			WriteLog(str);
		}
		break;
	case SECURITY_TYPE_OPTION:
		{
			CqdOption pOptionData;
			pOptionData.AttachDispatch(lpDispQuoteData);
			CString strSymbol = pOptionData.get_Symbol();
			LONGLONG llSymbolType = pOptionData.get_SecurityType();
			LONGLONG llDate = pOptionData.get_TradeDate();	

			//时间为格林威治需要转换到目前时区
			LONGLONG llTradeTime = pOptionData.get_FilledTime(); //更新时间
			LONG lYear = (LONG)llDate/10000;
			LONG lMonth = (LONG)llDate%10000/100;
			LONG lDay = (LONG)llDate%100;
			LONG lHour = (LONG)llTradeTime/10000;
			LONG lMinute = (LONG)llTradeTime%10000/100;
			LONG lSecond = (LONG)llTradeTime%100;
			CTime timeTrade(lYear, lMonth, lDay, lHour, lMinute, lSecond);
			CTimeSpan tmSpan(0, 8, 0, 0); 
			timeTrade += tmSpan;
			llDate = timeTrade.GetYear()*10000+timeTrade.GetMonth()*100+timeTrade.GetDay();
			llTradeTime = timeTrade.GetHour()*10000+timeTrade.GetMinute()*100+timeTrade.GetSecond();

			LONGLONG llLastPrice = pOptionData.get_TradingPrice();	//成交价
			LONGLONG llLastQty = pOptionData.get_TradeQuantity();	//成交量

			//用index取字串
			CString s13 = pOptionData.GetStringFromIndex(13);
			//用index取数字
			LONGLONG ll125 = pOptionData.GetValueFromIndex(125);
			CString str;
			str.Format(_T("[ProcessRealtimeQuoteData] Option Symbol=[%s] SymbolType[%I64d] TradeDate=[%I64d] filledTime=[%I64d] llLastPrice=[%I64d] llLastQty=[%I64d] s13=[%s] ll125=[%I64d]"),
				strSymbol,llSymbolType,llDate,llTradeTime,llLastPrice,llLastQty,s13,ll125);
			WriteLog(str);
		}
		break;

	}
}

//分时
void CTestWrapperAPIDlg::ProcessMatchListQuoteData(LONG lSecurityType, LPDISPATCH lpDispQuoteData)
{
	if (!lpDispQuoteData)
		return;

	CqdTimeAndSales objTimeAndSales;
	objTimeAndSales.AttachDispatch(lpDispQuoteData, FALSE);

	LONG lItemCount=objTimeAndSales.get_ItemCount();
	CString str;
	CString strSymbol = objTimeAndSales.get_Symbol();
	str.Format(_T("====MatchList symbol=[%s]===="),strSymbol);
	WriteLog(str);

	if(lItemCount>0)
	{
		CString strSymbol = objTimeAndSales.get_Symbol();
		CqdiTimeAndSalesItem item;
		if(item.CreateDispatch(_T("TCore.QuoteDataTimeAndSalesItem.1")))
		{
			if(objTimeAndSales.GetItem(lItemCount-1, item.m_lpDispatch))
			{
				long lIndex = item.get_ItemIndex();
				long lDate = item.get_Date();
				LONGLONG llPrice = item.get_TradingPrice();
				long lQty = item.get_TradeQuantity();
				long lVol = item.get_TradeVolume();
				str.Format(_T("MatchList LastItem ItemCount=[%d] Index=[%d], Time=[%d], Price=[%I64d], Qty=[%d], Volume=[%d]"),
					lItemCount,lIndex,lDate,llPrice,lQty,lVol);
	
				WriteLog(str);
			}
			else
				WriteLog(_T("Fail to get last TimeAndSalesItem"));
		}
		else
			WriteLog(_T("Fail to create TCore.QuoteDataTimeAndSalesItem.1"));
	}
	else
	{
		WriteLog(_T("MatchList no data"));
	}
	objTimeAndSales.DetachDispatch();
}

//分价
void CTestWrapperAPIDlg::ProcessPriceListQuoteData(LONG lSecurityType, LPDISPATCH lpDispQuoteData)
{
	if (!lpDispQuoteData)
		return;

	CqdPriceByVolume objPriceByVolume;
	objPriceByVolume.AttachDispatch(lpDispQuoteData);
	LONG lItemCount=objPriceByVolume.get_ItemCount();

	CString str;
	CString strSymbol = objPriceByVolume.get_Symbol();
	long lDate = objPriceByVolume.get_CurrentDate();
	long lTime = objPriceByVolume.get_LastTime();
	long lVol = objPriceByVolume.get_LastVolume();
	str.Format(_T("=====PriceList Symbol=[%s], count=[%d], CurrentData=[%d], LastTime=[%d], LastVolume=[%d]===="), 
		strSymbol,lItemCount,lDate,lTime,lVol);
	WriteLog(str);

	if (lItemCount>0)
	{
		CqdiPriceByVolumeItem item;
		if(item.CreateDispatch(_T("TCore.QuoteDataPriceByVolumeItem.1")))
		{
			str=_T("");
			CString ss;
			for(int i=0; i<lItemCount; i++)
			{
				if(objPriceByVolume.GetItem(i, item.m_lpDispatch))
				{
					LONGLONG llPrice = item.GetPrice(i);
					long lQuantity = item.GetQuantity(i);
					//item.get_ItemIndex();
					//	item.get_Price();
					//	item.get_Quantity();
					ss.Format(_T("Index=[%d], Price=[%I64d], Qty=[%d]\r\n"),i,llPrice,lQuantity);
					str+=ss;
				}
				else
					WriteLog(_T("Fail to get PriceByVolumeItem"));
			}
			WriteLog(str);
		}
		else
			WriteLog(_T("Fail to create TCore.QuoteDataTechanicalAnalysisItem.1"));
	}
	else
	{
		WriteLog(_T("PriceList no data"));
	}
	objPriceByVolume.DetachDispatch();
}

//K线
void CTestWrapperAPIDlg::ProcessTechanicalQuoteData(LONG lSecurityType, LPDISPATCH lpDispQuoteData)
{
	if (!lpDispQuoteData)
		return;
	CqdTechanicalAnalysis objTechanicalAnalysis;
	objTechanicalAnalysis.AttachDispatch(lpDispQuoteData,FALSE);
	CString str;
	CString strSymbol = objTechanicalAnalysis.get_Symbol();
	str.Format(_T("====Tech K symbol=[%s]===="),strSymbol);
	WriteLog(str);

	LONG lItemCount=objTechanicalAnalysis.get_ItemCount();
	if(lItemCount>0)
	{
		CqdiTechanicalAnalysisItem item;
		if(item.CreateDispatch(_T("TCore.QuoteDataTechanicalAnalysisItem.1")))
		{
			if(objTechanicalAnalysis.GetItem(lItemCount-1, item.m_lpDispatch))
			{
				long lIndex = item.get_ItemIndex();
				long lDate = item.get_Date();
				long lTime = item.get_Time();
				LONGLONG llVol = item.get_Volume();
				LONGLONG llOpen = item.get_Open();
				LONGLONG llHigh = item.get_High();
				LONGLONG llLow = item.get_Low();
				LONGLONG llClose = item.get_Close();
				long lUpTick = item.get_UpTick();
				long lUpVol = item.get_UpVolume();
				long lDownTick = item.get_DownTick();
				long lDownVol = item.get_DownVolume();

				str.Format(_T("LastItem Index=[%d], Date=[%d], Time=[%d], Volume=[%I64d], Price(open,high,low,close)=[%I64d, %I64d, %I64d, %I64d], Tick(upTick,upVol,DownTick,DownVol)=[%d, %d, %d, %d]"),
					lIndex, lDate,lTime,llVol,llOpen,llHigh,llClose,lUpTick,lUpVol,lDownTick,lDownVol);

				WriteLog(str);
			}
			else
				WriteLog(_T("Fail to get last TechanicalAnalysisItem"));
		}
		else
			WriteLog(_T("Fail to create TCore.QuoteDataTechanicalAnalysisItem.1"));
	}
	else
	{
		WriteLog(_T("NO Techanical DATA for"));
	}
	objTechanicalAnalysis.DetachDispatch();
}


void CTestWrapperAPIDlg::OnBnClickedBtnClear()
{
	// TODO: Add your control notification handler code here
	m_strLog = _T("");
	GetDlgItem(IDC_EDT_Result)->SetWindowText(m_strLog);
}

//连线状态
void CTestWrapperAPIDlg::OnTradeCommandMsg(long lMsgType, long lMsgCode, LPCTSTR strMsg)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	CString strLog;
	strLog.Format(_T("TradeAPI OnCommandMsg lMsgType=[%d], lMsgCode=[%d] strMsg=[%s]"), lMsgType, lMsgCode,CString(strMsg));
	WriteLog(strLog);

	if (lMsgType == COMMAND_MSG_SYSTEM_STATUS)
	{
		switch (lMsgCode)
		{
			case CONNECTION_STATUS_RECONNECT_FAIL:	//-5		//重连失败
			case CONNECTION_STATUS_DISCONNECTED:	//-4		//已结束连线
			case CONNECTION_STATUS_CONNECT_LOST:	//-3		//连线中断
			case CONNECTION_STATUS_LOGIN_FAIL:		//-2		//登入失败
			case CONNECTION_STATUS_CONNECT_FAIL:	//-1		//连线失败
				break;

			case CONNECTION_STATUS_RECONNECTING:	//3		//断线重连中
			case CONNECTION_STATUS_CONNECTING:		//0		//连线中
				break;
			case CONNECTION_STATUS_CONNECT_OK:		//1		//连线完成
				break;
		}
	}
}

//帐号与帐务资料
void CTestWrapperAPIDlg::OnTradeAccountUpdate(long Type, LPCTSTR AcctMask, long Count)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	CString strlog;
	strlog.Format(_T("[AccountUpdate] type=[%d] acct=[%s] count=[%d]"),Type,AcctMask,Count);
	WriteLog(strlog);

	switch (Type)
	{
		case ADT_ACCOUNT:
			ProcessAccount(Type,Count);
			break;
		case ADT_MARGIN:
			ProcessMargin(AcctMask,Count);
			break;
		case ADT_RT_POSITION:
			ProcessPositionRT(AcctMask,Count);
			break;
	}

}

//回报回补
void CTestWrapperAPIDlg::OnTradeReportReset()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	CrptReportItems dspRpts;
	dspRpts.CreateDispatch(_T("TCore.TradeRptReportItem.1"));
	LONG lRetVal = m_TradeAPI.GetReportData(3, _T(""), dspRpts.m_lpDispatch);

	CString strLog;
	strLog.Format(_T("=========[OnTradeReportReset] ret=[%d]============"),lRetVal);
	WriteLog(strLog);

	if (lRetVal == 1)
	{
		for (int i=0; i<dspRpts.get_Count(); i++)
		{
			CString strReportID = dspRpts.GetReportID(i);
			ProcessOrderReport(strReportID,false);
		}
	}
	dspRpts.ReleaseDispatch();
}

//即时委托
void CTestWrapperAPIDlg::OnTradeExecutionReport(LPCTSTR ReportID)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	CString strLog;
	strLog.Format(_T("=========[OnTradeExecutionReport] ReportID=[%s]============"),ReportID);
	WriteLog(strLog);

	ProcessOrderReport(ReportID,true);
}

void CTestWrapperAPIDlg::OnBnClickedBtnConnect2()
{
	// TODO: Add your control notification handler code here
	int nRtn = m_TradeAPI.Connect(_T("."), _T("AlgoUAT"), _T("XXXXXXXXXXX"), 1);
	m_cmbAccount.ResetContent();
}


void CTestWrapperAPIDlg::OnBnClickedBtnDisconnect2()
{
	// TODO: Add your control notification handler code here
	m_TradeAPI.Disconnect();
	
	for (int i=0;i<m_cmbAccount.GetCount();i++)
	{
		AccountData *pdata = (AccountData*)m_cmbAccount.GetItemData(i);
		delete pdata;
	}
	m_cmbAccount.ResetContent();
}

//帐号处理
void CTestWrapperAPIDlg::ProcessAccount(LONG lType, LONG lCount)
{
	if (lType != ADT_ACCOUNT && lType != ADT_GROUP_ACCOUNT)
		return;

	CString strlog;
	strlog.Format(_T("====[ProcessAccount] type=[%d] count=[%d]===="),lType,lCount);
	WriteLog(strlog);
	
	for (int i=0;i<m_cmbAccount.GetCount();i++)
	{
		AccountData *pdata = (AccountData*)m_cmbAccount.GetItemData(i);
		delete pdata;
	}
	m_cmbAccount.ResetContent();
	
	for (int i=0; i<lCount; i++)
	{
		CadiAccountItem dspAcct;
		dspAcct.CreateDispatch(_T("TCore.TradeDataAccount.1"));
		LONG lRet =	m_TradeAPI.GetAccountData(lType, i, _T(""), dspAcct.m_lpDispatch);
		
		if (lRet == 1)
		{
			LONG lStatus = dspAcct.get_Status();
			if ((lType == ADT_ACCOUNT && lStatus == 2) || (lType == ADT_GROUP_ACCOUNT)) // 群组帐号没有连线状态
			{
				CString strBroker = dspAcct.get_BrokerID();
				CString strAccount = dspAcct.get_Account();
				CString strAcctType = dspAcct.get_AccountType();
				CString strAcctName = dspAcct.get_AccountName();
				AccountData *pData = new AccountData;
				pData->strBroker = strBroker;
				pData->strAccount = strAccount;
				pData->strAcctType = strAcctType;
				pData->strAcctName = strAcctName;
				int nIndex = m_cmbAccount.AddString(strAccount);
				m_cmbAccount.SetItemData(nIndex,(DWORD)pData);

				//CString strAllAccount;
				//strAllAccount = strBroker + '-' + strAccount;
				strlog.Format(_T("[ProcessAccount] index=[%d] accIndex=[%d] broker=[%s] account[%s] accType=[%s] accountname=[%s] status=[%d]"),i,nIndex,strBroker,strAccount,strAcctType,strAcctName,lStatus);
				WriteLog(strlog);
			}
		}
	}
	if (lCount>0)
		m_cmbAccount.SetCurSel(0);

	WriteLog(strlog);
}

void CTestWrapperAPIDlg::OnBnClickedBtnDoorder()
{
	// TODO: Add your control notification handler code here
	if (m_cmbAccount.GetCurSel() <0)
	{
		AfxMessageBox(_T("无帐号资料"));
		return;
	}
	ORDER_INFO OrderInfo;

	AccountData *pAccdata = (AccountData*)m_cmbAccount.GetItemData(m_cmbAccount.GetCurSel());

	OrderInfo.strAccount = pAccdata->strAccount;
	OrderInfo.strBrokerID = pAccdata->strBroker;

	CString strPrice;
	m_edtTradeSymbol.GetWindowText(OrderInfo.strSymbol);
	m_edtBS.GetWindowText(OrderInfo.strBuySell);
	m_edtOrderType.GetWindowText(OrderInfo.strOrderType);
	m_edtPositionEffect.GetWindowText(OrderInfo.strPositionEffect);
	m_edtTimeInForce.GetWindowText(OrderInfo.strTimeInForce);
	m_edtPrice.GetWindowText(strPrice);
	m_edtQty.GetWindowText(OrderInfo.strQty);
	double dbPrice = _ttof(strPrice) * PRICEFORMAT;	//价格一律乘十个零
	LONGLONG llPrice = dbPrice;
	OrderInfo.strPrice.Format(_T("%I64d"),llPrice);
	
	int nRtn = m_TradeAPI.DoPlaceOrder(OrderInfo);
	CString strlog;
	strlog.Format(_T("[DoOrder] account=[%s] symbol=[%s] result=[%d]"),OrderInfo.strAccount,OrderInfo.strSymbol,nRtn);
	WriteLog(strlog);
}

//回报处理
void CTestWrapperAPIDlg::ProcessOrderReport(CString strReportID,bool bRealtime)
{
	CrptExecutionReportItem dspItem;
	dspItem.CreateDispatch(_T("TCore.TradeRptExecutionReportItem.1"));
	LONG lRetVal = m_TradeAPI.GetReportData(0, strReportID, dspItem.m_lpDispatch);
	CString strlog;
	if (bRealtime)
		strlog.Format(_T("[ProcessOrderReport] Realtime ret=[%d] strReportID=[%s]"),lRetVal,strReportID);
	else
		strlog.Format(_T("[ProcessOrderReport] Reset ret=[%d] strReportID=[%s]"),lRetVal,strReportID);

	WriteLog(strlog);

	CArray<CString> arFilledID;
	if (lRetVal == 1)
	{
		CString strSymbol = dspItem.get_Symbol();
		LONG lExecType = dspItem.get_ExecType();
		CString strAccount = dspItem.get_Account();
		CString strOrderID = dspItem.get_OrderID();
		int nOrderType = dspItem.get_OrderType();
		CString strExecTypeText = dspItem.get_ExecTypeText();
		LONGLONG llAvgPrice = dspItem.get_AvgPrice();
		LONGLONG llPrice = dspItem.get_Price();
		int nQty = dspItem.get_OrderQty();
		CString strItsOdSeq = dspItem.GetItemData(_T("ItsOdSeq"));

		strlog.Format(_T("[ProcessOrderReport] strReportID=[%s] strSymbol=[%s] strAccount=[%s] strOrderID=[%s] strItsOdSeq=[%s] nOrderType=[%d] lExecType=[%d] strExecTypeText=[%s] llAvgPrice=[%I64d] llPrice=[%I64d] nQty=[%d]"),
			strReportID,strSymbol,strAccount,strOrderID,strItsOdSeq,nOrderType,lExecType,strExecTypeText,llAvgPrice,llPrice,nQty);

		WriteLog(strlog);

		int nFillcount = dspItem.get_FilledOrdersCount();
		for (int i=0; i<nFillcount; i++)
			arFilledID.Add(dspItem.GetFilledOrderReportID(i));

	}
	dspItem.ReleaseDispatch();
	if (arFilledID.GetCount() >0)
	{
		strlog.Format(_T("======Do FilledOrderReport strReportID=[%s]======"),strReportID);
		for (int i=0;i<arFilledID.GetCount();i++)
		{
			ProcessFillOrderReport(arFilledID.GetAt(i));
		}
	}
	
}

//成交回报处理
void CTestWrapperAPIDlg::ProcessFillOrderReport(CString strReportID)
{
	CrptFilledOrderItem dspItem;
	dspItem.CreateDispatch(_T("TCore.TradeFilledOrderItem.1"));
	LONG lRetVal = m_TradeAPI.GetReportData(0, strReportID, dspItem.m_lpDispatch);

	CString strlog;
	strlog.Format(_T("[ProcessFillOrderReport] ReportID=%s, GetReportData=%d"), strReportID, lRetVal);
	WriteLog(strlog);

	if (lRetVal == 1)
	{
		CString strAccount = dspItem.get_Account();
		CString strOrderID = dspItem.get_OrderID();
		CString strItsOdSeq = dspItem.GetItemData(_T("ItsOdSeq"));
		long lSide = dspItem.get_Side();
		strlog.Format(_T("[ProcessFillOrderReport] strReportID=[%s] strAccount=[%s] strOrderID=[%s] strItsOdSeq=[%s] lSide=[%d]"),strReportID,strAccount,strOrderID,strItsOdSeq,lSide);
		WriteLog(strlog);
	}
	dspItem.ReleaseDispatch();
}

//资金处理
void CTestWrapperAPIDlg::ProcessMargin(CString strAcctMask, LONG lCount)
{
	CString strlog;
	strlog.Format(_T("====[ProcessMargin] strAcctMask=[%s] lCount=[%d]===="),strAcctMask,lCount);
	WriteLog(strlog);

	for (int i=0; i<lCount; i++)
	{
		CadiMarginItem dspMargin;
		dspMargin.CreateDispatch(_T("TCore.TradeDataMarginItem.1"));
		LONG lRet =	m_TradeAPI.GetAccountData(ADT_MARGIN, i, strAcctMask, dspMargin.m_lpDispatch);
		if (lRet == 1)
		{
			CString strAccount = dspMargin.get_Account();
			CString strCurrencyToClient = dspMargin.get_CurrencyToClient();
			CString strCurrencyToSystem = dspMargin.get_CurrencyToSystem();
			CString strObType = dspMargin.GetItemData(_T("OB"));//国内:2国外:1
			LONGLONG llExcessEquity = dspMargin.get_ExcessEquity();
			strlog.Format(_T("[ProcessMargin] strAccount=[%s] strCurrencyToClient=[%s] strCurrencyToSystem=[%s] strObType=[%s] strExcessEquity=[%I64d]"),strAccount,strCurrencyToClient,strCurrencyToSystem,strObType,llExcessEquity);
			WriteLog(strlog);

		}
		dspMargin.ReleaseDispatch();
	}
}

//部位处理
void CTestWrapperAPIDlg::ProcessPositionRT(CString strAcctMask, LONG lCount)
{
	CString strlog;
	strlog.Format(_T("====[ProcessPositionRT] strAcctMask=[%s] lCount=[%d]===="),strAcctMask,lCount);
	WriteLog(strlog);

	for (int i=0; i<lCount; i++)
	{
		CadiPositionItem dspPosition;
		dspPosition.CreateDispatch(_T("TCore.TradeDataPositionItem.1"));
		LONG lRet =	m_TradeAPI.GetAccountData(ADT_RT_POSITION, i, strAcctMask, dspPosition.m_lpDispatch);
		if (lRet == 1)
		{
			CString strAccount = dspPosition.get_Account();
			CString strSymbol = dspPosition.get_Symbol();
			long nBS = dspPosition.get_Side();
			long lQty = dspPosition.get_Quantity();
			LONGLONG llAvgPrice = dspPosition.get_AvgPrice();
			strlog.Format(_T("[ProcessPositionRT] strAccount=[%s] strSymbol=[%s] nBS=[%d] lQty=[%d] llAvgPrice=[%I64d]"),strAccount,strSymbol,nBS,lQty,llAvgPrice);
			WriteLog(strlog);
		}
		dspPosition.ReleaseDispatch();
	}
}

void CTestWrapperAPIDlg::OnBnClickedBtnQuery()
{
	// TODO: Add your control notification handler code here
	if (m_cmbAccount.GetCurSel() <0)
	{
		AfxMessageBox(_T("无帐号资料"));
	}

	if (m_ComboTradeQueryType.GetCurSel() > -1)
	{
		CString str;
		m_ComboTradeQueryType.GetLBText(m_ComboTradeQueryType.GetCurSel(),str);
		AccountData *pAccdata = (AccountData*)m_cmbAccount.GetItemData(m_cmbAccount.GetCurSel());
		if (str == TRADECOMBOTEXT1)
		{
			//m_TradeAPI.DoQueryAccountData(ADT_RT_POSITION,pAccdata->strBroker,pAccdata->strAccount);
			m_TradeAPI.DoQueryAccountData(ADT_POSITION,pAccdata->strBroker,pAccdata->strAccount);
		}
		else if (str == TRADECOMBOTEXT2)
		{
			m_TradeAPI.DoQueryAccountData(ADT_MARGIN,pAccdata->strBroker,pAccdata->strAccount);
		}

	}

}

//商品分类表更新
void CTestWrapperAPIDlg::OnQuoteSymbolClassificationsUpdate()
{
	m_blClassificationsUpdate = true;
}

void CTestWrapperAPIDlg::OnBnClickedBtnSymbolselect()
{
	// TODO: Add your control notification handler code here
	if(m_blClassificationsUpdate)
		SymbolSelect(1);
}


void CTestWrapperAPIDlg::OnBnClickedBtnSymbolselect2()
{
	// TODO: Add your control notification handler code here
	if(m_blClassificationsUpdate)
		SymbolSelect(2);

}

//呼叫商品选择
void CTestWrapperAPIDlg::SymbolSelect(int nSelect)
{
	CSymbolSelectDlg dlg;
	dlg.SetParent(this);
	dlg.SetFilter(_T("FUT;OPT"));
	if (dlg.DoModal() == IDOK)
	{
		if(nSelect == 1)
			GetDlgItem(IDC_EDT_Symbol)->SetWindowText(dlg.m_strSymbol);
		else
			GetDlgItem(IDC_EDT_TradeSymbol)->SetWindowText(dlg.m_strSymbol);
	}
}

//商品分类表更新
CString CTestWrapperAPIDlg::GetSymbolClassifications(CString strParam1, CString strParam2, CString strParam3, CString strParam4, CString strParam5)
{
	return m_QuoteAPI.GetSymbolClassifications(strParam1,strParam2,strParam3,strParam4,strParam5);
}