Topics
Replies
ncel01
16 Feb 2022, 14:36
RE:
amusleh said:
Hi,
The tick/pip value is constant and it represents the latest tick/Pip value of a symbol when you start the cBot for both real time and back test environments.
Hi amusleh,
Yes, indeed. But why doesn't this value keep synchronised with the current forex rate, since it is called OnTick?
When backtesting I can understand but not when running a cBot it in real time, which is a huge limitation.
How to get this value updated in real time for currency conversion purposes, as brokers are able to, when symbol and account currencies don't match?
Thank you once again!
@ncel01
ncel01
15 Feb 2022, 23:29
RE: RE: RE:
amusleh said:
ncel01 said:
amusleh said:
Hi,
The symbol tick value property gives you the monetary value of one single tick of the symbol.
The symbol tick size property gives you the numeric size of a symbol tick.
For getting the symbol bid/ask price you can use Symbol.Bid or Symbol.Ask.
amusleh,
Thanks for your reply.
The purpose is not to get symbol bid/ask price but to get the current currency conversion ratio and, EURUSD is not the applicable instrument here involved.
Symbol.TickValue/Symbol.TickSize is called OnTick() and matching the current EURUSD price when running cBot. However, I have noticed that this value remains constant and not matching EURUSD price afterwards.
Thank you!
Hi,
If the quote currency of a symbol is same as your account deposit currency then the tick value will not change.
For conversion you should use tick value not tick size, tick size is always constant and it's the numeric value of a symbol tick.
Hi amusleh,
No, symbol and account currencies are not the same.
In fact, I use ( Symbol.TickValue / Symbol.TickSize ) to get to the monetary value (in the account currency) of one monetary unit of the symbol currency.
Please consider the following:
- Account: USD
- Symbol: GER30 (EUR)
When running the code below (real-time), the first execution Symbol.TickValue / Symbol.TickSize will match the current EURUSD Bid Price, as expected. Nothing wrong here.
The problem is that the remaining "printed" values are all equal to the first, meaning that, Symbol.TickValue / Symbol.TickSize remains static and no longer matches the current EURUSD Bid Price.
protected override void OnTick()
{
Print("EURUSD current Bid Price: ", Symbol.TickValue / Symbol.TickSize);
}
What can be a reason for this?
Thank you once again!
@ncel01
ncel01
15 Feb 2022, 23:04
RE:
amusleh said:
Hi,
You can do something like this:
using cAlgo.API; using System.Collections.Generic; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class NewcBot : Robot { private Dictionary<int, double> _positionsVolume = new Dictionary<int, double>(100); protected override void OnStart() { foreach (var position in Positions) { _positionsVolume.Add(position.Id, position.VolumeInUnits); } Positions.Opened += Positions_Opened; Positions.Closed += Positions_Closed; Positions.Modified += Positions_Modified; } private void Positions_Closed(PositionClosedEventArgs obj) { if (_positionsVolume.ContainsKey(obj.Position.Id)) { _positionsVolume.Remove(obj.Position.Id); } } private void Positions_Opened(PositionOpenedEventArgs obj) { _positionsVolume.Add(obj.Position.Id, obj.Position.VolumeInUnits); } private void Positions_Modified(PositionModifiedEventArgs obj) { if (_positionsVolume.ContainsKey(obj.Position.Id)) { var positionPreviousVolume = _positionsVolume[obj.Position.Id]; if (positionPreviousVolume == obj.Position.VolumeInUnits) { // It means volume desn't changed } // volume changed else { // new volume added if (positionPreviousVolume < obj.Position.VolumeInUnits) { Print("Position {0} volume increased, new volume: {1} | previous volume: {2}", obj.Position.Id, obj.Position.VolumeInUnits, positionPreviousVolume); } // position partially closed else { Print("Position {0} partially closed, new volume: {1} | previous volume: {2}", obj.Position.Id, obj.Position.VolumeInUnits, positionPreviousVolume); } } _positionsVolume[obj.Position.Id] = obj.Position.VolumeInUnits; } else { _positionsVolume.Add(obj.Position.Id, obj.Position.VolumeInUnits); } } } }
amusleh,
That's clear. Thanks for the extra clarifications!
@ncel01
ncel01
14 Feb 2022, 14:23
RE:
amusleh said:
Hi,
The symbol tick value property gives you the monetary value of one single tick of the symbol.
The symbol tick size property gives you the numeric size of a symbol tick.
For getting the symbol bid/ask price you can use Symbol.Bid or Symbol.Ask.
amusleh,
Thanks for your reply.
The purpose is not to get symbol bid/ask price but to get the current currency conversion ratio and, EURUSD is not the applicable instrument here involved.
Symbol.TickValue/Symbol.TickSize is called OnTick() and matching the current EURUSD price when running cBot. However, I have noticed that this value remains constant and not matching EURUSD price afterwards.
Thank you!
@ncel01
ncel01
14 Feb 2022, 14:10
RE:
amusleh said:
Hi,
You can use Position Modified event for partial closes.
Hi amusleh,
Thanks for your reply.
It makes sense in fact. I forgot about this event.
Is there a way to filter (within this event) a modified position for a partial close only?
My intention is to provide instructions in case of a partial close only, but it can also happen that a position has been modified for TP, SL, etc.
Thank you!
@ncel01
ncel01
01 Feb 2022, 23:50
RE: RE:
ncel01 said:
amusleh said:
Hi,
Each instance of a cBot runs separate from others, one can't have any effect on other running cBots.
Most probably something is wrong with your cBot code, and its not related to running multiple instances.
You should use unique labels for each of your running cBot instances, and use it to only manage the positions and orders that were opened by that instance.
Please post your cBot code then we will be able to help you.
Regarding debugging multiple running instances, right now there is no feasible way to do this.
Hi amusleh,
In fact, every single order has a unique label based on its position (numbering) and respective cBot instance.
Still, I'll try to have this solved while implementing some other improvements to the cBot,
Should I am still unable to solve this I'll let you know.cBot code is really extensive ( > 1000 lines) to go through it, I am afraid.
Maybe if I only post the relevant classes this would be enough? Perhaps some issue can be already identified when checking these.
Thank you once again!
Hi amusleh,
Apparently this is now solved by following your suggestion to the thread https://ctrader.com/forum/calgo-support/37501?page=1#4
var myPositions = Positions.Where(position => position.Label.Equals("MyLabel", StringComparison.OrdinalIgnoreCase)).ToArray();
var myOrders = PendingOrders.Where(order => order.Label.Equals("MyLabel", StringComparison.OrdinalIgnoreCase)).ToArray();
Looks like .ToArray() reference made the difference here!
Thank you!!
@ncel01
ncel01
01 Feb 2022, 16:50
RE: RE: RE: RE: RE:
amusleh said:
ncel01 said:
amusleh,
That's the only purpose in fact.
Should I provide different names to the main class ( public class cBot_copy_n : Robot) for each cBot copy or, is this not relevant?
Thank you!
Hi,
It doesn't makes any difference if you use same class name or different class names.
amusleh,
Great. Thanks for clarifying!
@ncel01
ncel01
01 Feb 2022, 13:13
RE: RE: RE:
amusleh said:
ncel01 said:
Hi amusleh,
Thanks for your reply.
The benefit was to have the instances separated in groups, where each group is a cBot copy.
What would be the main issue here? Performance?
Is the strategy outcome/behaviour expected to be the same for both these cases?
Thank you!
Hi,
If you want to duplicate a cBot for grouping then yes you can and it will not have any effect on it's performance.
amusleh,
That's the only purpose in fact.
Should I provide different names to the main class ( public class cBot_copy_n : Robot) for each cBot copy or, is this not relevant?
Thank you!
@ncel01
ncel01
01 Feb 2022, 12:03
RE:
amusleh said:
Hi,
Copying a cBot doesn't give you any benefit at all, each running instance of a cBot runs fully separated from all other cBots running instances.
Hi amusleh,
Thanks for your reply.
The benefit was to have the instances separated in groups, where each group is a cBot copy.
What would be the main issue here? Performance?
Is the strategy outcome/behaviour expected to be the same for both these cases?
Thank you!
@ncel01
ncel01
24 Jan 2022, 21:38
RE:
amusleh said:
Hi,
The Find and FindAll methods are only available on Positions, it's basically a shorthand version of Linq where extension method:
var myPositions = Positions.Find("myLabel"); // Is equivalent to var myPositions = Positions.Where(position => position.Label == "myLabel"); // Note: Don't use == for string equality as it will use the current thread culture, // instead use Equal method of string and set the type of comparison you are looking // to do, personally I prefer to use var myPositions = Positions.Where(position => position.Label.Equals("MyLabel", StringComparison.InvariantCultureIgnoreCase)); // which is both case insensitive and has much better performance
Now regarding PendingOrders, you can use Linq here too, no need for any extra helper methods:
var myOrders = PendingOrders.Where(order => order.Label.Equals("MyLabel", StringComparison.OrdinalIgnoreCase));
And don't forget to call "ToArray" at the end:
var myPositions = Positions.Where(position => position.Label.Equals("MyLabel", StringComparison.OrdinalIgnoreCase)).ToArray(); var myOrders = PendingOrders.Where(order => order.Label.Equals("MyLabel", StringComparison.OrdinalIgnoreCase)).ToArray();
Otherwise anytime you iterate over it a new allocation will be made and the Linq query will be executed several times.
The Find/FindAll methods are added only to make things little bit easier for those who have no knowledge of .NET or Linq, but I strongly recommend you to use Linq.
Hi amusleh,
That's great.
Thanks for clarifying!
@ncel01
ncel01
23 Jan 2022, 19:13
RE:
amusleh said:
Hi,
Each instance of a cBot runs separate from others, one can't have any effect on other running cBots.
Most probably something is wrong with your cBot code, and its not related to running multiple instances.
You should use unique labels for each of your running cBot instances, and use it to only manage the positions and orders that were opened by that instance.
Please post your cBot code then we will be able to help you.
Regarding debugging multiple running instances, right now there is no feasible way to do this.
Hi amusleh,
In fact, every single order has a unique label based on its position (numbering) and respective cBot instance.
Still, I'll try to have this solved while implementing some other improvements to the cBot,
Should I am still unable to solve this I'll let you know.
cBot code is really extensive ( > 1000 lines) to go through it, I am afraid.
Maybe if I only post the relevant classes this would be enough? Perhaps some issue can be already identified when checking these.
Thank you once again!
@ncel01
ncel01
11 Jan 2022, 00:11
RE:
amusleh said:
Hi,
Do you mean something like this:
using System; using cAlgo.API; using cAlgo.API.Internals; using cAlgo.API.Indicators; using cAlgo.Indicators; namespace cAlgo { [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class TopYbottomYtest : Indicator { [Parameter("Source")] public DataSeries Source { get; set; } protected override void Initialize() { if (Source == Bars.HighPrices) { Print("High Prices"); } } public override void Calculate(int index) { } } }
Hi amusleh,
That's clear.
Thanks for the info!
@ncel01
ncel01
11 Jan 2022, 00:04
RE:
PanagiotisCharalampous said:
Hi ncel01,
The provider's contact is not accessible to investors unless the provider discloses his contact information in the strategy description.
Best Regards,
Panagiotis
Join us on Telegram and Facebook
Hi Panagiotis,
Thanks for confirming!
@ncel01
ncel01
08 Dec 2021, 14:05
RE:
PanagiotisCharalampous said:
Hi ncel01,
You can just save the info you need to maintain in a file and load it on start up.
Regarding the updates, we roll them out in stages, so some brokers receive them earlier than others.
Best Regards,
Panagiotis
Panagiotis,
That's clear.
Thank you!
@ncel01
ncel01
08 Dec 2021, 13:34
RE:
PanagiotisCharalampous said:
Hi ncel01,
Pending orders are not deleted when you restart cTrader. If you want your cBot to maintain the state between restarts, then you need to program this yourself.
Best Regards,
Panagiotis
Hi Panagiotis,
That's a good tip!
In fact I didn't think about coding this but I guess it can be easily implemented in my case! ????
Btw, are cTrader updates synchronized across all brokers platforms?
Thank you!
@ncel01
ncel01
08 Dec 2021, 12:32
RE:
Astroke said:
No, but you can wait until the weekend to relaunch cTrader
Hello Astroke,
Thank you for your reply.
That can be an option, however I am afraid this won't solve the issue, since there are several orders involved.
In that case, after running cBot again, I would need to go through every single pending order and only delete the new orders created, so that previous situation remains.
It would help a lot if an image of the current situation (pending orders incl. parameters) could be saved and then restored. Since market is closed there will be no issue with open positions, however, all newly generated pending orders need to be deleted accordingly to get to the previous situation.
@ncel01
ncel01
06 Dec 2021, 12:10
RE: RE: RE:
amusleh said:
ncel01 said:
Hi Panagiotis,
I forgot to mention but both my question and the example I provided was about indexes and not FX pairs.
PanagiotisCharalampous said:
Hi ncel01,
No, the equation is the one I provided above, assuming that the unit of measurement of the margin i.e. the currency, is the same to the one used for the account. Else you will need to make the relevant conversions.
Best Regards,
Panagiotis
Hi,
Without conversion you will not be able to calculate the used or required margin for all symbols.
And for conversion you need a symbol base asset and quote asset, also you need the symbol conversion chain which are not available right now in automate API.
You can open a thread on suggestions section for adding the symbol conversion feature if you want to.
Hi amusleh,
The example provided is a particular example for an indice (US500), where symbol and account currency is the same (USD).
In such a case, I think that conversion is not applicable and I was expecting both values (Account.Margin and calculated margin) as shown, to match.
Maybe I am still missing something here..
Thank you!
@ncel01
ncel01
03 Dec 2021, 16:53
RE:
Hi Panagiotis,
I forgot to mention but both my question and the example I provided was about indexes and not FX pairs.
PanagiotisCharalampous said:
Hi ncel01,
No, the equation is the one I provided above, assuming that the unit of measurement of the margin i.e. the currency, is the same to the one used for the account. Else you will need to make the relevant conversions.
Best Regards,
Panagiotis
@ncel01
ncel01
17 Feb 2022, 14:24
RE: RE: RE:
amusleh said:
Hi amusleh,
Thanks for your reply.
It's a pity that pip/value is only taken when cBot starts. This makes it not so effective as it should be, as I consider an accurate (real time) currency conversion of high importance.
@ncel01