⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tw.cpp

📁 接收证券行情数据接口的VC源代码,配合上mystock,可很好了解股票软件的内部源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// TW.cpp : implementation file
//

#include "stdafx.h"
#include "TW.h"
#include "SPTime.h"
#include "TSCache.h"

#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// TW Interface

static BYTE g_serial = 0x00;
static CTWStockArray g_serial_stocks[0x80];
static int g_serial_count[0x80];

BYTE GetNextSerial(TW_STOCK & stock, int count = 0)
{
	g_serial ++;
	if(g_serial > 0x7f)	g_serial = 0x01;
	if(g_serial >= 1 && g_serial <= 0x7f)
	{
		g_serial_stocks[g_serial].RemoveAll();
		g_serial_stocks[g_serial].Add(stock);
		g_serial_count[g_serial] = count;
	}
	return g_serial;
}

BYTE GetNextSerial(CTWStockArray & stocks, int count = 0)
{
	g_serial ++;
	if(g_serial > 0x7f)	g_serial = 0x01;
	if(g_serial >= 1 && g_serial <= 0x7f)
	{
		g_serial_stocks[g_serial].RemoveAll();
		g_serial_stocks[g_serial].Copy(stocks);
		g_serial_count[g_serial] = count;
	}
	return g_serial;
}

BOOL GetSerialStock(BYTE serial, TW_STOCK & stock, int * pcount = NULL)
{
	if(serial >= 1 && serial <= 0x7f)
	{
		memset(&stock, 0, sizeof(stock));
		if(g_serial_stocks[serial].GetSize() > 0)
			memcpy(&stock, &(g_serial_stocks[serial].ElementAt(0)), sizeof(stock));
		if(pcount)
			*pcount = g_serial_count[serial];
		return TRUE;
	}
	return FALSE;
}

BOOL GetSerialStock(BYTE serial, CTWStockArray & stocks, int * pcount = NULL)
{
	if(serial >= 1 && serial <= 0x7f)
	{
		stocks.RemoveAll();
		if(g_serial_stocks[serial].GetSize() > 0)
			stocks.Copy(g_serial_stocks[serial]);
		if(pcount)
			*pcount = g_serial_count[serial];
		return TRUE;
	}
	return FALSE;
}

int ConstructLength(TW_HEADER& header, int len)
{
	CString	string = itoa(len,header.m_length,16);
	int nZeros = TW_LENGTH_LEN-string.GetLength();
	int i;
	for(i=0; i<nZeros; i++)
		
	for(i=0; i<TW_LENGTH_LEN; i++)
	{
		if(i< nZeros)
			header.m_length[i] = '0';
		else
			header.m_length[i] = string[i-nZeros];
	}
	return len;
}

int ConstructLoginBuffer(BYTE* buffer, size_t maxlen, LPCTSTR lpszUser, LPCTSTR lpszPasswd)
{
	int nLen = 0;
	int nLenUser = strlen(lpszUser);
	int nLenPasswd = strlen(lpszPasswd);

	TW_LOGIN	packet;
	memset(&packet,0,sizeof(packet));
	packet.m_header.m_magic = TW_MAGIC;
	if(maxlen < (int)(5 + sizeof(TW_HEADER) + nLenUser + nLenPasswd))
	{
		nLen = 5 + sizeof(TW_HEADER);
		return -1;
	}
	packet.m_name_len = (WORD)nLenUser;
	memcpy(packet.m_data, lpszUser, nLenUser);
	*(WORD*)(packet.m_data + nLenUser)	=	(WORD)nLenPasswd;
	memcpy(packet.m_data + nLenUser + sizeof(WORD), lpszPasswd, nLenPasswd);

	nLen = 5 + sizeof(TW_HEADER) + nLenUser + nLenPasswd;
	ConstructLength(packet.m_header, nLen - sizeof(packet.m_header));

	if(buffer)
		memcpy(buffer, &packet, nLen);
	return nLen;
}

int ConstructAskInitBuffer(TW_ASK& ask)
{
	memset(&ask, 0, sizeof(ask));
	ask.m_header.m_magic = TW_MAGIC;

	const char * str_tag = "E013.45D013.04D022.03D043.20xcs1.00.is2.00";

	ask.m_tag1 = 0x01;
	ask.m_tag2 = 0x01;
	ask.m_serial = 0x00;
	ask.m_size = 0x0007;

	CSPTime sptime = CTSCache::GetInstance().GetLocalLatest();
	DWORD	date = sptime.ToStockTimeDay();
	memcpy(&(ask.m_stocks[0].m_type), &date, sizeof(date));
//	ask.m_stocks[0].m_type = 0xdc;
//	ask.m_stocks[0].m_code[0] = (char)0xcc;
//	ask.m_stocks[0].m_code[1] = 0x31;
//	ask.m_stocks[0].m_code[2] = (char)0x01;	//0xdc cc 31 01 = 20040924
	ask.m_stocks[0].m_code[3] = 0x00;
	ask.m_stocks[0].m_code[4] = 0x00;
	ask.m_stocks[0].m_code[5] = 0x00;
	memcpy(&(ask.m_stocks[1]), str_tag, strlen(str_tag));
	int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK) + strlen(str_tag));
	ConstructLength(ask.m_header, ret - sizeof(ask.m_header));
	return ret;
}

