MACD Script

Created at 16 Dec 2019, 13:58
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!
FR

frederickjjayres

Joined 03.12.2019

MACD Script
16 Dec 2019, 13:58


Not too long ago I posted a thread on the forum asking for some assistance with a MACD script to get it working. Since then I've spent some time on it, re-doing it from scratch, looking at other script examples etc.

 

I've included the DMS indicator as an option for future backtesting in this strategy I'm developing. However, there are a couple of issues that I could use some help with:

1) The script doesn't wait for a fresh crossover to occur on initialisation. Rather, it executes a long/short trade OnBar.

2) Regardless of the inclusion of a Histogram "parameter" in the #region Entry Criteria (line 74 & 82) (_MACD.Histogram.LastValue > -0.0001), backtesting shows that this is sometimes ignored.

I'm looking for a trade to be executed by this script when there's a MACD Crossover, and the value of the Histogram is greater/less than a value.

 

Script:

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

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class MacdBot : Robot
    {
        #region Standard Parameters

        private Position _position;


        [Parameter(DefaultValue = 1000, MinValue = 0)]
        public int Volume { get; set; }

        [Parameter(DefaultValue = 5, MinValue = 1)]
        public int StopLoss { get; set; }

        #endregion


        #region MACD Parameters

        private MacdCrossOver _MACD;


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

        [Parameter("Long Cycle", DefaultValue = 26)]
        public int LongCycle { get; set; }

        [Parameter("Short Cycle", DefaultValue = 12)]
        public int ShortCycle { get; set; }

        #endregion


        #region DMS Parameters

        public DirectionalMovementSystem _DMS;


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

        #endregion



        protected override void OnStart()
        {
            #region Indicator Initialisation

            _MACD = Indicators.MacdCrossOver(LongCycle, ShortCycle, MACDPeriod);
            _DMS = Indicators.DirectionalMovementSystem(DMSPeriod);

            #endregion
        }

        protected override void OnBar()
        {
            #region Entry Criteria

            if (Trade.IsExecuting)
                return;

            bool isLongPositionOpen = _position != null && _position.TradeType == TradeType.Buy;
            bool isShortPositionOpen = _position != null && _position.TradeType == TradeType.Sell;


            //if (_DMS.ADX.LastValue > 20 && _DMS.DIPlus.LastValue > _DMS.DIMinus.LastValue && _DMS.DIPlus.LastValue > _DMS.ADX.LastValue)
            if (_MACD.MACD.LastValue > _MACD.Signal.LastValue && _MACD.Histogram.LastValue < 0.0001 && !isLongPositionOpen)
            {
                ClosePosition();
                Buy();
            }


            //if (_DMS.ADX.LastValue > 20 && _DMS.DIPlus.LastValue < _DMS.DIMinus.LastValue && _DMS.DIPlus.LastValue < _DMS.ADX.LastValue)
            if (_MACD.MACD.LastValue < _MACD.Signal.LastValue && _MACD.Histogram.LastValue > -0.0001 && !isShortPositionOpen)
            {
                ClosePosition();
                Sell();
            }

            #endregion
        }


        #region Trade Management

        private void Buy()
        {
            Trade.CreateBuyMarketOrder(Symbol, Volume);
        }

        private void Sell()
        {
            Trade.CreateSellMarketOrder(Symbol, Volume);
        }


        private double? SetStopLoss(Position position, int stopLoss)
        {
            return position.TradeType == TradeType.Buy ? position.EntryPrice - Symbol.PipSize * StopLoss : position.EntryPrice + Symbol.PipSize * StopLoss;
        }


        protected override void OnPositionOpened(Position openedPosition)
        {
            _position = openedPosition;
            ModifyPosition(openedPosition, SetStopLoss(openedPosition, StopLoss), null);
        }


        private void ClosePosition()
        {
            if (_position == null)
                return;
            Trade.Close(_position);
            _position = null;
        }

        #endregion

    }
}

 


@frederickjjayres
Replies

frederickjjayres
16 Dec 2019, 21:56

I've updated the original post to show the latest version. I've solved issues since but also have new ones. This is reflected in the post as well.


@frederickjjayres