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

金融证券系统

开发平台:

Visual C++

  1. #include "config.h"
  2. #include <string>
  3. #include <vector>
  4. #include <set>
  5. #include <map>
  6. #include <iostream>
  7. //#include <boost/assign/std/vector.hpp>
  8. //#include <boost/assign/list_inserter.hpp>
  9. #include <boost/thread/detail/config.hpp>
  10. #include <boost/thread/thread.hpp>
  11. #include <boost/thread/recursive_mutex.hpp>
  12. #include <boost/date_time/gregorian/gregorian.hpp>
  13. #include "boost/filesystem/operations.hpp" // includes boost/filesystem/path.hpp
  14. #include "boost/filesystem/fstream.hpp"    // ditto
  15. // #include <boost/smart_assert/assert.hpp>
  16. #include <boost/foreach.hpp>
  17. #include "stockio.h"
  18. #include "util.hpp"
  19. #include "stock.h"
  20. using namespace boost;
  21. BOOST_CLASS_TRACKING(StockMarket::GBBQMap, serialization::track_never);
  22. namespace StockMarket{
  23. // using namespace assign;
  24. const float MarketInfo::tax = 0.01f; // 1 %
  25. unsigned int MarketInfo::stocks_count[MarketInfo::MARKET_MAX];
  26. StringSet  MarketInfo::stocks_set[MarketInfo::MARKET_MAX];
  27. recursive_mutex transact_mutex;
  28. recursive_mutex bid_mutex;
  29. StockTransact::DateTransact today_transact;
  30. StockTransact::TransactMap hist_transact;
  31. StockBid::BidMap  instant_price_list;
  32. #if 0
  33. int StockBasicInfo::apply_gbbq_front(const string &stock_code, const gregorian::date& ref_dt
  34. , const gregorian::date& dst_dt, int ref_price)
  35. {
  36. float new_price = static_cast<float>(ref_price);
  37. uint uint_ref_dt = date_to_uint(ref_dt);
  38. uint uint_dst_dt = date_to_uint(dst_dt);
  39. DateGBBQ &dgb = stock_gbbq_info[stock_code];
  40. for(DateGBBQ::const_iterator iter = dgb.begin(); iter < dgb.end(); ++iter)
  41. {
  42. if(iter->dt <= uint_ref_dt) 
  43. continue;
  44. else if(iter->dt <= uint_dst_dt) 
  45. {
  46. if(1 == iter->chg_type && iter->data.bonus.cash > 0.1) // 派发现金
  47. {
  48. new_price -= iter->data.bonus.cash * 10;
  49. }
  50. if(1 == iter->chg_type && iter->data.bonus.sell_price > 0.1) // 配股
  51. {
  52. float sell_price = 0, sell_count = 0;
  53. sell_price = iter->data.bonus.sell_price * 100; // 转化为分
  54. sell_count = iter->data.bonus.sell_count;
  55. new_price += ((sell_price * sell_count) / 10);
  56. }
  57. else if(1 == iter->chg_type&& iter->data.bonus.give_count > 0) // 送或配股或转增股上市
  58. {
  59. new_price = (new_price * 10) / (10 + iter->data.bonus.give_count);
  60. }
  61. else if(6 == iter->chg_type && iter->data.bonus.sell_price > 0.1) // 增发
  62. {
  63. }
  64. else if(8 == iter->chg_type) // 增发上市
  65. {
  66. }
  67. }
  68. else
  69. {
  70. break;
  71. }
  72. }
  73. if(new_price < 0) new_price = 0;
  74. return static_cast<int>(new_price);
  75. }
  76. #endif
  77. string StockBasicInfo::get_gbbq_file_name(uint tr_date)
  78. {
  79. const string stock_gbbq_file = "F:\Develop\stock\data\G";
  80. stringstream ss;
  81. ss << stock_gbbq_file << tr_date << ".mat";
  82. return ss.str();
  83. }
  84. bool StockBasicInfo::is_gbbq_file_exist(uint tr_date)
  85. {
  86. return is_file_exist(get_gbbq_file_name(tr_date));
  87. }
  88. void StockBasicInfo::clear_gbbq_info()
  89. {
  90. stock_gbbq_info.clear();
  91. }
  92. #if 0
  93. bool StockBasicInfo::load_gbbq_info(gregorian::date tr_date, int day_count)
  94. {
  95. while(day_count--)
  96. {
  97. if(is_gbbq_file_exist(date_to_uint(tr_date)))
  98. {
  99. string filename = get_gbbq_file_name(date_to_uint(tr_date));
  100. ifstream ifs(filename.c_str(), ios::binary);
  101. if(ifs)
  102. {
  103. archive::binary_iarchive ia(ifs);
  104. ia >> stock_gbbq_info;
  105. std::cout << "GBBQ file " << filename << " appliedrn";
  106. return true;
  107. }
  108. }
  109. tr_date -= gregorian::date_duration(1);
  110. }
  111. std::cout << "No GBBQ found!rn";
  112. return false;
  113. }
  114. #endif
  115. void StockBasicInfo::save_gbbq_info(uint tr_date)
  116. {
  117. if (is_gbbq_file_exist(tr_date))
  118. {
  119. return;
  120. }
  121. string filename = get_gbbq_file_name(tr_date);
  122. int maxDealCount = 0;
  123. GBBQMap::const_iterator iter;
  124. for(iter = stock_gbbq_info.begin();iter !=  stock_gbbq_info.end(); ++iter)
  125. {
  126. if(iter->second.size() > (uint)maxDealCount)
  127. {
  128. maxDealCount = iter->second.size();
  129. }
  130. }
  131. const int col_count = 8;
  132. int dims[3];
  133. dims[0] = col_count;
  134. dims[1] = maxDealCount;
  135. dims[2] = stock_gbbq_info.size();
  136. mxArray *mx_t0_data = mxCreateNumericArray(3, &dims[0], mxDOUBLE_CLASS, mxREAL);
  137. double *p_mxT0data = mxGetPr(mx_t0_data), *p_temp_mxT0data = p_mxT0data;
  138. const gregorian::date christ_date(2000,1,1);
  139. for(GBBQMap::const_reverse_iterator iter = stock_gbbq_info.rbegin(); iter != stock_gbbq_info.rend(); ++iter)
  140. {
  141. for(DateGBBQ::const_iterator iter_code = iter->second.begin();iter_code !=  iter->second.end(); ++iter_code)
  142. {
  143. p_temp_mxT0data[0] = iter->first;
  144. p_temp_mxT0data[1] = (uint_to_date(iter->first) - christ_date).days() + 730486; // 相当于 matlab 的 date_num
  145. p_temp_mxT0data[2] = atoi(iter_code->code.c_str());
  146. p_temp_mxT0data[3] = iter_code->chg_type;
  147. p_temp_mxT0data[4] = iter_code->data.gb.old_cir;
  148. p_temp_mxT0data[5] = iter_code->data.gb.old_ttl;
  149. p_temp_mxT0data[6] = iter_code->data.gb.new_cir;
  150. p_temp_mxT0data[7] = iter_code->data.gb.new_ttl;
  151. p_temp_mxT0data += col_count;
  152. }
  153. p_mxT0data += maxDealCount * col_count;
  154. p_temp_mxT0data = p_mxT0data;
  155. }
  156. matlab_engine::Instance().saveVarToFile(filename, mx_t0_data, "gbbq_info");
  157. mxDestroyArray(mx_t0_data);
  158. }
  159. bool StockBasicInfo::load_basic_info()
  160. {
  161. // 加载股票基本资料
  162. // 基本信息
  163. stock_base_info.clear();
  164. BaseInfo bs;
  165. const string stock_data_path = "C:\Program Files\xyzq\T0002\";
  166. string full_path = stock_data_path + "BASE.DBF";
  167. fstream fs(full_path.c_str(), ios::in);
  168. // fstream ofs("d:\temp\t.txt", ios::out);
  169. if(!fs) return false;
  170. int record_off = 0x522;
  171. fs.seekg(record_off);
  172. char c;
  173. fs >> c;
  174. while(!fs.eof() && -1 != fs.tellg())
  175. {
  176. fs >> bs;
  177. record_off += BaseInfo::record_len;
  178. stock_base_info.insert(make_pair(bs.stock_code, bs));
  179. // ofs << bs.stock_code << endl;
  180. fs.seekg(record_off);
  181. fs >> c;
  182. }
  183. return true;
  184. }
  185. void StockBasicInfo::save_basic_info()
  186. {
  187. const string filename = "F:\Develop\stock\data\basic_info.mat";
  188. StockBaseInfoMap::const_iterator iter_code;
  189. const int deal_col_count = 31;
  190. int dims[2];
  191. dims[0] = deal_col_count;
  192. dims[1] = stock_base_info.size();
  193. mxArray *mx_t0_data = mxCreateNumericArray(2, &dims[0], mxDOUBLE_CLASS, mxREAL);
  194. double *p_mxT0data = mxGetPr(mx_t0_data), *p_temp_mxT0data = p_mxT0data;
  195. for(iter_code = stock_base_info.begin();iter_code !=  stock_base_info.end(); ++iter_code)
  196. {
  197. p_temp_mxT0data[0] = atoi(iter_code->first.c_str());
  198. p_temp_mxT0data[1] = iter_code->second.update_time;
  199. p_temp_mxT0data[2] = iter_code->second.ttl_amount;
  200. p_temp_mxT0data[3] = iter_code->second.state_own_amount;
  201. p_temp_mxT0data[4] = iter_code->second.init_amount;
  202. p_temp_mxT0data[5] = iter_code->second.corp_amount;
  203. p_temp_mxT0data[6] = iter_code->second.b_amount;
  204. p_temp_mxT0data[7] = iter_code->second.h_amount;
  205. p_temp_mxT0data[8] = iter_code->second.cir_amount;
  206. p_temp_mxT0data[9] = iter_code->second.empl_amount;
  207. p_temp_mxT0data[10] = iter_code->second.ttl_asset;
  208. p_temp_mxT0data[11] = iter_code->second.varible_asset;
  209. p_temp_mxT0data[12] = iter_code->second.firm_asset;
  210. p_temp_mxT0data[13] = iter_code->second.invisible_asset;
  211. p_temp_mxT0data[14] = iter_code->second.long_term_invest; // 长期投资
  212. p_temp_mxT0data[15] = iter_code->second.varible_debt; // 流动负债
  213. p_temp_mxT0data[16] = iter_code->second.long_term_debt;  // 长期负债
  214. p_temp_mxT0data[17] = iter_code->second.accu_fund; // 公积金
  215. p_temp_mxT0data[18] = iter_code->second.net_asset; // 净资产
  216. p_temp_mxT0data[19] = iter_code->second.major_income; // 主营收入
  217. p_temp_mxT0data[20] = iter_code->second.major_profit; // 主营利润
  218. p_temp_mxT0data[21] = iter_code->second.bussiness_income; // 营业收入
  219. p_temp_mxT0data[22] = iter_code->second.invest_income; // 营业收入
  220. p_temp_mxT0data[23] = iter_code->second.allowance; // 补贴收入
  221. p_temp_mxT0data[24] = iter_code->second.non_bussiness_income; // 业外收入
  222. p_temp_mxT0data[25] = iter_code->second.income_adjustment; // 收入调整
  223. p_temp_mxT0data[26] = iter_code->second.ttl_profit;  // 利润总额
  224. p_temp_mxT0data[27] = iter_code->second.unknown3; // 
  225. p_temp_mxT0data[28] = iter_code->second.net_profit;  // 税后利润
  226. p_temp_mxT0data[29] = iter_code->second.undist_profit; // 未分配利润
  227. p_temp_mxT0data[30] = iter_code->second.per_net_assert2; // 每股净资产2
  228. p_temp_mxT0data += deal_col_count;
  229. }
  230. matlab_engine::Instance().saveVarToFile(filename, mx_t0_data, "basic_info");
  231. mxDestroyArray(mx_t0_data);
  232. }
  233. bool StockBasicInfo::load_block_info()
  234. {
  235. // 加载板块资料
  236. stock_block_info.clear();
  237. const string stock_data_path = "C:\Program Files\xyzq\T0002\";
  238. string full_path = stock_data_path + "BLOCK.DAT";
  239. fstream fs(full_path.c_str(), ios::in | ios::binary);
  240. if(!fs) return false;
  241. int p = 0;
  242. fs.seekg(0x182);
  243. while(!fs.eof() && -1 != (p =fs.tellg()))
  244. {
  245. char temp[10];
  246. fs.read(&temp[0],9);
  247. if(0 == temp[0]) break;
  248. string name(temp); // block name
  249. unsigned short cnt = 0;
  250. fs.read((char*)&cnt, 2);
  251. fs.seekg(2, ios::cur);
  252. while(cnt -- > 0)
  253. {
  254. fs.read(&temp[0],7);
  255. if(0 == temp[0]) break;
  256. string member(temp, 6);
  257. stock_block_info[name].push_back(member);
  258. }
  259. fs.seekg(p + 0x0afd);
  260. }
  261. return true;
  262. }
  263. void StockBasicInfo::save_block_info()
  264. {
  265. const string filename = "F:\Develop\stock\data\block_info.mat";
  266. int deal_col_count = 0;
  267. StockGroupMap::const_iterator iter_code;
  268. for(iter_code = stock_block_info.begin();iter_code !=  stock_block_info.end(); ++iter_code)
  269. {
  270. if(iter_code->second.size() > (uint)deal_col_count)
  271. {
  272. deal_col_count = iter_code->second.size();
  273. }
  274. }
  275. ++deal_col_count; // 加上名称
  276. int dims[2];
  277. dims[0] = deal_col_count;
  278. dims[1] = stock_block_info.size();
  279. int block_index = 1;
  280. mxArray *mx_t0_data = mxCreateNumericArray(2, &dims[0], mxDOUBLE_CLASS, mxREAL);
  281. double *p_mxT0data = mxGetPr(mx_t0_data), *p_temp_mxT0data = p_mxT0data;
  282. for(iter_code = stock_block_info.begin();iter_code !=  stock_block_info.end(); ++iter_code, ++block_index)
  283. {
  284. p_temp_mxT0data[0] = block_index; //  Block name
  285. int block_member_index = 1;
  286. for(StringVector::const_iterator iter_i = iter_code->second.begin();iter_i < iter_code->second.end();++iter_i, ++block_member_index)
  287. {
  288. p_temp_mxT0data[block_member_index] = atoi(iter_i->c_str());
  289. }
  290. p_temp_mxT0data += deal_col_count;
  291. }
  292. matlab_engine::Instance().saveVarToFile(filename, mx_t0_data, "block_info");
  293. mxDestroyArray(mx_t0_data);
  294. }
  295. void StockBasicInfo::save_stock_set()
  296. {
  297. uint d = date_to_uint(gregorian::day_clock::local_day()); 
  298. const string filename = "F:\Develop\stock\data\StockSet";
  299. stringstream ss;
  300. ss << filename << d << ".mat";
  301. if(is_file_exist(ss.str()))return;
  302. int deal_col_count = 0; int max_stock_count = 0;
  303. for(short m = MarketInfo::MARKET_FIRST; m < MarketInfo::MARKET_MAX; m++)
  304. {
  305. max_stock_count += MarketInfo::stocks_set[m].size();
  306. }
  307. int dims[2];
  308. dims[0] = 1;
  309. dims[1] = max_stock_count;
  310. mxArray *mx_t0_data = mxCreateNumericArray(2, &dims[0], mxDOUBLE_CLASS, mxREAL);
  311. double *p_mxT0data = mxGetPr(mx_t0_data), *p_temp_mxT0data = p_mxT0data;
  312. for(short m = MarketInfo::MARKET_FIRST; m < MarketInfo::MARKET_MAX; m++)
  313. {
  314. for(StringSet::const_iterator iter = MarketInfo::stocks_set[m].begin();iter != MarketInfo::stocks_set[m].end();++iter, ++p_temp_mxT0data)
  315. {
  316. *p_temp_mxT0data = atoi(iter->c_str());
  317. }
  318. }
  319. matlab_engine::Instance().saveVarToFile(ss.str(), mx_t0_data, "stock_set");
  320. mxDestroyArray(mx_t0_data);
  321. }
  322. void StockBasicInfo::add_stock_gbbq(uint dt, const GBBQ& gbbq)
  323. {
  324. stock_gbbq_info[dt].push_back(gbbq);
  325. }
  326. #if 0
  327. int StockBasicInfo::get_cir_amount(const string &stock_code, const gregorian::date& dt)
  328. {
  329. DateGBBQ &dgb = stock_gbbq_info[stock_code];
  330. uint uint_dt = date_to_uint(dt);
  331. float cir_amount = 0;
  332. for(DateGBBQ::const_iterator iter = dgb.begin(); iter < dgb.end(); ++iter)
  333. {
  334. if(2 == iter->chg_type || 5 == iter->chg_type || 8 == iter->chg_type)
  335. {
  336. if(iter->dt == uint_dt) 
  337. {
  338. cir_amount = iter->data.gb.new_cir;
  339. break;
  340. }
  341. else if(iter->dt > uint_dt)
  342. {
  343. cir_amount = iter->data.gb.old_cir;
  344. break;
  345. }
  346. else
  347. {
  348. cir_amount = iter->data.gb.new_cir;
  349. }
  350. }
  351. }
  352. if(cir_amount < 1.0) // 没有股本变迁数据。取当前值
  353. {
  354. if(stock_base_info.find(stock_code) != stock_base_info.end())
  355. cir_amount = static_cast<float>(stock_base_info[stock_code].cir_amount);
  356. else
  357. cir_amount = 10000.0;
  358. }
  359. return static_cast<int>(cir_amount);
  360. }
  361. #endif
  362. bool StockTransact::Transact::operator == (const StockTransact::Transact& t)
  363. {
  364. return (minute == t.minute
  365. && price == t.price
  366. && vol == t.vol
  367. && bs == t.bs);
  368. }
  369. const int BaseInfo::record_len = 0x1e1;
  370. fstream& operator >> (fstream& fs, BaseInfo& bs)
  371. {
  372. char code[MarketInfo::StocksCodeLen];
  373. fs.read(code, MarketInfo::StocksCodeLen);
  374. bs.stock_code = string(&code[0], MarketInfo::StocksCodeLen);
  375. fs >> bs.update_time;
  376. fs >> bs.ttl_amount;
  377. fs >> bs.state_own_amount; // 国家股
  378. fs >> bs.init_amount; // 发起股本
  379. fs >> bs.corp_amount; // 法人股本
  380. fs >> bs.b_amount; // B 股本
  381. fs >> bs.h_amount; // H 股本
  382. fs >> bs.cir_amount; // 流通 股本
  383. fs >> bs.empl_amount; // 职工 股本
  384. fs >> bs.unknown1; // 
  385. fs >> bs.ttl_asset; // 总资产
  386. fs >> bs.varible_asset; // 流动 资产
  387. fs >> bs.firm_asset; // 固定 资产
  388. fs >> bs.invisible_asset; // 无形 资产
  389. fs >> bs.long_term_invest; // 长期投资
  390. fs >> bs.varible_debt; // 流动负债
  391. fs >> bs.long_term_debt; // 长期负债
  392. fs >> bs.accu_fund; // 公积金
  393. fs >> bs.net_asset; // 净资产
  394. fs >> bs.major_income; // 主营收入
  395. fs >> bs.major_profit; // 主营利润
  396. fs >> bs.unknown2; // 
  397. fs >> bs.bussiness_income; // 营业收入
  398. fs >> bs.invest_income; // 投资收入
  399. fs >> bs.allowance; // 补贴收入
  400. fs >> bs.non_bussiness_income; // 业外收入
  401. fs >> bs.income_adjustment; // 收入调整
  402. fs >> bs.ttl_profit; // 利润总额
  403. fs >> bs.unknown3; // 
  404. fs >> bs.net_profit; // 税后利润
  405. fs >> bs.undist_profit; // 未分配利润
  406. fs >> bs.per_net_assert2; // 每股净资产2
  407. return fs;
  408. }
  409. extern void output_short_index_data();
  410. uint date_to_uint(gregorian::date d)
  411. {
  412. return d.year() * 10000 + d.month() * 100 + d.day();
  413. }
  414. gregorian::date uint_to_date(uint d)
  415. {
  416. return gregorian::date(d / 10000, d % 10000 / 100, d % 100);
  417. }
  418. string MarketInfo::get_first_stock()
  419. {
  420. // set the first stock
  421. for(short m = MarketInfo::MARKET_FIRST; m < MarketInfo::MARKET_MAX; m++)
  422. {
  423. StringSet::const_iterator iter = MarketInfo::stocks_set[m].begin();
  424. if(iter != MarketInfo::stocks_set[m].end())
  425. {
  426. return *iter;
  427. }
  428. }
  429. return "";
  430. }
  431. string MarketInfo::find_next_stock(const string& stock_code)
  432. {
  433. bool first_in_market = false;
  434. for(short m = MarketInfo::get_market_type(stock_code); m < MarketInfo::MARKET_MAX; m++)
  435. {
  436. StringSet::const_iterator iter ;
  437. if(! first_in_market)
  438. {
  439. iter = MarketInfo::stocks_set[m].find(stock_code);
  440. if( iter != MarketInfo::stocks_set[m].end())
  441. {
  442. ++iter;
  443. if(iter != MarketInfo::stocks_set[m].end())
  444. {
  445. return *iter;
  446. }
  447. }
  448. first_in_market = true;
  449. }
  450. else
  451. {
  452. iter = MarketInfo::stocks_set[m].begin();
  453. if(iter != MarketInfo::stocks_set[m].end())
  454. {
  455. return *iter;
  456. }
  457. }
  458. }
  459. return "";
  460. }
  461. void show_curr_bid(char const*  first, char const*  last )
  462. {
  463. cout << "show_curr_bid calledrn";
  464. recursive_mutex::scoped_lock guard(bid_mutex);
  465. StockBid::BidMap::const_iterator i = instant_price_list.begin();
  466. // has data
  467. if(i != instant_price_list.end())
  468. {
  469. // print title here
  470. }
  471. while(i++ != instant_price_list.end())
  472. {
  473. cout << i->first << endl;
  474. }
  475. }
  476. }