int ConstructAskReportBuffer(TW_ASK& ask, TW_STOCK* pStocks, size_t size)
{
	memset(&ask, 0, sizeof(ask));
	ask.m_header.m_magic = TW_MAGIC;

	SHORT shortSize = (SHORT)size;
	if(shortSize > sizeof(ask.m_stocks)/sizeof(TW_STOCK))
		shortSize = sizeof(ask.m_stocks)/sizeof(TW_STOCK);
	if(shortSize <= 0)
		return -1;

	ask.m_tag1 = 0x00;
	ask.m_tag2 = 0x03;
	CTWStockArray astocks;
	astocks.SetSize(0, size+1);
	for(size_t i=0; i<size; i++)	astocks.Add(pStocks[i]);
	ask.m_serial = GetNextSerial(astocks);
	ask.m_size = shortSize;

	if(size > sizeof(ask.m_stocks)/sizeof(TW_STOCK))
		return -1;

	if(pStocks && shortSize > 0)
		memcpy(ask.m_stocks, pStocks, shortSize*sizeof(TW_STOCK));

	int ret = (6 + sizeof(ask.m_header) + shortSize * sizeof(TW_STOCK));
	ConstructLength(ask.m_header, ret - sizeof(ask.m_header));
	return ret;
}

int ConstructAskMinuteBuffer(TW_ASK& ask, TW_STOCK* pStock)
{
	memset(&ask, 0, sizeof(ask));
	ask.m_header.m_magic = TW_MAGIC;

	ask.m_tag1 = 0x01;
	ask.m_tag2 = 0x04;
	ask.m_size = 0x0001;
	memcpy(&(ask.m_stocks[0]), pStock, sizeof(TW_STOCK));
	ask.m_serial = GetNextSerial(ask.m_stocks[0]);
	
	int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
	ConstructLength(ask.m_header, ret - sizeof(ask.m_header));
	return ret;
}

int ConstructAskHistoryBuffer(TW_ASK& ask, TW_STOCK* pStock, int nKType, int nDataCount, BOOL bChangeStock, BOOL bFirstRequest)
{
	memset(&ask, 0, sizeof(ask));
	ask.m_header.m_magic = TW_MAGIC;

	SHORT shortSize = (SHORT)nDataCount;

	ask.m_tag1 = 0x00;
	ask.m_tag2 = 0x09;
	ask.m_size = - shortSize;
	memcpy(&(ask.m_stocks[0]), pStock, sizeof(TW_STOCK));
	ask.m_serial = GetNextSerial(ask.m_stocks[0], nDataCount);

	if (ktypeMin5 == nKType)
		ask.m_tag1 |= 0x30;
	else if(ktypeMin15 == nKType)
		ask.m_tag1 |= 0x40;
	else if(ktypeMin30 == nKType)
		ask.m_tag1 |= 0x50;
	else if(ktypeMin60 == nKType)
		ask.m_tag1 |= 0x60;
	else if(ktypeDay == nKType)
		ask.m_tag1 |= 0x10;
	else if(ktypeWeek == nKType)
		ask.m_tag1 |= 0x80;
	else if(ktypeMonth == nKType)
		ask.m_tag1 |= 0x90;

	if (bChangeStock)
		ask.m_tag1 |= 0x03;
	else if(bFirstRequest)
		ask.m_tag1 |= 0x01;
	else
		ask.m_tag1 |= 0x02;

	if (ktypeDay == nKType && bChangeStock)
		ask.m_tag1 = 0x20;

	int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
	ConstructLength(ask.m_header, ret - sizeof(ask.m_header));

	return ret;
}

int ConstructAskMultisortBuffer(TW_ASK& ask, TW_STOCK* pStock)
{
	memset(&ask, 0, sizeof(ask));
	ask.m_header.m_magic = TW_MAGIC;

	BYTE	type = typeshA;
	if(pStock)
		type = pStock->m_type;

	TW_STOCK	stock;
	memset(&stock, 0, sizeof(stock));

	SHORT shortSize = 9;

	ask.m_tag1 = 0x0a;
	ask.m_tag2 = 0x08;
	ask.m_size = - shortSize;
	ask.m_stocks[0].m_type = type;
	ask.m_stocks[0].m_code[0] = 0x06;
	ask.m_stocks[0].m_code[1] = 0x00;
	ask.m_stocks[0].m_code[2] = (char)0xff;
	ask.m_stocks[0].m_code[3] = 0x01;
	ask.m_stocks[0].m_code[4] = 0x00;
	ask.m_stocks[0].m_code[5] = 0x00;
	ask.m_serial = GetNextSerial(stock);
	int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
	ConstructLength(ask.m_header, ret - sizeof(ask.m_header));
	return ret;
}

