Please help with code to open only 1 trade at a time.

Created at 15 May 2022, 12:45
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!
TU

tuanpham1208

Joined 19.04.2022

Please help with code to open only 1 trade at a time.
15 May 2022, 12:45


Hi guys,

I'm very new to CTrader and have no previous experiences in coding. I'm trying to write a bot to open BUY trade when EMA20 > EMA 50 > EMA 100 and price is above Ichimoku Cloud. And open SELL trade vice versa. Stop loss is at 1.5 ATR, take profit is at  ATR. So far I think I have got the EMA part and SL/TP right. But the bot keeps opening trade as long as conditions are satisfied. How can I make it opens only 1 trade when those conditions are satisfied the 1st time. Then only open a new trade again once the previous trade is closed, given conditions are met. Please take a look at what I have so far. Thank you all so much

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        private AverageTrueRange atr;
        private IchimokuKinkoHyo ichimoku;
        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage fastMa;
        private ExponentialMovingAverage mediumMa;
        private Position position;

        protected override void OnStart()
        {
            // Load indicators on start up
            atr = Indicators.AverageTrueRange(20, MovingAverageType.Exponential);
            ichimoku = Indicators.IchimokuKinkoHyo(9, 26, 52);
            fastMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 20);
            mediumMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);
            slowMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 100);
        }

        protected override void OnBar()
        {
            // Calculate Trade Amount based on ATR
            var PrevATR = Math.Round(atr.Result.Last(1) / Symbol.PipSize);
            var TradeAmount = (Account.Equity * 0.02) / (1.5 * PrevATR * Symbol.PipValue);
            TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);

            // EMA Crossovers and Ichimoku

            var ema_20 = fastMa.Result.Last(0);
            var ema_50 = mediumMa.Result.Last(0);
            var ema_100 = slowMa.Result.Last(0);

            if (ema_20 > ema_50 & ema_50 > ema_100)
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "EMA", 1.5 * PrevATR, PrevATR);
            }
            else if (ema_20 < ema_50 & ema_50 < ema_100)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, TradeAmount, "EMA", 1.5 * PrevATR, PrevATR);
            }

        }
        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}


@tuanpham1208
Replies

tuanpham1208
15 May 2022, 21:53

Updated. This is what I got at the moment. Still couldn't figure out how to instruct the bot to open only 1 trade at a time.

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        private AverageTrueRange atr;
        private IchimokuKinkoHyo ichimoku;
        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage fastMa;
        private ExponentialMovingAverage mediumMa;
        private Position position;
        private int longPositions = 0;

        private int shortPositions = 0;

        [Parameter("Short Trades", DefaultValue = 2, MinValue = 0)]
        public int MaxShortTrades { get; set; }

        [Parameter("Long Trades", DefaultValue = 2, MinValue = 0)]
        public int MaxLongTrades { get; set; }

        protected override void OnStart()
        {
            // Load indicators on start up
            atr = Indicators.AverageTrueRange(20, MovingAverageType.Exponential);
            ichimoku = Indicators.IchimokuKinkoHyo(9, 26, 52);
            fastMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 20);
            mediumMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);
            slowMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 100);
        }

        protected override void OnBar()
        {
            // Calculate Trade Amount based on ATR
            var PrevATR = Math.Round(atr.Result.Last(1) / Symbol.PipSize);
            var TradeAmount = (Account.Equity * 0.02) / (1.5 * PrevATR * Symbol.PipValue);
            TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);

            // EMA Crossovers and Ichimoku

            var ema_20 = fastMa.Result.Last(0);
            var ema_50 = mediumMa.Result.Last(0);
            var ema_100 = slowMa.Result.Last(0);
            var tenkan = ichimoku.TenkanSen;
            var kijun = ichimoku.KijunSen;
            var senkouA = ichimoku.SenkouSpanA;
            var senkouB = ichimoku.SenkouSpanB;
            var chikou = ichimoku.ChikouSpan;
            var cloudUpper = Math.Max(senkouA.Last(26), senkouB.Last(26));
            var cloudLower = Math.Min(senkouA.Last(26), senkouB.Last(26));
            var price = Bars.ClosePrices.Last(0);
            var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
            var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);

            if (longPositions < MaxLongTrades & ema_20 > ema_50 & ema_50 > ema_100 & price > cloudUpper)
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
            }
            else if (shortPositions < MaxShortTrades & ema_20 < ema_50 & ema_50 < ema_100 & price < cloudLower)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
            }

        }
        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}


@tuanpham1208

