Help to fix this code

Created at 03 Apr 2021, 23:50
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!
TH

thecaffeinatedtrader

Joined 22.07.2020

Help to fix this code
03 Apr 2021, 23:50


Hi,

I have a code here with 3 EMA's along with a stop loss and take profit.

What I would like instead but not sure how to go about converting it is...

I want to use the Slow Moving Average as a position bias, the Fast crossing the Medium moving average as the entry signal, and finally the Medium will also be used as the exit reason and basically as a trailing stop loss.

 

Long Positions

1. If price is above the Slow Moving Average, ONLY enter long positions.

2. If the Fast crosses above the Medium, enter long position. 

3. Close position when price crosses below Medium moving average.

 

Short Positions

1. If price is below the Slow Moving Average, ONLY enter short positions.

2. If the Fast crosses below the Medium, enter short position. 

3. Close position when price crosses above Medium moving average.

 

Therefore with this, I know I will not need the stop loss or take profit as it will have the exit as price crossing the medium moving average. I will optimize the moving average period values after to find out which work best for each pair I will be trading. 

 

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 EmaBiasWithCross : Robot
    {
        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }
        [Parameter("Label", DefaultValue = "EMA")]
        public string label { get; set; }

        [Parameter("Slow Periods", DefaultValue = 233)]
        public int SlowPeriods { get; set; }
        [Parameter("Medium Periods", DefaultValue = 55)]
        public int MediumPeriods { get; set; }
        [Parameter("Fast Periods", DefaultValue = 21)]
        public int FastPeriods { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10)]
        public int SL { get; set; }
        [Parameter("Take Profit", DefaultValue = 10)]
        public double TP { get; set; }
        [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage mediumMa;
        private ExponentialMovingAverage fastMa;


        protected override void OnStart()
        {

            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
            mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);

        }

        protected override void OnBar()
        {
            int index = MarketSeries.OpenTime.Count - 2;

            if ((fastMa.Result[index] > slowMa.Result[index]) && (mediumMa.Result[index] > slowMa.Result[index]) && (fastMa.Result[index - 1] < slowMa.Result[index - 1]) && (mediumMa.Result[index - 1] < slowMa.Result[index - 1]))
            {
                ExecuteMarketOrder(TradeType.Sell, Symbol, VolumeInUnits, label, SL, TP);

            }
            else if ((fastMa.Result[index] < slowMa.Result[index]) && (mediumMa.Result[index] < slowMa.Result[index]) && (fastMa.Result[index - 1] > slowMa.Result[index - 1]) && (mediumMa.Result[index - 1] > slowMa.Result[index - 1]))
            {

                ExecuteMarketOrder(TradeType.Buy, Symbol, VolumeInUnits, label, SL, TP);

            }

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


@thecaffeinatedtrader
Replies

amusleh
04 Apr 2021, 13:17

Hi,

Try this:

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EmaBiasWithCross : Robot
    {
        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }

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

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

        [Parameter("Medium Periods", DefaultValue = 55)]
        public int MediumPeriods { get; set; }

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

        [Parameter("Stop Loss", DefaultValue = 10)]
        public int SL { get; set; }

        [Parameter("Take Profit", DefaultValue = 10)]
        public double TP { get; set; }

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

        private ExponentialMovingAverage slowMa;
        private double _volumeInUnits;
        private ExponentialMovingAverage mediumMa;
        private ExponentialMovingAverage fastMa;

        protected override void OnStart()
        {
            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
            mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);

            _volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
        }

        protected override void OnBar()
        {
            int index = Bars.Count - 2;

            Entry(index);

            Exit(index);
        }

        private void Exit(int index)
        {
            var positions = Positions.FindAll(Label);

            foreach (var position in positions)
            {
                if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index])
                    || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index]))
                {
                    ClosePosition(position);
                }
            }
        }

        private void Entry(int index)
        {
            // Buy Only
            if (Bars.ClosePrices[index] > slowMa.Result[index])
            {
                // if fast crosses medium upward
                if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, SL, TP);
                }
            }
            // Sell only
            else if (Bars.ClosePrices[index] < slowMa.Result[index])
            {
                // if fast crosses medium downward
                if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, SL, TP);
                }
            }
        }
    }
}

