"x" number of candle closes above/below MA

Created at 28 Apr 2021, 19:39
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
TS

tsichert22

Joined 28.04.2021

"x" number of candle closes above/below MA
28 Apr 2021, 19:39


Hi,

I'm new and currently still learning how to code by reading forum posts and dismantling code step by step.

I'm looking for a cbot code that only opens a Buy position if a price closes above an EMA and the last e.g. 10 candle closes were below that EMA.

 

I was not able to find anything that looked remotely similar to this code.

Any help is appreciated.

Thank you :)
Thomas


@tsichert22
Replies

amusleh
29 Apr 2021, 11:27

Hi,

You can use this sample cBot:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EmaCloseSample : Robot
    {
        private double _volumeInUnits;

        private ExponentialMovingAverage _ema;

        [Parameter("Source")]
        public DataSeries MaSource { get; set; }

        [Parameter("Period", DefaultValue = 9)]
        public int MaPeriod { get; set; }

        [Parameter("Close Bars #", DefaultValue = 10)]
        public int CloseBarsNumber { get; set; }

        [Parameter("Volume (Lots)", DefaultValue = 0.01)]
        public double VolumeInLots { get; set; }

        [Parameter("Label", DefaultValue = "Sample")]
        public string Label { get; set; }

        public Position[] BotPositions
        {
            get
            {
                return Positions.FindAll(Label);
            }
        }

        protected override void OnStart()
        {
            _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);

            _ema = Indicators.ExponentialMovingAverage(MaSource, MaPeriod);

            CloseBarsNumber++;
        }

        protected override void OnBar()
        {
            if (Bars.Count < CloseBarsNumber) return;

            if (Bars.ClosePrices.Last(1) > _ema.Result.Last(1))
            {
                ClosePositions(TradeType.Sell);

                if (All((close, ema) => close < ema, CloseBarsNumber))
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
                }
            }
            else if (Bars.ClosePrices.Last(1) < _ema.Result.Last(1))
            {
                ClosePositions(TradeType.Buy);

                if (All((close, ema) => close > ema, CloseBarsNumber))
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
                }
            }
        }

        private bool All(Func<double, double, bool> predicate, int number)
        {
            for (var i = number; i > 1; i--)
            {
                if (predicate(Bars.ClosePrices.Last(i), _ema.Result.Last(i)) == false) return false;
            }

            return true;
        }

        private void ClosePositions(TradeType tradeType)
        {
            foreach (var position in BotPositions)
            {
                if (position.TradeType != tradeType) continue;

                ClosePosition(position);
            }
        }
    }
}

 


@amusleh