commands.cpp
上传用户:egreat
上传日期:2007-07-13
资源大小:29k
文件大小:9k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. #include "config.h"
  2. #include <vector>
  3. #include <set>
  4. #include <map>
  5. #include <queue>
  6. #include <boost/thread/detail/config.hpp>
  7. #include <boost/thread/thread.hpp>
  8. #include <boost/thread/recursive_mutex.hpp>
  9. #include <boost/smart_ptr.hpp>
  10. #include <boost/date_time/posix_time/posix_time_types.hpp>
  11. //#include <boost/smart_assert/assert.hpp>
  12. #include <boost/tuple/tuple.hpp>
  13. #include <loki/Factory.h>
  14. #include "tcpSocket.h"
  15. #include "stock.h"
  16. #include "request.h"
  17. #include "response.h"
  18. #include "commands.h"
  19. namespace StockMarket
  20. {
  21. static const int max_transaction_per_day = 6000;
  22. recursive_mutex InstantTransRes::inst_trans_res_map_mutex;
  23. InstantTransShareData g_InstantTransShareData;
  24. InstantTransReq::InstantTransReq(const string& stock_code, int count) 
  25. : s(stock_code, 0, count), finished(false) ,all_stock(false)
  26. {
  27. g_InstantTransShareData.current_stock = current_stock;
  28. }
  29. InstantTransReq::InstantTransReq(int count = 1000) : s("000000", 0, count), finished(true) ,all_stock(true)
  30. {
  31. // set the first stock
  32. if("" != (current_stock = MarketInfo::get_first_stock()))
  33. {
  34. g_InstantTransShareData.current_stock = current_stock;
  35. s.set_stock_code(current_stock);
  36. finished = false;
  37. }
  38. else
  39. {
  40. finished = true;
  41. }
  42. }
  43. char* InstantTransReq::buff()
  44. {
  45. return (char*)&s;
  46. }
  47. ulong InstantTransReq::len()
  48. {
  49. return sizeof(InstantTransStruct);
  50. }
  51. void InstantTransReq::send(TcpSocket& soc)
  52. {
  53. Request::send(soc);
  54. }
  55. InstantTransReq& InstantTransReq::operator++()
  56. {
  57. if("" != (current_stock = MarketInfo::find_next_stock(current_stock)))
  58. {
  59. g_InstantTransShareData.current_stock = current_stock;
  60. s.set_stock_code(current_stock);
  61. finished = false;
  62. }
  63. else
  64. {
  65. finished = true;
  66. }
  67. return *this;
  68. }
  69. InstantTransReq::operator bool ()
  70. {
  71. return !finished;
  72. }
  73. InstantTransReq::InstantTransStruct::InstantTransStruct(){}
  74. InstantTransReq::InstantTransStruct::InstantTransStruct(const string& stock_code,  ushort record_offset, ushort record_count )
  75. : header(CMD_INSTANT_TRANS, sizeof(InstantTransStruct)), 
  76. offset(record_offset), count(record_count)
  77. {
  78. set_stock_code(stock_code);
  79. }
  80. void InstantTransReq::InstantTransStruct::set_stock_code(const string& stock_code)
  81. {
  82. memcpy(code, stock_code.c_str(), MarketInfo::StocksCodeLen);
  83. location = MarketInfo::get_market_location(stock_code);
  84. }
  85. void InstantTransRes::operator()()
  86. {
  87. recursive_mutex::scoped_lock guard(inst_trans_res_map_mutex);
  88. const int recent_data_buffer = 1000;
  89. StockTransact::DailyTransact& today_t = today_transact[g_InstantTransShareData.current_stock];
  90. static StockTransact::Transact temp_daily_t[recent_data_buffer]; // 如果连续 多个 个相同,就认为是同一序列
  91. bool is_the_first_get = today_t.empty();
  92. StockTransact::Transact t;
  93. uint priceBase = 0;
  94. int first = 1;
  95. ushort count = get_ushort();
  96. int new_data_count = 0;
  97. while(count-- > 0)
  98. {
  99. t.minute = get_ushort();
  100. // relatively loose assert
  101. if(t.minute < 9 * 60 || t.minute > 16 * 60)
  102. {
  103. throw StockResWrongData(5);
  104. }
  105. if(first)
  106. {
  107. priceBase = t.price = parse_data2();
  108. first = 0;
  109. }
  110. else
  111. {
  112. priceBase = t.price = (uint)(parse_data2() + priceBase);
  113. }
  114. t.vol = parse_data2();
  115. t.count = get_uchar(); // 成交笔数。 0: 未知
  116. t.bs = get_uchar();
  117. skip_byte(1); // the ending zero
  118. if(is_the_first_get)
  119. {
  120. today_t.push_back(t);
  121. }
  122. else
  123. {
  124. temp_daily_t[new_data_count++] = t;
  125. }
  126. }
  127. if(is_the_first_get) return;
  128. // 确定两序列中要比较的记录数
  129. int to_compare_count = 5 < today_t.size() ? 5 : today_t.size();
  130. if(new_data_count < to_compare_count) return; // 太少数据,肯定出错了。
  131. // 匹配两序列中相同的部分
  132. bool matched = true; int i = 0, j = 0;
  133. for(; i < new_data_count; ++i)
  134. {
  135. matched = true;
  136. for(uint compare_index = today_t.size() - to_compare_count, j = i;
  137. compare_index < today_t.size(); ++compare_index, ++j)
  138. {
  139. if((today_t[compare_index].price != temp_daily_t[j].price) 
  140. || (today_t[compare_index].vol != temp_daily_t[j].vol)
  141. || (today_t[compare_index].minute != temp_daily_t[j].minute)
  142. || (today_t[compare_index].bs != temp_daily_t[j].bs))
  143. {
  144. matched = false;
  145. break;
  146. }
  147. }
  148. if(matched)
  149. {
  150. break;
  151. }
  152. }
  153. // 将不相同即新增部分,添加到原有数据后。
  154. if(matched)
  155. {
  156. for(++j; j < new_data_count; ++j)
  157. {
  158. today_t.push_back(temp_daily_t[j]);
  159. }
  160. }
  161. return;
  162. }
  163. recursive_mutex HisTransRes::his_trans_res_map_mutex;
  164. HisTransShareData g_HisTransShareData;
  165. HisTransReq::HisTransReq(const string& stock_code,  uint record_date)
  166. : s(stock_code, record_date, 0, to_get_count), current_stock(stock_code), finished(false), all_stock(false)
  167. {
  168. g_HisTransShareData.current_stock = current_stock;
  169. g_HisTransShareData.date = record_date;
  170. g_HisTransShareData.to_get_offset = 0;
  171. g_HisTransShareData.total_got_count = 0;
  172. g_HisTransShareData.got_one_stock = false;
  173. }
  174. HisTransReq::HisTransReq(uint record_date)
  175. : s("000000", record_date, 0, to_get_count), finished(true) ,all_stock(true)
  176. {
  177. // set the first stock
  178. if("" != (current_stock = MarketInfo::get_first_stock()))
  179. {
  180. s.set_stock_code(current_stock);
  181. finished = false;
  182. g_HisTransShareData.current_stock = current_stock;
  183. g_HisTransShareData.date = record_date;
  184. g_HisTransShareData.to_get_offset = 0;
  185. g_HisTransShareData.total_got_count = 0;
  186. g_HisTransShareData.got_one_stock = false;
  187. }
  188. else
  189. {
  190. finished = true;
  191. }
  192. }
  193. char* HisTransReq::buff()
  194. {
  195. return (char*)&s;
  196. }
  197. ulong HisTransReq::len()
  198. {
  199. return sizeof(HisTransStruct);
  200. }
  201. void HisTransReq::send(TcpSocket& soc)
  202. {
  203. Request::send(soc);
  204. }
  205. HisTransReq& HisTransReq::operator++()
  206. {
  207. if(!g_HisTransShareData.got_one_stock)
  208. {
  209. g_HisTransShareData.to_get_offset = g_HisTransShareData.total_got_count;
  210. s.set_offset(g_HisTransShareData.to_get_offset);
  211. return *this;
  212. }
  213. if("" != (current_stock = MarketInfo::find_next_stock(current_stock)))
  214. {
  215. g_HisTransShareData.current_stock = current_stock;
  216. g_HisTransShareData.to_get_offset = 0;
  217. g_HisTransShareData.total_got_count = 0;
  218. g_HisTransShareData.got_one_stock = false; // Next Stock
  219. s.set_stock_code(current_stock);
  220. s.set_offset(g_HisTransShareData.to_get_offset);
  221. finished = false;
  222. }
  223. else
  224. {
  225. finished = true;
  226. }
  227. return *this;
  228. }
  229. HisTransReq::operator bool ()
  230. {
  231. return !finished;
  232. }
  233. HisTransReq::HisTransStruct::HisTransStruct(){}
  234. HisTransReq::HisTransStruct::HisTransStruct(const string& stock_code,  uint record_date, ushort record_offset, ushort record_count)
  235. : header(CMD_HIS_TRANS, sizeof(HisTransStruct)), date(record_date), offset(record_offset), count(record_count)
  236. {
  237. set_stock_code(stock_code);
  238. }
  239. void HisTransReq::HisTransStruct::set_stock_code(const string& stock_code)
  240. {
  241. memcpy(code, stock_code.c_str(), MarketInfo::StocksCodeLen);
  242. location = MarketInfo::get_market_location(stock_code);
  243. }
  244. void HisTransReq::HisTransStruct::set_offset(ushort off)
  245. {
  246. offset = off;
  247. }
  248.    void HisTransRes::operator()()
  249. {
  250. recursive_mutex::scoped_lock guard(his_trans_res_map_mutex);
  251. static StockTransact::Transact temp_daily_t[max_transaction_per_day]; // 缓冲, 大一些安全一些
  252. int priceBase = 0;
  253. int first = 1;
  254. short count = get_short();
  255. skip_byte(4); // do not know what it is
  256. short got_count = count;
  257. g_HisTransShareData.total_got_count += count;
  258. int temp_count = g_HisTransShareData.total_got_count;
  259. if(g_HisTransShareData.total_got_count > max_transaction_per_day) // 缓冲满
  260. {
  261. cout << __FUNCTION__ << " code= " << g_HisTransShareData.current_stock << " date = " << g_HisTransShareData.date << "count= " << count << endl;
  262. throw StockResWrongData(6);
  263. }
  264. StockTransact::Transact *t = &temp_daily_t[max_transaction_per_day - g_HisTransShareData.total_got_count];
  265. while(count--)
  266. {
  267. t->minute = get_short();
  268. // relatively loose assert
  269. if(t->minute < 9 * 60 || t->minute > 16 * 60 || priceBase < 0)
  270. {
  271. cout << __FUNCTION__ << " code= " << g_HisTransShareData.current_stock << " date = " << g_HisTransShareData.date << "count= " << count << endl;
  272. throw StockResWrongData(7);
  273. }
  274. if(first)
  275. {
  276. priceBase = t->price = parse_data2();
  277. first = 0;
  278. }
  279. else
  280. {
  281. priceBase = t->price = parse_data2() + priceBase;
  282. }
  283. t->vol = parse_data2();
  284. t->bs = get_uchar();
  285. t->count = get_uchar();
  286. ++t;
  287. }
  288. if(got_count < HisTransReq::to_get_count) // 结束
  289. {
  290. StockTransact::DailyTransact& daily_t = hist_transact[g_HisTransShareData.date][g_HisTransShareData.current_stock];
  291. daily_t.assign(&temp_daily_t[max_transaction_per_day - g_HisTransShareData.total_got_count], &temp_daily_t[max_transaction_per_day]);
  292. g_HisTransShareData.got_one_stock = true;
  293. return;
  294. }
  295. }
  296. StockRes* CreateInstantTransRes()
  297. {
  298. return new InstantTransRes();
  299. }
  300. StockRes* CreateHisTransRes()
  301. {
  302. return new HisTransRes();
  303. }
  304. }