Coding help: Crossing EMA's

Created at 12 Jun 2016, 15:36
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!
JO

jonas_compernolle

Joined 12.06.2016

Coding help: Crossing EMA's
12 Jun 2016, 15:36


Hey all,

I have no coding experience, however I was messing around abit with this (well known and pretty straight forward) strategy based on EMA crossovers. 

The principle is I'd like to have a sell order on the opening of the next daily candle whenever the blue EMA (8) crosses under the yellow EMA (21) and vice versa ofcourse. In the example below you can see there's a sell order at the opening after the weekend without a crossover. The goal is to enter after the bearish candle closed (and where EMA's started to crossover) and then enter at the start of the second bearish candle. The closing strategy is still pending so that's less important at the moment, I'd just like to get these entries on point.

If somebody could help me out here would be highly appreciated

Thanks in advance

 

 

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleTrendcBot : Robot
    {

        [Parameter()]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Slow Periods", DefaultValue = 21)]
        public int SlowPeriods { get; set; }

        [Parameter("Fast Periods", DefaultValue = 8)]
        public int FastPeriods { get; set; }

        [Parameter("Closing Periods", DefaultValue = 3)]
        public int ClosePeriods { get; set; }

        [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage fastMa;
        private ExponentialMovingAverage closeMa;
        private const string label = "Sample Trend cBot";

        protected override void OnStart()
        {

        }

        protected override void OnBar()
        {

            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, 8);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, 21);
            closeMa = Indicators.ExponentialMovingAverage(SourceSeries, 3);

            var longPosition = Positions.Find(label, Symbol, TradeType.Buy);
            var shortPosition = Positions.Find(label, Symbol, TradeType.Sell);

            var currentSlowMa = slowMa.Result.Last(0);
            var currentFastMa = fastMa.Result.Last(0);
            var currentCloseMa = closeMa.Result.Last(0);
            var previousSlowMa = slowMa.Result.Last(1);
            var previousFastMa = fastMa.Result.Last(1);
            var currentcandleclose = MarketSeries.Close.Last(0);

            if (previousSlowMa > previousFastMa && currentSlowMa < currentFastMa && longPosition == null)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, VolumeInUnits, label);
            }
            else if (previousSlowMa < previousFastMa && currentSlowMa > currentFastMa && shortPosition == null)
            {
                ExecuteMarketOrder(TradeType.Sell, Symbol, VolumeInUnits, label);
            }

            if (longPosition != null & currentcandleclose < currentCloseMa)
                ClosePosition(longPosition);

            if (shortPosition != null & currentcandleclose > currentCloseMa)
                ClosePosition(shortPosition);
        }

        private long VolumeInUnits
        {
            get { return Symbol.QuantityToVolume(Quantity); }
        }
    }
}

 


@jonas_compernolle
Replies

cyfer
12 Jun 2016, 23:10 ( Updated at: 21 Dec 2023, 09:20 )

Hello 

First you should set your EMAs at Start of the Bot , not on each Bar 

