Bot not opening orders eventhough no margin required

Created at 27 Sep 2021, 08:05
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!
VE

velu130486

Joined 08.11.2019 Blocked

Bot not opening orders eventhough no margin required
27 Sep 2021, 08:05


Dear All,

I am not a developer, however I am learning Cbot coding based on the sample bots available in this forum. Recently I got the below Cbot from this forum which limits order opening based on the margin level. (i.e.) If the margin level is less than 10% it opens the position and if it is more than that no positions are opened.

However I had faced a situation no margin is required for opening the positions but bot is not opening it because it check the criteria first total margin is more than a limit and not by order direction.

For ex, I have already 2 Lots of EURUSD Buy Position open, as per Hedging account type no margin is required to open upto 2 Lots of EURUSD Sell Position, however the bot does not open the sell positions and vice versa.

Could you please help me to modify the code to avoid these problem

Thanks and Regards

R. Vadivelan

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 AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }
        private double _Margin;
        private int noOfPositions = 4;
        private int pips = 2;
        protected override void OnStart()
        {
            _Margin = Account.Balance;
            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }
        protected override void OnBar()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            if (Account.Margin / _Margin * 100 <= 10)
                if (buyCount == 0 || sellCount == 0)
                {
                    Volume += 1000;
                    noOfPositions += 2;
                    pips++;
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                    ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
                }
        }
    }
}

 


Replies

amusleh
27 Sep 2021, 10:36

Hi,

Try this:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }

        private int noOfPositions = 4;
        private int pips = 2;

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }

        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            // This will keep opening buy and sell positions unless your margin reach 10%, then it stops
            // It opens at most two buy and two sell positions (total 4)
            while (Account.Margin / Account.Equity * 100 < 10 && buyCount + sellCount < 4)
            {
                if (buyCount < 2)
                {
                    buyCount++;
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                }

                if (sellCount < 2)
                {
                    sellCount++;
                    ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
                }
            }
        }
    }
}

Modify it based on your needs, it uses a while loop to keep executing new positions until you reach 10% of account margin, then it stops.


@amusleh

velu130486
27 Sep 2021, 11:06

RE:

Thanks Ahmad for your quick reply. I will try it and update here.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

Try this:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }

        private int noOfPositions = 4;
        private int pips = 2;

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }

        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            // This will keep opening buy and sell positions unless your margin reach 10%, then it stops
            // It opens at most two buy and two sell positions (total 4)
            while (Account.Margin / Account.Equity * 100 < 10 && buyCount + sellCount < 4)
            {
                if (buyCount < 2)
                {
                    buyCount++;
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                }

                if (sellCount < 2)
                {
                    sellCount++;
                    ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
                }
            }
        }
    }
}

Modify it based on your needs, it uses a while loop to keep executing new positions until you reach 10% of account margin, then it stops.

 


velu130486
27 Sep 2021, 16:57

RE:

Hi Ahmad,

I had tried your code and I found in backtesting still the positions are created eventhough the margin is more than 10%. Also during backtesting I found in some cases sell positions are not created (i.e.) only buy positions are created.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

Try this:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }

        private int noOfPositions = 4;
        private int pips = 2;

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }

        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            // This will keep opening buy and sell positions unless your margin reach 10%, then it stops
            // It opens at most two buy and two sell positions (total 4)
            while (Account.Margin / Account.Equity * 100 < 10 && buyCount + sellCount < 4)
            {
                if (buyCount < 2)
                {
                    buyCount++;
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                }

                if (sellCount < 2)
                {
                    sellCount++;
                    ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
                }
            }
        }
    }
}

Modify it based on your needs, it uses a while loop to keep executing new positions until you reach 10% of account margin, then it stops.

 


amusleh
27 Sep 2021, 17:04

Hi,

The code I posted uses your account live equity and compare it with the amount of used margin, if you want to use your starting account balance as initial value then try this:


using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }

        private int noOfPositions = 4;
        private int pips = 2;

        private double _balance;

        protected override void OnStart()
        {
            _balance = Account.Balance;

            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }

        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            // This will keep opening buy and sell positions unless your margin reach 10%, then it stops
            // It opens at most two buy and two sell positions (total 4)
            while (Account.Margin / _balance * 100 < 10 && buyCount + sellCount < 4)
            {
                if (buyCount < 2)
                {
                    buyCount++;
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                }

                if (sellCount < 2)
                {
                    sellCount++;
                    ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
                }
            }
        }
    }
}

 


