Pending Order/Fragmentation Trading Panel

Created at 21 Aug 2021, 18:23
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!
WA

waym77

Joined 22.07.2021

Pending Order/Fragmentation Trading Panel
21 Aug 2021, 18:23


Hi all,

I've modified the cTrader sample Quick Trading Panel to support some extra features I wanted. The features added are as follows:

Pending orders (Both Stop & Limit).
Fragmentation of orders (Splitting total volume between the number of positions to create several smaller positions).
Close all pending orders at once.

However, I've encountered two errors with the fragmentation logic specifically. These errors are:

1. When the lot size per fragmented position is less than 1 (eg. 3 lots total over 6 positions for 0.5 lots total), I receive an error that the lot size is 0.

2. When the fragment is more than 1 only one order is opened. An example of this would be 3 lots total over 2 positions, meaning 2 positions of 1.5 lots each should be opened. Only one is opened though.

Here is the code:

 

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EasyStop : Robot
    {
        [Parameter("Vertical Position", Group = "Panel alignment", DefaultValue = VerticalAlignment.Top)]
        public VerticalAlignment PanelVerticalAlignment { get; set; }

        [Parameter("Horizontal Position", Group = "Panel alignment", DefaultValue = HorizontalAlignment.Left)]
        public HorizontalAlignment PanelHorizontalAlignment { get; set; }

        [Parameter("Default Price", Group = "Default trade parameters", DefaultValue = 1.17)]
        public double DefaultPrice { get; set; }

        [Parameter("Default Lots", Group = "Default trade parameters", DefaultValue = 0.01)]
        public double DefaultLots { get; set; }

        [Parameter("Default Fragmentation", Group = "Default trade parameters", DefaultValue = 1)]
        public double DefaultFrag { get; set; }

        [Parameter("Default Take Profit (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultTakeProfitPips { get; set; }

        [Parameter("Default Stop Loss (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultStopLossPips { get; set; }

        protected override void OnStart()
        {
            var tradingPanel = new TradingPanel(this, Symbol, DefaultPrice, DefaultFrag, DefaultLots, DefaultStopLossPips, DefaultTakeProfitPips);

            var border = new Border 
            {
                VerticalAlignment = PanelVerticalAlignment,
                HorizontalAlignment = PanelHorizontalAlignment,
                Style = Styles.CreatePanelBackgroundStyle(),
                Margin = "20 40 20 20",
                Width = 225,
                Child = tradingPanel
            };

            Chart.AddControl(border);
        }
    }

    public class TradingPanel : CustomControl
    {
        private const string LotsInputKey = "LotsKey";
        private const string PriceInputKey = "PriceKey";
        private const string FragInputKey = "FragKey";
        private const string TakeProfitInputKey = "TPKey";
        private const string StopLossInputKey = "SLKey";
        private readonly IDictionary<string, TextBox> _inputMap = new Dictionary<string, TextBox>();
        private readonly Robot _robot;
        private readonly Symbol _symbol;

        public TradingPanel(Robot robot, Symbol symbol, double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            _robot = robot;
            _symbol = symbol;
            AddChild(CreateTradingPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips));
        }

        private ControlBase CreateTradingPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var mainPanel = new StackPanel();

            var header = CreateHeader();
            mainPanel.AddChild(header);

            var contentPanel = CreateContentPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips);
            mainPanel.AddChild(contentPanel);

            return mainPanel;
        }

        private ControlBase CreateHeader()
        {
            var headerBorder = new Border 
            {
                BorderThickness = "0 0 0 1",
                Style = Styles.CreateCommonBorderStyle()
            };

            var header = new TextBlock 
            {
                Text = "Quick Trading Panel",
                Margin = "10 7",
                Style = Styles.CreateHeaderStyle()
            };

            headerBorder.Child = header;
            return headerBorder;
        }

        private StackPanel CreateContentPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var contentPanel = new StackPanel 
            {
                Margin = 10
            };
            var grid = new Grid(9, 3);
            grid.Columns[1].SetWidthInPixels(5);

            var sellmarketButton = CreateMarketTradeButton("MARKET SELL", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellmarketButton, 0, 0);

            var buymarketButton = CreateMarketTradeButton("MARKET BUY", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buymarketButton, 0, 2);

            var sellstopButton = CreateStopTradeButton("SELL STOP", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellstopButton, 1, 0);

            var buystopButton = CreateStopTradeButton("BUY STOP", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buystopButton, 1, 2);

            var selllimitButton = CreateLimitTradeButton("SELL LIMIT", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(selllimitButton, 3, 0);

            var buylimitButton = CreateLimitTradeButton("BUY LIMIT", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buylimitButton, 3, 2);

            var priceInput = CreateInputWithLabel("Pending Price", defaultPrice.ToString("F2"), PriceInputKey);
            grid.AddChild(priceInput, 4, 0);

            var fragInput = CreateInputWithLabel("Order Fragmentation", defaultFrag.ToString("F2"), FragInputKey);
            grid.AddChild(fragInput, 4, 2);

            var lotsInput = CreateInputWithLabel("Quantity (Lots)", defaultLots.ToString("F2"), LotsInputKey);
            grid.AddChild(lotsInput, 5, 0, 1, 3);

            var stopLossInput = CreateInputWithLabel("Stop Loss (Pips)", defaultStopLossPips.ToString("F1"), StopLossInputKey);
            grid.AddChild(stopLossInput, 6, 0);

            var takeProfitInput = CreateInputWithLabel("Take Profit (Pips)", defaultTakeProfitPips.ToString("F1"), TakeProfitInputKey);
            grid.AddChild(takeProfitInput, 6, 2);

            var closeAllPendingButton = CreateCloseAllPendingButton();
            grid.AddChild(closeAllPendingButton, 7, 0, 1, 3);

            var closeAllOpenButton = CreateCloseAllOpenButton();
            grid.AddChild(closeAllOpenButton, 8, 0, 1, 3);

            contentPanel.AddChild(grid);

            return contentPanel;
        }

        private Button CreateMarketTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button 
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceMarket(tradeType);

            return tradeButton;
        }

        private Button CreateStopTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button 
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceStop(tradeType);

            return tradeButton;
        }

        private Button CreateLimitTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button 
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceLimit(tradeType);

            return tradeButton;
        }

        private ControlBase CreateCloseAllPendingButton()
        {
            var closeAllBorder = new Border 
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button 
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Pending",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllPending();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private ControlBase CreateCloseAllOpenButton()
        {
            var closeAllBorder = new Border 
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button 
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Open",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllOpen();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private Panel CreateInputWithLabel(string label, string defaultValue, string inputKey)
        {
            var stackPanel = new StackPanel 
            {
                Orientation = Orientation.Vertical,
                Margin = "0 10 0 0"
            };

            var textBlock = new TextBlock 
            {
                Text = label
            };

            var input = new TextBox 
            {
                Margin = "0 5 0 0",
                Text = defaultValue,
                Style = Styles.CreateInputStyle()
            };

            _inputMap.Add(inputKey, input);

            stackPanel.AddChild(textBlock);
            stackPanel.AddChild(input);

            return stackPanel;
        }

        private void PlaceMarket(TradeType tradeType)
        {
            var _vol_usable = 0.0;
            var count = 0;
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                _vol_usable = Calc_LPT();
                var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
                var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
                var _price_usable = GetValueFromInput(PriceInputKey, 0);

                var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
                if (count != _frag)
                {
                    _robot.ExecuteMarketOrderAsync(tradeType, _symbol.Name, _volume_units, string.Empty, stopLossPips, takeProfitPips);
                    count++;
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }

        }

        private void PlaceStop(TradeType tradeType)
        {
            var _vol_usable = 0.0;
            var count = 0;
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                _vol_usable = Calc_LPT();
                var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
                var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
                var _price_usable = GetValueFromInput(PriceInputKey, 0);

                var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
                if (count != _frag)
                {
                    _robot.PlaceStopOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                    count++;
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }

        }

        private void PlaceLimit(TradeType tradeType)
        {
            var _vol_usable = 0.0;
            var count = 0;
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                _vol_usable = Calc_LPT();
                var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
                var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
                var _price_usable = GetValueFromInput(PriceInputKey, 0);

                var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
                if (count != _frag)
                {
                    _robot.PlaceLimitOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                    count++;
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }

        }

        private double Calc_LPT()
        {
            var _lots = GetValueFromInput(LotsInputKey, 0);
            var _frag = GetValueFromInput(FragInputKey, 0);
            var result = Math.Round(_lots / _frag, 2);
            return result;
        }

        private double GetValueFromInput(string inputKey, double defaultValue)
        {
            double value;

            return double.TryParse(_inputMap[inputKey].Text, out value) ? value : defaultValue;
        }

        private void CloseAllPending()
        {
            foreach (var pending in _robot.PendingOrders)
                _robot.CancelPendingOrderAsync(pending);
        }

        private void CloseAllOpen()
        {
            foreach (var position in _robot.Positions)
                _robot.ClosePositionAsync(position);
        }
    }

    public static class Styles
    {
        public static Style CreatePanelBackgroundStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.CornerRadius, 3);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#292929"), 0.85m), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.85m), ControlState.LightTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#3C3C3C"), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#C3C3C3"), ControlState.LightTheme);
            style.Set(ControlProperty.BorderThickness, new Thickness(1));

            return style;
        }

        public static Style CreateCommonBorderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.12m), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#000000"), 0.12m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateHeaderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#FFFFFF", 0.70m), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#000000", 0.65m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateInputStyle()
        {
            var style = new Style(DefaultStyles.TextBoxStyle);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#1A1A1A"), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#111111"), ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#E7EBED"), ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#D6DADC"), ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.CornerRadius, 3);
            return style;
        }

        public static Style CreateBuyButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#009345"), Color.FromHex("#10A651"));
        }

        public static Style CreateSellButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        public static Style CreateCloseButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        private static Style CreateButtonStyle(Color color, Color hoverColor)
        {
            var style = new Style(DefaultStyles.ButtonStyle);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.LightTheme);
            return style;
        }

        private static Color GetColorWithOpacity(Color baseColor, decimal opacity)
        {
            var alpha = (int)Math.Round(byte.MaxValue * opacity, MidpointRounding.AwayFromZero);
            return Color.FromArgb(alpha, baseColor);
        }
    }
}

 

