?? stockalgo.h
字號:
#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; // 區(qū)間交迭
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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -