Topics

Forum Topics not found

Replies

amusleh
06 Dec 2021, 08:46

RE: RE:

xiao-linlong said:

PanagiotisCharalampous said:Hi Panagiotis

Hi xiao-linlong,

When I use Stop Loss/Limit to place an order, it cannot be placed on top of other orders or alarms, and the system "Quicktrade" button can be achieved by just pressing and dragging to any place I want to reach and then letting go

This is not true. You can place your orders using drag and drop wherever you want. Existing orders and price alerts do not affect you.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Can I use the events currently provided to create the same actions as the "Quicktrade" button? When I place a stop loss/limit order, can I put it on top of other orders or alerts?

bestregards,Thanks。

Hi,

Yes, you can, but there will be an issue with your order placement going over other order lines or price alert lines, for that you have to use mouse enter/leave events to capture the last position of mouse cursor.


@amusleh

amusleh
04 Dec 2021, 18:02

RE: RE: RE: RE:

xiao-linlong said:

amusleh said:What you mean is that if the mouse moves over the alert, order or pending order price or its stop loss and take profit lines, the mouse event will be cancelled.
What I want is to be able to press the "Prepare button" and then click on the chart to place a "Stop Loss/Limit" order.
Can you tell me if there is a solution? grateful.

xiao-linlong said:

amusleh said:

Hi,

The order and price alert lines are under chart and the mouse events will not work while cursor is over them.

You can use Chart mouse leave and enter events to get the latest cursor position, if you move mouse over these lines the chart mouse leave event will be triggered and when you move back to other areas of chart the mouse enter event will be triggered.

Mr. amusleh, is there any event to ignore the order and price alert line? Or is it possible to open the drag and drop so that it solves the problem perfectly, looking forward to the reply, thanks.

Hi,

As I said on my previous post, you can use Chart mouse enter/leave events, when cursor goes over those lines the mouse leave event will be trigged and when it goes back to other parts of chart the mouse enter event will be triggered.

 

Hi,

Can't you use the latest location of mouse before mouse enter/leave event?


@amusleh

amusleh
03 Dec 2021, 08:37

Hi,

Try this:

using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ExponentialMovingAverageSample : Robot
    {
        private ExponentialMovingAverage _ema;

        protected override void OnStart()
        {
            _ema = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 20);
        }
        protected override void OnBar()
        {
            // This variable will have the cross price if there was any
            double maCrossPoint = double.NaN;
            
            // Bar close price crosses MA upward
            if (Bars.ClosePrices.Last(1) > _ema.Result.Last(1) && Bars.ClosePrices.Last(2) < _ema.Result.Last(2))
            {
                maCrossPoint = _ema.Result.Last(1);
            }
            // Bar close price crosses MA downward
            else if (Bars.ClosePrices.Last(1) < _ema.Result.Last(1) && Bars.ClosePrices.Last(2) > _ema.Result.Last(2))
            {
                maCrossPoint = _ema.Result.Last(1);
            }
        }
    }
}

 


@amusleh

amusleh
03 Dec 2021, 08:32

Hi,

Use C# Try/Catch block and log the exception by using cTrader Print method.


@amusleh

amusleh
03 Dec 2021, 08:27

RE: RE:

xiao-linlong said:

amusleh said:

Hi,

The order and price alert lines are under chart and the mouse events will not work while cursor is over them.

You can use Chart mouse leave and enter events to get the latest cursor position, if you move mouse over these lines the chart mouse leave event will be triggered and when you move back to other areas of chart the mouse enter event will be triggered.

Mr. amusleh, is there any event to ignore the order and price alert line? Or is it possible to open the drag and drop so that it solves the problem perfectly, looking forward to the reply, thanks.

Hi,

As I said on my previous post, you can use Chart mouse enter/leave events, when cursor goes over those lines the mouse leave event will be trigged and when it goes back to other parts of chart the mouse enter event will be triggered.


@amusleh

amusleh
02 Dec 2021, 14:02

RE: RE:

ncel01 said:

Hi amusleh,

 

