Category Other  Published on 17/02/2021

TimeOrder

Description

Place an order at a specific time. It can be Market, Limit, Stop, or Stop Limit order. 

Can place two orders from one cBot instance. It was created for placing StopLimit orders before the big news.


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 TimeOrder : Robot
    {
        [Parameter("Time UTC", DefaultValue = "17.02.2021 16:29:50")]
        public string TimeText { get; set; }


        [Parameter("Order Type", DefaultValue = 4, Group = "Order 1")]
        public OrderType OrderType1 { get; set; }

        [Parameter("Side", DefaultValue = 0, Group = "Order 1")]
        public TradeType Side1 { get; set; }

        [Parameter("Volume", DefaultValue = 1000, Group = "Order 1")]
        public double Volume1 { get; set; }

        [Parameter("Max slippage pips", DefaultValue = 2, Group = "Order 1")]
        public double MaxSlippagePips1 { get; set; }

        [Parameter("Order distance pips", DefaultValue = 2, Group = "Order 1")]
        public double OrderDistancePips1 { get; set; }

        [Parameter("Stop Loss pips", DefaultValue = 20, Group = "Order 1")]
        public double StopLossPips1 { get; set; }

        [Parameter("Take Profit pips", DefaultValue = 40, Group = "Order 1")]
        public double TakeProfitPips1 { get; set; }


        [Parameter("Order Type", DefaultValue = 4, Group = "Order 2")]
        public OrderType OrderType2 { get; set; }

        [Parameter("Side", DefaultValue = 1, Group = "Order 2")]
        public TradeType Side2 { get; set; }

        [Parameter("Volume", DefaultValue = 1000, Group = "Order 2")]
        public double Volume2 { get; set; }

        [Parameter("Max slippage pips", DefaultValue = 2, Group = "Order 2")]
        public double MaxSlippagePips2 { get; set; }

        [Parameter("Order Distance pips", DefaultValue = 2, Group = "Order 2")]
        public double OrderDistancePips2 { get; set; }

        [Parameter("Stop Loss pips", DefaultValue = 20, Group = "Order 2")]
        public double StopLossPips2 { get; set; }

        [Parameter("Take Profit pips", DefaultValue = 40, Group = "Order 2")]
        public double TakeProfitPips2 { get; set; }


        private DateTime OrdersTime;

        protected override void OnStart()
        {
            if (DateTime.TryParse(TimeText, out OrdersTime) == false)
            {
                throw new FormatException("Invalid format for Time UTC parameter, use dd.MM.yyyy HH:mm:ss");
            }

            if (OrdersTime <= Time)
            {
                throw new ArgumentException("Invalid Time UTC parameter, it should be in the future");
            }

            Timer.TimerTick += Timer_TimerTick;
            Timer.Start(1);

            UpdateCountdownLabel(false);
        }

        private void Timer_TimerTick()
        {
            UpdateCountdownLabel(false);
            if (OrdersTime > Time)
                return;

            Timer.TimerTick -= Timer_TimerTick;
            PlaceOrders();
            UpdateCountdownLabel(true);
        }

        private void UpdateCountdownLabel(bool ordersWasPlaced)
        {
            var timespanLeft = Time - OrdersTime;
            var dateFormat = timespanLeft.TotalDays < 1 ? "HH:mm:ss" : "dd.MM.yyyy HH:mm:ss";
            var currentTimeText = Time.ToString(dateFormat);
            var ordersTimeText = OrdersTime.ToString(dateFormat);
            var lastLime = ordersWasPlaced ? "Orders were placed" : "Time left " + timespanLeft.ToString("dd\\.hh\\:mm\\:ss");
            var text = string.Format("Current time {0}\nOrders time {1}\n{2}", currentTimeText, ordersTimeText, lastLime);
            Chart.DrawStaticText("countDownTimer", text, VerticalAlignment.Top, HorizontalAlignment.Left, Chart.ColorSettings.ForegroundColor);
        }

        private void PlaceOrders()
        {
            PlaceOrder(OrderType1, Side1, Volume1, MaxSlippagePips1, OrderDistancePips1, StopLossPips1, TakeProfitPips1);
            PlaceOrder(OrderType2, Side2, Volume2, MaxSlippagePips2, OrderDistancePips2, StopLossPips2, TakeProfitPips2);
        }

        private void PlaceOrder(OrderType orderType, TradeType side, double volume, double maxSlippagePips, double distancePips, double stopLossPips, double takeProfitPips)
        {
            if (orderType == OrderType.Market)
            {
                var entryPrice = side == TradeType.Buy ? Symbol.Ask : Symbol.Bid;
                ExecuteMarketRangeOrderAsync(side, SymbolName, volume, maxSlippagePips, entryPrice, null, stopLossPips, takeProfitPips);
            }
            else if (orderType == OrderType.Limit)
            {
                var entryPrice = GetEntryLimitPrice(side, distancePips);
                PlaceLimitOrderAsync(side, SymbolName, volume, entryPrice, null, stopLossPips, takeProfitPips);
            }
            else if (orderType == OrderType.Stop)
            {
                var entryPrice = GetStopEntryPrice(side, distancePips);
                PlaceStopOrderAsync(side, SymbolName, volume, entryPrice, null, stopLossPips, takeProfitPips);
            }
            else if (orderType == OrderType.StopLimit)
            {
                var entryPrice = GetStopEntryPrice(side, distancePips);
                PlaceStopLimitOrderAsync(side, SymbolName, volume, entryPrice, maxSlippagePips, null, stopLossPips, takeProfitPips);
            }
        }

        private double GetEntryLimitPrice(TradeType side, double distancePips)
        {
            var absoluteDistance = Symbol.PipSize * distancePips;
            var entryPrice = side == TradeType.Buy ? Symbol.Ask - absoluteDistance : Symbol.Bid + absoluteDistance;
            return entryPrice;
        }

        private double GetStopEntryPrice(TradeType side, double distancePips)
        {
            var absoluteDistance = Symbol.PipSize * distancePips;
            var entryPrice = side == TradeType.Buy ? Symbol.Ask + absoluteDistance : Symbol.Bid - absoluteDistance;
            return entryPrice;
        }
    }

    public enum OrderType
    {
        None = 0,
        Market = 1,
        Limit = 2,
        Stop = 3,
        StopLimit = 4
    }
}


MO
MoeT

Joined on 17.02.2021

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: TimeOrder.algo
  • Rating: 0
  • Installs: 1519
  • Modified: 13/10/2021 09:54
Comments
Log in to add a comment.
BS
bsicm0001 · 3 years ago

Dear MoeT:

Mind getting in touch?

Please leave me a comment at:

https://ctrader.com/jobs/959


With thanks,

Ben