Board logo

标题: 鼎元全自动C++软件【策略设计:如何从系统里面的bar数据中调用到想要的元素?(关键词:iterator迭代器,mapK,map)】 [打印本页]

作者: 龙听    时间: 2025-4-10 17:01     标题: 鼎元全自动C++软件【策略设计:如何从系统里面的bar数据中调用到想要的元素?(关键词:iterator迭代器,mapK,map)】

特定一个品种,一个运行周期的bar的数据是很多个包含bar信息的数据包,以螺纹rb2505合约日线数据为例,这个数据有上百个甚至好几百个bar数据包组成,每个bar的数据包包含:日期时间,开盘价,最高价,最低价,收盘价,成交量和持仓量。而螺纹rb2505的K线图是有大量的这种日线bar数据形成的。所以我们在设计策略过程中可能只需要每个bar的某些数据或当前bar前面的某些数据。也就是对bar数据进行处理。这里用到C++语言两个很重要的概念:迭代和遍历。

迭代即设置一个调用环,遍历即用这个调用环从bar数据的开始第一个bar或结尾最后一个bar向右或向左依次获取需要的元素,直到循环完,在运行过程中一旦有新的bar产生就会运行一次。

所以说迭代有两种,一是正向迭代,即从左边第一个bar,序号从0开始,依次高右,直到最后一个bar,即最新bar,序号为size()-1,即bar的总数量减1(因为序列号是从0开始,而 bar数量是从1开始。)
遍历:即一个for循环,按正向或逆向从bar数据的一端运行到另一端。

在迭代和遍历之后就可以将相应的需要的数据采集到一个或多个变量中,为后面的计算做原料数据。
  1. //调用bar数据,要包括品种合约,运行周期
  2.         RsqBar(sPeriod, sInst);
复制代码
  1. map<string, TKVALUE>::reverse_iterator it;//逆向迭代
  2. for (it = mapK[sPeriod][sInst].rbegin(); it != mapK[sPeriod][sInst].rend(); it++) //逆向遍历所有K线
  3.         {
  4.         }
复制代码
  1. map<string, TKVALUE>::iterator it;//正迭代
  2.         for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); it++) //遍历所有K线
  3.         {
  4. }
复制代码
说明:实际上我们可以将这个看作是一个for循环,根据是正向或逆向迭代对数据进行处理。

it->second.bar元素。每个bar中的数据元素有如下:
  1.         string sDate;
  2.        string sTime;
  3.        string InstrumentID;
  4.        string sPeriod;
  5.        double dOpen = 0;
  6.         double dHigh = 0;  
  7.       double dLow = 0;
  8.        double dClose = 0;  
  9.       int nVolume = 0;  
  10.       int nOpenInterest = 0;
  11.        string sDayNight;
复制代码
上面前面定义了变量的类型,后面是元素。比方说我想调用每个bar的开盘价,调用方法是
  1. it->second.dOpen;
复制代码
second的意义是说调用的是键值,而不是键。对于这两个不同有兴趣的可以查些基础的C++语言的书籍即可。


作者: 龙听    时间: 2025-4-10 18:54

在这里我们也可以想象一下,什么时候需要逆迭代,什么时候需要正迭代?
一、使用逆迭代的场景:

   从最新bar向左处理数据时。比方说:

   1、调用昨天的bar元素(开,高,低,收);调用length个bar之前的那个bar的元素(开,高,低,书)。
   2、计算最新bar向左length个bar的平均值(average),最高价(highest),最低价(lowest),标准差(STD)等。

二、使用正迭代的场景:

   从最左边最旧的数据开始向右直到最新的bar数据时。比方说:

   1、数据包括前一个数据的值,比方说EMA类的,EMA(t) = a*ema(t-1) + (1-a)[close-ema(t-1)]类,这种最新值中包含部分前值的。
   2、做为中间传递变量用的,用完后就扔掉了。所以我们可以发现只要是跟之前值有关的变量设计都要正序迭代。
作者: 龙听    时间: 2025-4-10 20:12

实例一:将每天的收盘价数据存入pc容器(price close简称)变量,这里使用正迭代
  1.         //调用bar数据,要包括品种合约,运行周期
  2.         RsqBar(sPeriod, sInst);
  3.         vector<double>pc;//进行数组设计时统一的数组变量,方便以后使用中统一口径;
  4.         //迭代
  5.         map<string, TKVALUE>::iterator it;//正向迭代
  6.         for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); it++)
  7.         {
  8.                 pc.push_back(it->second.dHigh); //从bar数据最左边的第一个数据开始将收盘价dClose 数据存入到pc容器中。
  9.         }
复制代码
当迭代从最左边第一个数据一直循环到最右边最后一个数据后,每一个bar 的收盘价就存入了pc容器中。序列号与bar的序列号一致。

最新一个bar的收盘价这样引用
  1. pc[pc.size()-1]
复制代码
实例二:将每天的收盘价数据存入pc容器(price close简称)变量,这里使用逆迭代
  1.         //调用bar数据,要包括品种合约,运行周期
  2.         RsqBar(sPeriod, sInst);
  3.         vector<double>pc;//进行数组设计时统一的数组变量,方便以后使用中统一口径;
  4.         //迭代
  5.         map<string, TKVALUE>::reverse_iterator it;//逆向迭代
  6.         for (it = mapK[sPeriod][sInst].rbegin(); it != mapK[sPeriod][sInst].rend(); it++) //逆向遍历所有K线
  7.         {
  8.          pc.push_back(it->second.dHigh); //从bar数据最左边的第一个数据开始将收盘价dClose 数据存入到pc容器中。
  9.         }
复制代码
与实例一不同,现在我们求的pc中收盘价是将bar数据中最右边的数据存放到pc容器的最左边,相当于对调一下顺序。

最新一个bar的收盘价数据调用方法:
  1. pc[0]
复制代码

作者: 龙听    时间: 2025-4-12 10:35

C++ 标准库 <iterator>学习参考:
本帖隐藏的内容需要积分高于 1 才可浏览





欢迎光临 龙听期货论坛 (http://www.qhlt.cn/) Powered by Discuz! 7.2