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

金融证券系统

开发平台:

Visual C++

  1. #ifndef _STOCK_ALGORITHM_H_
  2. #define  _STOCK_ALGORITHM_H_
  3. #include <vector>
  4. #include <deque>
  5. namespace StockMarket{
  6. template <typename T>
  7. class CalculatePara
  8. {
  9. private:
  10. struct ParaData
  11. {
  12. ParaData() : total_price(0), price_gain(0), price_vibration(0), total_buy_vol(0), total_sell_vol(0), transact_count(0) ,minute(0){}
  13. T cur_price;
  14. T total_price;
  15. T price_gain;
  16. T price_vibration;
  17. T total_buy_vol;
  18. T total_sell_vol;
  19. int transact_count;
  20. int minute;
  21. ParaData & operator += (const ParaData & second)
  22. {
  23. this->price_vibration += second.price_vibration;
  24. this->price_gain += second.price_gain;
  25. this->total_buy_vol += second.total_buy_vol;
  26. this->total_sell_vol += second.total_sell_vol;
  27. this->total_price += second.total_price;
  28. return *this;
  29. };
  30. ParaData & operator -= (const ParaData & second)
  31. {
  32. this->price_vibration -= second.price_vibration;
  33. this->price_gain -= second.price_gain;
  34. this->total_buy_vol -= second.total_buy_vol;
  35. this->total_sell_vol -= second.total_sell_vol;
  36. this->total_price -= second.total_price;
  37. return *this;
  38. };
  39. };
  40. struct normalizedPara
  41. {
  42. normalizedPara() : open_buy_vol(0.0), open_sell_vol(0.0), open_gain(0.0), current_gain(0.0)
  43. , long_price_vibration(0.0), long_vol(0.0),long_vol2(0.0)
  44. , mid_price_vibration(0.0), mid_vol(0.0), mid_vol2(0.0)
  45. , short_buy_vol(0.0), short_sell_vol(0.0), short_gain1(0.0)
  46. , short_gain2(0.0), mid_gain(0.0), long_gain(0.0)
  47. {}
  48. float open_gain; // 开盘升幅
  49. float open_buy_vol; // 开盘换手率
  50. float open_sell_vol; // 开盘换手率
  51. float short_gain1; // 最新短期升幅
  52. float short_gain2; // 次新短期升幅
  53. float current_gain; // 当前升幅
  54. float short_buy_vol; // 短期平均每分钟买量换手率
  55. float short_sell_vol; // 短期平均每分钟卖量换手率
  56. float mid_gain; // 中期平均每分钟换手率
  57. float mid_vol; // 中期平均每分钟换手率
  58. float mid_vol2; // 中期平均每分钟换手率
  59. float long_gain; // 中期平均每分钟换手率
  60. float long_vol; // 长期平均每分钟换手率
  61. float long_vol2; // 长期平均每分钟换手率
  62. float mid_price_vibration; // 中期振幅
  63. float long_price_vibration; // 长期振幅
  64. float close_gain; 
  65. };
  66. public:
  67. CalculatePara( uint short_peroid, uint mid_period, uint long_period) : open_price_(0), y_close_(0), total_vol_(0),
  68. short_period_(short_peroid), mid_period_(mid_period), long_period_(long_period),cur_price_(0)
  69. {
  70. if(short_peroid >=  mid_period || mid_period >=  long_period )
  71. {
  72. throw 5;
  73. }
  74. }
  75. void reset(string code, gregorian::date current, int open_price, int today_close)
  76. {
  77. #if 0
  78. int cir_amount = stock_basic_info::Instance().get_cir_amount(code, current); // 万股变成手
  79. {
  80. StockDayData outdata;
  81. gregorian::date outdt;
  82. today_close_ = today_close;
  83. if(stock_day_data::Instance().get_last_day_data(code, current, outdt, outdata))
  84. {
  85. y_close_ = stock_basic_info::Instance().apply_gbbq_front(code, outdt, current, outdata.close);
  86. }
  87. }
  88. if(0 == y_close_) // 没有取得前次收盘价, 取今天开盘价
  89. {
  90. y_close_ = open_price;
  91. }
  92. open_price_ = open_price;
  93. total_vol_ = cir_amount;
  94. #endif
  95. minute_para_.clear();
  96. // 每分钟记录一次,  最多有 240 + 5 (开盘) 分钟
  97. minute_para_.reserve(250);
  98. }
  99. double get_result()
  100. {
  101. return 0.0;
  102. }
  103. void calc(StockTransact::DailyTransact::const_iterator iter_begin, StockTransact::DailyTransact::const_iterator iter_end) 
  104. {
  105. int last_minute = 1, this_minute = 1;
  106. if(!minute_para_.empty())
  107. {
  108. last_minute = minute_para_.back().minute;
  109. }
  110. StockTransact::DailyTransact::const_iterator this_minute_begin_iter;
  111. StockTransact::DailyTransact::const_iterator iter_j;
  112. for(iter_j = iter_begin; iter_j <= iter_end; ++iter_j)
  113. {
  114. if(iter_j->minute > last_minute)  // have already stored
  115. {
  116. this_minute_begin_iter = iter_j;
  117. this_minute = this_minute_begin_iter->minute;
  118. iter_begin = iter_j;
  119. break;
  120. }
  121. }
  122. if(iter_j > iter_end) // not found
  123. {
  124. return;
  125. }
  126. // initialize
  127. T buy_vol(0), sell_vol(0), temp_price(0), mx_price(0), mn_price(10000000);
  128. for(StockTransact::DailyTransact::const_iterator iter_i = iter_begin; iter_i <= iter_end; ++iter_i)
  129. {
  130. if(iter_i->minute > this_minute) // 最后一分钟没有计算
  131. {
  132. // save
  133. ParaData para;
  134. para.minute = this_minute;
  135. para.price_gain = iter_i->price - this_minute_begin_iter->price;  // 区间交迭
  136. para.price_vibration = mx_price - mn_price;
  137. para.total_buy_vol = buy_vol;
  138. para.total_sell_vol = sell_vol;
  139. para.total_price = temp_price;
  140. cur_price_ = iter_i->price;
  141. para.cur_price = cur_price_;
  142. if(minute_para_.empty())
  143. {
  144. minute_para_.push_back(para);
  145. }
  146. else
  147. {
  148. ParaData &last_element = minute_para_.back();
  149. para += last_element; // 累计
  150. minute_para_.push_back(para);
  151. }
  152. // re-initialize
  153. buy_vol = 0;sell_vol = 0;temp_price = 0;mx_price = 0;mn_price = 10000000;
  154. last_minute = this_minute;
  155. this_minute_begin_iter = iter_i;
  156. this_minute = this_minute_begin_iter->minute;
  157. }
  158. // calculate
  159. temp_price += iter_i->price;
  160. if(iter_i->price > mx_price) 
  161. mx_price = iter_i->price;
  162. if(iter_i->price < mn_price)
  163. mn_price = iter_i->price;
  164. if(0 == iter_i->bs)
  165. buy_vol += iter_i->vol;
  166. else if(1 == iter_i->bs)
  167. sell_vol += iter_i->vol;
  168. }
  169. }
  170. normalizedPara normalize()
  171. {
  172. normalizedPara para;
  173. para.close_gain = (static_cast<float>(today_close_ - y_close_)) / y_close_;
  174. para.open_gain = (static_cast<float>(open_price_ - y_close_)) / y_close_;
  175. para.current_gain = (static_cast<float>(cur_price_ - y_close_)) / y_close_;
  176. para.open_buy_vol = (static_cast<float>(minute_para_[0].total_buy_vol)) / total_vol_;
  177. para.open_sell_vol = (static_cast<float>(minute_para_[0].total_sell_vol)) / total_vol_;
  178. ParaData tail_element = ParaData();
  179. ParaData last_element = minute_para_.back();
  180. uint size = minute_para_.size();
  181. int time_duration = 1;
  182. if(size > long_period_)
  183. tail_element = minute_para_[size - 1 - long_period_];
  184. else
  185. tail_element = minute_para_.front();
  186. if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
  187. time_duration = max(last_element.minute - tail_element.minute - 90, 1);
  188. else
  189. time_duration = max(last_element.minute - tail_element.minute, 1);
  190. para.long_price_vibration = (static_cast<float>(last_element.price_vibration - tail_element.price_vibration)) 
  191. / time_duration / y_close_;
  192. para.long_vol = (static_cast<float>(last_element.total_buy_vol + last_element.total_sell_vol - tail_element.total_buy_vol - tail_element.total_sell_vol)) 
  193. / time_duration / total_vol_ * 100;
  194. para.long_gain = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
  195. last_element = tail_element;
  196. if(size > 2 * long_period_)
  197. tail_element = minute_para_[size -1 - 2 * long_period_];
  198. else
  199. tail_element = minute_para_.front();
  200. if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
  201. time_duration = max(last_element.minute - tail_element.minute - 90, 1);
  202. else
  203. time_duration = max(last_element.minute - tail_element.minute, 1);
  204. para.long_vol2 = (static_cast<float>(last_element.total_buy_vol + last_element.total_sell_vol - tail_element.total_buy_vol - tail_element.total_sell_vol)) 
  205. / time_duration / total_vol_ * 100;
  206. last_element = minute_para_.back();
  207. if(size > mid_period_)
  208. tail_element = minute_para_[size -1 - mid_period_];
  209. else
  210. tail_element = minute_para_.front();
  211. if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
  212. time_duration = max(last_element.minute - tail_element.minute - 90, 1);
  213. else
  214. time_duration = max(last_element.minute - tail_element.minute, 1);
  215. para.mid_price_vibration = (static_cast<float>(last_element.price_vibration - tail_element.price_vibration)) 
  216.  / time_duration / y_close_;
  217. para.mid_vol = (static_cast<float>(last_element.total_buy_vol + last_element.total_sell_vol - tail_element.total_buy_vol - tail_element.total_sell_vol)) 
  218.  / time_duration / total_vol_ * 100;
  219. para.mid_gain = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
  220. last_element = tail_element;
  221. if(size > 2 * mid_period_)
  222. tail_element = minute_para_[size -1 - 2 * mid_period_];
  223. else
  224. tail_element = minute_para_.front();
  225. if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
  226. time_duration = max(last_element.minute - tail_element.minute - 90, 1);
  227. else
  228. time_duration = max(last_element.minute - tail_element.minute, 1);
  229. para.mid_vol2 = (static_cast<float>(last_element.total_buy_vol + last_element.total_sell_vol - tail_element.total_buy_vol - tail_element.total_sell_vol)) 
  230.  / time_duration / total_vol_ * 100;
  231. last_element = minute_para_.back();
  232. if(size > short_period_)
  233. tail_element = minute_para_[size -1 - short_period_];
  234. else
  235. tail_element = minute_para_.front();
  236. if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
  237. time_duration = max(last_element.minute - tail_element.minute - 90, 1);
  238. else
  239. time_duration = max(last_element.minute - tail_element.minute, 1);
  240. para.short_buy_vol = (static_cast<float>(last_element.total_buy_vol - tail_element.total_buy_vol)) / time_duration / total_vol_ * 100;
  241. para.short_sell_vol = (static_cast<float>(last_element.total_sell_vol - tail_element.total_sell_vol)) / time_duration / total_vol_ * 100;
  242. para.short_gain1 = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
  243. last_element = tail_element;
  244. if(size > 2 * short_period_)
  245. tail_element = minute_para_[size -1 - 2 * short_period_];
  246. else
  247. tail_element = minute_para_.front();
  248. para.short_gain2 = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
  249. return para;
  250. }
  251. bool output_to_file(ofstream& ofs)
  252. {
  253. if(minute_para_.size() <=0 ) return false;
  254. const int width = 11;
  255. normalizedPara para = normalize();
  256. ofs << setw(width) << para.open_gain <<  setw(width) << para.open_buy_vol << setw(width) << para.open_sell_vol 
  257. << setw(width) << para.short_gain1 << setw(width) << para.short_gain2 <<  setw(width) << para.current_gain
  258. << setw(width) << para.short_buy_vol << setw(width) << para.short_sell_vol
  259. << setw(width) << para.mid_gain << setw(width) << para.mid_vol << setw(width) << para.mid_vol2 
  260. << setw(width) << para.long_gain << setw(width) << para.long_vol << setw(width) << para.long_vol2 
  261. << setw(width) << para.mid_price_vibration << setw(width) << para.long_price_vibration << setw(width) << para.close_gain<< ' ';
  262. return true;
  263. }
  264. private:
  265. const uint short_period_;
  266. const uint mid_period_;
  267. const uint long_period_;
  268. int total_vol_;
  269. int cur_price_;
  270. int today_close_;
  271. int y_close_;
  272. int open_price_;
  273. vector<ParaData> minute_para_;
  274. };
  275. }
  276. #endif