Thanks in advance,


@waym77
Replies

artcfd
23 Aug 2021, 07:47

RE:

waym77 said:

Hi, I don't know how to write code, but according to your description, you are obviously missing a judgment logic. For example, when the order volume is between 1 lot and 3 lots, the order is divided into 3 orders on average; when the order volume is between 3 and 5 lots then the order is divided into 6 orders on average; also consider the problem of integer division. In addition this panel is best to also add a batch stop function is best, and each fragmentation order each scattered orders are the same stop gain and stop loss. Hope this gives you ideas, my friend "Xiao" from China

Hi all,

I've modified the cTrader sample Quick Trading Panel to support some extra features I wanted. The features added are as follows:

Pending orders (Both Stop & Limit).
Fragmentation of orders (Splitting total volume between the number of positions to create several smaller positions).
Close all pending orders at once.

However, I've encountered two errors with the fragmentation logic specifically. These errors are:

1. When the lot size per fragmented position is less than 1 (eg. 3 lots total over 6 positions for 0.5 lots total), I receive an error that the lot size is 0.

2. When the fragment is more than 1 only one order is opened. An example of this would be 3 lots total over 2 positions, meaning 2 positions of 1.5 lots each should be opened. Only one is opened though.

Here is the code:

 

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EasyStop : Robot
    {
        [Parameter("Vertical Position", Group = "Panel alignment", DefaultValue = VerticalAlignment.Top)]
        public VerticalAlignment PanelVerticalAlignment { get; set; }

        [Parameter("Horizontal Position", Group = "Panel alignment", DefaultValue = HorizontalAlignment.Left)]
        public HorizontalAlignment PanelHorizontalAlignment { get; set; }

        [Parameter("Default Price", Group = "Default trade parameters", DefaultValue = 1.17)]
        public double DefaultPrice { get; set; }

        [Parameter("Default Lots", Group = "Default trade parameters", DefaultValue = 0.01)]
        public double DefaultLots { get; set; }

        [Parameter("Default Fragmentation", Group = "Default trade parameters", DefaultValue = 1)]
        public double DefaultFrag { get; set; }

        [Parameter("Default Take Profit (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultTakeProfitPips { get; set; }

        [Parameter("Default Stop Loss (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultStopLossPips { get; set; }

        protected override void OnStart()
        {
            var tradingPanel = new TradingPanel(this, Symbol, DefaultPrice, DefaultFrag, DefaultLots, DefaultStopLossPips, DefaultTakeProfitPips);

            var border = new Border 
            {
                VerticalAlignment = PanelVerticalAlignment,
                HorizontalAlignment = PanelHorizontalAlignment,
                Style = Styles.CreatePanelBackgroundStyle(),
                Margin = "20 40 20 20",
                Width = 225,
                Child = tradingPanel
            };

            Chart.AddControl(border);
        }
    }

    public class TradingPanel : CustomControl
    {
        private const string LotsInputKey = "LotsKey";
        private const string PriceInputKey = "PriceKey";
        private const string FragInputKey = "FragKey";
        private const string TakeProfitInputKey = "TPKey";
        private const string StopLossInputKey = "SLKey";
        private readonly IDictionary<string, TextBox> _inputMap = new Dictionary<string, TextBox>();
        private readonly Robot _robot;
        private readonly Symbol _symbol;

        public TradingPanel(Robot robot, Symbol symbol, double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            _robot = robot;
            _symbol = symbol;
            AddChild(CreateTradingPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips));
        }

        private ControlBase CreateTradingPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var mainPanel = new StackPanel();

            var header = CreateHeader();
            mainPanel.AddChild(header);

            var contentPanel = CreateContentPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips);
            mainPanel.AddChild(contentPanel);

            return mainPanel;
        }

        private ControlBase CreateHeader()
        {
            var headerBorder = new Border 
            {
                BorderThickness = "0 0 0 1",
                Style = Styles.CreateCommonBorderStyle()
            };

            var header = new TextBlock 
            {
                Text = "Quick Trading Panel",
                Margin = "10 7",
                Style = Styles.CreateHeaderStyle()
            };

            headerBorder.Child = header;
            return headerBorder;
        }

        private StackPanel CreateContentPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var contentPanel = new StackPanel 
            {
                Margin = 10
            };
            var grid = new Grid(9, 3);
            grid.Columns[1].SetWidthInPixels(5);

            var sellmarketButton = CreateMarketTradeButton("MARKET SELL", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellmarketButton, 0, 0);

            var buymarketButton = CreateMarketTradeButton("MARKET BUY", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buymarketButton, 0, 2);

            var sellstopButton = CreateStopTradeButton("SELL STOP", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellstopButton, 1, 0);

            var buystopButton = CreateStopTradeButton("BUY STOP", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buystopButton, 1, 2);

            var selllimitButton = CreateLimitTradeButton("SELL LIMIT", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(selllimitButton, 3, 0);

            var buylimitButton = CreateLimitTradeButton("BUY LIMIT", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buylimitButton, 3, 2);

            var priceInput = CreateInputWithLabel("Pending Price", defaultPrice.ToString("F2"), PriceInputKey);
            grid.AddChild(priceInput, 4, 0);

            var fragInput = CreateInputWithLabel("Order Fragmentation", defaultFrag.ToString("F2"), FragInputKey);
            grid.AddChild(fragInput, 4, 2);

            var lotsInput = CreateInputWithLabel("Quantity (Lots)", defaultLots.ToString("F2"), LotsInputKey);
            grid.AddChild(lotsInput, 5, 0, 1, 3);

            var stopLossInput = CreateInputWithLabel("Stop Loss (Pips)", defaultStopLossPips.ToString("F1"), StopLossInputKey);
            grid.AddChild(stopLossInput, 6, 0);

            var takeProfitInput = CreateInputWithLabel("Take Profit (Pips)", defaultTakeProfitPips.ToString("F1"), TakeProfitInputKey);
            grid.AddChild(takeProfitInput, 6, 2);

            var closeAllPendingButton = CreateCloseAllPendingButton();
            grid.AddChild(closeAllPendingButton, 7, 0, 1, 3);

            var closeAllOpenButton = CreateCloseAllOpenButton();
            grid.AddChild(closeAllOpenButton, 8, 0, 1, 3);

            contentPanel.AddChild(grid);

            return contentPanel;
        }

        private Button CreateMarketTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button 
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceMarket(tradeType);

            return tradeButton;
        }

        private Button CreateStopTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button 
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceStop(tradeType);

            return tradeButton;
        }

        private Button CreateLimitTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button 
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceLimit(tradeType);

            return tradeButton;
        }

        private ControlBase CreateCloseAllPendingButton()
        {
            var closeAllBorder = new Border 
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button 
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Pending",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllPending();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private ControlBase CreateCloseAllOpenButton()
        {
            var closeAllBorder = new Border 
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button 
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Open",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllOpen();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private Panel CreateInputWithLabel(string label, string defaultValue, string inputKey)
        {
            var stackPanel = new StackPanel 
            {
                Orientation = Orientation.Vertical,
                Margin = "0 10 0 0"
            };

            var textBlock = new TextBlock 
            {
                Text = label
            };

            var input = new TextBox 
            {
                Margin = "0 5 0 0",
                Text = defaultValue,
                Style = Styles.CreateInputStyle()
            };

            _inputMap.Add(inputKey, input);

            stackPanel.AddChild(textBlock);
            stackPanel.AddChild(input);

            return stackPanel;
        }

        private void PlaceMarket(TradeType tradeType)
        {
            var _vol_usable = 0.0;
            var count = 0;
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                _vol_usable = Calc_LPT();
                var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
                var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
                var _price_usable = GetValueFromInput(PriceInputKey, 0);

                var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
                if (count != _frag)
                {
                    _robot.ExecuteMarketOrderAsync(tradeType, _symbol.Name, _volume_units, string.Empty, stopLossPips, takeProfitPips);
                    count++;
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }

        }

        private void PlaceStop(TradeType tradeType)
        {
            var _vol_usable = 0.0;
            var count = 0;
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                _vol_usable = Calc_LPT();
                var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
                var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
                var _price_usable = GetValueFromInput(PriceInputKey, 0);

                var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
                if (count != _frag)
                {
                    _robot.PlaceStopOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                    count++;
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }

        }

        private void PlaceLimit(TradeType tradeType)
        {
            var _vol_usable = 0.0;
            var count = 0;
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                _vol_usable = Calc_LPT();
                var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
                var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
                var _price_usable = GetValueFromInput(PriceInputKey, 0);

                var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
                if (count != _frag)
                {
                    _robot.PlaceLimitOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                    count++;
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }

        }

        private double Calc_LPT()
        {
            var _lots = GetValueFromInput(LotsInputKey, 0);
            var _frag = GetValueFromInput(FragInputKey, 0);
            var result = Math.Round(_lots / _frag, 2);
            return result;
        }

        private double GetValueFromInput(string inputKey, double defaultValue)
        {
            double value;

            return double.TryParse(_inputMap[inputKey].Text, out value) ? value : defaultValue;
        }

        private void CloseAllPending()
        {
            foreach (var pending in _robot.PendingOrders)
                _robot.CancelPendingOrderAsync(pending);
        }

        private void CloseAllOpen()
        {
            foreach (var position in _robot.Positions)
                _robot.ClosePositionAsync(position);
        }
    }

    public static class Styles
    {
        public static Style CreatePanelBackgroundStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.CornerRadius, 3);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#292929"), 0.85m), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.85m), ControlState.LightTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#3C3C3C"), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#C3C3C3"), ControlState.LightTheme);
            style.Set(ControlProperty.BorderThickness, new Thickness(1));

            return style;
        }

        public static Style CreateCommonBorderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.12m), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#000000"), 0.12m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateHeaderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#FFFFFF", 0.70m), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#000000", 0.65m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateInputStyle()
        {
            var style = new Style(DefaultStyles.TextBoxStyle);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#1A1A1A"), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#111111"), ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#E7EBED"), ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#D6DADC"), ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.CornerRadius, 3);
            return style;
        }

        public static Style CreateBuyButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#009345"), Color.FromHex("#10A651"));
        }

        public static Style CreateSellButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        public static Style CreateCloseButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        private static Style CreateButtonStyle(Color color, Color hoverColor)
        {
            var style = new Style(DefaultStyles.ButtonStyle);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.LightTheme);
            return style;
        }

        private static Color GetColorWithOpacity(Color baseColor, decimal opacity)
        {
            var alpha = (int)Math.Round(byte.MaxValue * opacity, MidpointRounding.AwayFromZero);
            return Color.FromArgb(alpha, baseColor);
        }
    }
}

 

