Replies

claye.weight
15 Jun 2021, 02:49

RE:

Thank you! This helps heaps!!

it works great!

 

amusleh said:

Hi,

I created a MTF exponential moving average for you:

using cAlgo.API;
using cAlgo.API.Internals;
using System;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MTFEMA : Indicator
    {
        private Bars _baseTimeFrameBars;

        private DataSeries _baseSeries;

        private double _multiplier;

        private bool _isInitialized;

        private int _baseTimeFramePreviousIndex;

        private double _baseTimeFramePreviousEma;

        [Parameter(DefaultValue = 14)]
        public double Periods { get; set; }

        [Parameter("Source", DefaultValue = DataSource.Close)]
        public DataSource Source { get; set; }

        [Parameter("Base Time Frame")]
        public TimeFrame BaseTimeFrame { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        protected override void Initialize()
        {
            _baseTimeFrameBars = MarketData.GetBars(BaseTimeFrame);

            _baseSeries = GetSeries(Source);

            _multiplier = 2 / (Periods + 1);
        }

        public override void Calculate(int index)
        {
            var baseTimeFrameIndex = _baseTimeFrameBars.OpenTimes.GetIndexByTime(Bars[index].OpenTime);

            if (baseTimeFrameIndex < Periods) return;

            if (!_isInitialized)
            {
                Result[index] = GetAverage(baseTimeFrameIndex);

                _isInitialized = true;
            }
            else
            {
                Result[index] = (_baseTimeFrameBars[baseTimeFrameIndex].Close - _baseTimeFramePreviousEma) * _multiplier + _baseTimeFramePreviousEma;
            }

            if (baseTimeFrameIndex != _baseTimeFramePreviousIndex)
            {
                _baseTimeFramePreviousIndex = baseTimeFrameIndex;
                _baseTimeFramePreviousEma = Result[index];
            }
        }

        private double GetAverage(int index)
        {
            var lastIndex = index - Periods;

            double sum = 0;

            for (var i = index; i > lastIndex; i--)
            {
                sum += _baseSeries[i];
            }

            return sum / Periods;
        }

        private DataSeries GetSeries(DataSource dataSource)
        {
            switch (dataSource)
            {
                case DataSource.Open:
                    return _baseTimeFrameBars.OpenPrices;

                case DataSource.High:
                    return _baseTimeFrameBars.HighPrices;

                case DataSource.Low:
                    return _baseTimeFrameBars.LowPrices;

                case DataSource.Close:
                    return _baseTimeFrameBars.ClosePrices;

                case DataSource.Volume:
                    return _baseTimeFrameBars.TickVolumes;

                case DataSource.Typical:
                    return _baseTimeFrameBars.TypicalPrices;

                case DataSource.Weighted:
                    return _baseTimeFrameBars.WeightedPrices;

                case DataSource.Median:
                    return _baseTimeFrameBars.MedianPrices;

                default:
                    throw new ArgumentOutOfRangeException("dataSource");
            }
        }
    }

    public enum DataSource
    {
        Open,
        High,
        Low,
        Close,
        Volume,
        Typical,
        Median,
        Weighted
    }
}

I checked it gives same result like built-in EMA, only the last bar value might be different because it waits for bar to finish then it updates the value as it should consider other time frames data, hopefully this will help you.

 


@claye.weight

claye.weight
14 Jun 2021, 13:23

RE:

My goal is to do an calculation for another time frames', close, open high, low. Then I want to turn that result into an EMA

 

Yeah, I want to calculate the EMA for another time frame. But it won't just be the close, so I can't use:

Ema4 = Indicators.ExponentialMovingAverage(barsTF1.ClosePrices, Periods4);

