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

📄 commands.cpp

📁 通信达接口引警 可直接下载股票数据,建立自已的股票软件
💻 CPP
字号:

#include "config.h"


#include <vector>
#include <set>
#include <map>
#include <queue>

#include <boost/thread/detail/config.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
//#include <boost/smart_assert/assert.hpp>
#include <boost/tuple/tuple.hpp>

#include <loki/Factory.h>

#include "tcpSocket.h"
#include "stock.h"
#include "request.h"
#include "response.h"
#include "commands.h"

namespace StockMarket
{

	static const int max_transaction_per_day = 6000;
	
	recursive_mutex InstantTransRes::inst_trans_res_map_mutex;

	InstantTransShareData g_InstantTransShareData;

	InstantTransReq::InstantTransReq(const string& stock_code, int count) 
		: s(stock_code, 0, count), finished(false) ,all_stock(false)
	{
		g_InstantTransShareData.current_stock = current_stock;
	}
	InstantTransReq::InstantTransReq(int count = 1000) : s("000000", 0, count), finished(true) ,all_stock(true)
	{
		// set the first stock
		if("" != (current_stock = MarketInfo::get_first_stock()))
		{
			g_InstantTransShareData.current_stock = current_stock;
			s.set_stock_code(current_stock);
			finished = false;
		}
		else
		{
			finished = true;
		}
	}
	char* InstantTransReq::buff()
	{
		return (char*)&s;
	}
	ulong InstantTransReq::len()
	{
		return sizeof(InstantTransStruct);
	}
	void InstantTransReq::send(TcpSocket& soc)
	{
		Request::send(soc);
	}

	InstantTransReq& InstantTransReq::operator++()
	{
		if("" != (current_stock = MarketInfo::find_next_stock(current_stock)))
		{
			g_InstantTransShareData.current_stock = current_stock;
			s.set_stock_code(current_stock);
			finished = false;
		}
		else
		{
			finished = true;
		}
		return *this;
	}
	InstantTransReq::operator bool ()
	{
		return !finished;
	}
	InstantTransReq::InstantTransStruct::InstantTransStruct(){}
	InstantTransReq::InstantTransStruct::InstantTransStruct(const string& stock_code,  ushort record_offset, ushort record_count )
		: header(CMD_INSTANT_TRANS, sizeof(InstantTransStruct)), 
		offset(record_offset), count(record_count)
	{
		set_stock_code(stock_code);
	}
	void InstantTransReq::InstantTransStruct::set_stock_code(const string& stock_code)
	{
		memcpy(code, stock_code.c_str(), MarketInfo::StocksCodeLen);
		location = MarketInfo::get_market_location(stock_code);
	}

	void InstantTransRes::operator()()
	{
		recursive_mutex::scoped_lock guard(inst_trans_res_map_mutex);

		const int recent_data_buffer = 1000;

		StockTransact::DailyTransact& today_t = today_transact[g_InstantTransShareData.current_stock];
		static StockTransact::Transact temp_daily_t[recent_data_buffer];	// 如果连续 多个 个相同,就认为是同一序列
		bool is_the_first_get = today_t.empty();

		StockTransact::Transact t;
		uint priceBase = 0;
		int first = 1;
		
		ushort count = get_ushort();

		int new_data_count = 0;
		
		while(count-- > 0)
		{
			t.minute = get_ushort();
			// relatively loose assert
			if(t.minute < 9 * 60 || t.minute > 16 * 60)
			{
				throw StockResWrongData(5);
			}
			if(first)
			{
				priceBase = t.price = parse_data2();
				first = 0;
			}
			else
			{
				priceBase = t.price = (uint)(parse_data2() + priceBase);
			}
			t.vol = parse_data2();
			t.count = get_uchar();		// 成交笔数。 0: 未知
			t.bs = get_uchar();
			skip_byte(1);			// the ending zero

			if(is_the_first_get)
			{
				today_t.push_back(t);
			}
			else
			{
				temp_daily_t[new_data_count++] = t;
			}
		}
		if(is_the_first_get) return;

		// 确定两序列中要比较的记录数
		int to_compare_count = 5 < today_t.size() ? 5 : today_t.size();

		if(new_data_count < to_compare_count) return;	// 太少数据,肯定出错了。

		// 匹配两序列中相同的部分
		bool matched = true; int i = 0, j = 0;
		for(; i < new_data_count; ++i)
		{
			matched = true;
			for(uint compare_index = today_t.size() - to_compare_count, j = i;
				compare_index < today_t.size(); ++compare_index, ++j)
			{
				if((today_t[compare_index].price != temp_daily_t[j].price) 
					|| (today_t[compare_index].vol != temp_daily_t[j].vol)
					|| (today_t[compare_index].minute != temp_daily_t[j].minute)
					|| (today_t[compare_index].bs != temp_daily_t[j].bs))
				{
					matched = false;
					break;
				}
			}
			if(matched)
			{
				break;
			}
		}
		// 将不相同即新增部分,添加到原有数据后。
		if(matched)
		{
			for(++j; j < new_data_count; ++j)
			{
				today_t.push_back(temp_daily_t[j]);
			}
		}
		return;

	}

	recursive_mutex HisTransRes::his_trans_res_map_mutex;