I forgot to mention but the currencies involved will be only EUR and USD.

In such a case, can Symbol.TickValue/Symbol.TickSize be used to get the conversion ratio symbol/account currency? Is this correct?

How to get symbol currency? The equivalent to the account currency given by Account.Asset.Name but for a symbol?

 

Thank you!

 

amusleh said:

Hi,

Right now you can't convert all symbols involved currency values to your account currency as the symbols currency conversion chain is not available on automate API.

You can do it for Forex symbols, by splitting the symbol manually into base and quote currencies, but this will not work for other symbols.

The only option for now is to use Open API which has this data.

You can also open a thread on suggestion section for this feature to be added on Automate API.

 

Hi,

Yes, you can use Symbol.TickValue, but as I said it will only work for some of the symbols not all symbols.

To convert one symbol TickValue to another currency you need the symbol conversion chain which is not available right now on Automate API.

 


@amusleh

amusleh
02 Dec 2021, 09:50

RE: RE: RE: RE: RE: RE: RE: RE:

yuval.ein said:

OK so how can I prevent from running code inside OnTick after disconnection?

 

Hi,

You can guard your code by using the Server.IsConnected property like I said before.


@amusleh

amusleh
02 Dec 2021, 08:52

Hi,

You can just pass the Position current parameters and provide new value only for those parameters that you want to change.

For ex:

        protected override void OnTick()
        {
            var position = Positions.First();

            var newStopLossValue = 1.23423;
            // Here I just modify the stop loss
            ModifyPositionAsync(position, newStopLossValue, position.TakeProfit);
        }

 


@amusleh

amusleh
02 Dec 2021, 08:49

Hi,

Right now you can't convert all symbols involved currency values to your account currency as the symbols currency conversion chain is not available on automate API.

You can do it for Forex symbols, by splitting the symbol manually into base and quote currencies, but this will not work for other symbols.

The only option for now is to use Open API which has this data.

You can also open a thread on suggestion section for this feature to be added on Automate API.


@amusleh

amusleh
02 Dec 2021, 08:47

Hi,

There is no limit on number of symbols you can subscribe to, but the limits are on number of requests you can make per second and number of active connections your application has with API.

Please check here for API limitation: Protocol Buffers - Open API (spotware.github.io)


@amusleh

amusleh
02 Dec 2021, 08:45

RE: RE: RE: RE: RE: RE:

yuval.ein said:

 

Please view the "DISCONNECTED" errors I got below. I can upload the entire logf but i'm not sure how to upload files to the forum.

They happened during a simple 'ModifyStopLossPrice' which always works fine, including on the day of the errors, until the errors occured.

 

2021.11.30 16:02:17.920 | Request to amend position PID64902077 (SL: 1.49319) is sent to server
2021.11.30 16:02:19.186 | Request to amend position PID64919920 (SL: 1577.54) is sent to server
2021.11.30 16:02:21.202 | Request to Buy 0.01 Lots SpotCrude is sent to server
2021.11.30 16:02:22.137 | → Request to amend position PID64902077 (SL: 1.49319) is REJECTED with error "DISCONNECTED"
2021.11.30 16:02:22.146 | → Request to amend position PID64919920 (SL: 1577.54) is REJECTED with error "DISCONNECTED"
2021.11.30 16:02:22.211 | → Order OID0 is REJECTED with error "DISCONNECTED"
2021.11.30 16:02:22.315 | Request to close position PID64902077 is sent to server
2021.11.30 16:02:22.362 | → Failed to close position PID64902077 with error "DISCONNECTED"
2021.11.30 16:02:22.365 | Request to close position PID64919920 is sent to server
2021.11.30 16:02:22.376 | → Failed to close position PID64919920 with error "DISCONNECTED"
2021.11.30 16:02:23.651 | cBot "Main" was stopped for SpotCrude, Ra1.
2021.11.30 16:02:28.941 | Request to close position PID64902077 is sent to server
2021.11.30 16:02:29.109 | → Request to close position PID64902077 is ACCEPTED, order OID101746508 created (30/11/2021 16:02:29.028 UTC+0)
2021.11.30 16:02:29.420 | → Order OID101746508 is FILLED at 1.48182, position PID64902077 closed (30/11/2021 16:02:29.059 UTC+0)
2021.11.30 16:02:29.597 | cBot "Main" was stopped for CHFSGD, Ra1.
2021.11.30 16:12:40.758 | cBot "Main" was stopped for XAUEUR, Ra1.
2021.11.30 16:38:17.105 | cTrader started

 

 

