鼎元C++期货量化/程序化教程如何使用容器(vector)对bar数据进行中级处理【vector容器使用范例:正迭代计算简单均线average】
  
- UID
- 2
- 积分
- 2929514
- 威望
- 1414793 布
- 龙e币
- 1514721 刀
- 在线时间
- 13682 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2025-4-5

|
鼎元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变量:- vector<double>ema(vector<double>pc, int num);//ema计算返回数组vector形式指数移动平均
复制代码 test.cpp源文件中将收盘价存储 到上面声明的变量中- 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容器中,按正序排序
- }
复制代码 (2)、编辑均线计算方法,数组形式
test.h头文件中先声明vector变量:- vector<double>averagearray(vector<double> pc, int num); //ema计算公式(返回数组);
复制代码 设计均线计算方法(数组形式):- //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;
- }
复制代码 解析:当bar的数量不够num个周期时就简单的将所有的pc的收盘价加总然后除以bar的数目获得值替代为简单平均值。
若是bar的数目大于或等于num个周期时,比方说一共num个bar的元素数据,它的序列号是num-1,然后向前加总num个数据,正好加到序列号为0的第一个pc的数据。所以我在for循环中又加了一个for循环。就能当每一个大循环序列号数据,都会在次循环中运行一次。或前面的替代均值或后面的加总除num求均值。
相比逆迭代和遍历的简洁性,正迭代和遍历又复杂又烧脑。所以说能不正迭代就不要正迭代。
(3)、在主程序中调用公式函数进行计算
先在头文件中声明一个变量:在主文件中调用:- averager = averagearray(pc, length); //数组形式的均线值
-
- InsertLog("正迭代之均线值: " + to_string(averager[averager.size() - 1])); //将新变量最新值输出到日志
复制代码 注意事项:声明的变量也一定要是vector才行。要不装不进vector元素。最后用经典的调用法调用到最新的那个数据。 |
论坛官方微信、群(期货热点、量化探讨、开户与绑定实盘)
|
|
|
|
|
|
  
- UID
- 2
- 积分
- 2929514
- 威望
- 1414793 布
- 龙e币
- 1514721 刀
- 在线时间
- 13682 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2025-4-5

|
上面我是通过建立收盘价vector容器后,写一个返回数组的均线值计算方法,调用这个函数然后计算出均线值的。
下面我再在主程序里面直接计算求均线值的方法:
头文件中声明变量:- vector<double>pc;//进行数组设计时统一的数组变量,方便以后使用中统一口径;
- vector<double> re1;
- int r1=0 ;
- double d1=0;
- double e1=0;
复制代码 这里我建立上面的几个变量,pc是装收盘价的,re1是装计算好的线值。剩下的几个变量是中间变量用来传递数据用的。
在主程序中写法如下:- 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])); //将新变量最新值输出到日志
复制代码 解析:
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计算时不会受到当前值的影响。 |
|
|
|
|
|
|