It might have some bugs, for more info please read the API references and check the sample cBots/indicators code.


@amusleh

thecaffeinatedtrader
04 Apr 2021, 17:28

RE:

amusleh said:

Hi,

Try this:

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EmaBiasWithCross : Robot
    {
        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }

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

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

        [Parameter("Medium Periods", DefaultValue = 55)]
        public int MediumPeriods { get; set; }

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

        [Parameter("Stop Loss", DefaultValue = 10)]
        public int SL { get; set; }

        [Parameter("Take Profit", DefaultValue = 10)]
        public double TP { get; set; }

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

        private ExponentialMovingAverage slowMa;
        private double _volumeInUnits;
        private ExponentialMovingAverage mediumMa;
        private ExponentialMovingAverage fastMa;

        protected override void OnStart()
        {
            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
            mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);

            _volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
        }

        protected override void OnBar()
        {
            int index = Bars.Count - 2;

            Entry(index);

            Exit(index);
        }

        private void Exit(int index)
        {
            var positions = Positions.FindAll(Label);

            foreach (var position in positions)
            {
                if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index])
                    || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index]))
                {
                    ClosePosition(position);
                }
            }
        }

        private void Entry(int index)
        {
            // Buy Only
            if (Bars.ClosePrices[index] > slowMa.Result[index])
            {
                // if fast crosses medium upward
                if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, SL, TP);
                }
            }
            // Sell only
            else if (Bars.ClosePrices[index] < slowMa.Result[index])
            {
                // if fast crosses medium downward
                if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, SL, TP);
                }
            }
        }
    }
}

It might have some bugs, for more info please read the API references and check the sample cBots/indicators code.

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 EmaBiasWithCross : Robot
    {
        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }

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

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

        [Parameter("Medium Periods", DefaultValue = 55)]
        public int MediumPeriods { get; set; }

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

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

        private ExponentialMovingAverage slowMa;
        private double _volumeInUnits;
        private ExponentialMovingAverage mediumMa;
        private ExponentialMovingAverage fastMa;

        protected override void OnStart()
        {
            fastMa = Indicators.ExponentialMovingAverage(SourceSeries, FastPeriods);
            mediumMa = Indicators.ExponentialMovingAverage(SourceSeries, MediumPeriods);
            slowMa = Indicators.ExponentialMovingAverage(SourceSeries, SlowPeriods);

            _volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);
        }

        protected override void OnBar()
        {
            int index = Bars.Count - 2;

            Entry(index);

            Exit(index);
        }

        private void Exit(int index)
        {
            var positions = Positions.FindAll(Label);

            foreach (var position in positions)
            {
                if ((position.TradeType == TradeType.Buy && Bars.ClosePrices[index] < mediumMa.Result[index]) || (position.TradeType == TradeType.Sell && Bars.ClosePrices[index] > mediumMa.Result[index]))
                {
                    ClosePosition(position);
                }
            }
        }

        private void Entry(int index)
        {
            // Buy Only
            if (Bars.ClosePrices[index] > slowMa.Result[index])
            {
                // if fast crosses medium upward
                if (fastMa.Result[index] > mediumMa.Result[index] && fastMa.Result[index - 1] < mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label);
                }
            }
            // Sell only
            else if (Bars.ClosePrices[index] < slowMa.Result[index])
            {
                // if fast crosses medium downward
                if (fastMa.Result[index] < mediumMa.Result[index] && fastMa.Result[index - 1] > mediumMa.Result[index - 1])
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label);
                }
            }
        }
    }
}


Here I've taken out the Stop Loss and Take Profit and it builds fine. Thank you!!! From what I see so far, I don't see any issues with it. 


@thecaffeinatedtrader