Hi,

It looks like cTrader got disconnected while your cBot code was running, and all the code commands failed as cTrader was disconnected.

So you were already inside OnTick, it wasn't called after disconnection, it was called while cTrader was connected and while it was executing cTrader got disconnected.


@amusleh

amusleh
01 Dec 2021, 12:37

RE: RE: RE: RE:

yuval.ein said:

I want to show you the error. Does the journal is saved to somewhere?

 

Hi,

You can post the cTrader logs for your cBot and if possible the portion of your cBot code that can replicate this issue.


@amusleh

amusleh
01 Dec 2021, 10:32

RE: RE:

yuval.ein said:

OK but how is it possible that the OnTick method was even running while the cBot is disconnected?

 

Thanks

 

It's not possible, if your platform is not connected then there will be no new tick data and the OnTick method will not be called.


@amusleh

amusleh
01 Dec 2021, 10:31

RE: RE:

sue.bugg said:

amusleh said:

Hi,

You can limit the number of orders your cBot opens programmatically, there are lots of different ways you can do such a thing with code.

Use Positions opened/closed events and when a position got opened by your cBot you can put your cBot on a sleep mode by using a boolean flag until the position is closed.

Hi Amusleh

Thank you for the information. The cBot already goes to sleep once a position is opened. It awakens once the position is closed, if still in the trading time frame. Most losses occur much quicker than a profit. If it closes in a Loss before the 1.5 hours is up (the set trading times), it will take another trade if triggered (all parameters of cBot met). I don't want it to take another trade. Just one trade per asset in total for the trading period. So, once a postion is opened, I want it to go to sleep, turn off, stop completely until I manually turn it back on again the next trading day. Does that make sense?

Thanks

Sue

Hi,

You can code this behavior easily, you can limit your cBot to not open more than one trade during specific time period.

If you know how to code then you can do it easily, otherwise you can post your cBot code and I will help or you can post a job request or ask our consultants to do it for you.


@amusleh

amusleh
01 Dec 2021, 09:47

Hi,

You can use properties for your buttons and then you will be able to access them from class instance and do whatever you want to with them.

