Replies

newbee
23 Oct 2023, 08:04

RE: Executing Orders

PanagiotisChar said: 

Hi,

No it cannot. Only cBots can execute trading operations

Thank you PanagiotisChar.

Regards


@newbee

newbee
20 Oct 2023, 09:54 ( Updated at: 21 Oct 2023, 06:57 )

RE: combobox.SelectedItemChanged

amusleh said: 

Hi,

This works fine for me on 4.6.2 and .NET 6:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;namespace cAlgo{    [Indicator(AccessRights = AccessRights.None)]    public class ComboBoxTest : Indicator    {        private ComboBox myDropList;        protected override void Initialize()        {            myDropList = new ComboBox            {                   Width = 100,                Height = 20,                HorizontalContentAlignment = HorizontalAlignment.Center,                VerticalContentAlignment = VerticalAlignment.Center            };                        myDropList.AddItem("Item 1");            myDropList.AddItem("Item 2");            myDropList.AddItem("Item 3");                        Chart.AddControl(myDropList);                        myDropList.SelectedItemChanged += myDropList_SelectedIndexChanged;        }                private void myDropList_SelectedIndexChanged(ComboBoxSelectedItemChangedEventArgs e)        {            if (myDropList.SelectedIndex != -1)            {                string selectedValue = myDropList.SelectedItem.ToString();                switch (selectedValue)                {                    case "Item 1":                        Print("Item 1 selected");                        break;                    case "Item 2":                        Print("Item 2 selected");                        break;                    case "Item 3":                        Print("Item 3 selected");                        break;                    default:                        MessageBox.Show("The selected item was not recognized. Please contact the developer for assistance. Telegram: @DelFonseca");                        break;                }            }            else            {                MessageBox.Show("Please select an item from the dropdown list.");            }        }        public override void Calculate(int index)        {            //...        }    }}

 

Check event signature before using it: SelectedItemChanged Event - cTrader Automate API

Hello again amusleh,

Further to my query earlier today please ignore it. I've actually got closer to working in out for myself. thank you anyway.

 May be one general question please. with the trading panel can we make it Interactive instead of static. (like IsInteractive = true?)

thank you


@newbee

newbee
20 Oct 2023, 02:12 ( Updated at: 20 Oct 2023, 05:18 )

RE: combobox.SelectedItemChanged

amusleh said: 

Hi,

This works fine for me on 4.6.2 and .NET 6:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;namespace cAlgo{    [Indicator(AccessRights = AccessRights.None)]    public class ComboBoxTest : Indicator    {        private ComboBox myDropList;        protected override void Initialize()        {            myDropList = new ComboBox            {                   Width = 100,                Height = 20,                HorizontalContentAlignment = HorizontalAlignment.Center,                VerticalContentAlignment = VerticalAlignment.Center            };                        myDropList.AddItem("Item 1");            myDropList.AddItem("Item 2");            myDropList.AddItem("Item 3");                        Chart.AddControl(myDropList);                        myDropList.SelectedItemChanged += myDropList_SelectedIndexChanged;        }                private void myDropList_SelectedIndexChanged(ComboBoxSelectedItemChangedEventArgs e)        {            if (myDropList.SelectedIndex != -1)            {                string selectedValue = myDropList.SelectedItem.ToString();                switch (selectedValue)                {                    case "Item 1":                        Print("Item 1 selected");                        break;                    case "Item 2":                        Print("Item 2 selected");                        break;                    case "Item 3":                        Print("Item 3 selected");                        break;                    default:                        MessageBox.Show("The selected item was not recognized. Please contact the developer for assistance. Telegram: @DelFonseca");                        break;                }            }            else            {                MessageBox.Show("Please select an item from the dropdown list.");            }        }        public override void Calculate(int index)        {            //...        }    }}

 

Check event signature before using it: SelectedItemChanged Event - cTrader Automate API

Hello amusleh,

You helped resolve a query with ComboBox's not so long ago, (found here https://ctrader.com/forum/calgo-support/40141) and I was hoping you may be able to help me too. I've been trying to add a this ComboBox to the SampleTradePanel for some time now but unfortunately have not been able to work it out. 

Are you able to help me with a sample code showing how to add this combobox to the SampleTradingPanel. If we just replaced the “close all button” with this ComboBox please.

Below is the code from the SampleTradePanel

Any assistance would be greatly appreciated. Thank you

 

Following is the Sample trade Panel:

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleTradingPanel : 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 Lots", Group = "Default trade parameters", DefaultValue = 0.01)]
        public double DefaultLots { get; set; }

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

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

        protected override void OnStart()
        {
            var tradingPanel = new TradingPanel(this, Symbol, 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 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 defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            _robot = robot;
            _symbol = symbol;
            AddChild(CreateTradingPanel(defaultLots, defaultStopLossPips, defaultTakeProfitPips));
        }

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

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

            var contentPanel = CreateContentPanel(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 defaultLots, double defaultStopLossPips, double defaultTakeProfitPips)
        {
            var contentPanel = new StackPanel 
            {
                Margin = 10
            };
            var grid = new Grid(4, 3);
            grid.Columns[1].SetWidthInPixels(5);

            var sellButton = CreateTradeButton("SELL", Styles.CreateSellButtonStyle(), TradeType.Sell);
            grid.AddChild(sellButton, 0, 0);

            var buyButton = CreateTradeButton("BUY", Styles.CreateBuyButtonStyle(), TradeType.Buy);
            grid.AddChild(buyButton, 0, 2);

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

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

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

            var closeAllButton = CreateCloseAllButton();
            grid.AddChild(closeAllButton, 3, 0, 1, 3);

            contentPanel.AddChild(grid);

            return contentPanel;
        }

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

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

            return tradeButton;
        }

        private ControlBase CreateCloseAllButton()
        {
            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",
                Margin = "0 10 0 0"
            };

            closeButton.Click += args => CloseAll();
            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 ExecuteMarketOrderAsync(TradeType tradeType)
        {
            var lots = GetValueFromInput(LotsInputKey, 0);
            if (lots <= 0)
            {
                _robot.Print(string.Format("{0} failed, invalid Lots", tradeType));
                return;
            }

            var stopLossPips = GetValueFromInput(StopLossInputKey, 0);
            var takeProfitPips = GetValueFromInput(TakeProfitInputKey, 0);

            _robot.Print(string.Format("Open position with: LotsParameter: {0}, StopLossPipsParameter: {1}, TakeProfitPipsParameter: {2}", lots, stopLossPips, takeProfitPips));

            var volume = _symbol.QuantityToVolumeInUnits(lots);
            _robot.ExecuteMarketOrderAsync(tradeType, _symbol.Name, volume, "Trade Panel Sample", stopLossPips, takeProfitPips);
        }

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

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

        private void CloseAll()
        {
            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);
        }
    }
}


@newbee

newbee
06 Apr 2023, 17:08

RE:

Hello Panagiotis,

Perfect, thank you very much.

 


@newbee

newbee
05 Apr 2023, 13:15

RE:

PanagiotisCharalampous said:

Hi MongolTrader,

Instead of passing a Robot object to the Init() method, try passing a TestMulti object.

Aieden Technologies

Need help? Join us on Telegram

Need premium support? Trade with us

 

Hello Panagiotis,

Thank you for this. It is newbee here.

I've been trying to do what you suggested since you sent me this answer but unfortunately to no avail. I simply don't know how to do that. Can you please give me a sample of how to pass a TestMulti object.

Thank you again.


@newbee

newbee
05 Apr 2023, 07:49

RE: Multi Symbol cbot & Paramaters

Hello Panagiotis,

Attached below is a sample of a multi symbol cbot I found which I believe was at (downhttps://ctrader.com/forum/calgo-support/22633) however, this link is no longer available.

It is excellent and I have been adding to this code however I am stuck when adding a Parameters as I can't get it to read the parameter. For example:

Say I wanted to add a Parameter for the "Periods" that will be used for the RSI indicator (which is sitting in the "public void init(Robot bot, string symbol)")

[Parameter("RSI Period", DefaultValue = 14)]

public int period { get; set; }

Or another example would be a parameter to set a "Max Number" of trades & pass this through to "void OnBarOpened(BarOpenedEventArgs obj)" section

[Parameter("Max Open Trades", DefaultValue = 10)]

 public double MaxPositionsAllowedPerSymbol { get; set; }

When I do, for some reason they simply aren't available to utilize or pass through to the RSI indicator sitting in the "public void init(Robot bot, string symbol)" etc.

I know I'm missing something, but I just can't seem to find what that is. I've been trying for weeks. Any assistance sample would be greatly appreciated.

Thank you!

 

Code sample below

 

using System;

using System.Linq;

using System.Collections.Generic;

using cAlgo.API;

using cAlgo.API.Indicators;

using cAlgo.API.Internals;

using cAlgo.Indicators;

namespace cAlgo.Robots

{

    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]

    public class TestMulti : Robot

    {

        // Multi symbol bot test

        string[] symbols =

        {

           "AUDCAD",

            "AUDCHF",

            "EURUSD",

            "CHFJPY"

            "EURUSD",

        };

        List<RSI_Strategy> strategies = new List<RSI_Strategy>();

        protected override void OnStart()

        {

            foreach (var sym in symbols)

            {

                var rsiStrategy = new RSI_Strategy();

                rsiStrategy.init(this, sym);

                strategies.Add(rsiStrategy);

            }

        }

    }

    // Sell when RSI crosses above 70

    public class RSI_Strategy

    {

        RelativeStrengthIndex rsi;

        Robot bot;

        string symbol;

        public void init(Robot bot, string symbol)

        {

            this.symbol = symbol;

            this.bot = bot;

            Bars bars = bot.MarketData.GetBars(bot.TimeFrame, symbol);

            rsi = bot.Indicators.RelativeStrengthIndex(bars.ClosePrices, 14);

            bars.BarOpened += OnBarOpened;

        }

        void OnBarOpened(BarOpenedEventArgs obj)

        {

            if (rsi.Result.Last(1) > 70 && rsi.Result.Last(2) <= 70)

            {

                bot.ExecuteMarketOrder(TradeType.Sell, symbol, 10000, symbol, 10.0, 10.0);

            }

            if (rsi.Result.Last(1) < 30 && rsi.Result.Last(2) >= 30)

            {

                bot.ExecuteMarketOrder(TradeType.Buy, symbol, 10000, symbol, 10.0, 10.0);

            }

        }

    }

}


@newbee

newbee
30 Mar 2022, 11:13

Thank you

Thanks amusleh. Thanks for clarifying this and the lesson/note on how it works. Looks good and makes more sense now. I will play around with it. Thanks again 


@newbee

newbee
30 Mar 2022, 01:51

RE: Hello again Amusleh. Been trying to work it out but failed. Don't know how to get the X1 & X2. Here is what I did can you please assist me further thanks.

 private double GetAngle(int x1, double y1, int x2, double y2)
        {
            double xDiff = x2 - x1;
            var yDiff = ema20.Result.Last(2) - ema20.Result.Last(1);

            return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
        }


@newbee

newbee
30 Mar 2022, 01:47

RE: Hello again Amusleh. Been trying to work it out but failed. Don't know how to ge the X1 & X2. Here is what I did can you please assist me further thanks. private double GetAngle(int x1, double y1, int x2, double y2) { double xDiff

amusleh said:

Hi,

No, you can't get the angle from API, but you can calculate it if you want to:

        private double GetAngle(ChartTrendLine trendLine)
        {
            var x1 = Bars.OpenTimes.GetIndexByTime(trendLine.Time1);
            var x2= Bars.OpenTimes.GetIndexByTime(trendLine.Time2);

            double xDiff = x2 - x1;
            var yDiff = trendLine.Y2 - trendLine.Y1;

            return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
        }

The above method will return the angle of a trend line in Degree, it will not work properly if your trend line is drawn in future time, because it uses bar indices for x axis.

If you to get the angle from API then please open a thread on forum suggestions section.

 


@newbee

newbee
28 Mar 2022, 04:56

RE: Hello amusleh. Thank you for this. Can you please help me understand how to get this value to use in a cbot. Also can this be used to find the Angle of the EMA instead of a trendline. thank you

amusleh said:

Hi,

No, you can't get the angle from API, but you can calculate it if you want to:

        private double GetAngle(ChartTrendLine trendLine)
        {
            var x1 = Bars.OpenTimes.GetIndexByTime(trendLine.Time1);
            var x2= Bars.OpenTimes.GetIndexByTime(trendLine.Time2);

            double xDiff = x2 - x1;
            var yDiff = trendLine.Y2 - trendLine.Y1;

            return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
        }

The above method will return the angle of a trend line in Degree, it will not work properly if your trend line is drawn in future time, because it uses bar indices for x axis.

If you to get the angle from API then please open a thread on forum suggestions section.

 


@newbee

newbee
28 Mar 2022, 04:53

RE: Angle of trendline

amusleh said:

Hi,

No, you can't get the angle from API, but you can calculate it if you want to:

        private double GetAngle(ChartTrendLine trendLine)
        {
            var x1 = Bars.OpenTimes.GetIndexByTime(trendLine.Time1);
            var x2= Bars.OpenTimes.GetIndexByTime(trendLine.Time2);

            double xDiff = x2 - x1;
            var yDiff = trendLine.Y2 - trendLine.Y1;

            return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
        }

The above method will return the angle of a trend line in Degree, it will not work properly if your trend line is drawn in future time, because it uses bar indices for x axis.

If you to get the angle from API then please open a thread on forum suggestions section.

 


@newbee

newbee
04 Feb 2018, 10:34

Hello, same isue commenced today and it is unusable. Every two seconds disconnects and reconnects non stop. It's been happenning all day. Any help would be appreciated.


@newbee

newbee
26 Nov 2015, 23:22

Back testing

T​hank you TraderM.

I'll look at it & see how it goes.

Regards

 


@newbee

newbee
26 Nov 2015, 04:48

Back testing

Hello, I've struck a situation in calgo while back testing and am hoping someone can assist or point me in the right direction.

My cbot includes a parameter for trading hours. (ie Start Hour & Stop Hour - -  eg Trade between 8pm & 10pm etc)

When the back testing is complete, in the results it seems that there are trades with an entry time outside the selected time parameter, in this case between Start hour 19 & stop hour 21.(or 7pm to 9pm)

One would expect to only see trades with an entry time between the filtered start & stop times. Is this correct or am I missing something?

Any assistance would be appreciated

Thank you

 


@newbee

newbee
24 Jul 2015, 15:20

That's fantastic.

Thank you so much. I'll play around with this further.


@newbee