#ifndef _RESPONSE_H #define _RESPONSE_H #include <set> #include <map> #include "stock.h" #include "BidQuoteObserver.h" using namespace std; typedef set<string> StringSet; typedef map <int, StringSet> IntStringSetMap; // 股票板块列表 class StockRes { public: StockRes(); StockRes(char* pData, long data_len); virtual ~StockRes(); unsigned int read(const uchar* pData, long data_len); long buff_left(); bool end(); void reset(); virtual void operator()() = 0; unsigned int get_packet_len(); static unsigned int get_packet_len(const uchar*); unsigned int get_seq_id(); static unsigned int get_seq_id(const uchar* pData); unsigned short get_cmd_id(); static unsigned short get_cmd_id(const uchar*); virtual void SetRequestInfo( const ReqTimeInfo& stInfo ); float GetPrice1k( int iA, int iB ); double GetVolume( int iVolRaw ); protected: void skip_byte(long count); void skip_data(long count); char get_char(); short get_short(); unsigned short get_ushort(); int get_int(); unsigned int get_uint(); float get_float(); int parse_data(); int parse_data2(); int get_time( int& iHour, int& iMinute ); int get_datetime( int iCategory, int& iYear, int& iMonth, int& iDay, int& iHour, int& iMinute ); protected: uchar* raw_data; // the raw data passed in long raw_len; // the raw data len uchar* data; // payload data, long len; // payload len uchar* current; // pointer to parse long left; // len left unparsed private: void umcompress_if(); bool dataNew; }; class StockHeartBeatRes: public StockRes { public: void operator()(); }; class StockListRes: public StockRes { public: StockListRes(); StockListRes(char* pData, long data_len); void operator()(); }; class GetStockCountRes: public StockRes { public: GetStockCountRes(); GetStockCountRes(char* pData, long data_len); void operator()(); }; class GetStockQuotesRes: public StockRes { public: GetStockQuotesRes(); GetStockQuotesRes(char* pData, long data_len); ~GetStockQuotesRes(); void operator()(); void SetObserver( BidQuoteObserver * pObserver ) { m_pObserver = pObserver; } private: BidQuoteObserver * m_pObserver; }; struct StockResWrongData : public std::exception { StockResWrongData(int i = 0); virtual const char *what( ) const throw(); int n_; }; class GetMinuteDataRes: public StockRes { public: GetMinuteDataRes(); GetMinuteDataRes(char* pData, long data_len); void operator()(); }; class GetHisMinuteDataRes: public StockRes { public: GetHisMinuteDataRes(); GetHisMinuteDataRes(char* pData, long data_len); void operator()(); }; class GetTransactionDataRes: public StockRes { public: GetTransactionDataRes(); GetTransactionDataRes(char* pData, long data_len); void operator()(); }; class GetHisTransactionDataRes: public StockRes { public: GetHisTransactionDataRes(); GetHisTransactionDataRes(char* pData, long data_len); void operator()(); }; class GetIndexBarsRes: public StockRes { public: GetIndexBarsRes(); GetIndexBarsRes(char* pData, long data_len); void operator()(); virtual void SetRequestInfo( const ReqTimeInfo& stInfo ); private: int m_iCategory; }; StockRes* CreateStockHeartBeatRes(); StockRes* CreateGetStockCountRes(); StockRes* CreateGetStockQuotesRes(); StockRes* CreateGetMinuteDataRes(); StockRes* CreateGetHisMinuteDataRes(); StockRes* CreateGetTransactionDataRes(); StockRes* CreateGetHisTransactionDataRes(); StockRes* CreateGetIndexBarsRes(); #endif
#include "stdafx.h" #include <string> #include <vector> #include <set> #include <map> #include <iostream> #include <math.h> #include <time.h> #include "zlib/zlib.h" #include "stock.h" #include "response.h" #include "request.h" #include "util.hpp" #include "commands.h" StockRes::StockRes() :raw_data(0), raw_len(0), data(0),len(0),current(0),left(0),dataNew(false) { } StockRes::StockRes(char* pData, long data_len) : raw_data((uchar*)pData), raw_len(data_len) { this->read((uchar*)pData, data_len); } StockRes::~StockRes() { if ( dataNew ) { delete[] data; data = NULL; } } // if the data is compressed, then uncompressed them; Or else do nothing void StockRes::umcompress_if() { len = *(unsigned short*)(current); long new_len = *(unsigned short*)(current + 2); long new_len2 = new_len; skip_byte(4); // now the current moved to the real or compressed data //cout << "after skip_byte:" << get_raw_string( string( (char*) current, 2 ) ) << endl; if ( (uchar)0x78 == current[0] && (uchar)0x9c == current[1] ) { //cout << "has to uncompress " << endl; uchar* new_data = new uchar[new_len]; if ( 0 == uncompress((Byte*)new_data, (unsigned long*)&new_len, (Byte*)current, len) && new_len == new_len2 ) { dataNew = true; current = data = new_data; left = len = new_len; //cout << "uncompress succ" << endl; } else { delete[] new_data; throw StockResWrongData(2); } } else { data += 16; current = data; } } unsigned int StockRes::read( const uchar* pData, long data_len ) { raw_data = current = data = (uchar*)pData; dataNew = false; long len1 = get_packet_len(); len1 = len1 < data_len ? len1 : data_len; raw_len = left = len = len1; long len2 = *(unsigned short*)(pData + 14); skip_byte(16 - 4); // this time, the data and len are re-adjust !! // reserve the len2 for umcompress_if umcompress_if(); if ( len != len2 ) { throw StockResWrongData(8); } return len1; } long StockRes::buff_left() { return left; } bool StockRes::end() { return 0 == left; } void StockRes::reset() { raw_data = NULL; raw_len = 0; len = 0; current = NULL; left = 0; if ( dataNew ) { delete[] data; dataNew = false; } data = NULL; } void StockRes::skip_byte( long count ) { if ( count > left ) { throw StockResWrongData(1); } current += count; left -= count; } void StockRes::skip_data(long count) { while(count --) { if(current[0] < 0x80) skip_byte(1); else if(current[1] < 0x80) skip_byte(2); else skip_byte(3); } } char StockRes::get_char() { char v = (*current); skip_byte(1); return v; } short StockRes::get_short() { short v = *(short*)current; skip_byte(2); return v; } unsigned short StockRes::get_ushort() { unsigned short v = *(unsigned short*)current; skip_byte(2); return v; } int StockRes::get_int() { int v = *(int*)current; skip_byte(4); return v; } unsigned int StockRes::get_uint() { unsigned int v = *(unsigned int*)current; skip_byte(4); return v; } float StockRes::get_float() { float v = *(float*)current; skip_byte(4); return v; } int StockRes::parse_data() { if ( ( current[0] >= 0x40 && current[0] < 0x80 ) || current[0] >= 0xc0 ) // negative { return 0x40 - parse_data2(); } else { return parse_data2(); } } int StockRes::parse_data2() // we don't know this is correct yet { // 8f ff ff ff 1f == -49 // bd ff ff ff 1f == -3 // b0 fe ff ff 1f == -80 // 8c 01 == 76 // a8 fb b6 01 == 1017 万 // a3 8e 11 == 14.02 万 // 82 27 == 2498 int v; int nBytes = 0; while(current[nBytes] >= 0x80) { ++nBytes; } ++nBytes; switch(nBytes) { case 1: v = current[0]; break; case 2: v = current[1] * 0x40 + current[0] - 0x80; break; case 3: v = (current[2] * 0x80 + current[1] - 0x80) * 0x40 + current[0] - 0x80; break; case 4: v = ((current[3] * 0x80 + current[2] - 0x80) * 0x80 + current[1] - 0x80) * 0x40 + current[0] - 0x80; break; case 5: // over flow, positive to negative v = (((current[4] * 0x80 + current[3] - 0x80) * 0x80 + current[2] - 0x80) * 0x80 + current[1] - 0x80)* 0x40 + current[0] - 0x80; break; case 6: // over flow, positive to negative v = ((((current[5] * 0x80 + current[4] -0x80) * 0x80 + current[3] - 0x80) * 0x80 + current[2] - 0x80) * 0x80 + current[1] - 0x80) * 0x40 + current[0] - 0x80; break; default: throw StockResWrongData(10); } skip_byte(nBytes); return v; } /* def get_time(buffer, pos): (tminutes, ) = struct.unpack("<H", buffer[pos: pos + 2]) hour = int(tminutes / 60) minute = tminutes % 60 pos += 2 return hour, minute, pos */ int StockRes::get_time( int& iHour , int& iMinute ) { ushort iValue = get_ushort(); iHour = iValue / 60; iMinute = iValue % 60; return 0; } /* def get_datetime(category, buffer, pos): year = 0 month = 0 day = 0 hour = 15 minute = 0 if category < 4 or category == 7 or category == 8: (zipday, tminutes) = struct.unpack("<HH", buffer[pos: pos + 4]) year = (zipday >> 11) + 2004 month = int((zipday % 2048) / 100) day = (zipday % 2048) % 100 hour = int(tminutes / 60) minute = tminutes % 60 else: (zipday,) = struct.unpack("<I", buffer[pos: pos + 4]) year = int(zipday / 10000); month = int((zipday % 10000) / 100) day = zipday % 100 pos += 4 return year, month, day, hour, minute, pos */ int StockRes::get_datetime( int iCategory, int& iYear, int& iMonth, int& iDay, int& iHour, int& iMinute ) { iYear = 0; iMonth = 0; iDay = 0; iHour = 15; iMinute = 0; if ( iCategory < 4 || iCategory ==7 || iCategory == 8 ) { ushort uZipDay = get_ushort(); ushort uMinutes = get_ushort(); iYear = (uZipDay >> 11) + 2004; iMonth = int((uZipDay % 2048) / 100); iDay = (uZipDay % 2048) % 100; iHour = int(uMinutes / 60); iMinute = uMinutes % 60; } else { uint iZipDay = get_uint(); iYear = int(iZipDay / 10000); iMonth = int((iZipDay % 10000) / 100); iDay = iZipDay % 100; } return 0; } void StockRes::SetRequestInfo( const ReqTimeInfo& stInfo ) { } float StockRes::GetPrice1k( int iA, int iB ) { return ( iA + iB ) / 1000.0; } /* def get_volume(ivol): logpoint = ivol >> (8 * 3) hheax = ivol >> (8 * 3); # [3] hleax = (ivol >> (8 * 2)) & 0xff; # [2] lheax = (ivol >> 8) & 0xff; # [1] lleax = ivol & 0xff; # [0] dbl_1 = 1.0 dbl_2 = 2.0 dbl_128 = 128.0 dwEcx = logpoint * 2 - 0x7f; dwEdx = logpoint * 2 - 0x86; dwEsi = logpoint * 2 - 0x8e; dwEax = logpoint * 2 - 0x96; if dwEcx < 0: tmpEax = - dwEcx else: tmpEax = dwEcx dbl_xmm6 = 0.0 dbl_xmm6 = pow(2.0, tmpEax) if dwEcx < 0: dbl_xmm6 = 1.0 / dbl_xmm6 dbl_xmm4 = 0 if hleax > 0x80: tmpdbl_xmm3 = 0.0 tmpdbl_xmm1 = 0.0 dwtmpeax = dwEdx + 1 tmpdbl_xmm3 = pow(2.0, dwtmpeax) dbl_xmm0 = pow(2.0, dwEdx) * 128.0 dbl_xmm0 += (hleax & 0x7f) * tmpdbl_xmm3 dbl_xmm4 = dbl_xmm0 else: dbl_xmm0 = 0.0 if dwEdx >= 0: dbl_xmm0 = pow(2.0, dwEdx) * hleax else: dbl_xmm0 = (1 / pow(2.0, dwEdx)) * hleax dbl_xmm4 = dbl_xmm0 dbl_xmm3 = pow(2.0, dwEsi) * lheax dbl_xmm1 = pow(2.0, dwEax) * lleax if hleax & 0x80: dbl_xmm3 *= 2.0 dbl_xmm1 *= 2.0 dbl_ret = dbl_xmm6 + dbl_xmm4 + dbl_xmm3 + dbl_xmm1 return dbl_ret */ double StockRes::GetVolume( int iVolRaw ) { int logpoint = iVolRaw >> (8 * 3); int hheax = iVolRaw >> (8 * 3); int hleax = (iVolRaw >> (8 * 2)) & 0xff; int lheax = (iVolRaw >> 8) & 0xff; int lleax = iVolRaw & 0xff; double l1 = 1.0; double l2 = 2.0; double d128 = 128.0; int dwEcx = logpoint * 2 - 0x7f; int dwEdx = logpoint * 2 - 0x86; int dwEsi = logpoint * 2 - 0x8e; int dwEax = logpoint * 2 - 0x96; int tmpEax = 0; if ( dwEcx < 0 ) { tmpEax = - dwEcx; } else { tmpEax = dwEcx; } double dbl_xmm6 = pow(2.0, tmpEax); if ( dwEcx < 0 ) { dbl_xmm6 = 1.0 / dbl_xmm6; } double dbl_xmm4 = 0.0; double dbl_xmm0 = 0.0; if ( hleax > 0x80 ) { double tmpdbl_xmm3 = 0.0; double tmpdbl_xmm1 = 0.0; int dwtmpeax = dwEdx + 1; tmpdbl_xmm3 = pow(2.0, dwtmpeax); dbl_xmm0 = pow(2.0, dwEdx) * 128.0; dbl_xmm0 += (hleax & 0x7f) * tmpdbl_xmm3; dbl_xmm4 = dbl_xmm0; } else { if ( dwEdx >= 0 ) { dbl_xmm0 = pow(2.0, dwEdx) * hleax; } else { dbl_xmm0 = (1 / pow(2.0, dwEdx)) * hleax; } dbl_xmm4 = dbl_xmm0; } double dbl_xmm3 = pow(2.0, dwEsi) * lheax; double dbl_xmm1 = pow(2.0, dwEax) * lleax; if ( hleax & 0x80 ) { dbl_xmm3 *= 2.0; dbl_xmm1 *= 2.0; } return dbl_xmm6 + dbl_xmm4 + dbl_xmm3 + dbl_xmm1; } //============================================== void StockHeartBeatRes ::operator()() { } unsigned int StockRes::get_packet_len() { return get_packet_len(raw_data); } unsigned int StockRes::get_packet_len(const uchar* pData) { return (*(unsigned short*)(pData + 12)) + 16; } unsigned int StockRes::get_seq_id() { return get_seq_id(raw_data); } unsigned int StockRes::get_seq_id(const uchar* pData) { return *(unsigned int*)(pData + 5); } unsigned short StockRes::get_cmd_id() { return get_cmd_id(raw_data); } unsigned short StockRes::get_cmd_id(const uchar* pData) { return *(unsigned short*)(pData + 10); } GetStockCountRes::GetStockCountRes():StockRes() { } GetStockCountRes::GetStockCountRes(char* pData, long data_len):StockRes(pData, data_len) { } /* 获取股票数量 深市 GetStockCount 发送 0c 0c 18 6c 00 01 08 00 08 00 4e 04 00 00 75 c7 33 01 接收 Bc cb 74 00 0c 0c 18 6c 00 00 4e 04 02 00 02 00 e7 19 Bc cb 74 00 为固定的4个字节的头,0c 固定表示没有压缩 0c 18 6c 00 为seq_id 4e 04 不知道是什么 02 00 为长度,2个字节 02 00 重复长度 e7 19 为16进制的body 体,目前表示是股票数量字段 0x19 e7 为 6631 In [61]: 0x19e7 Out[61]: 6631 沪市 发送 0c 0c 18 6c 00 01 08 00 08 00 4e 04 01 00 75 c7 33 01 接收 Bc cb 74 00 0c 0c 18 6c 00 00 4e 04 02 00 02 00 b3 33 In [63]: 0x333b Out[63]: 13115 */ void GetStockCountRes::operator()() { short iCount = get_ushort(); cout << "stock count is " << iCount << endl; } //================================================================ GetStockQuotesRes::GetStockQuotesRes() :StockRes(),m_pObserver( NULL ) { } GetStockQuotesRes::GetStockQuotesRes( char* pData, long data_len ):StockRes( pData, data_len ), m_pObserver( NULL ) { } GetStockQuotesRes::~GetStockQuotesRes() { if ( m_pObserver ) { delete m_pObserver; m_pObserver = NULL; } } /* 获取股票实时行情 深市 发送 0c 01 00 00 00 02 13 00 13 00 3e 05 05 00 00 00 00 00 00 00 01 00 00 30 30 30 30 30 31 接收 b1 cb 74 0 c 1 0 0 0 0 3e 5 53 0 53 0 两个长度字段重复 真正的数据段从这里开始 64 4c 后面两个字节为股票的数量,short 1 0 后面依次为一个字节的market,6个字节的股票编码 0 30 30 30 30 31 两个字节的 活跃度 active rate 字段 6e e bb 11 10 c c 46 85 87 ef d fb 11 97 f8 36 b6 1 9a 2f f6 4d 87 aa 1f 90 ce 17 1 a7 d 0 1 99 e 95 2f 41 2 88 1 95 18 42 3 b2 2b a4 c 43 4 8d 20 b0 4 44 5 8c 4b 8b f 8 11 0 1c 20 9 11 0 6e e */ void GetStockQuotesRes::operator()() { // 此时 data 指向buffer开头 + 16个字节的位置,也就是真正的数据段 skip_byte(2);// 跳过 64 4c ushort count = get_ushort(); //cout << "count is " << count << endl; StockBid::Bid bid; memset( (char*)&bid, 0, sizeof(bid) ); while ( count-- ) { std::string code((char*)(current + 1), MarketInfo::StocksCodeLen); //cout << "stock code is " << code << endl; strcpy( bid.stock_code, code.c_str() ); skip_byte( MarketInfo::StocksCodeLen + 1 ); bid.minute = 3600; bid.act = get_ushort(); bid.price = parse_data(); bid.y_close = parse_data() + bid.price; bid.open = parse_data() + bid.price; bid.high = parse_data() + bid.price; bid.low = parse_data() + bid.price; bid.buy = parse_data() + bid.price; bid.sell = parse_data() + bid.price; bid.total_vol = parse_data2(); bid.avail_vol = parse_data2(); skip_byte(4); bid.inner_vol = parse_data2(); bid.outer_vol = parse_data2(); bid.updown = parse_data(); skip_data(1); bid.buy_price1 = parse_data() + bid.price; bid.sell_price1 = parse_data() + bid.price; bid.buy_vol1 = parse_data2(); bid.sell_vol1 = parse_data2(); bid.buy_price2 = parse_data() + bid.price; bid.sell_price2 = parse_data() + bid.price; bid.buy_vol2 = parse_data2(); bid.sell_vol2 = parse_data2(); bid.buy_price3 = parse_data() + bid.price; bid.sell_price3 = parse_data() + bid.price; bid.buy_vol3 = parse_data2(); bid.sell_vol3 = parse_data2(); bid.buy_price4 = parse_data() + bid.price; bid.sell_price4 = parse_data() + bid.price; bid.buy_vol4 = parse_data2(); bid.sell_vol4 = parse_data2(); bid.buy_price5 = parse_data() + bid.price; bid.sell_price5 = parse_data() + bid.price; bid.buy_vol5 = parse_data2(); bid.sell_vol5 = parse_data2(); //cout << "get one bid: bid.act:" << bid.act << ",bid.price:" << bid.price << "," // << "bid.y_close:" << bid.y_close << ",bid.open:" << bid.open << "," // << "bid.high:" << bid.high << ",bid.low:" << bid.low << endl; bid.update_time = time(NULL); if ( m_pObserver ) { m_pObserver->BidQuoteReceived( bid ); } // find next item. if ( 0 != count ) { skip_byte(8); const uchar* p = 0; if(0 != ( p = stock_code_search((const uchar*)current, 15))) { skip_byte(p - current - 1); } else { throw StockResWrongData(3); } } } return; } //================================================================== StockResWrongData::StockResWrongData( int i) : n_(i) { } const char * StockResWrongData::what() const throw() { return "StockResWrongData"; } //============================================ GetMinuteDataRes::GetMinuteDataRes():StockRes() { } GetMinuteDataRes::GetMinuteDataRes(char* pData, long data_len):StockRes(pData, data_len) { } /* 获取股票分时行情 深市 发送 0c 1b 08 00 01 01 0e 00 0e 00 1d 05 00 00 30 30 30 30 30 31 00 00 00 00 接收 b1 cb 74 0 1c 1 0 0 0 0 1d 5 78 9c 表示是压缩的数据,需要解压缩。解压后 头两个字节为数量 后两个字节跳过 未知 后面依次为 iPriceRaw , iReserved1, iVol */ void GetMinuteDataRes::operator()() { cout << "now current is:" << get_raw_string( string( (char*) current , len ) ) << endl; ushort count = get_ushort(); cout << "count is " << count << endl; skip_byte(2); MinuteData stData; memset( (char*)&stData, 0, sizeof(stData) ); int iLastPrice = 0; while ( count-- ) { stData.iPriceRaw = parse_data(); stData.iReserved1 = parse_data(); stData.iVol = parse_data(); iLastPrice += stData.iPriceRaw; cout << "get one MinuteData: iPriceRaw:" << stData.iPriceRaw << ", iReserved1:" << stData.iReserved1 << ",iVol:" << stData.iVol << ",iLastPrice:" << iLastPrice << endl; } return; } GetHisMinuteDataRes::GetHisMinuteDataRes():StockRes() { } GetHisMinuteDataRes::GetHisMinuteDataRes(char* pData, long data_len):StockRes(pData, data_len) { } /* 发送 0c 1b 08 00 01 01 0e 00 0e 00 1d 05 00 00 30 30 30 30 30 31 00 00 00 00 接收 b1 cb 74 0 1c 1 0 0 0 0 1d 5 78 9c 表示是压缩的数据,需要解压缩。解压后 头两个字节为数量 后4个字节跳过 未知 后面依次为 iPriceRaw , iReserved1, iVol */ void GetHisMinuteDataRes::operator()() { cout << "now current is:" << get_raw_string( string( (char*) current , len ) ) << endl; ushort count = get_ushort(); cout << "count is " << count << endl; skip_byte(4); MinuteData stData; memset( (char*)&stData, 0, sizeof(stData) ); int iLastPrice = 0; while ( count-- ) { stData.iPriceRaw = parse_data(); stData.iReserved1 = parse_data(); stData.iVol = parse_data(); iLastPrice += stData.iPriceRaw; cout << "get one HisMinuteData: iPriceRaw:" << stData.iPriceRaw << ", iReserved1:" << stData.iReserved1 << ",iVol:" << stData.iVol << ",iLastPrice:" << iLastPrice << endl; } return; } GetTransactionDataRes::GetTransactionDataRes():StockRes() { } GetTransactionDataRes::GetTransactionDataRes(char* pData, long data_len):StockRes(pData, data_len) { } /* 接收 b1 cb 74 0 1c 1 0 0 0 0 1d 5 */ void GetTransactionDataRes::operator()() { cout << "now current is:" << get_raw_string( string( (char*) current , len ) ) << endl; ushort count = get_ushort(); cout << "count is " << count << endl; MatchedData stData; memset( (char*)&stData, 0, sizeof(stData) ); int iLastPrice = 0; while ( count-- ) { get_time( stData.iHour , stData.iMinute ); stData.iPriceRaw = parse_data(); stData.iVol = parse_data(); stData.iNum = parse_data(); stData.iBuyOrSell = parse_data(); stData.iReserved = parse_data(); iLastPrice += stData.iPriceRaw; cout << "get one TransactionData: iHour:" << stData.iHour << ", iMinute:"<< stData.iMinute <<",iPriceRaw:" << stData.iPriceRaw << ",iVol:" << stData.iVol << ", iNum:" << stData.iNum << ",iBuyOrSell:" << stData.iBuyOrSell << ", iLastPrice:" << iLastPrice << endl; } return; } GetHisTransactionDataRes::GetHisTransactionDataRes():StockRes() { } GetHisTransactionDataRes::GetHisTransactionDataRes(char* pData, long data_len):StockRes(pData, data_len) { } void GetHisTransactionDataRes::operator()() { cout << "now current is:" << get_raw_string( string( (char*) current , len ) ) << endl; ushort count = get_ushort(); cout << "count is " << count << endl; skip_byte(4); MatchedData stData; memset( (char*)&stData, 0, sizeof(stData) ); int iLastPrice = 0; while ( count-- ) { get_time( stData.iHour , stData.iMinute ); stData.iPriceRaw = parse_data(); stData.iVol = parse_data(); stData.iBuyOrSell = parse_data(); stData.iReserved = parse_data(); iLastPrice += stData.iPriceRaw; cout << "get one HisTransactionData: iHour:" << stData.iHour << ", iMinute:"<< stData.iMinute <<",iPriceRaw:" << stData.iPriceRaw << ",iVol:" << stData.iVol << ", iNum:" << stData.iNum << ",iBuyOrSell:" << stData.iBuyOrSell << ", iLastPrice:" << iLastPrice << endl; } return; } GetIndexBarsRes::GetIndexBarsRes():StockRes() { } GetIndexBarsRes::GetIndexBarsRes(char* pData, long data_len):StockRes(pData, data_len) { } void GetIndexBarsRes::SetRequestInfo( const ReqTimeInfo& stInfo ) { m_iCategory = stInfo.iCategory; } void GetIndexBarsRes::operator()() { cout << "now current is:" << get_raw_string( string( (char*) current , len ) ) << endl; ushort count = get_ushort(); cout << "count is " << count << endl; IndexBarsData stData; memset( (char*)&stData, 0, sizeof(stData) ); int iLastPrice = 0; int iPreDiffBase = 0; while ( count-- ) { get_datetime( m_iCategory, stData.iYear, stData.iMonth, stData.iDay, stData.iHour , stData.iMinute ); stData.iPriceOpenDiff = parse_data(); stData.iPriceCloseDiff = parse_data(); stData.iPriceHighDiff = parse_data(); stData.iPriceLowDiff = parse_data(); stData.iVolRaw = get_uint(); double dVol = GetVolume( stData.iVolRaw ); stData.iDbVolRaw = get_uint(); double dDbVol = GetVolume( stData.iDbVolRaw ); stData.iUpCount = get_ushort(); stData.iDownCount = get_ushort(); float fOpen = GetPrice1k( iPreDiffBase , stData.iPriceOpenDiff ); int iPriceOpenDiff = iPreDiffBase + stData.iPriceOpenDiff; float fClose = GetPrice1k( iPriceOpenDiff , stData.iPriceCloseDiff ); float fHigh = GetPrice1k( iPriceOpenDiff, stData.iPriceHighDiff ); float fLow = GetPrice1k( iPriceOpenDiff, stData.iPriceLowDiff ); iPreDiffBase = stData.iPriceOpenDiff + stData.iPriceCloseDiff; cout << "get one indexbardata: iYear:" << stData.iYear << ",iMonth:" << stData.iMonth <<",iDay:" << stData.iDay << ",iHour:" << stData.iHour << ", iMinute:"<< stData.iMinute <<",open:" << fOpen << ",close:" << fClose << ", high:" << fHigh << ", low:" << fLow << ",iVol:" << dVol << ", dDbVol:" << dDbVol << ",iUpCount:" << stData.iUpCount << ", iDownCount:" << stData.iDownCount << endl; } return; } //====================================== StockRes* CreateStockHeartBeatRes() { return new StockHeartBeatRes(); } StockRes* CreateGetStockCountRes() { return new GetStockCountRes(); } StockRes* CreateGetStockQuotesRes() { GetStockQuotesRes* pRes = new GetStockQuotesRes(); BidQuoteObserver * pObserver = new BidQuoteObserver(); pRes->SetObserver( pObserver ); return pRes; } StockRes* CreateGetMinuteDataRes() { return new GetMinuteDataRes(); } StockRes* CreateGetHisMinuteDataRes() { return new GetHisMinuteDataRes(); } StockRes* CreateGetTransactionDataRes() { return new GetTransactionDataRes(); } StockRes* CreateGetHisTransactionDataRes() { return new GetHisTransactionDataRes(); } StockRes* CreateGetIndexBarsRes() { return new GetIndexBarsRes(); }