Too many stop orders within time frame

Created at 24 Jan 2021, 20:28
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!
PU

PUdPUd

Joined 24.01.2021

Too many stop orders within time frame
24 Jan 2021, 20:28


I would like to open several new stop orders once at the opening of the trading day. I am using Eastern standard time to account for daylight savings. Currently the orders are continuously placed throughout the hour selected rather than just once at the beginning of the hour. I have tried restricting the count of open orders, as well as putting 24 hours between orders and neither works. They seem to be spaced out per minute regardless of whether I select the hourly or daily bar across the opening hour of the day. 

 

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.EasternStandardTime, AccessRights = AccessRights.None)]
    public class Test1 : Robot
    {
        private DateTime _startTime;
        private DateTime _stopTime;
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        [Parameter("Start Hour", DefaultValue = 0)]
        public double StartTime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 1)]
        public double StopTime { get; set; }

        private DateTime _lastExecutedOrder;


        protected override void OnStart()
        {

            //Start Time is the same day at Server Time
            _startTime = Server.Time.Date.AddHours(StartTime);

            //Stop Time is the next day at Server Time
            _stopTime = Server.Time.Date.AddHours(StopTime);

            Print("Start Time {0},", _startTime);
            Print("Stop Time {0},", _stopTime);

        }


        protected override void OnTick()
        {

            if (Account.Equity >= 0)
            {
                foreach (var order in PendingOrders)
                {
                    CancelPendingOrder(order);
                }
            }

            if (Trade.IsExecuting)
                return;

            var currentHours = Server.Time.TimeOfDay.TotalHours;
            bool tradeTime = StartTime < StopTime ? currentHours > StartTime && currentHours < StopTime : currentHours < StopTime || currentHours > StartTime;

            if (!tradeTime)
                return;

            if (Positions.Count != 0)
                return;

            PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid, "Trade1");
            PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask, "Trade2");


            foreach (var pendingOrder in PendingOrders)
            {
                Print("Order placed with label {0}, id {1}", pendingOrder.Label, pendingOrder.Id);
            }

        }

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


@PUdPUd
Replies

PanagiotisCharalampous
25 Jan 2021, 09:09

RE:

Hi PUdPUd,

Why did you write your logic in OnTick(). You can just subscribe to daily bars and execute the logic in BarOpened once per day. See below

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

        protected override void OnStart()
        {
            var dailyBars = MarketData.GetBars(TimeFrame.Daily);
            dailyBars.BarOpened += OnDailyBarsBarOpened;
        }
        
        void OnDailyBarsBarOpened(BarOpenedEventArgs obj)
        {
            // Put your order placement logic here
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

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

 

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

PUdPUd
25 Jan 2021, 19:05 ( Updated at: 25 Jan 2021, 19:18 )

RE: RE:

Hi Panagiotis 

Thanks for your comments. I tried your recommendation and during backtesting the first day 6 stop orders were successfully entered into the system, but  every other day after then anywhere between 8 and 25 stop orders were placed per day. Also, this only seems to work for indices and commodities but not currency pairs. Perhaps I have missed something? If I put that logic in OnBar() only the first 2 stop orders are executed but on some days 3 stop orders are executed by duplicating the first or second order again. 

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.EasternStandardTime, AccessRights = AccessRights.None)]
    public class Test2 : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }


        protected override void OnStart()
        {
            var dailyBars = MarketData.GetBars(TimeFrame.Daily);
            dailyBars.BarOpened += OnDailyBarsBarOpened;
        }

        void OnDailyBarsBarOpened(BarOpenedEventArgs obj)
        {
            PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid, "Trade1");
            PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask, "Trade2");
            PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid, "Trade3");
            PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask, "Trade4");
            PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid, "Trade5");
            PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask, "Trade6");            

foreach (var pendingOrder in PendingOrders)
            {
                Print("Order placed with label {0}, id {1}", pendingOrder.Label, pendingOrder.Id);
            }

        }


        protected override void OnBar()
        {

        }


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

 

 


@PUdPUd

PanagiotisCharalampous
26 Jan 2021, 08:02

Hi PUdPUd,

