I've converted the AFIRMA indicator from MQL4
to C#
. It outputs the first series correctly (FIRMA) but the second one is stuck somewhere in the code (ARMA). Any ideas where or what keeps it from outputting? It seems like it's stuck somewhere.
我已经将AFIRMA指示器从MQL4转换为c#。它正确地输出了第一个序列(FIRMA),但是第二个序列在代码(ARMA)的某个地方被卡住了。有什么想法或什么原因阻止它输出吗?好像被困在什么地方了。
Thank you for your time.
谢谢您的时间。
namespace cAlgo.Indicators
{
[Indicator(ScalePrecision = 5, AutoRescale = true, IsOverlay = true, AccessRights = AccessRights.None)]
public class AFIRMA : Indicator
{
[Parameter("Periods", DefaultValue = 12)]
public int Periods { get; set; }
[Parameter("Taps", DefaultValue = 25)]
public int Taps { get; set; }
[Parameter("Window", DefaultValue = 4)]
public int Window { get; set; }
[Output("FIRMA", Color = Colors.Blue, PlotType = PlotType.DiscontinuousLine)]
public IndicatorDataSeries FIRMA { get; set; }
[Output("ARMA", Color = Colors.Red, PlotType = PlotType.DiscontinuousLine)]
public IndicatorDataSeries ARMA { get; set; }
int n;
double den;
double sx6;
double sx5;
double sx4;
double sx3;
double sx2;
double wsum;
double[] w;
protected override void Initialize()
{
//Calculate weights
Array.Resize(ref w, Taps);
wsum = 0.0;
for (int k = 0; k < Taps; k++)
{
switch (Window)
{
case 1:
w[k] = 1.0;
break;
case 2:
w[k] = 0.5 - 0.5 * Math.Cos(2.0 * Math.PI * k / Taps);
break;
case 3:
w[k] = 0.54 - 0.46 * Math.Cos(2.0 * Math.PI * k / Taps);
break;
case 4:
w[k] = 0.42 - 0.5 * Math.Cos(2.0 * Math.PI * k / Taps) + 0.08 * Math.Cos(4.0 * Math.PI * k / Taps);
break;
case 5:
w[k] = 0.35875 - 0.48829 * Math.Cos(2.0 * Math.PI * k / Taps) + 0.14128 * Math.Cos(4.0 * Math.PI * k / Taps) - 0.01168 * Math.Cos(6.0 * Math.PI * k / Taps);
break;
default:
w[k] = 1;
break;
}
if (k != Taps / 2.0)
w[k] = w[k] * Math.Sin(Math.PI * (k - Taps / 2.0) / Periods) / Math.PI / (k - Taps / 2.0);
wsum += w[k];
}
//Calculate sums for the least-squares method
n = (Taps - 1) / 2;
sx2 = (2 * n + 1) / 3.0;
sx3 = n * (n + 1) / 2.0;
sx4 = sx2 * (3 * n * n + 3 * n - 1) / 5.0;
sx5 = sx3 * (2 * n * n + 2 * n - 1) / 3.0;
sx6 = sx2 * (3 * n * n * n * (n + 2) - 3 * n + 1) / 7.0;
den = sx6 * sx4 / sx5 - sx5;
}
public override void Calculate(int index)
{
//Calculate FIR MA for all bars except for the last n bars
for (int i = 0; i <= Bars - Taps; i++)
{
FIRMA[i + n] = 0.0;
for (int k = 0; k < Taps; k++)
FIRMA[i + n] += MarketSeries.Close[i + k] * w[k] / wsum;
}
//Calculate regressive MA for the remaining n bars
double a0 = FIRMA[n];
double a1 = FIRMA[n] - FIRMA[n + 1];
double sx2y = 0.0;
double sx3y = 0.0;
for (int i = 0; i <= n; i++)
{
sx2y += i * i * MarketSeries.Close[n - i];
sx3y += i * i * i * MarketSeries.Close[n - i];
}
sx2y = 2.0 * sx2y / n / (n + 1);
sx3y = 2.0 * sx3y / n / (n + 1);
double p = sx2y - a0 * sx2 - a1 * sx3;
double q = sx3y - a0 * sx3 - a1 * sx4;
double a2 = (p * sx6 / sx5 - q) / den;
double a3 = (q * sx4 / sx5 - p) / den;
for (int i = 0; i <= n; i++)
{
ARMA[n - i] = a0 + i * a1 + i * i * a2 + i * i * i * a3;
return;
}
}
private int Bars
{
get { return MarketSeries.Close.Count; }
}
}
}
MQL4 reference code:
MQL4参考代码:
#property copyright "Copyright © 2006, gpwr."
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_width1 2
#property indicator_width2 2
//Global constants
#define pi 3.141592653589793238462643383279502884197169399375105820974944592
//Input parameters
extern int Periods = 4; // 1/(2*Periods) sets the filter bandwidth
extern int Taps = 21; // must be an odd number
extern int Window = 4; // selects windowing function
//Global variables
double w[], wsum, sx2, sx3, sx4, sx5, sx6, den;
int n;
//Indicator buffers
double FIRMA[];
double ARMA[];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
//Calculate weights
ArrayResize(w, Taps);
wsum = 0.0;
for(int k = 0; k < Taps; k++)
{
switch(Window)
{
case 1: w[k] = 1.0; // Rectangular window
break;
case 2: w[k] = 0.50 - 0.50*MathCos(2.0*pi*k / Taps); // Hanning window
break;
case 3: w[k] = 0.54 - 0.46*MathCos(2.0*pi*k / Taps); // Hamming window
break;
case 4: w[k] = 0.42 - 0.50*MathCos(2.0*pi*k / Taps) +
0.08*MathCos(4.0*pi*k / Taps); // Blackman window
break;
case 5: w[k] = 0.35875 - 0.48829*MathCos(2.0*pi*k / Taps) +
0.14128*MathCos(4.0*pi*k / Taps) -
0.01168*MathCos(6.0*pi*k / Taps); // Blackman - Harris window
break;
default: w[k] = 1; //Rectangular window
break;
}
if(k != Taps / 2.0)
w[k] = w[k]*MathSin(pi*(k - Taps / 2.0) / Periods) / pi / (k - Taps / 2.0);
wsum += w[k];
}
//Calculate sums for the least-squares method
n = (Taps - 1) / 2;
sx2 = (2*n + 1) / 3.0;
sx3 = n*(n + 1) / 2.0;
sx4 = sx2*(3*n*n+3*n - 1) / 5.0;
sx5 = sx3*(2*n*n+2*n - 1) / 3.0;
sx6 = sx2*(3*n*n*n*(n + 2) - 3*n+1) / 7.0;
den = sx6*sx4 / sx5 - sx5;
//Initialize indicator
IndicatorBuffers(2);
SetIndexBuffer(0, FIRMA);
SetIndexBuffer(1, ARMA);
SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 2);
SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 2);
IndicatorShortName("AFIRMA");
return(0);
}
int deinit()
{
return(0);
}
int start()
{
//Calculate FIR MA for all bars except for the last n bars
ArrayInitialize(FIRMA, EMPTY_VALUE);
for(int i = 0; i <= Bars - Taps; i++)
{
FIRMA[i+n] = 0.0;
for(int k = 0; k < Taps; k++)
FIRMA[i+n] += Close[i+k]*w[k] / wsum;
}
//Calculate regressive MA for the remaining n bars
double a0 = FIRMA[n];
double a1 = FIRMA[n] - FIRMA[n+1];
double sx2y = 0.0;
double sx3y = 0.0;
for(i = 0; i <= n; i++)
{
sx2y += i*i*Close[n-i];
sx3y += i*i*i*Close[n-i];
}
sx2y = 2.0*sx2y / n / (n + 1);
sx3y = 2.0*sx3y / n / (n + 1);
double p = sx2y - a0*sx2 - a1*sx3;
double q = sx3y - a0*sx3 - a1*sx4;
double a2 = (p*sx6 / sx5 - q) / den;
double a3 = (q*sx4 / sx5 - p) / den;
ArrayInitialize(ARMA, EMPTY_VALUE);
for(i = 0; i <= n; i++)
ARMA[n-i] = a0 + i*a1 + i*i*a2 + i*i*i*a3;
return(0);
}
Indicator Copyright: Vladimir (Copyright © 2006, gpwr) Link: https://www.mql5.com/ru/code/11186
指示器版权:弗拉基米尔(版权©2006,gpwr)链接:https://www.mql5.com/ru/code/11186
How it should look:
Dark Blue and Dark Red lines: Original and proper way the indicator should Output. Bright Blue line: How this specific code is outputting and Orange line which does not output at all.
深蓝和深红线:原始和正确的方式,指示灯应该输出。亮蓝色的线:这个特定的代码是如何输出的,而橙色的线根本不输出。
Addendum from a comment below:
All the values of variables used:
The output seems to have everything it needs in order to render but still, something is preventing it to do so. Even with an offsetted output it should still render something on the chart. That's why I chose to set an Autoscale to see if anything pops up anytime.
输出似乎有它所需要的一切来渲染,但仍然有一些东西阻止它这样做。即使输出是分离的,它也应该在图表上显示一些东西。这就是为什么我选择设置一个自动缩放以查看是否有任何东西在任何时候弹出。
Update: Almost Done!
I've managed to fix the Outputting problem for ARMA. It was a problem of indexing. But on a new bar, I see, some variables don't render anymore and the output completely disappears. If i go hit build for the indicator code it renders again for 1 bar(dynamic fluctuations within the variables during the present candle are happening, so it works just fine, up until the new bar). This should be the last issue to fix and we can call it a solved case. Anyone? Any ideas?
我已经为ARMA解决了输出问题。这是索引的问题。但是在一个新的工具条上,我看到,一些变量不再渲染,输出完全消失。如果我为指示器代码点击build,它会为1 bar重新呈现(当前蜡烛中变量的动态波动正在发生,所以直到新的bar)。这应该是最后一个需要解决的问题,我们可以称之为已解决的案例。有人知道吗?什么好主意吗?
namespace cAlgo.Indicators
{
[Indicator(ScalePrecision = 5, AutoRescale = true, IsOverlay = true, AccessRights = AccessRights.None)]
public class AFIRMA: Indicator
{
[Parameter("Periods", DefaultValue = 15)]
public int Periods { get; set; }
[Parameter("Taps", DefaultValue = 31)]
public int Taps { get; set; }
[Parameter("Window", DefaultValue = 4)]
public int Window { get; set; }
[Output("FIRMA", Color = Colors.Blue, PlotType = PlotType.DiscontinuousLine)]
public IndicatorDataSeries FIRMA { get; set; }
[Output("ARMA", Color = Colors.Red, PlotType = PlotType.DiscontinuousLine)]
public IndicatorDataSeries ARMA { get; set; }
int n;
double den;
double sx6;
double sx5;
double sx4;
double sx3;
double sx2;
double wsum;
double[] w;
protected override void Initialize()
{
//Calculate weights
Array.Resize(ref w, Taps);
wsum = 0.0;
for (int k = 0; k < Taps; k++)
{
switch (Window)
{
case 1:
w[k] = 1.0;
break;
case 2:
w[k] = 0.5 - 0.5 * Math.Cos(2.0 * Math.PI * k / Taps);
break;
case 3:
w[k] = 0.54 - 0.46 * Math.Cos(2.0 * Math.PI * k / Taps);
break;
case 4:
w[k] = 0.42 - 0.5 * Math.Cos(2.0 * Math.PI * k / Taps) + 0.08 * Math.Cos(4.0 * Math.PI * k / Taps);
break;
case 5:
w[k] = 0.35875 - 0.48829 * Math.Cos(2.0 * Math.PI * k / Taps) + 0.14128 * Math.Cos(4.0 * Math.PI * k / Taps) - 0.01168 * Math.Cos(6.0 * Math.PI * k / Taps);
break;
default:
w[k] = 1;
break;
}
if (k != Taps / 2.0)
w[k] = w[k] * Math.Sin(Math.PI * (k - Taps / 2.0) / Periods) / Math.PI / (k - Taps / 2.0);
wsum += w[k];
}
//Calculate sums for the least-squares method
n = (Taps - 1) / 2;
sx2 = (2 * n + 1) / 3.0;
sx3 = n * (n + 1) / 2.0;
sx4 = sx2 * (3 * n * n + 3 * n - 1) / 5.0;
sx5 = sx3 * (2 * n * n + 2 * n - 1) / 3.0;
sx6 = sx2 * (3 * n * n * n * (n + 2) - 3 * n + 1) / 7.0;
den = sx6 * sx4 / sx5 - sx5;
//Calculate FIR MA for all bars except for the last n bars
for (int i = 0; i <= Bars - Taps; i++)
{
FIRMA[i + n] = 0.0;
for (int k = 0; k < Taps; k++)
FIRMA[i + n] += MarketSeries.Close[i + k] * w[k] / wsum;
}
}
public override void Calculate(int index)
{
//Calculate regressive MA for the remaining n bars
double a0 = FIRMA[index - n];
double a1 = FIRMA[index - n] - FIRMA[index - n - 1];
double sx2y = 0.0;
double sx3y = 0.0;
for (int i = 0; i <= n; i++)
{
sx2y += i * i * MarketSeries.Close[index + i - n];
sx3y += i * i * i * MarketSeries.Close[index + i - n];
}
sx2y = 2.0 * sx2y / n / (n + 1);
sx3y = 2.0 * sx3y / n / (n + 1);
double p = sx2y - a0 * sx2 - a1 * sx3;
double q = sx3y - a0 * sx3 - a1 * sx4;
double a2 = (p * sx6 / sx5 - q) / den;
double a3 = (q * sx4 / sx5 - p) / den;
for (int i = 0; i <= n; i++)
{
ARMA[index + i - n] = a0 + i * a1 + i * i * a2 + i * i * i * a3;
//ChartObjects.DrawText("test", "ARMA: " + ARMA[index + i - n] + "\na0: " + a0 + "\na1: " + a1 + "\na2: " + a2 + "\na3: " + a3 + "\nn: " + n + "\ni: " + i + "\np: " + p + "\nq: " + q + "\nsx2y: " + sx2y + "\nsx3y: " + sx3y + "\nsx2: " + sx2 + "\nsx3: " + sx3 + "\nsx4: " + sx4 + "\nsx5: " + sx5 + "\nsx6: " + sx6 + "\nden: " + den, StaticPosition.TopRight);
}
}
private int Bars
{
get { return MarketSeries.Close.Count; }
}
}
}
2 个解决方案
#1
0
Shall that produce something like this?
How about the head-part?
Is that an intention or is that an un-corrected residual of mistake in the progressive, batch-driven CustomIndicator
calculus, using an MQL4 TimeSeries habit of processing a reversed, forward-stepping Bar-number indexed arrays?
这是一种意图,还是在渐进的、批处理的定制指示器演算中,使用MQL4时间序列习惯处理反向的、向前进步的Bar-number索引数组的错误残余?
#2
0
It is a simple bug: Return of the ARMA loop is in the incorrect place and loop returns immediately.
这是一个简单的错误:ARMA循环返回的位置不正确,循环立即返回。
for (int i = 0; i <= n; i++)
{
ARMA[n - i] = a0 + i * a1 + i * i * a2 + i * i * i * a3;
return; // Not here
}
return; //But here.
#1
0
Shall that produce something like this?
How about the head-part?
Is that an intention or is that an un-corrected residual of mistake in the progressive, batch-driven CustomIndicator
calculus, using an MQL4 TimeSeries habit of processing a reversed, forward-stepping Bar-number indexed arrays?
这是一种意图,还是在渐进的、批处理的定制指示器演算中,使用MQL4时间序列习惯处理反向的、向前进步的Bar-number索引数组的错误残余?
#2
0
It is a simple bug: Return of the ARMA loop is in the incorrect place and loop returns immediately.
这是一个简单的错误:ARMA循环返回的位置不正确,循环立即返回。
for (int i = 0; i <= n; i++)
{
ARMA[n - i] = a0 + i * a1 + i * i * a2 + i * i * i * a3;
return; // Not here
}
return; //But here.