amusleh
16 May 2022, 10:30

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        private AverageTrueRange atr;
        private IchimokuKinkoHyo ichimoku;
        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage fastMa;
        private ExponentialMovingAverage mediumMa;
        private Position position;
        private int longPositions = 0;

        private int shortPositions = 0;

        [Parameter("Short Trades", DefaultValue = 2, MinValue = 0)]
        public int MaxShortTrades { get; set; }

        [Parameter("Long Trades", DefaultValue = 2, MinValue = 0)]
        public int MaxLongTrades { get; set; }

        protected override void OnStart()
        {
            // Load indicators on start up
            atr = Indicators.AverageTrueRange(20, MovingAverageType.Exponential);
            ichimoku = Indicators.IchimokuKinkoHyo(9, 26, 52);
            fastMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 20);
            mediumMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);
            slowMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 100);
        }

        protected override void OnBar()
        {
            if (Positions.FindAll("BOT").Any()) return;

            // Calculate Trade Amount based on ATR
            var PrevATR = Math.Round(atr.Result.Last(1) / Symbol.PipSize);
            var TradeAmount = (Account.Equity * 0.02) / (1.5 * PrevATR * Symbol.PipValue);
            TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);

            // EMA Crossovers and Ichimoku

            var ema_20 = fastMa.Result.Last(0);
            var ema_50 = mediumMa.Result.Last(0);
            var ema_100 = slowMa.Result.Last(0);
            var tenkan = ichimoku.TenkanSen;
            var kijun = ichimoku.KijunSen;
            var senkouA = ichimoku.SenkouSpanA;
            var senkouB = ichimoku.SenkouSpanB;
            var chikou = ichimoku.ChikouSpan;
            var cloudUpper = Math.Max(senkouA.Last(26), senkouB.Last(26));
            var cloudLower = Math.Min(senkouA.Last(26), senkouB.Last(26));
            var price = Bars.ClosePrices.Last(0);
            var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
            var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);

            if (longPositions < MaxLongTrades & ema_20 > ema_50 & ema_50 > ema_100 & price > cloudUpper)
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
            }
            else if (shortPositions < MaxShortTrades & ema_20 < ema_50 & ema_50 < ema_100 & price < cloudLower)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
            }
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@amusleh

tuanpham1208
16 May 2022, 21:34

RE:

amusleh said:

Hi,

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        private AverageTrueRange atr;
        private IchimokuKinkoHyo ichimoku;
        private ExponentialMovingAverage slowMa;
        private ExponentialMovingAverage fastMa;
        private ExponentialMovingAverage mediumMa;
        private Position position;
        private int longPositions = 0;

        private int shortPositions = 0;

        [Parameter("Short Trades", DefaultValue = 2, MinValue = 0)]
        public int MaxShortTrades { get; set; }

        [Parameter("Long Trades", DefaultValue = 2, MinValue = 0)]
        public int MaxLongTrades { get; set; }

        protected override void OnStart()
        {
            // Load indicators on start up
            atr = Indicators.AverageTrueRange(20, MovingAverageType.Exponential);
            ichimoku = Indicators.IchimokuKinkoHyo(9, 26, 52);
            fastMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 20);
            mediumMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);
            slowMa = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 100);
        }

        protected override void OnBar()
        {
            if (Positions.FindAll("BOT").Any()) return;

            // Calculate Trade Amount based on ATR
            var PrevATR = Math.Round(atr.Result.Last(1) / Symbol.PipSize);
            var TradeAmount = (Account.Equity * 0.02) / (1.5 * PrevATR * Symbol.PipValue);
            TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);

            // EMA Crossovers and Ichimoku

            var ema_20 = fastMa.Result.Last(0);
            var ema_50 = mediumMa.Result.Last(0);
            var ema_100 = slowMa.Result.Last(0);
            var tenkan = ichimoku.TenkanSen;
            var kijun = ichimoku.KijunSen;
            var senkouA = ichimoku.SenkouSpanA;
            var senkouB = ichimoku.SenkouSpanB;
            var chikou = ichimoku.ChikouSpan;
            var cloudUpper = Math.Max(senkouA.Last(26), senkouB.Last(26));
            var cloudLower = Math.Min(senkouA.Last(26), senkouB.Last(26));
            var price = Bars.ClosePrices.Last(0);
            var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
            var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);

            if (longPositions < MaxLongTrades & ema_20 > ema_50 & ema_50 > ema_100 & price > cloudUpper)
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
            }
            else if (shortPositions < MaxShortTrades & ema_20 < ema_50 & ema_50 < ema_100 & price < cloudLower)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
            }
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 

Thank you so much man


@tuanpham1208