int ConstructAskDetailBuffer(TW_ASK& ask, TW_STOCK* pStock)
{
	memset(&ask, 0, sizeof(ask));
	ask.m_header.m_magic = TW_MAGIC;

	ask.m_tag1 = 0x01;
	ask.m_tag2 = 0x02;
	ask.m_size = 0x0001;
	memcpy(&(ask.m_stocks[0]), pStock, sizeof(TW_STOCK));
	ask.m_serial = GetNextSerial(ask.m_stocks[0]);
	int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
	ConstructLength(ask.m_header, ret - sizeof(ask.m_header));
	return ret;
}

int ConstructAskBaseBuffer(TW_ASK& ask, TW_STOCK* pStock)
{
	memset(&ask, 0, sizeof(ask));
	ask.m_header.m_magic = TW_MAGIC;

	ask.m_tag1 = 0x05;
	ask.m_tag2 = 0x0b;
	ask.m_size = 0x0005;
	memcpy(&(ask.m_stocks[0]), pStock, sizeof(TW_STOCK));
	ask.m_serial = GetNextSerial(ask.m_stocks[0]);
	int ret = (6 + sizeof(ask.m_header) + 5*sizeof(TW_STOCK));
	ConstructLength(ask.m_header, ret - sizeof(ask.m_header));
	return ret;
}

size_t TryGetLength(TW_HEADER& header)
{
	if(TW_MAGIC != header.m_magic || 0 != header.m_end)
		return 0;
	int len = (int)strtol(header.m_length,NULL,16);
	if(len < 0)
		return 0;
	return (size_t)len;
}

size_t TryGetLength(BYTE* buffer, size_t len)
{
	if(len < sizeof(TW_HEADER))
		return 0;
	TW_HEADER * pheader = (TW_HEADER*)buffer;
	return TryGetLength(*pheader);
}

BOOL IsLoginOK(BYTE* buffer, size_t len)
{
	if(len < sizeof(TW_ANS))
		return FALSE;
	TW_ANS * pans = (TW_ANS *)buffer;
	if(TW_MAGIC != pans->m_header.m_magic)
		return FALSE;
	if(0x00 != pans->m_tag1 || 0x00 != pans->m_tag2)
		return FALSE;
	return TRUE;
}

int TryGetInit(BYTE* buffer, size_t len, PRCV_DATA pRCV_DATA)
{
	if(len < sizeof(TW_ANS))
		return 0;
	TW_ANS * pans = (TW_ANS*)buffer;
	if(TW_MAGIC != pans->m_header.m_magic)
		return 0;
	if(0x02 != pans->m_tag1 || 0x01 != pans->m_tag2)
		return 0;

	// get it, fill pRCV_DATA
	size_t dataoffset = 469;
	int datalen = len - dataoffset;

	CSPTime tLatest(CSPTime::GetLatestTradeTime(time(NULL)));
	if(len > 128)
	{
		DWORD date = (*(DWORD*)(buffer+45));
		CSPTime sptime;
		if(sptime.FromStockTimeDay(date))
			tLatest = CSPTime(sptime.GetYear(),sptime.GetMonth(),sptime.GetDay(),9,15,0).GetTime();
	}
	if(pRCV_DATA && datalen >= (int)sizeof(TW_ANS_INIT))
	{
		// 每组28个字节, 共XXXX组,最后以0xfdfdfdfd为结尾
		TW_ANS_INIT * pinit = (TW_ANS_INIT*)(buffer+dataoffset);
		int packetsize = datalen/(int)sizeof(TW_ANS_INIT);

		memset(pRCV_DATA, 0, sizeof(RCV_DATA));
		pRCV_DATA->m_wDataType	=	RCV_REPORT;	// no use
		pRCV_DATA->m_nPacketNum	=	packetsize;
		pRCV_DATA->m_bDISK		=	FALSE;
		pRCV_DATA->m_pReport	=	new RCV_REPORT_STRUCTEx[packetsize];
		memset(pRCV_DATA->m_pReport, 0, sizeof(RCV_REPORT_STRUCTEx)*packetsize);

		for(int i=0;i <packetsize; i++)
		{
			if(pinit[i].m_tag != TW_MAGIC_BYTE)
				continue;
			pRCV_DATA->m_pReport[i].m_cbSize = sizeof(RCV_REPORT_STRUCTEx);
			pRCV_DATA->m_pReport[i].m_time = tLatest.GetTime();

			pRCV_DATA->m_pReport[i].m_wMarket = (pinit[i].m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
			pRCV_DATA->m_pReport[i].m_fLastClose = (float)(pinit[i].m_lastclose * 0.001);
			strncpy(pRCV_DATA->m_pReport[i].m_szLabel, pinit[i].m_code,
					min(sizeof(pRCV_DATA->m_pReport[i].m_szLabel),sizeof(pinit[i].m_code)));
			strncpy(pRCV_DATA->m_pReport[i].m_szName, pinit[i].m_name,
					min(sizeof(pRCV_DATA->m_pReport[i].m_szName),sizeof(pinit[i].m_name)));
			strncpy(pRCV_DATA->m_pReport[i].m_szName+sizeof(pinit[i].m_name)+2, pinit[i].m_shortname,
					min(sizeof(pRCV_DATA->m_pReport[i].m_szName)-sizeof(pinit[i].m_name)-2,sizeof(pinit[i].m_shortname)));
		}

		return len;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -