C++ 包装器类用于计算移动平均值





5.00/5 (2投票s)
C++ 包装器类用于计算移动平均值
引言
有时您需要计算某个数量的移动平均值。在本文中,我将描述帮助您计算移动平均值的包装类。有多种方法可以计算移动平均值,例如简单移动平均值、加权移动平均值和指数移动平均值。由于时间限制,我只实现了前两种。
背景
维基百科上有一篇关于移动平均线的好文章:Wikipedia。但是,我将在这里简单介绍一下。
当您测量平均值时,您正在测量整个数据范围内数量的平均值。有时,仅测量最后 N 个样本值的平均值是有用的。例如,交易者可能想知道某只股票过去七天的平均价格,并且他/她每天都想要这个值。这将通过计算移动平均值来完成。每次将新样本添加到数据中时,我们需要丢弃最旧的样本,将新样本添加到数据中并计算平均值。
加权移动平均值是简单移动平均值的修改版本,其中可以根据应用或分析为每个样本分配权重。通常,最近的样本被分配最高的权重,而最近最远的样本被分配最低的权重。
指数加权移动平均值是加权移动平均值的另一种版本,其中权重呈指数增加或减少。
我有两个 C++ 包装类 - CSimpleMovingAverage
用于简单移动平均,CWeightedMovingAverage
用于加权移动平均。这两个类都派生自 CMovingAverage
,因此它们提供统一的接口。这样,有人可以将更复杂的移动平均值添加到“库”中。
Using the Code
为了使用 CSimpleMovingAverage
或 CWeightedMovingAverage
,您必须首先像这样创建对象
CSimpleMovingAverage movingAvgCtr;
这两个类仅实现两种方法,这两种方法都非常容易理解
virtual void AddSample(const float a_fSample) = 0;
virtual float GetAverage() const = 0;
默认情况下,这些类将测量最近 10 个样本的平均值。假设您想要更大的样本间隔,您可以将所需的样本大小传递给构造函数
CSimpleMovingAverage movingAvgCtr(20);
现在要开始获取平均值,您需要使用 AddSample
方法添加样本
movingAvgCtr.AddSample(44.5);
您可以使用 GetAverage()
方法在任何时间点获得移动平均值。
实现细节
在内部,样本使用 STL 队列容器维护。由于在获取 N 个样本后,我们需要丢弃最近最少的样本并添加新样本,因此我发现队列的 push、pop、front 和 back 操作在编码时非常直观。
关注点
我编写此代码的原因是,当我需要它时,我在网上找不到任何 C++ 代码。我知道这些类在某些方面有所欠缺。在 CWeightedMovingAverage
中,我为最近的样本分配了最高的权重,有人可能想要反过来,为最近最少的样本分配最高的权重(为什么?这取决于应用程序,不幸的是我对统计的理解不是很好,所以我不知道)。当然,库中也缺少指数移动平均。
我的弱点之一是我没有编写足够的自动化测试用例。在 *main.cpp* 中,我编写了一个最简单的测试用例,我用它来验证代码的正确性。当我在数据中包含负样本值时,我得到了加权移动平均线的奇怪值。我不确定这是代码中的错误还是预期结果?
历史
- 2009 年 4 月 28 日:初始发布