Can you send us information to reproduce this behavior on backtesting?

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

PUdPUd
26 Jan 2021, 13:08 ( Updated at: 26 Jan 2021, 13:09 )

RE:

Dear Panagiotis 

The code is very simple and without indicators and is supplied below. Both versions were applied to US500 Daily chart. Here is the code for where the order is replicated anywhere between 8-25 times per day, the other code is supplied after that:.

---------------------------------------------------------------Code that produces 8-25 trades per day rather than 6

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.EasternStandardTime, AccessRights = AccessRights.None)]
    public class Test2 : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }


        protected override void OnStart()
        {
            var dailyBars = MarketData.GetBars(TimeFrame.Daily);
            dailyBars.BarOpened += OnDailyBarsBarOpened;
        }

        void OnDailyBarsBarOpened(BarOpenedEventArgs obj)
        {
            PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid + 2 * Symbol.PipSize, "OpenStopBuy", 18, 21);
            PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask - 2 * Symbol.PipSize, "OpenStopSell", 18, 21);
            PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid + 22 * Symbol.PipSize, "2ndStopBuy", 18, 21);
            PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask - 22 * Symbol.PipSize, "2ndStopSell", 18, 21);
            PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid + 42 * Symbol.PipSize, "3rdStopBuy", 18, 21);
            PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask - 42 * Symbol.PipSize, "3rdStopSell", 18, 21);

            foreach (var pendingOrder in PendingOrders)
            {
                Print("Order placed with label {0}, id {1}", pendingOrder.Label, pendingOrder.Id);
            }

        }


        protected override void OnBar()
        {

        }


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

 

---------------------------------------------------------------Code that produces only two trades out of the six per day:

 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.EasternStandardTime, AccessRights = AccessRights.None)]
    public class Test2 : Robot
    
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }


        protected override void OnStart()
        {
            var dailyBars = MarketData.GetBars(TimeFrame.Daily);
            dailyBars.BarOpened += OnDailyBarsBarOpened;
        }
        
        protected override void OnBar()
        void OnDailyBarsBarOpened(BarOpenedEventArgs obj)
        {
           PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid + 2 * Symbol.PipSize, "OpenStopBuy", 18, 21);
           PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask - 2 * Symbol.PipSize, "OpenStopSell", 18, 21);
           PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid + 22 * Symbol.PipSize, "2ndStopBuy", 18, 21);
           PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask - 22 * Symbol.PipSize, "2ndStopSell", 18, 21);
           PlaceStopOrder(TradeType.Buy, SymbolName, 1, Symbol.Bid + 42 * Symbol.PipSize, "3rdStopBuy", 18, 21);
           PlaceStopOrder(TradeType.Sell, SymbolName, 1, Symbol.Ask - 42 * Symbol.PipSize, "3rdStopSell", 18, 21);
           

            foreach (var pendingOrder in PendingOrders)
            {
                Print("Order placed with label {0}, id {1}", pendingOrder.Label, pendingOrder.Id);
            }
        }


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

 


@PUdPUd

PanagiotisCharalampous
26 Jan 2021, 13:26

Hi PUdPUd,

Why do you expect 6 trades per day? The code places 6 orders every day. It does not mean they will be executed on the same day.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

PUdPUd
26 Jan 2021, 13:36

RE:

Dear Panagiotis 

I don't expect 6 trades a day, I expect 6 stop orders per day. This code prints the name of the stop order once placed, and according to the log file the incorrect number of stop orders are placed as described previously. 

PUdPud

 


@PUdPUd

PUdPUd
26 Jan 2021, 13:48 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE:

Here are some screenshots corresponding to the problems described. Here on 03/01/2020 over a dozen orders were placed:

Here only the first two trades in the list are placed each day:


@PUdPUd

PanagiotisCharalampous
26 Jan 2021, 14:14 ( Updated at: 21 Dec 2023, 09:22 )

Hi PUdPUd,

You should be checking the Trading category of messages or the Events tab.

Your print logic doesn't necessarily print the orders placed at that moment, since PendingOrders might contain past orders or still miss some of the latest ones. You can also try using Visual Backtesting to visualize what actually happens.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous