Topics
Forum Topics not found
Replies
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: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, 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, 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:35
Hi,
Please check your other thread: cTDN Forum - a way to know when the app is disconnected and reconnected (ctrader.com)
@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
06 Dec 2021, 08:46
RE: RE:
xiao-linlong said:
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