C++程序化/量化学习视频教程系列 第024节:鼎元C++量化之调用map调用bar数据(K线开、高、低及收盘价格调用)知识及C++量化开发中的注意事项【C++量化指标公式开发系列】
- UID
- 2
- 积分
- 2892617
- 威望
- 1396340 布
- 龙e币
- 1496277 刀
- 在线时间
- 13326 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2024-12-25
|
C++程序化/量化学习视频教程系列 第024节:鼎元C++量化之调用map调用bar数据(K线开、高、低及收盘价格调用)知识及C++量化开发中的注意事项【C++量化指标公式开发系列】
论坛官方微信、群(期货热点、量化探讨、开户与绑定实盘)
|
|
|
|
|
|
- UID
- 2
- 积分
- 2892617
- 威望
- 1396340 布
- 龙e币
- 1496277 刀
- 在线时间
- 13326 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2024-12-25
|
演示:用数组、容器及map进行数据的操作:- #include<iostream>
- #include<map>
- #include <cstring>
- #include <vector>
- #include <math.h>
- #include <iomanip>
- using namespace std;
- using std::setw;
- int main()
- {
- double nice[5]={0,1,2,3,4};
- for (int i = 0; i < 5; i++)
- {
- cout << nice[i] << endl;
- }
- for (int j = 0; j < 5; j++)
- {
- nice[j] = 2 * j;
- cout << nice[j] << endl;
- }
- vector<double>mynice = { 0,1,2,3,4,5 };
- for (int i = 0; i < 5; i++)
- {
- cout << "用vector输出:" << mynice[i] <<endl;
- }
- for (int i = 0; i < 5; i++)
- {
- mynice.push_back(i*2);
- cout << mynice[i] << endl;
- }
- for (int i = 0; i < mynice.size(); i++)
- {
- cout << mynice[i] << endl;
- }
- return 0;
- }
复制代码 |
|
|
|
|
|
|
- UID
- 2
- 积分
- 2892617
- 威望
- 1396340 布
- 龙e币
- 1496277 刀
- 在线时间
- 13326 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2024-12-25
|
声明 map 容器:- std::map<key_type, value_type> myMap;
复制代码 key_type 是键的类型。
value_type 是值的类型。
插入元素:访问元素:遍历 map:- for (std::map<key_type, value_type>::iterator it = myMap.begin(); it != myMap.end(); ++it) {
- std::cout << it->first << " => " << it->second << std::endl;
- }
复制代码- std::map<key_type, value_type>::iterator
- for (it = myMap.begin(); it != myMap.end(); ++it) {
- std::cout << it->first << " => " << it->second << std::endl;
- }
复制代码- #include <iostream>#include <map>
- #include <string>
- int main() {
- // 创建一个 map 容器,存储员工的姓名和年龄
- std::map<std::string, int> employees;
- // 插入员工信息
- employees["Alice"] = 30;
- employees["Bob"] = 25;
- employees["Charlie"] = 35;
- // 遍历 map 并打印员工信息
- std::map<std::string, int>::iterator
- for ( it = employees.begin(); it != employees.end(); ++it) {
- std::cout << it->first << " is " << it->second << " years old." << std::endl;
- }
- return 0;
- }
复制代码 在鼎元C++中请求调用数据函数:
RsqBar:- RsqBar(sPeriod, sInst);//查询历史K线数据
- ma = average(sPeriod, sInst, length); //调用简单移动平均线数值
复制代码- void test::RsqBar(string period, string inst)
- {
- TRSQBAR* t = new TRSQBAR();
- t->Name = sName;
- t->Type = "RsqBar";
- t->Period = period;
- t->Inst = inst;
- if (hwnd)SendMessage(hwnd, WM_RSQBAR, (WPARAM)t, (LPARAM)36);
- }
复制代码
函数注意事项:- double test::average(string period, string inst, int num)
复制代码- struct TKVALUE
- {
- string sDate;
- string sTime;
- string InstrumentID;
- string sPeriod;
- double dOpen = 0;
- double dHigh = 0;
- double dLow = 0;
- double dClose = 0;
- int nVolume = 0;
- int nOpenInterest = 0;
- string sDayNight;
- };
复制代码 逆向遍历:- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); ++it)
复制代码 正向遍历:- map<string, TKVALUE >::iterator it;
- for (it = mapK[period][inst].begin(); it != mapK[period][inst].end(); ++it)
复制代码 形象展示:
说明:
1、因为周期、品种合约代码都是固定的。所以在map里面KVALUE中的要素还包括:
2、日期和时间:平时多用不着。但是当需要从左向右的正序调用数据时或从 右向左逆向调用数据时时间是一个排序的工具。
3、k线的主要要素(开、高、低、收)。
4、成交量;
5、持仓量;
总结:以蜡烛图的四要素与成交持仓两要素组成了交易策略的大部分设计元素。
如何调用:- map<string, TKVALUE >::iterator it; //建立正迭代器,标号从0开始,一般从左向右开始
- for (it = mapK[period][inst].begin(); it != mapK[period][inst].end(); ++it) //从第一开始的bar数据开始遍历
- {
- it->second.
- }
复制代码 在TKVALUE中能调用的素材:- string sDate;
- string sTime;
- string InstrumentID;
- string sPeriod;
- double dOpen = 0;
- double dHigh = 0;
- double dLow = 0;
- double dClose = 0;
- int nVolume = 0;
- int nOpenInterest = 0;
- string sDayNight;
复制代码 所以在用k线做策略时我们多数能调用的也就是dhigh,dlow,dopen,dclose,nvolume,nopeninterest 这六个要素。制作均线,常用的就是dclose,区间上沿多用dhigh,区间下沿多用dlow。 |
|
|
|
|
|
|
- UID
- 2
- 积分
- 2892617
- 威望
- 1396340 布
- 龙e币
- 1496277 刀
- 在线时间
- 13326 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2024-12-25
|
我要是想调用最新bar的开盘价。
我要做三件事:
1、建立遍历用的迭代器,因为我是要用到最新的,所以我要建立一个逆向迭代器。
2、找到最新的bar,因为我是用的逆向的,所以第一个数据就是我要调用的,只需要循环一次就行了。我要用到一个开关,就是控制只允许它循环一轮就结束。
3、把dopen调来用。
完整流程是这样的:
1、建立正向迭代器:- map<string, TKVALUE>::reverse_iterator it;
复制代码 2、用for循环来进行遍历:(因为我仅允许它循环一次,所以我加一个开关)- int key = 0; //建立一个开关,下面看我是怎么使用这个开关的
- int closep; //声明一个变量用来存储最新bar的开盘价
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- }
复制代码 3、调用我需要的最新的开盘价
(1)声明一个变量用来存这个收盘价: int closep;
(2) 将最新的bar的开盘价赋值给(1)中的变量:closep = it ->second.dopen;
完整的程式码是这样的:- RsqBar(period, sInst); //申请调用数据指令
- double key = 0; //建立一个开关
- map<string, TKVALUE>::reverse_iterator it; //建立逆向迭代器
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); ++it) //进行遍历
- {
- closep = it->second.dopen; //将最新的bar的开盘价赋值给closep;
- key++; //开关自动加1,即从0变为1
- if (key > 0) break; //进行判断如果key大于0就跳出结束循环,也可以使用key == 1 然后结束循环等等
- }
复制代码 |
|
|
|
|
|
|
- UID
- 2
- 积分
- 2892617
- 威望
- 1396340 布
- 龙e币
- 1496277 刀
- 在线时间
- 13326 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2024-12-25
|
另一种办法调用最新bar的开盘价。
1、思路:
1、大体思路仍然是建立迭代器、for循环。
2、但是建立for循环后我用一个vector来装TKVALUE中所有bar的开盘价。
3、然后我用vector[标号]来直接引用。
4、甚至我要是想进行平均,计算方差类的,也可以继续用这个vector。
完整流程是这样的:
(1)、在头文件中声明变量:(2)、在源文件:- RsqBar(sPeriod, sInst); //调用数据申请指令
- map<string, TKVALUE >::iterator it; //建立一个正向的迭代器
- for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); ++it) //建立for遍历
- {
- openp.push_back(it->second.dopen); //从左至右将每一个bar的开盘价加到openp容器vector中
- }
- closep = openp[openp.size()-1]; //通过下标号将用最新的dopen价格给closep;
复制代码 |
|
|
|
|
|
|
- UID
- 2
- 积分
- 2892617
- 威望
- 1396340 布
- 龙e币
- 1496277 刀
- 在线时间
- 13326 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2024-12-25
|
使用场景有两个:一个是在onrun中调用最新bar的开价,然后在tick中直接使用即可。二是将上面的的程式码再加到onbariopen中。每新生成一个bar就会运行一次,将最新的bar开盘价调用出来供使用。 |
|
|
|
|
|
|
- UID
- 2
- 积分
- 2892617
- 威望
- 1396340 布
- 龙e币
- 1496277 刀
- 在线时间
- 13326 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2024-12-25
|
再发个更详细的map(TKVALUE)形象图:
|
|
|
|
|
|
|