@amusleh

velu130486
29 Sep 2021, 10:43

RE:

Hi Ahmad,

Thanks for your modifications, I had already updated the while function in my multiple symbol multitimeframe based bot, however it results in Hanging of Ctrader. But the bot works fine with if condition. So is there any other alternate solution for this.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

The code I posted uses your account live equity and compare it with the amount of used margin, if you want to use your starting account balance as initial value then try this:


using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }

        private int noOfPositions = 4;
        private int pips = 2;

        private double _balance;

        protected override void OnStart()
        {
            _balance = Account.Balance;

            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }

        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            // This will keep opening buy and sell positions unless your margin reach 10%, then it stops
            // It opens at most two buy and two sell positions (total 4)
            while (Account.Margin / _balance * 100 < 10 && buyCount + sellCount < 4)
            {
                if (buyCount < 2)
                {
                    buyCount++;
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                }

                if (sellCount < 2)
                {
                    sellCount++;
                    ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
                }
            }
        }
    }
}

 

 


amusleh
29 Sep 2021, 11:43

Hi,

I just tested my posted code on a 2 year historical data back tester, it didn't hanged my PC nor it caused any other issue.

Back to your original code, the issue it not margin calculation, cTrader API Account.Margin value doesn't increase if you open an opposite position, you can test it.

The issue of not opening new positions most probably is caused by your condition that check the buy/sell count.

You are also using OnBar method on your code, which is executed once per each bar open, not on each tick, and that might be the cause because the method will be executed only when a new bar opens.

Try this:

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 AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }

        private double _Margin;
        private int noOfPositions = 4;
        private int pips = 2;

        protected override void OnStart()
        {
            _Margin = Account.Balance;
            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }

        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            if (Account.Margin / _Margin * 100 <= 10)
            {
                Volume += 1000;
                noOfPositions += 2;
                pips++;
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }
        }
    }
}

I removed your condition for buy/sell count check from if statement, you can add them back if you want to.

