StockAlgo.h
上传用户:egreat
上传日期:2007-07-13
资源大小:29k
文件大小:11k
- #ifndef _STOCK_ALGORITHM_H_
- #define _STOCK_ALGORITHM_H_
- #include <vector>
- #include <deque>
- namespace StockMarket{
- template <typename T>
- class CalculatePara
- {
- private:
- struct ParaData
- {
- ParaData() : total_price(0), price_gain(0), price_vibration(0), total_buy_vol(0), total_sell_vol(0), transact_count(0) ,minute(0){}
- T cur_price;
- T total_price;
- T price_gain;
- T price_vibration;
- T total_buy_vol;
- T total_sell_vol;
- int transact_count;
- int minute;
- ParaData & operator += (const ParaData & second)
- {
- this->price_vibration += second.price_vibration;
- this->price_gain += second.price_gain;
- this->total_buy_vol += second.total_buy_vol;
- this->total_sell_vol += second.total_sell_vol;
- this->total_price += second.total_price;
- return *this;
- };
- ParaData & operator -= (const ParaData & second)
- {
- this->price_vibration -= second.price_vibration;
- this->price_gain -= second.price_gain;
- this->total_buy_vol -= second.total_buy_vol;
- this->total_sell_vol -= second.total_sell_vol;
- this->total_price -= second.total_price;
- return *this;
- };
- };
- struct normalizedPara
- {
- normalizedPara() : open_buy_vol(0.0), open_sell_vol(0.0), open_gain(0.0), current_gain(0.0)
- , long_price_vibration(0.0), long_vol(0.0),long_vol2(0.0)
- , mid_price_vibration(0.0), mid_vol(0.0), mid_vol2(0.0)
- , short_buy_vol(0.0), short_sell_vol(0.0), short_gain1(0.0)
- , short_gain2(0.0), mid_gain(0.0), long_gain(0.0)
- {}
- float open_gain; // 开盘升幅
- float open_buy_vol; // 开盘换手率
- float open_sell_vol; // 开盘换手率
- float short_gain1; // 最新短期升幅
- float short_gain2; // 次新短期升幅
- float current_gain; // 当前升幅
- float short_buy_vol; // 短期平均每分钟买量换手率
- float short_sell_vol; // 短期平均每分钟卖量换手率
- float mid_gain; // 中期平均每分钟换手率
- float mid_vol; // 中期平均每分钟换手率
- float mid_vol2; // 中期平均每分钟换手率
-
- float long_gain; // 中期平均每分钟换手率
- float long_vol; // 长期平均每分钟换手率
- float long_vol2; // 长期平均每分钟换手率
- float mid_price_vibration; // 中期振幅
- float long_price_vibration; // 长期振幅
- float close_gain;
- };
- public:
- CalculatePara( uint short_peroid, uint mid_period, uint long_period) : open_price_(0), y_close_(0), total_vol_(0),
- short_period_(short_peroid), mid_period_(mid_period), long_period_(long_period),cur_price_(0)
- {
- if(short_peroid >= mid_period || mid_period >= long_period )
- {
- throw 5;
- }
- }
- void reset(string code, gregorian::date current, int open_price, int today_close)
- {
- #if 0
- int cir_amount = stock_basic_info::Instance().get_cir_amount(code, current); // 万股变成手
- {
- StockDayData outdata;
- gregorian::date outdt;
- today_close_ = today_close;
- if(stock_day_data::Instance().get_last_day_data(code, current, outdt, outdata))
- {
- y_close_ = stock_basic_info::Instance().apply_gbbq_front(code, outdt, current, outdata.close);
- }
- }
- if(0 == y_close_) // 没有取得前次收盘价, 取今天开盘价
- {
- y_close_ = open_price;
- }
- open_price_ = open_price;
- total_vol_ = cir_amount;
- #endif
- minute_para_.clear();
- // 每分钟记录一次, 最多有 240 + 5 (开盘) 分钟
- minute_para_.reserve(250);
- }
- double get_result()
- {
- return 0.0;
- }
- void calc(StockTransact::DailyTransact::const_iterator iter_begin, StockTransact::DailyTransact::const_iterator iter_end)
- {
- int last_minute = 1, this_minute = 1;
- if(!minute_para_.empty())
- {
- last_minute = minute_para_.back().minute;
- }
- StockTransact::DailyTransact::const_iterator this_minute_begin_iter;
- StockTransact::DailyTransact::const_iterator iter_j;
- for(iter_j = iter_begin; iter_j <= iter_end; ++iter_j)
- {
- if(iter_j->minute > last_minute) // have already stored
- {
- this_minute_begin_iter = iter_j;
- this_minute = this_minute_begin_iter->minute;
- iter_begin = iter_j;
- break;
- }
- }
- if(iter_j > iter_end) // not found
- {
- return;
- }
-
- // initialize
- T buy_vol(0), sell_vol(0), temp_price(0), mx_price(0), mn_price(10000000);
- for(StockTransact::DailyTransact::const_iterator iter_i = iter_begin; iter_i <= iter_end; ++iter_i)
- {
- if(iter_i->minute > this_minute) // 最后一分钟没有计算
- {
- // save
- ParaData para;
- para.minute = this_minute;
- para.price_gain = iter_i->price - this_minute_begin_iter->price; // 区间交迭
- para.price_vibration = mx_price - mn_price;
- para.total_buy_vol = buy_vol;
- para.total_sell_vol = sell_vol;
- para.total_price = temp_price;
- cur_price_ = iter_i->price;
- para.cur_price = cur_price_;
-
- if(minute_para_.empty())
- {
- minute_para_.push_back(para);
- }
- else
- {
- ParaData &last_element = minute_para_.back();
- para += last_element; // 累计
- minute_para_.push_back(para);
- }
- // re-initialize
- buy_vol = 0;sell_vol = 0;temp_price = 0;mx_price = 0;mn_price = 10000000;
- last_minute = this_minute;
- this_minute_begin_iter = iter_i;
- this_minute = this_minute_begin_iter->minute;
- }
- // calculate
- temp_price += iter_i->price;
- if(iter_i->price > mx_price)
- mx_price = iter_i->price;
- if(iter_i->price < mn_price)
- mn_price = iter_i->price;
- if(0 == iter_i->bs)
- buy_vol += iter_i->vol;
- else if(1 == iter_i->bs)
- sell_vol += iter_i->vol;
- }
- }
- normalizedPara normalize()
- {
- normalizedPara para;
- para.close_gain = (static_cast<float>(today_close_ - y_close_)) / y_close_;
- para.open_gain = (static_cast<float>(open_price_ - y_close_)) / y_close_;
- para.current_gain = (static_cast<float>(cur_price_ - y_close_)) / y_close_;
- para.open_buy_vol = (static_cast<float>(minute_para_[0].total_buy_vol)) / total_vol_;
- para.open_sell_vol = (static_cast<float>(minute_para_[0].total_sell_vol)) / total_vol_;
- ParaData tail_element = ParaData();
- ParaData last_element = minute_para_.back();
- uint size = minute_para_.size();
- int time_duration = 1;
-
- if(size > long_period_)
- tail_element = minute_para_[size - 1 - long_period_];
- else
- tail_element = minute_para_.front();
- if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
- time_duration = max(last_element.minute - tail_element.minute - 90, 1);
- else
- time_duration = max(last_element.minute - tail_element.minute, 1);
- para.long_price_vibration = (static_cast<float>(last_element.price_vibration - tail_element.price_vibration))
- / time_duration / y_close_;
- 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))
- / time_duration / total_vol_ * 100;
- para.long_gain = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
- last_element = tail_element;
- if(size > 2 * long_period_)
- tail_element = minute_para_[size -1 - 2 * long_period_];
- else
- tail_element = minute_para_.front();
- if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
- time_duration = max(last_element.minute - tail_element.minute - 90, 1);
- else
- time_duration = max(last_element.minute - tail_element.minute, 1);
- 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))
- / time_duration / total_vol_ * 100;
- last_element = minute_para_.back();
- if(size > mid_period_)
- tail_element = minute_para_[size -1 - mid_period_];
- else
- tail_element = minute_para_.front();
-
- if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
- time_duration = max(last_element.minute - tail_element.minute - 90, 1);
- else
- time_duration = max(last_element.minute - tail_element.minute, 1);
-
- para.mid_price_vibration = (static_cast<float>(last_element.price_vibration - tail_element.price_vibration))
- / time_duration / y_close_;
- 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))
- / time_duration / total_vol_ * 100;
- para.mid_gain = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
- last_element = tail_element;
- if(size > 2 * mid_period_)
- tail_element = minute_para_[size -1 - 2 * mid_period_];
- else
- tail_element = minute_para_.front();
-
- if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
- time_duration = max(last_element.minute - tail_element.minute - 90, 1);
- else
- time_duration = max(last_element.minute - tail_element.minute, 1);
- 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))
- / time_duration / total_vol_ * 100;
- last_element = minute_para_.back();
- if(size > short_period_)
- tail_element = minute_para_[size -1 - short_period_];
- else
- tail_element = minute_para_.front();
-
- if(last_element.minute >= 13 * 60 && tail_element.minute <= 11 * 60 + 30)
- time_duration = max(last_element.minute - tail_element.minute - 90, 1);
- else
- time_duration = max(last_element.minute - tail_element.minute, 1);
-
- para.short_buy_vol = (static_cast<float>(last_element.total_buy_vol - tail_element.total_buy_vol)) / time_duration / total_vol_ * 100;
- para.short_sell_vol = (static_cast<float>(last_element.total_sell_vol - tail_element.total_sell_vol)) / time_duration / total_vol_ * 100;
- para.short_gain1 = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
- last_element = tail_element;
- if(size > 2 * short_period_)
- tail_element = minute_para_[size -1 - 2 * short_period_];
- else
- tail_element = minute_para_.front();
- para.short_gain2 = (static_cast<float>(last_element.cur_price - tail_element.cur_price)) / y_close_;
- return para;
-
- }
- bool output_to_file(ofstream& ofs)
- {
- if(minute_para_.size() <=0 ) return false;
- const int width = 11;
- normalizedPara para = normalize();
- ofs << setw(width) << para.open_gain << setw(width) << para.open_buy_vol << setw(width) << para.open_sell_vol
- << setw(width) << para.short_gain1 << setw(width) << para.short_gain2 << setw(width) << para.current_gain
- << setw(width) << para.short_buy_vol << setw(width) << para.short_sell_vol
- << setw(width) << para.mid_gain << setw(width) << para.mid_vol << setw(width) << para.mid_vol2
- << setw(width) << para.long_gain << setw(width) << para.long_vol << setw(width) << para.long_vol2
- << setw(width) << para.mid_price_vibration << setw(width) << para.long_price_vibration << setw(width) << para.close_gain<< ' ';
- return true;
- }
- private:
- const uint short_period_;
- const uint mid_period_;
- const uint long_period_;
- int total_vol_;
- int cur_price_;
- int today_close_;
- int y_close_;
- int open_price_;
- vector<ParaData> minute_para_;
- };
- }
- #endif