Thanks in advance,

 

 

@artcfd

amusleh
07 Sep 2021, 09:21

Hi,

You should use a loop to execute multiple orders, try this:

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EasyStop : Robot
    {
        [Parameter("Vertical Position", Group = "Panel alignment", DefaultValue = VerticalAlignment.Top)]
        public VerticalAlignment PanelVerticalAlignment { get; set; }

        [Parameter("Horizontal Position", Group = "Panel alignment", DefaultValue = HorizontalAlignment.Left)]
        public HorizontalAlignment PanelHorizontalAlignment { get; set; }

        [Parameter("Default Price", Group = "Default trade parameters", DefaultValue = 1.17)]
        public double DefaultPrice { get; set; }

        [Parameter("Default Lots", Group = "Default trade parameters", DefaultValue = 0.01)]
        public double DefaultLots { get; set; }

        [Parameter("Default Fragmentation", Group = "Default trade parameters", DefaultValue = 1)]
        public double DefaultFrag { get; set; }

        [Parameter("Default Take Profit (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultTakeProfitPips { get; set; }

        [Parameter("Default Stop Loss (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultStopLossPips { get; set; }

        protected override void OnStart()
        {
            var tradingPanel = new TradingPanel(this, Symbol, DefaultPrice, DefaultFrag, DefaultLots, DefaultStopLossPips, DefaultTakeProfitPips);

            var border = new Border
            {
                VerticalAlignment = PanelVerticalAlignment,
                HorizontalAlignment = PanelHorizontalAlignment,
                Style = Styles.CreatePanelBackgroundStyle(),
                Margin = "20 40 20 20",
                Width = 225,
                Child = tradingPanel
            };

            Chart.AddControl(border);
        }
    }

    public class TradingPanel : CustomControl
    {
        private const string LotsInputKey = "LotsKey";
        private const string PriceInputKey = "PriceKey";
        private const string FragInputKey = "FragKey";
        private const string TakeProfitInputKey = "TPKey";
        private const string StopLossInputKey = "SLKey";
        private readonly IDictionary<string, TextBox> _inputMap = new Dictionary<string, TextBox>();
        private readonly Robot _robot;
        private readonly Symbol _symbol;

        public TradingPanel(Robot robot, Symbol symbol, double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            _robot = robot;
            _symbol = symbol;
            AddChild(CreateTradingPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips));
        }

        private ControlBase CreateTradingPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var mainPanel = new StackPanel();

            var header = CreateHeader();
            mainPanel.AddChild(header);

            var contentPanel = CreateContentPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips);
            mainPanel.AddChild(contentPanel);

            return mainPanel;
        }

        private ControlBase CreateHeader()
        {
            var headerBorder = new Border
            {
                BorderThickness = "0 0 0 1",
                Style = Styles.CreateCommonBorderStyle()
            };

            var header = new TextBlock
            {
                Text = "Quick Trading Panel",
                Margin = "10 7",
                Style = Styles.CreateHeaderStyle()
            };

            headerBorder.Child = header;
            return headerBorder;
        }

        private StackPanel CreateContentPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var contentPanel = new StackPanel
            {
                Margin = 10
            };
            var grid = new Grid(9, 3);
            grid.Columns[1].SetWidthInPixels(5);

            var sellmarketButton = CreateMarketTradeButton("MARKET SELL", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellmarketButton, 0, 0);

            var buymarketButton = CreateMarketTradeButton("MARKET BUY", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buymarketButton, 0, 2);

            var sellstopButton = CreateStopTradeButton("SELL STOP", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellstopButton, 1, 0);

            var buystopButton = CreateStopTradeButton("BUY STOP", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buystopButton, 1, 2);

            var selllimitButton = CreateLimitTradeButton("SELL LIMIT", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(selllimitButton, 3, 0);

            var buylimitButton = CreateLimitTradeButton("BUY LIMIT", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buylimitButton, 3, 2);

            var priceInput = CreateInputWithLabel("Pending Price", defaultPrice.ToString("F2"), PriceInputKey);
            grid.AddChild(priceInput, 4, 0);

            var fragInput = CreateInputWithLabel("Order Fragmentation", defaultFrag.ToString("F2"), FragInputKey);
            grid.AddChild(fragInput, 4, 2);

            var lotsInput = CreateInputWithLabel("Quantity (Lots)", defaultLots.ToString("F2"), LotsInputKey);
            grid.AddChild(lotsInput, 5, 0, 1, 3);

            var stopLossInput = CreateInputWithLabel("Stop Loss (Pips)", defaultStopLossPips.ToString("F1"), StopLossInputKey);
            grid.AddChild(stopLossInput, 6, 0);

            var takeProfitInput = CreateInputWithLabel("Take Profit (Pips)", defaultTakeProfitPips.ToString("F1"), TakeProfitInputKey);
            grid.AddChild(takeProfitInput, 6, 2);

            var closeAllPendingButton = CreateCloseAllPendingButton();
            grid.AddChild(closeAllPendingButton, 7, 0, 1, 3);

            var closeAllOpenButton = CreateCloseAllOpenButton();
            grid.AddChild(closeAllOpenButton, 8, 0, 1, 3);

            contentPanel.AddChild(grid);

            return contentPanel;
        }

        private Button CreateMarketTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceMarket(tradeType);

            return tradeButton;
        }

        private Button CreateStopTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceStop(tradeType);

            return tradeButton;
        }

        private Button CreateLimitTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceLimit(tradeType);

            return tradeButton;
        }

        private ControlBase CreateCloseAllPendingButton()
        {
            var closeAllBorder = new Border
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Pending",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllPending();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private ControlBase CreateCloseAllOpenButton()
        {
            var closeAllBorder = new Border
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Open",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllOpen();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private Panel CreateInputWithLabel(string label, string defaultValue, string inputKey)
        {
            var stackPanel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                Margin = "0 10 0 0"
            };

            var textBlock = new TextBlock
            {
                Text = label
            };

            var input = new TextBox
            {
                Margin = "0 5 0 0",
                Text = defaultValue,
                Style = Styles.CreateInputStyle()
            };

            _inputMap.Add(inputKey, input);

            stackPanel.AddChild(textBlock);
            stackPanel.AddChild(input);

            return stackPanel;
        }

        private void PlaceMarket(TradeType tradeType)
        {
            var _vol_usable = Calc_LPT();
            var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
            var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
            var _price_usable = GetValueFromInput(PriceInputKey, 0);

            var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
            var lots = GetValueFromInput(LotsInputKey, 0);

            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                for (int i = 0; i < _frag; i++)
                {
                    _robot.ExecuteMarketOrderAsync(tradeType, _symbol.Name, _volume_units, string.Empty, stopLossPips, takeProfitPips);
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }
        }

        private void PlaceStop(TradeType tradeType)
        {
            var _vol_usable = Calc_LPT();
            var lots = GetValueFromInput(LotsInputKey, 0);
            var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
            var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
            var _price_usable = GetValueFromInput(PriceInputKey, 0);

            var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);

            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                for (int i = 0; i < _frag; i++)
                {
                    _robot.PlaceStopOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }
        }

        private void PlaceLimit(TradeType tradeType)
        {
            var _vol_usable = Calc_LPT();
            var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
            var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
            var _price_usable = GetValueFromInput(PriceInputKey, 0);

            var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                for (int i = 0; i < _frag; i++)
                {
                    _robot.PlaceLimitOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }
        }

        private double Calc_LPT()
        {
            var _lots = GetValueFromInput(LotsInputKey, 0);
            var _frag = GetValueFromInput(FragInputKey, 0);
            var result = Math.Round(_lots / _frag, 2);
            return result;
        }

        private double GetValueFromInput(string inputKey, double defaultValue)
        {
            double value;

            return double.TryParse(_inputMap[inputKey].Text, out value) ? value : defaultValue;
        }

        private void CloseAllPending()
        {
            foreach (var pending in _robot.PendingOrders)
                _robot.CancelPendingOrderAsync(pending);
        }

        private void CloseAllOpen()
        {
            foreach (var position in _robot.Positions)
                _robot.ClosePositionAsync(position);
        }
    }

    public static class Styles
    {
        public static Style CreatePanelBackgroundStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.CornerRadius, 3);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#292929"), 0.85m), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.85m), ControlState.LightTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#3C3C3C"), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#C3C3C3"), ControlState.LightTheme);
            style.Set(ControlProperty.BorderThickness, new Thickness(1));

            return style;
        }

        public static Style CreateCommonBorderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.12m), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#000000"), 0.12m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateHeaderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#FFFFFF", 0.70m), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#000000", 0.65m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateInputStyle()
        {
            var style = new Style(DefaultStyles.TextBoxStyle);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#1A1A1A"), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#111111"), ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#E7EBED"), ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#D6DADC"), ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.CornerRadius, 3);
            return style;
        }

        public static Style CreateBuyButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#009345"), Color.FromHex("#10A651"));
        }

        public static Style CreateSellButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        public static Style CreateCloseButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        private static Style CreateButtonStyle(Color color, Color hoverColor)
        {
            var style = new Style(DefaultStyles.ButtonStyle);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.LightTheme);
            return style;
        }

        private static Color GetColorWithOpacity(Color baseColor, decimal opacity)
        {
            var alpha = (int)Math.Round(byte.MaxValue * opacity, MidpointRounding.AwayFromZero);
            return Color.FromArgb(alpha, baseColor);
        }
    }
}

 


