鼎元C++期货量化/程序化教程如何使用容器(vector)对bar数据进行中级处理【vector容器使用范例:正迭代计算简单均线average】
1、通过上面的几节,我们通过逆迭代和逆遍历计算计算了均线、高低点等常用的函数公式,今天我们用正迭代再计算一次,主要是熟练使用正迭代与正遍历。2、正迭代与负迭代的使用影响是不同的,比方说函数与公式跟前值没有关系的适合逆迭代,要是本值需要用到前一个值时,就只能使用正迭代了。
3、通常的做法是这样的:
1、先把需要处理的数据放到一个vector容器中,容器里面元素的数量大小跟bar的数量大小是一致的,也可以理解为将每一个bar的某些信息采集后放到vector中相应的序列号位置上面。
2、用数组的方式先编辑一个如何处理的公式。
3、再申请一个或几个新的vector变量,将上面获得的vector的数据套上上面的公式得到新的vector数据放到新的vector里面。
4、通过变量[变量.size()-1]来引用或调用处理后的数据。
5、我们以求简单均线来做一个范例
(1)、将bar正迭代遍历,将收盘价存储到pc容器中。
test.h头文件中先声明vector变量:[code]
vector<double>ema(vector<double>pc, int num);//ema计算返回数组vector形式指数移动平均
[/code]test.cpp源文件中将收盘价存储 到上面声明的变量中[code]
RsqBar(sPeriod, sInst);
map<string, TKVALUE>::iterator it;//迭代
for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); it++) //遍历所有K线
{
pc.push_back(it->second.dClose);//将收盘价存储到pc容器中,按正序排序
}
[/code](2)、编辑均线计算方法,数组形式
test.h头文件中先声明vector变量:[code]vector<double>averagearray(vector<double> pc, int num); //ema计算公式(返回数组);[/code]设计均线计算方法(数组形式):[code]
//averagearray计算公式开始(返回数组)
vector<double> test::averagearray(vector<double> pc, int num)
{
vector<double> re;
double r = 0;
double d = 0;
double e = 0;
for (int i = 0; i < pc.size(); i++)
{
if (r < num) //如果bar的数目不够基本的周期,则返回加总除以bar数目代替
{
d = (d + pc[i])/(r);
r++;
re.push_back(d);
}
else //如何bar数目大于基本周期num个数据,则通过for循环向前加总num个数组除num周期得均线值
{
for (size_t j = 0; j < num ; j++) //循环num次
{
e = e + pc[i - j]; //从现有bar向左加总num个数据
}
d = e/num;
re.push_back(d);
e = 0;//将e重置成0方便下一个bar继续循环使用
}
}
return re;
}
[/code][b]解析:当bar的数量不够num个周期时就简单的将所有的pc的收盘价加总然后除以bar的数目获得值替代为简单平均值。
若是bar的数目大于或等于num个周期时,比方说一共num个bar的元素数据,它的序列号是num-1,然后向前加总num个数据,正好加到序列号为0的第一个pc的数据。所以我在for循环中又加了一个for循环。就能当每一个大循环序列号数据,都会在次循环中运行一次。或前面的替代均值或后面的加总除num求均值。
相比逆迭代和遍历的简洁性,正迭代和遍历又复杂又烧脑。所以说能不正迭代就不要正迭代。[/b]
(3)、在主程序中调用公式函数进行计算
先在头文件中声明一个变量:[code]
vector<double>averager;[/code]在主文件中调用:[code] averager = averagearray(pc, length); //数组形式的均线值
InsertLog("正迭代之均线值: " + to_string(averager[averager.size() - 1])); //将新变量最新值输出到日志[/code]注意事项:声明的变量也一定要是vector才行。要不装不进vector元素。最后用经典的调用法调用到最新的那个数据。 上面我是通过建立收盘价vector容器后,写一个返回数组的均线值计算方法,调用这个函数然后计算出均线值的。
[b]下面我再在主程序里面直接计算求均线值的方法:[/b]
头文件中声明变量:[code]
vector<double>pc;//进行数组设计时统一的数组变量,方便以后使用中统一口径;
vector<double> re1;
int r1=0 ;
double d1=0;
double e1=0;
[/code]这里我建立上面的几个变量,pc是装收盘价的,re1是装计算好的线值。剩下的几个变量是中间变量用来传递数据用的。
在主程序中写法如下:[code]
RsqBar(sPeriod, sInst);
map<string, TKVALUE>::iterator it;//迭代
for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); it++) //遍历所有K线
{
pc.push_back(it->second.dClose);//将收盘价存储到pc容器中,按正序排序
}
//主程序中用VECTOR计算均线值
for (int i = 0; i < pc.size(); i++)
{
if (r1 < length) //如果bar的数目不够基本的周期,则返回加总除以bar数目代替
{
d1 = (d1 + pc[i]) / (r1);
r1++;
re1.push_back(d1);
}
else //如何bar数目大于基本周期num个数据,则通过for循环向前加总num个数组除num周期得均线值
{
for (size_t j = 0; j < length; j++) //循环num次
{
e1 = e1 + pc[i - j]; //从现有bar向左加总num个数据
}
d1 = e1 / length;
re1.push_back(d1);
e1 = 0;//将e重置成0方便下一个bar继续循环使用
}
}
InsertLog("正迭代之均线值引用公式计算: " + to_string(re1[re1.size() - 1])); //将新变量最新值输出到日志
[/code][b]解析:
1、RsqBar(sPeriod, sInst),申请数据
2、将收盘价按正序装入pc容器中。
3、计算均线的函数:
首先若是bar的数量小于我们均线周期设置数量时,我们用这个bar加总之前的bar的收盘价,然后 除以现在的bar数来代替length周期的均线值。
若是bar数量大于等于length 个时,就开始正式计算,方法是用for语句从当前bar开始向左加总length-1个bar的值,因为是从0开始的,所以仍然是length个bar的数据,加总后除以length周期数就能得到length周期的均线值了。然后我们还要将e1加总的变量重置成0,方便下一根bar计算时不会受到当前值的影响。[/b]
页:
[1]