	HisTransShareData g_HisTransShareData;
	
	HisTransReq::HisTransReq(const string& stock_code,  uint record_date)
		: s(stock_code, record_date, 0, to_get_count), current_stock(stock_code), finished(false), all_stock(false)
	{
		g_HisTransShareData.current_stock = current_stock;
		g_HisTransShareData.date = record_date;
		g_HisTransShareData.to_get_offset = 0;
		g_HisTransShareData.total_got_count = 0;
		g_HisTransShareData.got_one_stock = false;
	}
	HisTransReq::HisTransReq(uint record_date)
		: s("000000", record_date, 0, to_get_count), finished(true) ,all_stock(true)
	{
		// set the first stock
		if("" != (current_stock = MarketInfo::get_first_stock()))
		{
			s.set_stock_code(current_stock);
			finished = false;

			g_HisTransShareData.current_stock = current_stock;
			g_HisTransShareData.date = record_date;
			g_HisTransShareData.to_get_offset = 0;
			g_HisTransShareData.total_got_count = 0;
			g_HisTransShareData.got_one_stock = false;
		}
		else
		{
			finished = true;
		}
	}
	char* HisTransReq::buff()
	{
		return (char*)&s;
	}
	ulong HisTransReq::len()
	{
		return sizeof(HisTransStruct);
	}
	void HisTransReq::send(TcpSocket& soc)
	{
		Request::send(soc);
	}
	HisTransReq& HisTransReq::operator++()
	{
		if(!g_HisTransShareData.got_one_stock)
		{
			g_HisTransShareData.to_get_offset = g_HisTransShareData.total_got_count;
			s.set_offset(g_HisTransShareData.to_get_offset);
			return *this;
		}

		if("" != (current_stock = MarketInfo::find_next_stock(current_stock)))
		{
			g_HisTransShareData.current_stock = current_stock;
			g_HisTransShareData.to_get_offset = 0;
			g_HisTransShareData.total_got_count = 0;
			g_HisTransShareData.got_one_stock = false;			// Next Stock

			s.set_stock_code(current_stock);
			s.set_offset(g_HisTransShareData.to_get_offset);
			finished = false;
		}
		else
		{
			finished = true;
		}
		return *this;
	}
	HisTransReq::operator bool ()
	{
		return !finished;
	}
	
	HisTransReq::HisTransStruct::HisTransStruct(){}
	HisTransReq::HisTransStruct::HisTransStruct(const string& stock_code,  uint record_date, ushort record_offset, ushort record_count)
		: header(CMD_HIS_TRANS, sizeof(HisTransStruct)), date(record_date), offset(record_offset), count(record_count)
	{
		set_stock_code(stock_code);
	}
	void HisTransReq::HisTransStruct::set_stock_code(const string& stock_code)
	{
		memcpy(code, stock_code.c_str(), MarketInfo::StocksCodeLen);
		location = MarketInfo::get_market_location(stock_code);
	}
	void HisTransReq::HisTransStruct::set_offset(ushort off)
	{
		offset = off;
	}

  	void HisTransRes::operator()()
	{
		recursive_mutex::scoped_lock guard(his_trans_res_map_mutex);

		static StockTransact::Transact temp_daily_t[max_transaction_per_day];				// 缓冲, 大一些安全一些

		int priceBase = 0;
		int first = 1;
		
		short count = get_short();
		skip_byte(4);													// do not know what it is

		short got_count = count;
		g_HisTransShareData.total_got_count += count;

		int temp_count = g_HisTransShareData.total_got_count;
		
		if(g_HisTransShareData.total_got_count > max_transaction_per_day)										// 缓冲满
		{
			cout << __FUNCTION__ << " code= " << g_HisTransShareData.current_stock << " date = " << g_HisTransShareData.date << "count= " << count << endl;
			throw StockResWrongData(6);
		}

		StockTransact::Transact *t = &temp_daily_t[max_transaction_per_day - g_HisTransShareData.total_got_count];
		while(count--)
		{
			t->minute = get_short();
			// relatively loose assert
			if(t->minute < 9 * 60 || t->minute > 16 * 60 || priceBase < 0)
			{
				cout << __FUNCTION__ << " code= " << g_HisTransShareData.current_stock << " date = " << g_HisTransShareData.date << "count= " << count << endl;
				throw StockResWrongData(7);
			}
			if(first)
			{
				priceBase = t->price = parse_data2();
				first = 0;
			}
			else
			{
				priceBase = t->price = parse_data2() + priceBase;
			}
			t->vol = parse_data2();
			t->bs = get_uchar();
			t->count = get_uchar();

			++t;
		}
		if(got_count < HisTransReq::to_get_count)				// 结束
		{
			StockTransact::DailyTransact& daily_t = hist_transact[g_HisTransShareData.date][g_HisTransShareData.current_stock];
			daily_t.assign(&temp_daily_t[max_transaction_per_day - g_HisTransShareData.total_got_count], &temp_daily_t[max_transaction_per_day]);
			g_HisTransShareData.got_one_stock = true;
			return;
		}
	}

	StockRes* CreateInstantTransRes()
	{
		return new InstantTransRes();
	}
	
	StockRes* CreateHisTransRes()
	{
		return new HisTransRes();
	}
	

}


⌨️ 快捷键说明

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