Opening Positions after the second moving average crossover.

Created at 24 Jun 2023, 05:31
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!
OJ

ojey39

Joined 14.02.2022

Opening Positions after the second moving average crossover.
24 Jun 2023, 05:31


Hi Guys,

Please help with code on how to open positions after the the second moving average crossover? I want the CBOT to ignore the first crossover and only open positions afterwards. 


 

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ClickAlgoSchoolSMA : Robot
    {
        #region User defined parameters

        [Parameter("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

        [Parameter("Lot Size", DefaultValue = 0.1)]
        public double LotSize { get; set; }

        [Parameter("Source SMA #1")]
        public DataSeries SourceSma1 { get; set; }

        [Parameter("Source SMA #2")]
        public DataSeries SourceSma2 { get; set; }

        [Parameter("Period SMA #1", DefaultValue = 5, MinValue = 1, MaxValue = 100)]
        public int PeriodsSma1 { get; set; }

        [Parameter("Period SMA #2", DefaultValue = 20, MinValue = 1, MaxValue = 100)]
        public int PeriodsSma2 { get; set; }

        [Parameter("Calculate OnBar", DefaultValue = false)]
        public bool CalculateOnBar { get; set; }

        #endregion

        #region Indicator declarations

        private SimpleMovingAverage _sma1 { get; set; }
        private SimpleMovingAverage _sma2 { get; set; }

        #endregion

        #region cTrader events

        /// <summary>
        /// This is called when the robot first starts, it is only called once.
        /// </summary>
        protected override void OnStart()
        {
            // construct the indicators
            _sma1 = Indicators.SimpleMovingAverage(SourceSma1, PeriodsSma1);
            _sma2 = Indicators.SimpleMovingAverage(SourceSma2, PeriodsSma2);
        }

        /// <summary>
        /// This method is called every time the price changes for the symbol
        /// </summary>
        protected override void OnTick()
        {
            if (CalculateOnBar)
            {
                return;
            }

            ManagePositions();
        }

        /// <summary>
        /// This method is called at every candle (bar) close, when it has formed
        /// </summary>
        protected override void OnBar()
        {
            if (!CalculateOnBar)
            {
                return;
            }

            ManagePositions();
        }

        /// <summary>
        /// This method is called when your robot stops, can be used to clean-up memory resources.
        /// </summary>
        protected override void OnStop()
        {
            // unused
        }

        #endregion

        #region Position management

        private void ManagePositions()
        {
            if (_sma1.Result.LastValue > _sma2.Result.LastValue)
            {
                // if there is no buy position open, open one and close any sell position that is open
                if (!IsPositionOpenByType(TradeType.Buy))
                {
                    OpenPosition(TradeType.Buy);
                }

                ClosePosition(TradeType.Sell);
            }

            // if a sell position is already open and signal is buy do nothing
            if (_sma1.Result.LastValue < _sma2.Result.LastValue)
            {
                // if there is no sell position open, open one and close any buy position that is open
                if (!IsPositionOpenByType(TradeType.Sell))
                {
                    OpenPosition(TradeType.Sell);
                }

                ClosePosition(TradeType.Buy);
            }
        }

        /// <summary>
        /// Opens a new long position
        /// </summary>
        /// <param name="type"></param>
        private void OpenPosition(TradeType type)
        {
            // calculate volume from lot size.
            long volume = Symbol.QuantityToVolume(LotSize);

            // open a new position
            ExecuteMarketOrder(type, this.Symbol, volume, InstanceName, null, null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName, this.Symbol, type);

            if (p != null)
            {
                ClosePosition(p);
            }
        }

        #endregion

        #region Position Information

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private bool IsPositionOpenByType(TradeType type)
        {
            var p = Positions.FindAll(InstanceName, Symbol, type);

            if (p.Count() >= 1)
            {
                return true;
            }

            return false;
        }

        #endregion
    }
}

@ojey39
Replies

firemyst
24 Jun 2023, 17:19

This is a multistep process:

 

1) create a global variable that counts the number of crossovers.

private int _maCrossOverCount;

2) In the OnStart method, set the count to zero:

_maCrossOverCount = 0;

3) Every time a cross over happens, increase the count by 1. However, you have to decide if you want the cross over to count if it happens when a "tick" comes in or a new bar. Reason being is obviously if the MA's are close, they could cross over hundreds of time within a bar on every tick depending on how much price fluctuates

if (_sma1.Result.LastValue > _sma2.Result.LastValue)
            {
              _maCrossOverCount += 1;



//and


if (_sma1.Result.LastValue < _sma2.Result.LastValue)
            {
              _maCrossOverCount += 1;

 

 

4) Check the crossover count before you open a position:

if (_maCrossOverCount > 1)

{

   /// code what you need to in order to open your position

}


@firemyst

ojey39
27 Jun 2023, 12:35

RE:

firemyst said:

This is a multistep process:

 

1) create a global variable that counts the number of crossovers.

private int _maCrossOverCount;

2) In the OnStart method, set the count to zero:

_maCrossOverCount = 0;

3) Every time a cross over happens, increase the count by 1. However, you have to decide if you want the cross over to count if it happens when a "tick" comes in or a new bar. Reason being is obviously if the MA's are close, they could cross over hundreds of time within a bar on every tick depending on how much price fluctuates

if (_sma1.Result.LastValue > _sma2.Result.LastValue)
            {
              _maCrossOverCount += 1;



//and


if (_sma1.Result.LastValue < _sma2.Result.LastValue)
            {
              _maCrossOverCount += 1;

 

 

4) Check the crossover count before you open a position:

if (_maCrossOverCount > 1)

{

   /// code what you need to in order to open your position

}

Thanks a lot.


@ojey39