You don't have to nest if statements like that, you can add multiple conditions on a single if statement one after another:

            if (Account.Margin / _Margin * 100 <= 10 && (buyCount == 0 || sellCount == 0))
            {
                Volume += 1000;
                noOfPositions += 2;
                pips++;
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

 


@amusleh

velu130486
29 Sep 2021, 13:53

RE:

Hi Ahmad,

Thanks for your quick reply. The Cbot posted in my previous post works fine even with while condition, however I had implemented the same condition in my multiple symbol Cbot, and it causes the problem.

I had pasted the extract of Cbot code below where the trade is executed, because the Original Cbot is more than 1500 lines since it filters the signal based on top-down analysis and indicators for multiple symbols.

I had implemented the margin check condition in line no 6, which will check margin is more than 10% or not before opening the orders. I had used “if” condition and it works fine however when I use “while” condition Ctrader is not responding.

Assuming that Cbot already opened 0.20 Lot buy positions with margin more than 10%, then I expect Cbot not to open any new Buy positions even though buy signal is provided. At the same time, I want the bot to open sell positions up to 0.20 Lot if there is a sell signal provided, because as you said Ctrader API Account.Margin value doesn't increase if you open an opposite position.

I had checked the live demo where the Cbot provide sell signals, but based on the condition implemented in line no 6, Cbot is not allowing to open any positions and directly executes the last else statement. I had already changed the margin check to 2nd if condition also but still not working.

Please help me to fix this problem, since I am trying to find a solution for last 1 week.

Thanks and Regards

R. Vadivelan

void tradeExecution(TradeType type, string sym, string label)
{
    double maxEquity = Account.Balance > startEquity ? Account.Balance : startEquity;
    var losspercentage = Account.Margin / maxEquity * 100;

    if (autoMode2 && losspercentage <= EquityLoss)
    {
        if (type == TradeType.Buy)
        {
            double close = lowBar[sym].ClosePrices.LastValue;
            double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
            double atr = ATR[sym].Result.LastValue;
            double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
            var tp_1st = Math.Round(gap, 0);
            var sl_1st = Math.Round((gap * 20), 0);
            automode2PositionCount(sym, TradeType.Buy, close + atr, close - atr);

            if (pcount > 0)
            {
                if (close > pAboveprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
                if (close < pBelowprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Buy, sym, minvolume * (pcount + 1), "EA", 0, 0);
            }
            else
            {
                ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", sl_1st, tp_1st);
            }
            Print(sym + " : BUY" + " ATR : " + gap + "  Count: " + pcount + "   Within: " + pcountwithin);
        }
        if (type == TradeType.Sell)
        {
            double close = lowBar[sym].ClosePrices.LastValue;
            double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
            double atr = ATR[sym].Result.LastValue;
            double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
            var tp_1st = Math.Round(gap, 0);
            var sl_1st = Math.Round((gap * 20), 0);
            automode2PositionCount(sym, TradeType.Sell, close + atr, close - atr);

            if (pcount > 0)
            {
                if (close > pAboveprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Sell, sym, minvolume * (pcount + 1), "EA", 0, 0);
                if (close < pBelowprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
            }
            else
            {
                ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", sl_1st, tp_1st);
            }
            Print(sym + " : SELL" + " ATR : " + gap + "  Count : " + pcount + "   Within : " + pcountwithin);
        }
    }
    else
    {
        Print(sym + " : Max Equity Drawdown Trade not allowed " + losspercentage);
    }
}

amusleh said:

Hi,

I just tested my posted code on a 2 year historical data back tester, it didn't hanged my PC nor it caused any other issue.

Back to your original code, the issue it not margin calculation, cTrader API Account.Margin value doesn't increase if you open an opposite position, you can test it.

The issue of not opening new positions most probably is caused by your condition that check the buy/sell count.

You are also using OnBar method on your code, which is executed once per each bar open, not on each tick, and that might be the cause because the method will be executed only when a new bar opens.

Try this:

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 AdvancedHedgingBot : Robot
    {
        [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)]
        public int Volume { get; set; }

        private double _Margin;
        private int noOfPositions = 4;
        private int pips = 2;

        protected override void OnStart()
        {
            _Margin = Account.Balance;
            ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
            ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
        }

        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                if (position.Pips > pips)
                {
                    ClosePosition(position);
                }
            }
            if (Positions.Count < noOfPositions)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

            int buyCount = 0;
            int sellCount = 0;
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy)
                    buyCount++;
                if (position.TradeType == TradeType.Sell)
                    sellCount++;
            }

            if (Account.Margin / _Margin * 100 <= 10)
            {
                Volume += 1000;
                noOfPositions += 2;
                pips++;
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }
        }
    }
}

I removed your condition for buy/sell count check from if statement, you can add them back if you want to.

You don't have to nest if statements like that, you can add multiple conditions on a single if statement one after another:

            if (Account.Margin / _Margin * 100 <= 10 && (buyCount == 0 || sellCount == 0))
            {
                Volume += 1000;
                noOfPositions += 2;
                pips++;
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY");
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL");
            }

 

 


amusleh
30 Sep 2021, 11:26

Hi,

I checked your code, there is no issue on your margin condition.

Can you just use balance not equity and see if it executes any trade or not.

I think your equity fell below your max margin loss percentage amount, and that stops the bot from opening new positions.


@amusleh

velu130486
30 Sep 2021, 12:45

RE:

Hi Ahmad,

I had modified the code based on Balance (as per your sample code), but still the new positions are not opening.