I'm trying to reproduce your code here in a way I can understand 

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleTrendcBot : Robot
    {

        [Parameter()]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Slow Periods", DefaultValue = 21)]
        public int SlowPeriods { get; set; }

        [Parameter("Fast Periods", DefaultValue = 8)]
        public int FastPeriods { get; set; }

        [Parameter("Closing Periods", DefaultValue = 3)]
        public int ClosePeriods { get; set; }

        [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage fastMa;
        private ExponentialMovingAverage closeMa;
        private const string label = "Sample Trend cBot";
        private Position longPosition;
        private Position shortPosition;

        protected override void OnStart()
        {
            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, 8);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, 21);
            closeMa = Indicators.ExponentialMovingAverage(SourceSeries, 3);


        }

        protected override void OnBar()
        {

            longPosition = Positions.Find(label, Symbol, TradeType.Buy);
            shortPosition = Positions.Find(label, Symbol, TradeType.Sell);

            var currentCloseMa = closeMa.Result.Last(0);
            // var currentSlowMa = slowMa.Result.Last(1);
            // var currentFastMa = fastMa.Result.Last(1);
            // var previousSlowMa = slowMa.Result.Last(2);
            // var previousFastMa = fastMa.Result.Last(2);
            var currentcandleclose = MarketSeries.Close.Last(0);

            if (fastMa.Result.Last(1) < slowMa.Result.Last(1) && fastMa.Result.Last(0) > slowMa.Result.Last(0) && longPosition == null)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, VolumeInUnits, label);
            }
            else if (fastMa.Result.Last(1) > slowMa.Result.Last(1) && fastMa.Result.Last(0) < slowMa.Result.Last(0) && shortPosition == null)
            {
                ExecuteMarketOrder(TradeType.Sell, Symbol, VolumeInUnits, label);
            }

            if (longPosition != null & currentcandleclose < currentCloseMa)
                ClosePosition(longPosition);

            if (shortPosition != null & currentcandleclose > currentCloseMa)
                ClosePosition(shortPosition);
        }

        private long VolumeInUnits
        {
            get { return Symbol.QuantityToVolume(Quantity); }
        }
    }
}

Now , assuming you want to open a Sell/Buy order not after the Cross of EMAs but after the Cross and on the start of the new candle 

I Think you should then a Bool Switch 

For example : When 2 EMAs cross , Bool value is true (OpenBuyTrade = True) and When this value is tested on the next Bar , it will open the trade 

                     same for Sell order 

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleTrendcBot : Robot
    {

        private bool OpenBuyTrade;
        private bool OpenSellTrade;
        [Parameter()]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Slow Periods", DefaultValue = 21)]
        public int SlowPeriods { get; set; }

        [Parameter("Fast Periods", DefaultValue = 8)]
        public int FastPeriods { get; set; }

        [Parameter("Closing Periods", DefaultValue = 3)]
        public int ClosePeriods { get; set; }

        [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage fastMa;
        private ExponentialMovingAverage closeMa;
        private const string label = "Sample Trend cBot";
        private Position longPosition;
        private Position shortPosition;

        protected override void OnStart()
        {
            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, 8);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, 21);
            closeMa = Indicators.ExponentialMovingAverage(SourceSeries, 3);

            OpenBuyTrade = false;
            OpenSellTrade = false;

        }

        protected override void OnBar()
        {

            longPosition = Positions.Find(label, Symbol, TradeType.Buy);
            shortPosition = Positions.Find(label, Symbol, TradeType.Sell);

            var currentCloseMa = closeMa.Result.Last(0);
            // var currentSlowMa = slowMa.Result.Last(1);
            // var currentFastMa = fastMa.Result.Last(1);
            // var previousSlowMa = slowMa.Result.Last(2);
            // var previousFastMa = fastMa.Result.Last(2);
            var currentcandleclose = MarketSeries.Close.Last(0);
            if (OpenBuyTrade)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, VolumeInUnits, label);
                OpenBuyTrade = false;
            }

            if (OpenSellTrade)
            {
                ExecuteMarketOrder(TradeType.Sell, Symbol, VolumeInUnits, label);
                OpenSellTrade = false;
            }
            if (fastMa.Result.Last(1) < slowMa.Result.Last(1) && fastMa.Result.Last(0) > slowMa.Result.Last(0) && longPosition == null)
            {
                OpenBuyTrade = true;

            }
            else if (fastMa.Result.Last(1) > slowMa.Result.Last(1) && fastMa.Result.Last(0) < slowMa.Result.Last(0) && shortPosition == null)
            {
                OpenSellTrade = true;

            }

            if (longPosition != null & currentcandleclose < currentCloseMa)
                ClosePosition(longPosition);

            if (shortPosition != null & currentcandleclose > currentCloseMa)
                ClosePosition(shortPosition);
        }

        private long VolumeInUnits
        {
            get { return Symbol.QuantityToVolume(Quantity); }
        }
    }
}

 

I wish that answers your question

 


@cyfer