Problem with closing trade

Created at 24 Mar 2016, 12:27
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!
A1

a1112

Joined 24.03.2016

Problem with closing trade
24 Mar 2016, 12:27


Hello everyone. I am very new to programming and possibly my problem is some simple mistake that you will pick up easily.

I am using the code from the standard martingale robot provided. I simply force it to start with a sell in the code below, other than that is the usual martingale code and works fine.

My problem is, I have introduced a "count" for failed trades, after 3 failed trades I want it to close the last trade and stop. Also send me email (which works fine). As you will see in the log, it tries to close a trade but as you will notice, the trade ID is not that of the last trade but of the first one it started when entered the martingale loop. So it fails to close the last trade. Maybe you can spot why this happens?

So you see its trying to close the order 6008036, rather than the last one and of course it fails.

and below a little explanation of what I do.

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 letstestthis : Robot
    {
        [Parameter("Initial Quantity (Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double InitialQuantity { get; set; }
        [Parameter("Stop Loss", DefaultValue = 40)]
        public int StopLoss { get; set; }
        [Parameter("Take Profit", DefaultValue = 40)]
        public int TakeProfit { get; set; }
        private Random random = new Random();

        int count = 0;

        protected override void OnStart()
        {
            Positions.Closed += OnPositionsClosed;
            ExecuteOrder(InitialQuantity, TradeType.Sell);
        }

        private void ExecuteOrder(double quantity, TradeType tradeType)
        {
            var volumeInUnits = Symbol.QuantityToVolume(quantity);
            var result = ExecuteMarketOrder(tradeType, Symbol, volumeInUnits, "Martingale", StopLoss, TakeProfit);
            if (result.Error == ErrorCode.NoMoney)
                Stop();
        }

        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            Print("Closed");
            var position = args.Position;

            if (position.Label != "Martingale" || position.SymbolCode != Symbol.Code)
                return;

            if (position.GrossProfit > 0)
            {
                ExecuteOrder(InitialQuantity, GetRandomTradeType());
            }
            else
            {
                ExecuteOrder(position.Quantity * 2, position.TradeType);

                count = count + 1;
                Print("Failed", count);

                if (count == 2)
                {
                    Print("Done 3 losers in a row, so closing and sending email");
                    ClosePosition(position);
                    Notifications.SendEmail("email@gmail.com", "email@gmail.com", "Robot Martingale closing after 3 fails", "Closing robot");
                    Stop();
                }
            }
        }

        private TradeType GetRandomTradeType()
        {
            return random.Next(2) == 0 ? TradeType.Buy : TradeType.Sell;
        }
    }
}

Thank you for your help


@a1112
Replies

a1112
24 Mar 2016, 19:47 ( Updated at: 21 Dec 2023, 09:20 )

So i realised there was a hole in my logic above. I needed to start the count of failed trades before the next martingale started and the 

if (count == 3);

{Stop( );}

earlier.  

 

Still i don't understand why the ClosePosition(position); was looking for the ID of the first trade taken inside the Martingale loop. I thought that it was supposed to close all open trades, but anyway. 


@a1112

croucrou
24 Mar 2016, 20:49

To see how to close all open position, you might take a look at the code of the other robot closing profitable positions by using "foreach".


@croucrou

a1112
30 Mar 2016, 09:02

Hi "croucrou", thank you for your answer. I am looking into it.


@a1112

Waxy
01 Apr 2016, 06:01

This code has some bugs

First: You can't close a position that's already closed, most of your code happens when a position is closed, so you can't ask it to close it again, you could check it throws an error with: "Entity not found"

TradeResult OperationResult = ClosePosition(position);
                    if (!OperationResult.IsSuccessful)
                    {
                        Print("Operation could not be done, error: {0}",OperationResult.Error);
                    }

Second: You don't reset the counter if the last position is profitable, btw if you want to check the losers in a row do this.

            int losercount = 0; //declare it earlier
            foreach (var hist in History)
            {
                if (hist.Label == "Martingale") //within your bot trade history
                {
                    if (hist.NetProfit < 0)
                    {
                        losercount++;
                        if (losercount == 3)
                            Stop();
                    }
                    else
                    {
                        losercount = 0;
                    } 
                }
            }

 


@Waxy

a1112
01 Apr 2016, 11:55

Hi Waxy, thank you for your corrections. 

Now i understand the problem with the 1st.

As for the 2nd, i run into this last night. I then realized it wasn't resetting after a successful trade as it should, but was closing them on total count of failed. I fixed it by resetting the count  here with [ count=0; ] and seems to work fine like that so far, 

            if (position.GrossProfit > 0)
            {
                ExecuteOrder(InitialQuantity, GetRandomTradeType());
                count = 0;
                Print("Count is reset, new count {0}", count);
            }

but thank you for your code example, i understand it :)


@a1112