Login Page - Create Account

Support Board


Date/Time: Fri, 14 Mar 2025 12:34:45 +0000



John Ehlers Deviation Scaled MA Code

View Count: 197

[2024-12-28 14:11:59]
cmet - Posts: 677
This is a version of the Deviation Scaled Moving Average by John Ehlers. If any ACSIL experts have time, was hoping you could look at the code below and give any comments/criticisms.

The PDF of the DSMA from Ehlers which contains the original code is also attached for reference.

Thanks in advance for any help.

#include "sierrachart.h"

SCDLLName("DSMA");

SCSFExport scsf_DSMA(SCStudyInterfaceRef sc)
{
SCSubgraphRef Subgraph_DSMA = sc.Subgraph[0];

SCInputRef Input_Period = sc.Input[0];
SCInputRef Input_Data = sc.Input[1];
SCInputRef Input_StdDevs = sc.Input[2];

if (sc.SetDefaults)
{
sc.GraphName = "DSMA";
sc.AutoLoop = 1;

Subgraph_DSMA.Name = "DSMA";
Subgraph_DSMA.PrimaryColor = RGB(0, 255, 0);
Subgraph_DSMA.DrawStyle = DRAWSTYLE_LINE;
Subgraph_DSMA.LineWidth = 2;
Subgraph_DSMA.DrawZeros = true;

Input_Period.Name = "Period";
Input_Period.SetInt(40);
Input_Period.SetIntLimits(1, MAX_STUDY_LENGTH);

Input_Data.Name = "Input Data";
Input_Data.SetInputDataIndex(SC_LAST); // Includes standard inputs

Input_StdDevs.Name = "Standard Deviations Multiplier";
Input_StdDevs.SetFloat(5.0f);
Input_StdDevs.SetFloatLimits(0.1f, 100.0f);

return;
}

// Variables
float a1, b1, c1, c2, c3;
SCFloatArrayRef Zeros = Subgraph_DSMA.Arrays[0];
SCFloatArrayRef Filt = Subgraph_DSMA.Arrays[1];
SCFloatArrayRef ScaledFilt = Subgraph_DSMA.Arrays[2];
SCFloatArrayRef RMS = Subgraph_DSMA.Arrays[3];

int Period = Input_Period.GetInt();
float StdDevs = Input_StdDevs.GetFloat();
SCFloatArrayRef DataArray = sc.BaseData[Input_Data.GetInputDataIndex()];

// Initialize filter coefficients
a1 = expf(-1.414f * 3.14159f / (0.5f * (float)Period));
b1 = 2.0f * a1 * cosf(1.414f * 180.0f / (0.5f * (float)Period));
c2 = b1;
c3 = -a1 * a1;
c1 = 1.0f - c2 - c3;

// Compute Zeros
Zeros[sc.Index] = DataArray[sc.Index] - DataArray[sc.Index - 2];

// Apply Super Smoother Filter
Filt[sc.Index] = c1 * (Zeros[sc.Index] + Zeros[sc.Index - 1]) / 2.0f
+ c2 * Filt[sc.Index - 1]
+ c3 * Filt[sc.Index - 2];

// Compute RMS over the Period
float sumSquares = 0.0f;
for (int i = 0; i < Period; ++i)
{
sumSquares += Filt[sc.Index - i] * Filt[sc.Index - i];
}
RMS[sc.Index] = sqrtf(sumSquares / (float)Period);

// Rescale filter in terms of Standard Deviations
if (RMS[sc.Index] != 0.0f)
{
ScaledFilt[sc.Index] = Filt[sc.Index] / RMS[sc.Index];
}
else
{
ScaledFilt[sc.Index] = 0.0f;
}

// Compute DSMA
float alpha1 = fabsf(ScaledFilt[sc.Index]) * StdDevs / (float)Period;
Subgraph_DSMA[sc.Index] = alpha1 * DataArray[sc.Index] + (1.0f - alpha1) * Subgraph_DSMA[sc.Index - 1];
}

Date Time Of Last Edit: 2024-12-28 14:19:31
attachmentEhlers DSMA.pdf - Attached On 2024-12-28 14:11:49 UTC - Size: 275.46 KB - 47 views

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account