Which is why trying to create a data series. (if that's the right thing to do?)

 

for what you posted; I set EMA3 to the same time frame and period as EMA4 (the one with the data series) and made them both just the close (no high - low) and the results are different?

Am I missing something?

 

I appreciate all the help

amusleh said:

Hi,

I don't know what you are trying to do, but the correct way to work with another time frame data is what I just posted.

Do you want to calculate the exponential moving average value of another time frame? 

 


@claye.weight

claye.weight
14 Jun 2021, 12:58

RE:

Hey, Thanks for the reply and your help!

unfortunately i'm still having issues. On certain time frames the EMA returns NaN - and when it does return a value. It doesn't return the correct values.

I've taken out -         (High(index) + Low(index)) / 2;

and i'm just trying to print the correct values of a regular moving average. It seems to be something with the dataseries, but i dont know what. As soon as I take it out and write

 

Ema4 = Indicators.ExponentialMovingAverage(barsTF1.ClosePrices, Periods4);

It works. But i need to use a data series so I can perform calculations on the price....

not sure what to do.

 

 

amusleh said:

Hi,

You can't use index for another time frame bars data, in your code you used the current chart bars index to get another time frame bars data: barsTF1.ClosePrices[index]

Try this:

using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using System;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TripleEMA : Indicator
    {
        [Parameter("EMA Fast", DefaultValue = 50)]
        public int Periods { get; set; }

        [Parameter("EMA Slow", DefaultValue = 100)]
        public int Periods1 { get; set; }

        [Parameter("EMA Trend", DefaultValue = 200)]
        public int Periods2 { get; set; }

        [Parameter("EMA Trend", DefaultValue = 100)]
        public int Periods3 { get; set; }

        [Parameter("TimeFrame", DefaultValue = "Daily")]
        public TimeFrame EMATimeframe1 { get; set; }

        [Output("EMA1", LineColor = "Blue")]
        public IndicatorDataSeries EMA1 { get; set; }

        [Output("EMA2", LineColor = "Red")]
        public IndicatorDataSeries EMA2 { get; set; }

        [Output("EMA3", LineColor = "Yellow")]
        public IndicatorDataSeries EMA3 { get; set; }

        private Bars series1;
        private Bars barsTF1;

        private ExponentialMovingAverage Ema1;
        private ExponentialMovingAverage Ema2;
        private ExponentialMovingAverage Ema3;
        private ExponentialMovingAverage Ema4;

        private IndicatorDataSeries _iDataSeries1;

        protected override void Initialize()
        {
            //series1 = MarketData.GetSeries(EMATimeframe1);
            series1 = MarketData.GetBars(EMATimeframe1);

            Ema1 = Indicators.ExponentialMovingAverage(series1.ClosePrices, Periods);
            Ema2 = Indicators.ExponentialMovingAverage(series1.ClosePrices, Periods1);
            Ema3 = Indicators.ExponentialMovingAverage(series1.ClosePrices, Periods2);

            barsTF1 = MarketData.GetBars(TimeFrame.Hour4);
            _iDataSeries1 = CreateDataSeries();

            Ema4 = Indicators.ExponentialMovingAverage(_iDataSeries1, Periods3);
        }

        public override void Calculate(int index)
        {
            var index1 = GetIndexByDate(series1, Bars.OpenTimes[index]);
            if (index1 != -1)
            {
                EMA1[index] = Ema1.Result[index1];
            }

            var index2 = GetIndexByDate(series1, Bars.OpenTimes[index]);
            if (index2 != -1)
            {
                EMA2[index] = Ema2.Result[index2];
            }

            var index3 = GetIndexByDate(series1, Bars.OpenTimes[index]);
            if (index3 != -1)
            {
                EMA3[index] = Ema3.Result[index3];
            }

            var barsTF1Index = barsTF1.OpenTimes.GetIndexByTime(Bars[index].OpenTime);

            _iDataSeries1[index] = barsTF1.ClosePrices[barsTF1Index] - (High(index) + Low(index)) / 2;

            Print("EMA : " + Ema4.Result[index]);
        }

        private int GetIndexByDate(Bars series, DateTime time)
        {
            for (int i = series.Count - 1; i > 0; i--)
            {
                if (time == series.OpenTimes[i])
                    return i;
            }
            return -1;
        }

        private double High(int index)
        {
            double high = Bars.HighPrices[index - 10];

            for (int i = index - 10 + 1; i <= index; i++)
            {
                if (Bars.HighPrices[i] > high)
                    high = Bars.HighPrices[i];
            }

            return high;
        }

        private double Low(int index)
        {
            double low = Bars.LowPrices[index - 10];

            for (int i = index - 10 + 1; i <= index; i++)
            {
                if (Bars.LowPrices[i] < low)
                    low = Bars.LowPrices[i];
            }

            return low;
        }
    }
}

 

 


@claye.weight

claye.weight
04 Feb 2021, 09:09

Hi,

When will this update be push out and available for everyone, not just public beta users?


@claye.weight