void tradeExecution(TradeType type, string sym, string label)
{
    var losspercentage = Account.Margin / Account.Balance * 100;

    if (autoMode2 && losspercentage <= 10)
    {
        if (type == TradeType.Buy)
        {
            double close = lowBar[sym].ClosePrices.LastValue;
            double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
            double atr = ATR[sym].Result.LastValue;
            double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
            var tp_1st = Math.Round(gap, 0);
            var sl_1st = Math.Round((gap * 20), 0);
            automode2PositionCount(sym, TradeType.Buy, close + atr, close - atr);

            if (pcount > 0)
            {
                if (close > pAboveprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
                if (close < pBelowprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Buy, sym, minvolume * (pcount + 1), "EA", 0, 0);
            }
            else
            {
                ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", sl_1st, tp_1st);
            }
            Print(sym + " : BUY" + " ATR : " + gap + "  Count: " + pcount + "   Within: " + pcountwithin);
        }
        if (type == TradeType.Sell)
        {
            double close = lowBar[sym].ClosePrices.LastValue;
            double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
            double atr = ATR[sym].Result.LastValue;
            double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
            var tp_1st = Math.Round(gap, 0);
            var sl_1st = Math.Round((gap * 20), 0);
            automode2PositionCount(sym, TradeType.Sell, close + atr, close - atr);

            if (pcount > 0)
            {
                if (close > pAboveprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Sell, sym, minvolume * (pcount + 1), "EA", 0, 0);
                if (close < pBelowprice && pcountwithin == 0)
                    ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
            }
            else
            {
                ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", sl_1st, tp_1st);
            }
            Print(sym + " : SELL" + " ATR : " + gap + "  Count : " + pcount + "   Within : " + pcountwithin);
        }
    }
    else
    {
        Print(sym + " : Max Equity Drawdown Trade not allowed " + losspercentage);
    }
}

As I said before the problem is happening on this line

if (autoMode2 && losspercentage <= 10)

Cbot open the Buy or Sell position when the losspercentage is less than 10, but when it is more than 10 it is directly go to last else statement, so no new positions are opened.

However my expectation is

New Sell position to be opened if existing Buy Position volume is more, because no margin is required

New Buy position to be opened if existing Sell Position volume is more, because no margin is required

For Ex I have starting balance 1000, Margin used 116, Buy Positions opened 0.5 Lot EUR/USD, Sell positions 0.2 Lot EUR/USD.

When the Cbot generate Buy Signal no new position to be opened because margin is more than 10%. However if the sell signal is provided it has to open a new position because no margin is required for Sell positions. However with the above code it go to last else statement.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

I checked your code, there is no issue on your margin condition.

Can you just use balance not equity and see if it executes any trade or not.

I think your equity fell below your max margin loss percentage amount, and that stops the bot from opening new positions.

 


amusleh
01 Oct 2021, 09:38

Hi,

I still don't understand your exact issue, the Account.Margin gives you the amount of used margin.

The 116 is the amount of margin you need for a 1:500 leverage account to open a 0.5 lots buy EURUSD position, and the 0.2 lots sell position doesn't cost you any extra margin.

Here is my used margin when I opened the first 0.5 lots buy position:

And here is my used margin after I opened the second sell position:

You see my used margin didn't increased at all, that's the exact value you get from Account.Margin.

So, the sell position doesn't increase your used margin, you are using 10% of your margin, if you want to keep opening positions then set the percentage of margin to 20% not 10%.


@amusleh

velu130486
01 Oct 2021, 10:47 ( Updated at: 21 Dec 2023, 09:22 )

RE:

Hi Ahmad,

I will try to explain better. As you said there is no problem in margin % calculation. So once the Buy position is opened by Bot, margin will be consumed 10% and it is fine. However when the bot generates sell signal, sell positions are not opened in my bot (even though no margin is required).

Main issue is due to the following condition, since the margin % > 10, it directly skip to last else statement.

if (autoMode2 && losspercentage <= EquityLoss)

I want to implement EquityLoss condition at the same time Bot should open only sell positions till 0.5 Lot.

In manual trading I can open the positions and margin is not increased, however in Auto trading Cbot not opening the sell positions.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

I still don't understand your exact issue, the Account.Margin gives you the amount of used margin.

The 116 is the amount of margin you need for a 1:500 leverage account to open a 0.5 lots buy EURUSD position, and the 0.2 lots sell position doesn't cost you any extra margin.

Here is my used margin when I opened the first 0.5 lots buy position:

And here is my used margin after I opened the second sell position:

You see my used margin didn't increased at all, that's the exact value you get from Account.Margin.

So, the sell position doesn't increase your used margin, you are using 10% of your margin, if you want to keep opening positions then set the percentage of margin to 20% not 10%.

 


amusleh
01 Oct 2021, 11:50

Hi,

For equity loss you don't have to use margin, instead you can calculate the percentage you are in loss by using only account equity and balance:

        private void tradeExecution(TradeType type, string sym, string label)
        {
            var equityLossPercentage = (Account.Equity - Account.Balance) / Account.Balance * 100;

            if (autoMode2 && equityLossPercentage >= -10)
            {
                if (type == TradeType.Buy)
                {
                    double close = lowBar[sym].ClosePrices.LastValue;
                    double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
                    double atr = ATR[sym].Result.LastValue;
                    double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
                    var tp_1st = Math.Round(gap, 0);
                    var sl_1st = Math.Round((gap * 20), 0);
                    automode2PositionCount(sym, TradeType.Buy, close + atr, close - atr);

                    if (pcount > 0)
                    {
                        if (close > pAboveprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
                        if (close < pBelowprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Buy, sym, minvolume * (pcount + 1), "EA", 0, 0);
                    }
                    else
                    {
                        ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", sl_1st, tp_1st);
                    }
                    Print(sym + " : BUY" + " ATR : " + gap + "  Count: " + pcount + "   Within: " + pcountwithin);
                }
                if (type == TradeType.Sell)
                {
                    double close = lowBar[sym].ClosePrices.LastValue;
                    double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
                    double atr = ATR[sym].Result.LastValue;
                    double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
                    var tp_1st = Math.Round(gap, 0);
                    var sl_1st = Math.Round((gap * 20), 0);
                    automode2PositionCount(sym, TradeType.Sell, close + atr, close - atr);

                    if (pcount > 0)
                    {
                        if (close > pAboveprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Sell, sym, minvolume * (pcount + 1), "EA", 0, 0);
                        if (close < pBelowprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
                    }
                    else
                    {
                        ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", sl_1st, tp_1st);
                    }
                    Print(sym + " : SELL" + " ATR : " + gap + "  Count : " + pcount + "   Within : " + pcountwithin);
                }
            }
            else
            {
                Print(sym + " : Max Equity Drawdown Trade not allowed " + losspercentage);
            }
        }

For example, your account balance is 1000 and your equity is 900, it means you are down -10%.

 


@amusleh

velu130486
01 Oct 2021, 12:56 ( Updated at: 21 Dec 2023, 09:22 )

RE:

Hi Ahmad,

Thanks for your kind reply and update to the cbot code. Sorry for the wrong wording "EquityLoss" in my coding, my intention is use margin as a filter for opening positions. (i.e.) Bot should open positions up to use of 10% margin.

Currently my bot opens buy and sell positions till I use 10% margin, once it is reached Cbot is not opening any positions.

Below is the scenario

From the above scenario, margin used is more than 10%, so Bot will not open new Buy Position in EURUSD/Sell position in GBPUSD however still 0.1 Sell Position of EUR/USD/0.1 buy position of GBPUSD can be opened because no margin is required. However Bot is not opening the same because of following condition.

var lossmargin = Account.Margin / maxEquity * 100;

if (autoMode2 && lossmargin <= 10)

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

For equity loss you don't have to use margin, instead you can calculate the percentage you are in loss by using only account equity and balance:

        private void tradeExecution(TradeType type, string sym, string label)
        {
            var equityLossPercentage = (Account.Equity - Account.Balance) / Account.Balance * 100;

            if (autoMode2 && equityLossPercentage >= -10)
            {
                if (type == TradeType.Buy)
                {
                    double close = lowBar[sym].ClosePrices.LastValue;
                    double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
                    double atr = ATR[sym].Result.LastValue;
                    double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
                    var tp_1st = Math.Round(gap, 0);
                    var sl_1st = Math.Round((gap * 20), 0);
                    automode2PositionCount(sym, TradeType.Buy, close + atr, close - atr);

                    if (pcount > 0)
                    {
                        if (close > pAboveprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
                        if (close < pBelowprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Buy, sym, minvolume * (pcount + 1), "EA", 0, 0);
                    }
                    else
                    {
                        ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", sl_1st, tp_1st);
                    }
                    Print(sym + " : BUY" + " ATR : " + gap + "  Count: " + pcount + "   Within: " + pcountwithin);
                }
                if (type == TradeType.Sell)
                {
                    double close = lowBar[sym].ClosePrices.LastValue;
                    double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
                    double atr = ATR[sym].Result.LastValue;
                    double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
                    var tp_1st = Math.Round(gap, 0);
                    var sl_1st = Math.Round((gap * 20), 0);
                    automode2PositionCount(sym, TradeType.Sell, close + atr, close - atr);

                    if (pcount > 0)
                    {
                        if (close > pAboveprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Sell, sym, minvolume * (pcount + 1), "EA", 0, 0);
                        if (close < pBelowprice && pcountwithin == 0)
                            ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
                    }
                    else
                    {
                        ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", sl_1st, tp_1st);
                    }
                    Print(sym + " : SELL" + " ATR : " + gap + "  Count : " + pcount + "   Within : " + pcountwithin);
                }
            }
            else
            {
                Print(sym + " : Max Equity Drawdown Trade not allowed " + losspercentage);
            }
        }

For example, your account balance is 1000 and your equity is 900, it means you are down -10%.

 


amusleh
01 Oct 2021, 13:41 ( Updated at: 01 Oct 2021, 13:43 )

Hi,

You have to calculate each open position used margin, if your account deposit currency is USD you can do that by: 

USD / XXX (ex: USD/CAD):  

           margin =  contract size / leverage;

XXX / USD (ex: EUR/USD):

           margin = current price * contract size / leverage;

if your account deposit currency is not USD then you have to convert it to that currency by using other FX cross symbols (which will become more complicated).

After you got the total margin used for example buy EURUSD position then you can check if you have enough margin for sell position or not.

Example:

        private double GetUsedMargin(string symbolName, TradeType tradeType)
        {
            var symbol = Symbols.GetSymbol(symbolName);

            var positionsCopy = Positions.ToArray();

            double usedMargin = 0;

            foreach (var position in positionsCopy)
            {
                if (position.SymbolName.Equals(symbolName, StringComparison.OrdinalIgnoreCase) && position.TradeType == tradeType)
                {
                    usedMargin += symbolName.StartsWith("USD", StringComparison.OrdinalIgnoreCase)
                        ? position.VolumeInUnits / Account.PreciseLeverage
                        : symbol.Bid * position.VolumeInUnits / Account.PreciseLeverage;
                }
            }

            return usedMargin;
        }

The above method will give you the amount of used margin by a symbol buy or sell positions, the symbol must be in XXX/USD or USD/XXX format, otherwise it will not work.

Once you got a symbol buy/sell positions total margin you can use it on your if condition instead of Account.Margin.


@amusleh

velu130486
01 Oct 2021, 14:12

RE:

Thanks Ahmad for your quick reply. I don't want complicate the things in my bot since I don't have enough knowledge on coding. So I will try to use Equity loss as condition for opening the positions.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

You have to calculate each open position used margin, if your account deposit currency is USD you can do that by: 

USD / XXX (ex: USD/CAD):  

           margin =  contract size / leverage;

XXX / USD (ex: EUR/USD):

           margin = current price * contract size / leverage;

if your account deposit currency is not USD then you have to convert it to that currency by using other FX cross symbols (which will become more complicated).

After you got the total margin used for example buy EURUSD position then you can check if you have enough margin for sell position or not.

Example:

        private double GetUsedMargin(string symbolName, TradeType tradeType)
        {
            var symbol = Symbols.GetSymbol(symbolName);

            var positionsCopy = Positions.ToArray();

            double usedMargin = 0;

            foreach (var position in positionsCopy)
            {
                if (position.SymbolName.Equals(symbolName, StringComparison.OrdinalIgnoreCase) && position.TradeType == tradeType)
                {
                    usedMargin += symbolName.StartsWith("USD", StringComparison.OrdinalIgnoreCase)
                        ? position.VolumeInUnits / Account.PreciseLeverage
                        : symbol.Bid * position.VolumeInUnits / Account.PreciseLeverage;
                }
            }

            return usedMargin;
        }

The above method will give you the amount of used margin by a symbol buy or sell positions, the symbol must be in XXX/USD or USD/XXX format, otherwise it will not work.

Once you got a symbol buy/sell positions total margin you can use it on your if condition instead of Account.Margin.