Replies

tuanpham1208
23 Jun 2022, 19:30

RE:

amusleh said:

Hi,

You have to learn C# and read Automate API documentation.

You can find Automate API documentation at: cTrader Automate | cTrader Help Center

Here is an example that might help you (read my added comments):

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 Crossover : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        private ExponentialMovingAverage ema20, ema50, ema100;
        private SimpleMovingAverage sma10;
        private AverageTrueRange atr;
        private IchimokuKinkoHyo ichimoku;
        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
            sma10 = Indicators.SimpleMovingAverage(Bars.ClosePrices, 10);
            ema20 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 20);
            ema50 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 50);
            ema100 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 100);
            atr = Indicators.AverageTrueRange(14, MovingAverageType.Exponential);
            ichimoku = Indicators.IchimokuKinkoHyo(9, 26, 52);
        }

        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);

            var price = Bars.ClosePrices.Last(0);
            var Prevprice = Bars.ClosePrices.Last(1);
            var ema_20 = ema20.Result.Last(0);
            var ema_50 = ema50.Result.Last(0);
            var ema_100 = ema100.Result.Last(0);

            var senkouA = ichimoku.SenkouSpanA;
            var senkouB = ichimoku.SenkouSpanB;
            var cloudUpper = Math.Max(senkouA.Last(26), senkouB.Last(26));
            var cloudLower = Math.Min(senkouA.Last(26), senkouB.Last(26));

            var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
            var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);

            if (Positions.Count == 0)
            {
                if (longPositions < MaxLongTrades & ema20.Result.HasCrossedAbove(ema100.Result, 0) & ema_50 > ema_100 & price > cloudUpper)
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
                }
                else if (shortPositions < MaxShortTrades & ema20.Result.HasCrossedBelow(ema100.Result, 0) & ema_50 < ema_100 & price < cloudLower)
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR);
                }
            }

            // This will give you all the positions with label "BOT"
            var botPositions = Positions.FindAll("BOT");

            // Then we iterate over BOT positions
            foreach (var position in botPositions)
            {
                // Close the position if trade type is buy and ema_20 < ema_50
                // Close the position if trade type is sell and ema_20 > ema_50
                if ((position.TradeType == TradeType.Buy && ema_20 < ema_50) || (position.TradeType == TradeType.Sell && ema_20 > ema_50))
                {
                    ClosePosition(position);
                }
            }
        }
    }
}

 

Thank you amusleh. Quick question. How to I express "or" condition. I know that we use "&" for "and". But what if I want to express, for example, RSI smaller than or equal  to 70? rsi.Result.Last(0) =< 70. Thank you


@tuanpham1208

tuanpham1208
01 Jun 2022, 09:23

RE: RE: RE:

amusleh said:

tuanpham1208 said:

amusleh said:

Hi,

You can use the EMA value as your position stop loss / take profit, ema20.Result.LastValue will give the latest value of EMA.

Yes. Thank you. I know how to express it as a variable. But how do I express it as a condition for Stop Loss. Because I cannot insert ema20.Result.LastValue < ema50.Result.LastValue into ExecuteMarketOrder(), can I ? So for example 

ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", ema20.Result.LastValue < ema50.Result.LastValue, PrevATR)

It shows these errors:

Error CS1502: The best overloaded method match for 'cAlgo.API.Robot.ExecuteMarketOrder(cAlgo.API.TradeType, string, double, string, double?, double?)' has some invalid arguments

Error CS1503: Argument 5: cannot convert from 'bool' to 'double?'

Much appreciated

 

Hi,

So you want to close a position when EMA cross happens? you can't put a logic on a position stop loss, to close a position when certain criteria meets you have to keep checking the criteria on OnBar or OnTick methods.

Hi,

Sorry. I'm very new to CTrader and API in general. In fact I only picked up pieces from Youtube and forums, here and there. Could you please elaborate more or give me a brief example on how to structure such criteria ? Thank you so much


@tuanpham1208

tuanpham1208
30 May 2022, 14:19

RE:

amusleh said:

Hi,

You can use the EMA value as your position stop loss / take profit, ema20.Result.LastValue will give the latest value of EMA.

Yes. Thank you. I know how to express it as a variable. But how do I express it as a condition for Stop Loss. Because I cannot insert ema20.Result.LastValue < ema50.Result.LastValue into ExecuteMarketOrder(), can I ? So for example 

ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", ema20.Result.LastValue < ema50.Result.LastValue, PrevATR)

It shows these errors:

Error CS1502: The best overloaded method match for 'cAlgo.API.Robot.ExecuteMarketOrder(cAlgo.API.TradeType, string, double, string, double?, double?)' has some invalid arguments

Error CS1503: Argument 5: cannot convert from 'bool' to 'double?'

Much appreciated

 


@tuanpham1208

tuanpham1208
30 May 2022, 10:24

RE:

amusleh said:

Hi,

What help you need? please be precise on what you are asking.

Hi,

As I said in the beginning of my post. I would like to know how to express Stop Loss / Take Profit as logics in stead of simple number of pips.

So for example, 

ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, "BOT", 1.5 * PrevATR, PrevATR)

How do I replace 1.5*PrevATR (i.e my SL) with EMA20 crosses below EMA50.

Thank you 


@tuanpham1208

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

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