Try this (Change the OnTick if conditions):

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TESTPOS_Original : Robot
    {
        private TradingPanel _tradingPanel;

        [Parameter("Trading Direction Short", Group = "Trading Direction", DefaultValue = false)]
        public static bool ShortsEnabled { get; set; }

        [Parameter("Trading Direction Long", Group = "Trading Direction", DefaultValue = false)]
        public static bool LongsEnabled { get; set; }

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

        protected override void OnStart()
        {
            _tradingPanel = new TradingPanel(this, Symbol);

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

            Chart.AddControl(border);
        }

        protected override void OnTick()
        {
            if (x > y)
            {
                _tradingPanel.SToggleButton.IsChecked = true;
            }

            if (y > x)
            {
                _tradingPanel.LToggleButton.IsChecked = true;
            }
        }

        protected override void OnStop()
        {
        }

        public class TradingPanel : CustomControl
        {
            private readonly IDictionary<string, TextBox> _inputMap = new Dictionary<string, TextBox>();
            private readonly Robot _robot;
            private readonly Symbol _symbol;

            public TradingPanel(Robot robot, Symbol symbol)
            {
                _robot = robot;
                _symbol = symbol;
                AddChild(CreateTradingPanel());
            }

            public ToggleButton SToggleButton { get; private set; }

            public ToggleButton LToggleButton { get; private set; }

            private ControlBase CreateTradingPanel()
            {
                var mainPanel = new StackPanel();

                var contentPanel = CreateContentPanel();
                mainPanel.AddChild(contentPanel);

                return mainPanel;
            }

            private StackPanel CreateContentPanel()
            {
                var contentPanel = new StackPanel
                {
                    Margin = 10
                };
                var grid = new Grid(4, 3);
                grid.Columns[1].SetWidthInPixels(5);

                SToggleButton = new ToggleButton
                {
                    Text = "SHORT - AWAITING INPUT",
                    Margin = 10,
                    Style = Styles.TradeOFF()
                };
                SToggleButton.Checked += SToggleButton_Checked;
                SToggleButton.Unchecked += SToggleButton_Unchecked;
                contentPanel.AddChild(SToggleButton);

                LToggleButton = new ToggleButton
                {
                    Text = "LONG - AWAITING INPUT",
                    Margin = 10,
                    Style = Styles.TradeOFF()
                };
                LToggleButton.Checked += LToggleButton_Checked;
                LToggleButton.Unchecked += LToggleButton_Unchecked;
                contentPanel.AddChild(LToggleButton);

                contentPanel.AddChild(grid);
                return contentPanel;
            }

            public static void SToggleButton_Checked(ToggleButtonEventArgs obj)
            {
                //_robot.ExecuteMarketOrder(TradeType.Sell, _symbol.Name, 1000);
                obj.ToggleButton.Text = ("SHORT POSITIONS ON");
                obj.ToggleButton.Style = Styles.ShortON();
                ShortsEnabled = true;
            }

            public static void SToggleButton_Unchecked(ToggleButtonEventArgs obj)
            {
                obj.ToggleButton.Text = ("SHORT POSITIONS OFF");
                obj.ToggleButton.Style = Styles.TradeOFF();
                ShortsEnabled = false;
            }

            public static void LToggleButton_Checked(ToggleButtonEventArgs obj)
            {
                //_robot.ExecuteMarketOrder(TradeType.Buy, _symbol.Name, 1000);
                obj.ToggleButton.Text = ("LONG POSITIONS ON");
                obj.ToggleButton.Style = Styles.LongON();
                LongsEnabled = true;
            }

            public static void LToggleButton_Unchecked(ToggleButtonEventArgs obj)
            {
                obj.ToggleButton.Text = ("LONG POSITIONS OFF");
                obj.ToggleButton.Style = Styles.TradeOFF();
                LongsEnabled = false;
            }
        }

        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 TradeOFF()
            {
                var style = new Style();
                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 LongON()
            {
                var style = new Style();
                style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#009345"), 0.85m), ControlState.DarkTheme);
                style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#009345"), 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 ShortON()
            {
                var style = new Style();
                style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#F05824"), 0.85m), ControlState.DarkTheme);
                style.Set(ControlProperty.BackgroundColor, GetColorWithOpacity(Color.FromHex("#F05824"), 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;
            }

            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, color, ControlState.DarkTheme);
                style.Set(ControlProperty.BackgroundColor, color, ControlState.LightTheme);
                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

amusleh
01 Dec 2021, 09:38

Hi,

You can limit the number of orders your cBot opens programmatically, there are lots of different ways you can do such a thing with code.

Use Positions opened/closed events and when a position got opened by your cBot you can put your cBot on a sleep mode by using a boolean flag until the position is closed.


@amusleh

amusleh
01 Dec 2021, 09:34

Hi,

You can use Server Connected and Disconnected events or IsConnected property: cAlgo API Reference - IServer Interface (ctrader.com)


@amusleh

amusleh
29 Nov 2021, 15:38

Hi,

The order and price alert lines are under chart and the mouse events will not work while cursor is over them.

You can use Chart mouse leave and enter events to get the latest cursor position, if you move mouse over these lines the chart mouse leave event will be triggered and when you move back to other areas of chart the mouse enter event will be triggered.


@amusleh

amusleh
29 Nov 2021, 14:47

Hi,

Your cBot will always be linked to a symbol which is the current chart symbol.

You  can ignore the OnTick/OnBar and use any symbol BarOpened or Tick event you want to.


@amusleh