Description
Without alerting stuff and other useless things from other version, additionally, painting arrows when price gets back from below/above upper or lower band
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TMABandsv2 : Indicator
{
[Parameter(DefaultValue = 60, MinValue = 1)]
public int HalfLength { get; set; }
[Parameter()]
public DataSeries Price { get; set; }
[Parameter(DefaultValue = 2.5)]
public double ATRMultiplier { get; set; }
[Parameter(DefaultValue = 100)]
public int ATRPeriod { get; set; }
[Output("Center", LineColor = "red", PlotType = PlotType.Points)]
public IndicatorDataSeries Center { get; set; }
[Output("Upper", LineColor = "blue")]
public IndicatorDataSeries Upper { get; set; }
[Output("Lower", LineColor = "blue")]
public IndicatorDataSeries Lower { get; set; }
private AverageTrueRange _atr;
private bool previousClosesAbove;
private bool previousClosesBelow;
private int arrowLastCalculated;
protected override void Initialize()
{
_atr = Indicators.AverageTrueRange(ATRPeriod, MovingAverageType.Simple);
}
public override void Calculate(int index)
{
if (index < HalfLength)
return;
double sum = (HalfLength + 1) * Price[index];
double sumw = (HalfLength + 1);
for (int j = 1, k = HalfLength; j <= HalfLength; j++,k--)
{
sum += k * Price[index - j];
sumw += k;
}
double range = _atr.Result[index - 10] * ATRMultiplier;
Center[index] = sum / sumw;
Upper[index] = Center[index] + range;
Lower[index] = Center[index] - range;
paintArrows(index);
}
private void paintArrows(int index)
{
if (arrowLastCalculated == index || index == 0)
{
return;
}
arrowLastCalculated = index;
previousClosesAbove = Bars[index - 2].Close > Upper[index - 2];
previousClosesBelow = Bars[index - 2].Close < Lower[index - 2];
if (previousClosesAbove && Bars[index - 1].Close < Upper[index - 1])
{
Chart.DrawIcon(index + "AD", ChartIconType.DownArrow, Bars[index - 1].OpenTime, Math.Max(Bars[index - 2].High, Bars[index - 1].High), Color.Yellow);
}
if (previousClosesBelow && Bars[index - 1].Close > Lower[index - 1])
{
Chart.DrawIcon(index + "AU", ChartIconType.UpArrow, Bars[index - 1].OpenTime, Math.Min(Bars[index - 2].Low, Bars[index - 1].Low), Color.LightBlue);
}
}
}
}
kamilsz
Joined on 23.12.2020
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: TMABands v2.algo
- Rating: 5
- Installs: 2500
- Modified: 13/10/2021 09:54
Comments
Hello Kamilsz,
good job ! i would like to ask you some help, your indicator seems very close to an MT4 version which is not exactly the same and do some repaint but i would like to do the same, do you know how to change your code to get the same please ?
here the part of mt4 code :
int counted_bars=IndicatorCounted();
int i,j,k,limit;
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit=MathMin(Bars-1,Bars-counted_bars+HalfLength);
if (returnBars) { buffer1[0] = limit+1; return(0); }
if (calculateValue || timeFrame==Period())
{
for (i=limit; i>=0; i--)
{
double sum = (HalfLength+1)*iMA(NULL,0,1,0,MODE_SMA,Price,i);
double sumw = (HalfLength+1);
for(j=1, k=HalfLength; j<=HalfLength; j++, k--)
{
sum += k*iMA(NULL,0,1,0,MODE_SMA,Price,i+j);
sumw += k;
if (j<=i)
{
sum += k*iMA(NULL,0,1,0,MODE_SMA,Price,i-j);
sumw += k;
}
}
double range = iATR(NULL,0,ATRPeriod,i+10)*ATRMultiplier;
buffer1[i] = sum/sumw;
buffer2[i] = buffer1[i]+range;
buffer3[i] = buffer1[i]-range;
//
//
//
//
//
}
}
thanks for your help !
This is great, thankyou very much for sharing.
I'm not aware how price boreder works, mine is rewritten based on https://ctrader.com/algos/indicators/show/295 which is based on TMA+CG mt4 indicator
Hi, is this the same as in MT4 https://www.best-metatrader-indicators.com/price-border-indicator/
Thank you
Its not interpolating.
So more Boilinger style.
Got 2 on my mt4 iam planning to try to get over to ctrade