龙听期货论坛's Archiver

龙听 发表于 2024-11-13 11:40

鼎元C++期货量化/程序化教程【平滑异同移动平均线(Moving Average Convergence Divergence,MACD)计算方法及调用方法】

鼎元C++期货量化/程序化教程【平滑异同移动平均线(Moving Average Convergence Divergence,MACD)计算方法及调用方法】

1、头文件变量声明:[code]
        vector<double>pc;//priceclose,pc简称
        vector<double>emashort,emalong,diff,dea;
        double macd;//获取macd值,柱状图线数值
[/code]2、源文件加入数组vector返回 ema均线数据程式码模块:[code]
//ema计算公式开始(返回数组)
/*
从map<string,mapK>制式数据中分离需要处理的数据,然后通过这此的ema方式取得这些数据的ema平均,返回值仍然是数组vector
*/
vector<double> test::ema(vector<double> pc, int num)
{
        vector<double> ema;
        double emavector = 0;
        int i = 0;

        for (int it = 0; it < pc.size(); ++it)
        {
                if (i < num)
                {
                        emavector = (emavector + pc[it]) / (i + 1);
                        i++;
                        ema.push_back(emavector);
                }
                else
                {
                        emavector = (2 * pc[it] + (num - 1) * emavector) / (num + 1);
                        ema.push_back(emavector);
                }
        }
        return ema;
}
[/code]3、源文件加入MACD程式码模块:[code]
RsqBar(sPeriod, sInst);
        map<string,TKVALUE>::iterator it;
        for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); it++)
        {
                pc.push_back(it->second.dClose); //将收盘价放入pc容器vector
        }
        emashort = ema(pc,12);
        emalong = ema(pc,26);

        for (int i = 0; i < emalong.size(); i++)
        {
                diff.push_back(emashort[i] - emalong[i]); //DIFF - DEA
        }
        dea = ema(diff,9); //dea = xaverage(diff,9)
        macd = (diff[diff.size()-1] - dea[dea.size()-1])*2; //获取MACD柱数值
[/code]3、调用方法:[code]
        InsertLog("diff值为: " + to_string(diff[diff.size() - 1]));
        InsertLog("dea均线值为: " + to_string(dea[dea.size() - 1]));
        InsertLog("MACD值为: " + to_string(macd));
[/code]类似这样。

龙听 发表于 2024-12-28 15:38

上面的计算总是有些出入,所以这里我重新设计了一下,对比一下东财的数据,还是基本不错的。

龙听 发表于 2024-12-28 15:44

第一部分:头文件声明部分[code]
        vector<double>EMAvectorCaL(vector<double>pc, int num);//EMA容器计算形式
        vector<double>MACDcalculate(vector<double>pc, int shortPeriod, int longPeriod);//计算MACD
[/code][code]
        vector<double>pc,diff, dea, macd;
[/code]第二部分:源文件公式函数部分[code]
////////////////////////////////////////////////////////////////////////////////////////////////////////////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公式计算
[/code]第三部分:主程式模块[code]
        RsqBar(sPeriod, sInst);
        map<string, TKVALUE >::iterator it;
        for (it = mapK[sPeriod][sInst].begin(); it != mapK[sPeriod][sInst].end(); ++it)
        {
                pc.push_back(it->second.dClose);
        }
       
        // MACD 参数
        int shortPeriod = 12; // 快速 EMA 周期
        int longPeriod = 26;  // 慢速 EMA 周期
        int signalPeriod = 9; // 信号线 EMA 周期
        // 计算并输出diff
        diff = MACDcalculate(pc, shortPeriod, longPeriod);
        dea  = EMAvectorCaL(diff, signalPeriod);
        //计算 MACD 柱状图
        vector<double> macd(pc.size());
        for (size_t i = 0; i < pc.size(); i++)
        {
                macd[i] = 2 * (diff[i] - dea[i]); // 通常将 MACD 值乘以 2
        }
        InsertLog("最新diff " + to_string(diff[diff.size() - 1]) + "最新dea " + to_string(dea[dea.size() - 1]) + "最新MACD " + to_string(macd[macd.size() - 1]));
[/code]

页: [1]