  
- UID
- 2
- 积分
- 2945117
- 威望
- 1422595 布
- 龙e币
- 1522522 刀
- 在线时间
- 13794 小时
- 注册时间
- 2009-12-3
- 最后登录
- 2025-4-24

|
2025年4.12日我重新整理的函数公式变量声明和模板
test.h头文件声明部分:- //指标公式变量声明******************************************************************test头文件指标公式变量名称模块开始(修改与编辑指标参数变量)
- double iff(bool cond1, int num, int ref);//iff函数
- double max2(double a, double b);//返回a,b中较大值
- double max3(double a, double b, double c);//返回a,b,c中最大值
- double min2(double a, double b); //返回a,b中较小值
- double min3(double a, double b, double c);//返回a,b,c中最小值
- double waverage(string period, string inst, int num);//计算Weighted Moving Average,加权移动平均线
- double average(string period, string inst, int num); //average,ma函数变量,atr计算功能
- double highest(string period, string inst, int num);//计算NUM周期最高价格
- double highestN(string period, string inst, int num, int ref);//计算REF前个bar的num周期最高价格
- double lowest(string period, string inst, int num); //计算NUM周期最低价格
- double lowestN(string period, string inst, int num, int ref);//计算ref前个bar的num周期的最低价格
- double closeN(string period, string inst, int ref);//计算ref前个bar的收盘价格
- double avgtruerange(string period, string inst, int num); //计算真实波动幅度平均值(average true range)
- double Variance(string period, string inst, int num);//计算方差公式变量
- double StandardDev(string period, string inst, int num);//计算标准差公式变量
- double Volatility(string period, string inst, int num);//计算历史波动率(CALCULATING HISTORICAL VOLATILITY)
- double bollingerbands(string period, string inst, int num, int ref); //计算boll布林带变量
- //指数移动平均返回具体数据时调用xaverage,返回数组时则用ema调用。数组形式多用于指标计算中间变量
- double xaverage(string period, string inst, int num);//计算num周期指数移动平均(Exponential Moving Average)值
- vector<double>ema(vector<double>pc, int num);//ema计算返回数组vector形式指数移动平均
- //指数移动平均返回具体数据时调用xaverage,返回数组时则用ema调用。数组形式多用于指标计算中间变量
- vector<double>EMAvectorCaL(vector<double>pc, int num);//EMA容器计算形式
- vector<double>MACDcalculate(vector<double>pc, int shortPeriod, int longPeriod);//计算MACD
- double mav(vector<double>pc, int num);//计算简单MA数组形式
- double hhv(vector<double> pc, int num);
- double llv(vector<double> pc, int num);
- double AEMA(string period, string inst, int num, int pds);//自适应移动平均线(Adaptive Exponential Moving Average, AEMA)
- vector<double>aema, highs, lows; //vector变量容器
- double a0, a1, a2, a3, a4, value2, value3, mltp1, mltp2, rate, aema1, aema2;//必要变量,自适应移动平均线
- double marketstrength(string period,string inst, int num);//marketstrength函数调用与计算
- double Momentum(string period, string inst, int num); //动量指标(Momentum Index,MTM)计算与指标调用
- //指标公式变量声明******************************************************************test头文件指标公式变量名称模块结束(修改与编辑指标参数变量)
复制代码 函数模板模块:- //****************************************************************外部引用文件开始(谨慎修改)
- #include "pch.h"
- #include "test.h"
- #include <vector>
- #include <windows.h>
- #include <fstream>
- #include <stdio.h>
- #include <mmsystem.h>
- #include <thread>
- #pragma comment(lib,"winmm.lib")
- #include <algorithm> // For std::min_element and std::max_element
- #include <deque>
- using namespace std;
- //****************************************************************主程序指标公式function计算模块(公式编辑与设计区)
- // iff功能函数开始
- double test::iff(bool cond1, int num, int ref)
- {
- int d = 0;
- if (cond1)
- {
- d = num;
- }
- else
- {
- d = ref;
- }
- return d;
- }
- //max2(a,b)比较a,b两个数字
- double test::max2(double a, double b)
- {
- double c = 0;
- if (a >= b)
- {
- c = a;
- }
- else
- {
- c = b;
- }
- return c;
- }
- //max3(a,b)比较a,b,c三个数字
- double test::max3(double a, double b, double c)
- {
- double d = 0;
- if (a >= b)
- {
- d = a;
- }
- else if (a < b)
- {
- d = b;
- }
- if (d < c)
- {
- d = c;
- }
- return d;
- }
- //min2(a,b)比较两个数字大小
- double test::min2(double a, double b)
- {
- double c = 0;
- if (a >= b)
- {
- c = b;
- }
- else
- {
- c = a;
- }
- return c;
- }
- //min3(a,b,c)比较三个数字大小
- double test::min3(double a, double b, double c)
- {
- double d = 0;
- if (a >= b)
- {
- d = b;
- }
- else if (a < b)
- {
- d = a;
- }
- if (d > c)
- {
- d = c;
- }
- return d;
- }
- //均线average计算公式开始
- double test::average(string period, string inst, int num)
- {
- int key = 0;
- double sump = 0;
- if (mapK[period][inst].size() < num) return 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[sPeriod][sInst].rbegin(); it != mapK[sPeriod][sInst].rend(); it++)
- {
- sump = sump + it->second.dClose;
- key++;
- if (key >= num)break;
- }
- return sump / num;
- }
- //计算num周期内bar最高价格
- double test::highest(string period, string inst, int num)
- {
- double hiprice = 0;
- int key = 0;
- map<string, TKVALUE>::reverse_iterator it; //建立逆向迭代器从右往左
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++) //FOR循环遍历
- {
- if (hiprice < it->second.dHigh) hiprice = it->second.dHigh; //如果hiprice值小于遍历的bar的最高价,则将最高价赋值给hiprice
- key++;//计算循环次数
- if (key >= num)break; //达到num个bar后跳出循环
- }
- return hiprice;//将获取的最高价格值返回
- }
- //计算num周期内bar的最低价格
- double test::lowest(string period, string inst, int num)
- {
- double lowprice = 0;
- int key = 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- if (lowprice == 0)lowprice = it->second.dLow;
- if (lowprice > it->second.dLow)lowprice = it->second.dLow;
- key++;
- if (key >= num)break;
- }
- return lowprice;
- }
- //计算历史波动率(calculating historical volatility)
- double test::Volatility(string period, string inst, int num)
- {
- double PreClose = 0;//获取每个bar前一个bar的收盘价
- double tr = 0; //tr的值计算
- int key = 0; //计数器
- vector<double>vtr; //建立一个数组,用来存放每个bar对应的truerange值,它们的下标号与bar的是一致的
- if (mapK[period][inst].size() < num) return 0; //如果数据数量不够返回0;
- map<string, TKVALUE >::iterator it; //建立正迭代器,标号从0开始,从左向右开始
- for (it = mapK[period][inst].begin(); it != mapK[period][inst].end(); ++it) //从第一开始的bar数据开始遍历
- {
- if (PreClose != 0) //如果值不为0说明是在中间的bar,开始在bar数据要素中采集需要的变量数值
- {
- double dHL = it->second.dHigh - it->second.dLow; //当根bar的最高减最低
- double dHC = abs(it->second.dHigh - PreClose); //当根bar最高减昨日收盘
- double dLC = abs(it->second.dLow - PreClose); //当根bar最低减昨日收盘
- double e = max3(dHL, dHC, dLC); //获得每一个bar对应的truerange值(上面三者之最大者)
- vtr.push_back(e); //将上面e的值放到tr的vector(数组)里面供下面使用
- }
- PreClose = it->second.dClose; //将当前bar的收盘价数值赋给此变量供下一个bar使用
- }
- //计算tr的num周期指数移动平均值
- if (key <= num)
- {
- tr = 0;
- key++;
- }
- else
- {
- tr = (vtr[vtr.size() - 1]) * 2 / (num + 1) + tr * (num - 1) / (num + 1); // 2/(num + 1)指数移动平均线的平滑因子
- //tr = (2 * vtr[vtr.size()-1] + (num - 1) * tr)/(num + 1); //第二种计算vtr指数移动平均方式,平滑因子不变
- }
- return tr;
- }
- //计算真实波动幅度平均值(average true range)
- double test::avgtruerange(string period, string inst, int num)
- {
- double preclose = 0; //设计一个局部变量存储上一日收盘价
- double sumatr = 0; // 设计一个加总变量, 存储atr的值
- vector<double>vatr;//设计一个vector变量,存储tr值
- if (mapK[period][inst].size() < num) return 0; //如果数据不够用返回0
- map<string, TKVALUE>::iterator it;//建立一个正向迭代器
- for (it = mapK[period][inst].begin(); it != mapK[period][inst].end(); it++) //建立 for 循环采集需要的要素数据
- {
- if (preclose != 0) //这次不是第一次循环
- {
- double dHL = it->second.dHigh - it->second.dLow; //当天最高价减当天最低价
- double dHC = abs(it->second.dHigh - preclose); //当天最高价减昨天收盘价
- double dLC = abs(it->second.dLow - preclose); //当天最低价减昨天收盘价
- vatr.push_back(max3(dHL, dHC, dLC)); //将上面三个值中最大值加入到vector里面
- }
- preclose = it->second.dClose; //每次遍历后将当天的收盘价赋值给preclose供下次遍历使用
- }
- for (int i = 1; i <= length; i++)
- {
- sumatr = sumatr + vatr[vatr.size() - i];//将vatr中的数据从右至左依顺序加总num个
- }
- return sumatr / num;
- }
- //方差计算公式
- double test::Variance(string period, string inst, int num)
- {
- double ma = average(sPeriod, sInst, num);//中间均线
- int key = 0;
- double sumdev = 0;
- double madev = 0;
- if (mapK[period][inst].size() < num) return 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- sumdev += pow(it->second.dClose - ma, 2); //计算偏离平方和
- key++;
- if (key >= num)break; //num次循环后跳出
- }
- return sumdev / num;
- }
- //标准差计算公式
- double test::StandardDev(string period, string inst, int num)
- {
- double value1 = 0;
- if (mapK[period][inst].size() < num) return 0;
- value1 = Variance(sPeriod, sInst, num);
- return sqrt(value1);
- }
- //boll布林带计算公式
- double test::bollingerbands(string period, string inst, int num, int ref)
- {
- double ma = average(sPeriod, sInst, num); //获取num周期平均线ma
- int key = 0;
- double sumdev = 0;
- double madev = 0;
- if (mapK[period][inst].size() < num) return 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- sumdev += pow(it->second.dClose - ma, 2);
- key++;
- if (key >= num)break;
- }
- madev = sqrt(sumdev / num); //获得标准差
- return ma + ref * madev;
- }
- //计算num周期指数移动平均(Exponential Moving Average)值
- double test::xaverage(string period, string inst, int num)
- {
- double n = 0;
- double ema = 0;
- if (mapK[period][inst].size() < num) return 0;
- map<string, TKVALUE>::iterator it;
- for (it = mapK[period][inst].begin(); it != mapK[period][inst].end(); it++)
- {
- if (n < num)
- {
- ema = (ema + it->second.dClose) / (n + 1);
- n++;
- }
- else
- {
- ema = (2 * it->second.dClose + (n - 1) * ema) / (n + 1); //指数移动平均计算核心公式,ema = a*close + (1-a)*ema[1],a为加权因子,通常=2/(N+1)
- }
- }
- return ema;
- }
- //计算Weighted Moving Average,加权移动平均
- double test::waverage(string period, string inst, int num)
- {
- double sumwma = 0;
- int i = 0;
- if (mapK[period][inst].size() < num) return 0; //bar数量小于num个时返回0
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- sumwma += (num-i) * it->second.dClose; //计算num*close + (num-1)*close[1] +...+ 1*close[num-1]的总和
- i++;
- if(i >= num) break;
- }
- double d = (num+1)*num * 0.5; //计算num从1到num的总和
- return sumwma / d;
- }
- //ema计算返回数组vector形式指数移动平均
- vector<double>test::ema(vector<double>pc, int num)
- {
- vector<double>emav;
- double emavector = 0;
- int i = 0;
- for (int it = 0; it < pc.size(); it++)
- {
- // if (i < num)
- // {
- // emavector = (emavector + pc[it])/(i+1);
- // i++;
- // emav.push_back(emavector);
- // }
- // else
- // {
- //// emavector = (2*pc[it]+(num-1)*emavector)/(num+1);//ema均线计算公式
- // emavector = emavector + 2 * (pc[it] - emavector) / (num + 1);
- // emav.push_back(emavector);
- // }
- if (it == 0)
- {
- emavector = emavector + pc[it];
- emav.push_back(pc[0]);
- }else
- {
- // emavector = (2*pc[it]+(num-1)*emavector)/(num+1);//ema均线计算公式
- emavector = emavector + 2 * (pc[it] - emavector) / (num + 1);
- emav.push_back(emavector);
- }
- }
- return emav;
- }
- //计算REF前个bar的num周期最高价格
- double test::highestN(string period, string inst, int num, int ref)
- {
- double d = 0;
- int n = 0;
- int r = 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- r++;
- if (r <= ref)continue; //需要跳过的bar数
- if (d < it->second.dHigh)d = it->second.dHigh; //将最大值赋值给d
- n++;
- if (n >= num) break; //num 次循环后跳出(从0开始,所以从num-1个后就退出)
- }
- return d; //返回d
- }
- //计算ref前个bar的num周期的最低价格
- double test::lowestN(string period, string inst, int num, int ref)
- {
- double d = 0;
- int n = 0;
- int r = 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- r++;
- if (r <= ref) continue; //需要跳过的bar数
- if (d == 0)d = it->second.dLow; //判断是否是第一次循环
- if (d > it->second.dLow)d = it->second.dLow; //将低最值赋给d
- n++;
- if (n >= num)break; //num个循环后退出
- }
- return d; //返回d值
- }
- //返回ref个bar前的收盘价
- double test::closeN(string period, string inst, int ref)
- {
- double d = 0;
- int r = 0;
- int n = 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- r++;
- if (r <= ref)continue; //跳过ref个bar
- d = it->second.dClose; //将ref个bar前一个bar的收盘价赋值给d ;
- break;
- }
- return d;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////MACD公式计算
- vector<double>test::EMAvectorCaL(vector<double>pc, int num)//EMA容器计算形式
- {
- vector<double> ema(pc.size());
- double multiplier = 2.0 / (num + 1);
- ema[0] = pc[0]; // 初始化第一值为价格的第一个值
- for (int i = 1; i < pc.size(); i++) {
- ema[i] = (pc[i] - ema[i - 1]) * multiplier + ema[i - 1];
- }
- return ema;
- }
- vector<double>test::MACDcalculate(vector<double>pc, int shortPeriod, int longPeriod)
- {
- // 计算快线和慢线的 EMA
- vector<double> shortEMA = EMAvectorCaL(pc, shortPeriod);
- vector<double> longEMA = EMAvectorCaL(pc, longPeriod);
- // 计算 DIFF
- vector<double> diff(pc.size());
- for (int i = 0; i < pc.size(); i++)
- {
- diff[i] = shortEMA[i] - longEMA[i];
- }
- return diff;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////MACD公式计算
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////KDJ公式计算
- double test::hhv(vector<double> pc, int num)
- {
- double d = 0;
- for (size_t i = pc.size() - 1; i >= pc.size() - num; i--)
- {
- d = max2(d, pc[i]);
- }
- return d;
- }
- double test::llv(vector<double> pc, int num)
- {
- double d = 999999;
- for (size_t i = pc.size() - 1; i >= pc.size() - num; i--)
- {
- d = min2(d, pc[i]);
- }
- return d;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////KDJ公式计算
- double test::mav(vector<double>pc, int num)//计算简单MA数组形式
- {
- if (pc.size() <2) return 0;
- double d = 0;
- for (size_t i = pc.size() - 1; i >= pc.size() - num; i--)
- {
- d = d + pc[i];
- }
- return d / num;
- }
- //自适应移动平均线(Adaptive Exponential Moving Average, AEMA)
- double test::AEMA(string period, string inst, int num, int pds)//自适应移动平均线(Adaptive Exponential Moving Average, AEMA)
- {
- int key = 0;
- mltp1 = 2/(pds+1);
- mltp2 = 0;
- rate = 0;
- aema1 = 0;
- aema2 = 0;
- value2 = -99999;
- value3 = 99999;
- map<string, TKVALUE>::iterator it;
- for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); it++)
- {
- highs.push_back(it->second.dHigh);//将最高价装入vector中
- lows.push_back(it->second.dLow); //将最低价装入vector中
- a0 = it->second.dClose;
- if (key < num)
- {
- aema1 = aema1 + a0;//收盘价总和
- aema2 = aema1 / (key + 1);
- key++;
- }
- else
- {
- for (int i = 0; i < pds; i++) //将近10个周期的bar最高值装入vector
- {
- value2 = max2(value2, highs[key - 1 - i]); //遍历最近10个最高价找到最大的那个值放入value2
- value3 = min2(value3, lows[key - 1 - i]);
- }
- a1 = (a0 - value3);
- a2 = (value2 - a0);
- a3 = value2 - value3;
- a4 = abs(a1 - a2);
- if (a3 != 0)mltp2 = a4 / a3;
- rate = (1 + mltp2) * 2 / 11;
- aema2 = aema2 + rate * (it->second.dClose - aema2);
- key++;
- }
- }
- return aema2;
- }
- //marketstrength函数调用与计算
- double test::marketstrength(string period, string inst, int num)
- {
- double val1 = 0;
- double val2 = 0;
- double val3 = 0;
- int key = 0;
- double marketstrength = 0;
- map<string, TKVALUE>::reverse_iterator it; //建立逆向迭代
- for (it = mapK[sPeriod][sInst].rbegin(); it != mapK[sPeriod][sInst].rend(); it++) //遍历
- {
- pc.push_back(it->second.dClose); //将收盘价装入pc容器,注意是反向的,越靠前数据越新,比方说pc[0]是最新价格
- if (key > length)break; //截取前0-11个收盘价,一共12个数据
- key++;
- }
- for (int i = 0; i <= num; i++)
- {
- val1 += iff(pc[i] > pc[i + 1], pc[i], -pc[i]);
- val2 += iff(pc[i] > pc[i + 1], pc[i], 0);
- val3 += iff(pc[i] > pc[i + 1], 0, pc[i]);
- }
- if (val1 >= 0)
- {
- marketstrength = 100 * val1 / val2;
- }
- else
- {
- marketstrength = 100 * val1 / val3;
- }
- return marketstrength;
- }
- //动量指标(Momentum Index,MTM)计算与指标调用
- double test::Momentum(string period, string inst, int num)
- {
- double d = 0;
- int r = 0;
- int n = 0;
- map<string, TKVALUE>::reverse_iterator it;
- for (it = mapK[period][inst].rbegin(); it != mapK[period][inst].rend(); it++)
- {
- if (r == 0) n = it->second.dClose;
- r++;
- if (r < num)continue; //跳过NUM个bar
- d = it->second.dClose; //将ref个bar前一个bar的收盘价赋值给d ;
- break;
- }
- return n - d;
- }
复制代码 |
|