@amusleh

waym77
08 Sep 2021, 09:56

RE:

amusleh said:

Hi,

You should use a loop to execute multiple orders, try this:

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class EasyStop : Robot
    {
        [Parameter("Vertical Position", Group = "Panel alignment", DefaultValue = VerticalAlignment.Top)]
        public VerticalAlignment PanelVerticalAlignment { get; set; }

        [Parameter("Horizontal Position", Group = "Panel alignment", DefaultValue = HorizontalAlignment.Left)]
        public HorizontalAlignment PanelHorizontalAlignment { get; set; }

        [Parameter("Default Price", Group = "Default trade parameters", DefaultValue = 1.17)]
        public double DefaultPrice { get; set; }

        [Parameter("Default Lots", Group = "Default trade parameters", DefaultValue = 0.01)]
        public double DefaultLots { get; set; }

        [Parameter("Default Fragmentation", Group = "Default trade parameters", DefaultValue = 1)]
        public double DefaultFrag { get; set; }

        [Parameter("Default Take Profit (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultTakeProfitPips { get; set; }

        [Parameter("Default Stop Loss (pips)", Group = "Default trade parameters", DefaultValue = 10)]
        public double DefaultStopLossPips { get; set; }

        protected override void OnStart()
        {
            var tradingPanel = new TradingPanel(this, Symbol, DefaultPrice, DefaultFrag, DefaultLots, DefaultStopLossPips, DefaultTakeProfitPips);

            var border = new Border
            {
                VerticalAlignment = PanelVerticalAlignment,
                HorizontalAlignment = PanelHorizontalAlignment,
                Style = Styles.CreatePanelBackgroundStyle(),
                Margin = "20 40 20 20",
                Width = 225,
                Child = tradingPanel
            };

            Chart.AddControl(border);
        }
    }

    public class TradingPanel : CustomControl
    {
        private const string LotsInputKey = "LotsKey";
        private const string PriceInputKey = "PriceKey";
        private const string FragInputKey = "FragKey";
        private const string TakeProfitInputKey = "TPKey";
        private const string StopLossInputKey = "SLKey";
        private readonly IDictionary<string, TextBox> _inputMap = new Dictionary<string, TextBox>();
        private readonly Robot _robot;
        private readonly Symbol _symbol;

        public TradingPanel(Robot robot, Symbol symbol, double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            _robot = robot;
            _symbol = symbol;
            AddChild(CreateTradingPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips));
        }

        private ControlBase CreateTradingPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var mainPanel = new StackPanel();

            var header = CreateHeader();
            mainPanel.AddChild(header);

            var contentPanel = CreateContentPanel(defaultPrice, defaultFrag, defaultLots, defaultStopLossPips, defaultTakeProfitPips);
            mainPanel.AddChild(contentPanel);

            return mainPanel;
        }

        private ControlBase CreateHeader()
        {
            var headerBorder = new Border
            {
                BorderThickness = "0 0 0 1",
                Style = Styles.CreateCommonBorderStyle()
            };

            var header = new TextBlock
            {
                Text = "Quick Trading Panel",
                Margin = "10 7",
                Style = Styles.CreateHeaderStyle()
            };

            headerBorder.Child = header;
            return headerBorder;
        }

        private StackPanel CreateContentPanel(double defaultPrice, double defaultFrag, double defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var contentPanel = new StackPanel
            {
                Margin = 10
            };
            var grid = new Grid(9, 3);
            grid.Columns[1].SetWidthInPixels(5);

            var sellmarketButton = CreateMarketTradeButton("MARKET SELL", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellmarketButton, 0, 0);

            var buymarketButton = CreateMarketTradeButton("MARKET BUY", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buymarketButton, 0, 2);

            var sellstopButton = CreateStopTradeButton("SELL STOP", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellstopButton, 1, 0);

            var buystopButton = CreateStopTradeButton("BUY STOP", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buystopButton, 1, 2);

            var selllimitButton = CreateLimitTradeButton("SELL LIMIT", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(selllimitButton, 3, 0);

            var buylimitButton = CreateLimitTradeButton("BUY LIMIT", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buylimitButton, 3, 2);

            var priceInput = CreateInputWithLabel("Pending Price", defaultPrice.ToString("F2"), PriceInputKey);
            grid.AddChild(priceInput, 4, 0);

            var fragInput = CreateInputWithLabel("Order Fragmentation", defaultFrag.ToString("F2"), FragInputKey);
            grid.AddChild(fragInput, 4, 2);

            var lotsInput = CreateInputWithLabel("Quantity (Lots)", defaultLots.ToString("F2"), LotsInputKey);
            grid.AddChild(lotsInput, 5, 0, 1, 3);

            var stopLossInput = CreateInputWithLabel("Stop Loss (Pips)", defaultStopLossPips.ToString("F1"), StopLossInputKey);
            grid.AddChild(stopLossInput, 6, 0);

            var takeProfitInput = CreateInputWithLabel("Take Profit (Pips)", defaultTakeProfitPips.ToString("F1"), TakeProfitInputKey);
            grid.AddChild(takeProfitInput, 6, 2);

            var closeAllPendingButton = CreateCloseAllPendingButton();
            grid.AddChild(closeAllPendingButton, 7, 0, 1, 3);

            var closeAllOpenButton = CreateCloseAllOpenButton();
            grid.AddChild(closeAllOpenButton, 8, 0, 1, 3);

            contentPanel.AddChild(grid);

            return contentPanel;
        }

        private Button CreateMarketTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceMarket(tradeType);

            return tradeButton;
        }

        private Button CreateStopTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceStop(tradeType);

            return tradeButton;
        }

        private Button CreateLimitTradeButton(string text, Style style, TradeType tradeType)
        {
            var tradeButton = new Button
            {
                Text = text,
                Style = style,
                Height = 25
            };

            tradeButton.Click += args => PlaceLimit(tradeType);

            return tradeButton;
        }

        private ControlBase CreateCloseAllPendingButton()
        {
            var closeAllBorder = new Border
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Pending",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllPending();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private ControlBase CreateCloseAllOpenButton()
        {
            var closeAllBorder = new Border
            {
                Margin = "0 10 0 0",
                BorderThickness = "0 1 0 0",
                Style = Styles.CreateCommonBorderStyle()
            };

            var closeButton = new Button
            {
                Style = Styles.CreateCloseButtonStyle(),
                Text = "Close All Open",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAllOpen();
            closeAllBorder.Child = closeButton;

            return closeAllBorder;
        }

        private Panel CreateInputWithLabel(string label, string defaultValue, string inputKey)
        {
            var stackPanel = new StackPanel
            {
                Orientation = Orientation.Vertical,
                Margin = "0 10 0 0"
            };

            var textBlock = new TextBlock
            {
                Text = label
            };

            var input = new TextBox
            {
                Margin = "0 5 0 0",
                Text = defaultValue,
                Style = Styles.CreateInputStyle()
            };

            _inputMap.Add(inputKey, input);

            stackPanel.AddChild(textBlock);
            stackPanel.AddChild(input);

            return stackPanel;
        }

        private void PlaceMarket(TradeType tradeType)
        {
            var _vol_usable = Calc_LPT();
            var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
            var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
            var _price_usable = GetValueFromInput(PriceInputKey, 0);

            var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
            var lots = GetValueFromInput(LotsInputKey, 0);

            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                for (int i = 0; i < _frag; i++)
                {
                    _robot.ExecuteMarketOrderAsync(tradeType, _symbol.Name, _volume_units, string.Empty, stopLossPips, takeProfitPips);
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }
        }

        private void PlaceStop(TradeType tradeType)
        {
            var _vol_usable = Calc_LPT();
            var lots = GetValueFromInput(LotsInputKey, 0);
            var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
            var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
            var _price_usable = GetValueFromInput(PriceInputKey, 0);

            var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);

            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                for (int i = 0; i < _frag; i++)
                {
                    _robot.PlaceStopOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }
        }

        private void PlaceLimit(TradeType tradeType)
        {
            var _vol_usable = Calc_LPT();
            var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
            var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);
            var _price_usable = GetValueFromInput(PriceInputKey, 0);

            var _volume_units = _symbol.QuantityToVolumeInUnits(_vol_usable);
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var _frag = GetValueFromInput(FragInputKey, 0);
            if (_frag >= 1)
            {
                for (int i = 0; i < _frag; i++)
                {
                    _robot.PlaceLimitOrderAsync(tradeType, _symbol.Name, _volume_units, _price_usable, string.Empty, stopLossPips, takeProfitPips, null);
                }
            }
            else if (_frag < 1)
            {
                _robot.Print(string.Format("{0} failed, invalid Frag", tradeType));
                return;
            }
        }

        private double Calc_LPT()
        {
            var _lots = GetValueFromInput(LotsInputKey, 0);
            var _frag = GetValueFromInput(FragInputKey, 0);
            var result = Math.Round(_lots / _frag, 2);
            return result;
        }

        private double GetValueFromInput(string inputKey, double defaultValue)
        {
            double value;

            return double.TryParse(_inputMap[inputKey].Text, out value) ? value : defaultValue;
        }

        private void CloseAllPending()
        {
            foreach (var pending in _robot.PendingOrders)
                _robot.CancelPendingOrderAsync(pending);
        }

        private void CloseAllOpen()
        {
            foreach (var position in _robot.Positions)
                _robot.ClosePositionAsync(position);
        }
    }

    public static class Styles
    {
        public static Style CreatePanelBackgroundStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.CornerRadius, 3);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#292929"), 0.85m), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.85m), ControlState.LightTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#3C3C3C"), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, Color.FromHex("#C3C3C3"), ControlState.LightTheme);
            style.Set(ControlProperty.BorderThickness, new Thickness(1));

            return style;
        }

        public static Style CreateCommonBorderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#FFFFFF"), 0.12m), ControlState.DarkTheme);
            style.Set(ControlProperty.BorderColor, GetColorWithOpacity(Color.FromHex("#000000"), 0.12m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateHeaderStyle()
        {
            var style = new Style();
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#FFFFFF", 0.70m), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, GetColorWithOpacity("#000000", 0.65m), ControlState.LightTheme);
            return style;
        }

        public static Style CreateInputStyle()
        {
            var style = new Style(DefaultStyles.TextBoxStyle);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#1A1A1A"), ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#111111"), ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#E7EBED"), ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, Color.FromHex("#D6DADC"), ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.CornerRadius, 3);
            return style;
        }

        public static Style CreateBuyButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#009345"), Color.FromHex("#10A651"));
        }

        public static Style CreateSellButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        public static Style CreateCloseButtonStyle()
        {
            return CreateButtonStyle(Color.FromHex("#F05824"), Color.FromHex("#FF6C36"));
        }

        private static Style CreateButtonStyle(Color color, Color hoverColor)
        {
            var style = new Style(DefaultStyles.ButtonStyle);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.DarkTheme);
            style.Set(ControlProperty.BackgroundColor, color, ControlState.LightTheme);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.DarkTheme | ControlState.Hover);
            style.Set(ControlProperty.BackgroundColor, hoverColor, ControlState.LightTheme | ControlState.Hover);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.DarkTheme);
            style.Set(ControlProperty.ForegroundColor, Color.FromHex("#FFFFFF"), ControlState.LightTheme);
            return style;
        }

        private static Color GetColorWithOpacity(Color baseColor, decimal opacity)
        {
            var alpha = (int)Math.Round(byte.MaxValue * opacity, MidpointRounding.AwayFromZero);
            return Color.FromArgb(alpha, baseColor);
        }
    }
}

 

Hi amusleh,

 

That's brilliant, thank you so much!

 

If you wouldn't mind, I have another thread regarding something new I'm trying in this same bot: 

 


@waym77