Topics
Replies

firemyst
02 Aug 2022, 16:08

RE:

Anka Software said:

Hi,

   Any way to get symbol type ie forex/index/cash etc?

Regards

Vivek

Maybe create C# HashSet objects calle "forex", "index", "cash" etc. IN each Has object, add the symbols you'll be trading that you would classify as forex, index, cash, etc, respectively.


@firemyst

firemyst
02 Aug 2022, 16:06

Have you tried adding the reference through cTrader? In the bot under "Automate", there are 3 vertical dots. From those, you can select "Manage References". Add the indicator as a reference that way, and then launch your development environment.


@firemyst

firemyst
02 Aug 2022, 16:01

RE:

ctid4771555 said:

Hi

Is there any project template for Visual Studio already available to use, or it could be built in the future ?

 

Thanks

 

Not sure what you're asking for since if you're using Visual Studio you can easily create your own.

Just go into cTrader, under Automate, create a new indicator/bot, and then click to "edit in Visual Studio".

Why not save that as your template?


@firemyst

firemyst
02 Aug 2022, 03:12

RE:

PanagiotisCharalampous said:

Hi firemyst,

There is a new debugging process documented here.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook 

Thank you @PanagiotisCharalampous!

The above worked for me using Visual Studio 2017.


@firemyst

firemyst
29 Jul 2022, 03:02 ( Updated at: 21 Dec 2023, 09:22 )

Issue with cTrader 4.2 attaching to processes for debugging

Hi @Spotware  / @Panagiotis:

These are some great features and additions.

However, there's one that as an annoying drawback. Let's say you have at least 3-5 tabs open with trading charts with custom indicators. Now you have Visual Studio open trying to debug one of those indicators. You want to attach Visual Studio to the process.

How do you know which one to attach to?

Here you can see that there's at least 10 algohost processes launched, none of which have a title.

How does anyone know what process to attach the specific code they're debugging to from IDE's like Visual Studio?

I have to attach to the first one. Are breakpoints hit? No? Ok, I have to try the second one. Are breakpoints hit now? No? I have to try attaching to the next process. And so on and so forth.

Is there any way to make this a bit easier for developers? Like, can't @Spotware include a "Title" (or some other identifying information) when the separate algohost processes are spawned?

Thank you.


@firemyst

firemyst
14 Jul 2022, 03:26

" am trying to make this cbot open trades exactly on the MA crossing"

This depends on when you define a MA crossing. Right now, your code doesn't check the current bar/candle to see if the MA's crossed. Rather, it checks the previous bar and the bar before that (last(1) and last(2)).

If you want it on the exact tick that it happens, then you need to check the current values of the MA against the previous bar's values. Eg, last(0) and last(1) instead of last(1) and last(2).


@firemyst

firemyst
07 Jul 2022, 16:31

RE:

safaeianmohsen said:

Hello . Can anyone guide me? I want to add a code to the Ichimoku indicator so that whenever the values of Kijunsen and Span B are equal to each other, Only on the chart that is open , a sound allert will be generated.

If possible, please send it here. 

You would do something like this (pseudo code) in your indicator's calculate method:

 

if (Kijunsen.Result.Last(0) == SpanB.Result.Last(0))

{

    System.Media.SystemSounds.Exclamation.Play();

}


@firemyst

firemyst
07 Jul 2022, 16:28

"Are there now multiple instances of the historical bars taking up memory, or is cTrader intelligent enough to know it only needs one copy of this data for reference by any number of bots that need it?"

This is a question that only @Spotware / @Panagiotis / @Amusleh can answer.

 


@firemyst

firemyst
06 Jul 2022, 03:40

If it doesn't matter, why not just look for the first OnTick that happens after your specified time and execute the order then? So instead of checking if the time matches exactly, just check if onTickTime >= your specified time and if so, execute your actions. If you want it limited to only occur within a few seconds after your specified time, then pseudo logic would be:

if (onTIckTime >= yourSpecifiedTime && onTickTime <= OnTickTime + numberOfAllowedSecondsAfter)

{

   // do what you have to do

}

 

If you do want it at the exact hour:minute:second and a tick doesn't come through, then there's nothing you can do as that's based on the market.


@firemyst

firemyst
29 Jun 2022, 05:16

RE:

cedric.boudreau said:

Do you have somewhere all founction of mathematique , document , i am litle tire to losse 1-2 hrs everytime to found the correct word...

 

i think addind that in your api guide will be appreciated.

 

in that case math.round(dsfd,2,   up)  ?

The "Math" api functions have nothing to do with Spotware as they are all part of the Microsoft .Net framework.

So you need to Google and find what you need on MIcrosoft.

For example, here's Microsoft's documentation for the Math class:

 


@firemyst

firemyst
27 Jun 2022, 07:14

//Quick example on how to sort positions by NetProfit (not gross profit)
//Change things around if you want to sort by time or something else.

foreach (Position p in Positions.FindAll(YourLabel, s.Name).OrderBy(x => x.NetProfit))
{
	ClosePositionAsync(p, (TradeResult r) =>
	{
		if (r.IsSuccessful)
		{
			Print("Closed position \"{0} {1}\".", p.Id, p.Label);
		}
		else if (!r.IsSuccessful)
		{
			Print("WARNING! Could not close position \"{0} {1}\"!", p.Id, p.Label);
			Print("Error message: {0}", r.Error.Value);
		}
	});
}

 


@firemyst

firemyst
25 Jun 2022, 17:34

RE: RE: RE: RE:

ctid2032775 said:

amusleh said:

genappsforex said:

ctid2032775 said:

 A little bit strange is that as soon as I switch to .NET 6, run any bot and close the cTrader application the cTrader process is not terminated, as well.

I noticed that too, This behaviour eats Memory and CPU . Think they're forgetting to clean up/Close old threads.

Hi,

We can only help you if we were able to reproduce the issues you are facing, if we can't then there is no way for us to know what's going wrong.

 

Hi,

after quite a frustrating time I stopped development in ctrader and migrated the project to MetaTrader 5. The trading part is written in MQL, the machine learning part was developed as an external library in C# and there everything is working as expected (on the same environment (!)).

As this part is now finished I got curious and did some further investigation...

What I found out is that it's working in any Windows 10 Home environment (both on an Acer gaming notebook and in a virtual environment (VirtualBox)) but I never got it to work on Windows 10 Professional or Enterprise (both x64 clean installations)!

The problem is that the bot needs to run on a Minix Neo with Windows 10 Pro installed where it's not possible to "downgrade" to home edition (and even if it would be possible I wouldn't do this...).

Accordingly, I kindly ask you to verify possible reasons and keep me updated about the solution.

Many thanks and regards,
Christian

I think what would help the @Spotware crew is if you can record your desktop (or whatever) while reproducing the cTrader issue. This way, their team can see it actually happening.


@firemyst

firemyst
25 Jun 2022, 17:31

Yes.

Example:

System.Media.SystemSounds.Exclamation.Play();

 


@firemyst

firemyst
24 Jun 2022, 05:40 ( Updated at: 21 Dec 2023, 09:22 )

RE:

gennimatas said:

Following code is not playing on my win10 system after introduction of cTrader 4.2

Paths and files do exist.

Please advise.

Regards

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace testSound
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.FileSystem)]

    public class testSound : Indicator
    {

        [Parameter(DefaultValue = "tada")]
        public string wav { get; set; }

        protected override void Initialize()
        {
            IndicatorArea.MouseDown += IndicatorArea_MouseDown;
        }

        private void IndicatorArea_MouseDown(ChartMouseEventArgs obj)
        {
            var windowsFolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
            var path = System.IO.Path.Combine(windowsFolder, "Media", wav + ".wav");
            Print(path);
            // C:\WINDOWS\Media\tada.wav
            Notifications.PlaySound(path);
            // Notification: PlaySound of 'C:\WINDOWS\Media\tada.wav' failed. Exception message: 'Invalid URI: The URI is empty.'

            path = @"C:\Windows\Media\Ring01.wav";
            Print(path);
            // C:\Windows\Media\Ring01.wav
            Notifications.PlaySound(path);
            // Notification: PlaySound of 'C:\Windows\Media\Ring01.wav' failed. Exception message: 'Invalid URI: The URI is empty.'
        }

        protected override void OnDestroy()
        {
        }

        public override void Calculate(int index)
        {
        }

    }
}

 

If it helps, I use this instead:

System.Media.SystemSounds.Exclamation.Play();

and in Windows itself I assign the sound I want to the "Exclamation" sound from the Control Panel as follows:


@firemyst

firemyst
24 Jun 2022, 05:35

RE: RE:

Marin0ss said:

So another solution which would work for me is a snippet of code that stops the robot after the last 5 trades closed negative.

 

Here's a snippet to help you get started.

This assumes you've created an event method when a position is closed called "Positions_Closed":

 

private void Positions_Closed(PositionClosedEventArgs args)
{
	Position p1 = args.Position;
//in case there are multiple, you can narrow it down by symbol name and label
	if (p1.SymbolName == Symbol.Name && p1.Label == _positionLabel)
	{
		//Consecutive Losing Trades
		if (p1.NetProfit < 0)
			_numberOfConsecutiveLosingTrades += 1;
		else
			_numberOfConsecutiveLosingTrades = 0;
	}
//
// blah blah blah with other stuff you may need to do
//
// then stop the bot if it's greater than your threshold
    if (_numberOfConsecutiveLosingTrades >= 5)
        Stop();
}

 


@firemyst

firemyst
21 Jun 2022, 11:48 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE:

amusleh said:

Hi,

The cTrader Pips column shows the different in Pips between position entry price and current price.

If you add new volume to the position then the entry price of position will change, and for Pips it will use the new entry price.

That's how it's calculated on cTrader, so for:

What I mean by overall pips is if my positions are:

1) 10000 units of EURCAD @ 1.3547

2) 1000 units of EURCAD @ 1.3562

3) 1000 units of EURCAD @ 1.36701

and price is currently at 1.35835

cTrader will use 1.36701 as entry price and 1.35835 as current price, the difference will be position Pips, it doesn't take into account the previous entry prices.

That can't be totally accurate, because if you look at this capture:

by your last reply, the last entry price is 1.01315, but the position closed closed negative from the last entry, yet it says the overall trade was up 13.5 pips.

So I'm confused because it obviously does take into account the previous price points.

????


@firemyst

firemyst
20 Jun 2022, 12:09

RE:

amusleh said:

Hi,

So you are trying to calculate the Pips for positions that are partially closed or added?

If that's what you are looking to do then you can't, because the API doesn't give you the data for partially closed / added positions.

When you close part of a position or add more volume to it the history is not updated until you close the whole position, nor the positions closed / opened events are triggered.

 

 

 

But there's obviously some mathematical formula that's used because cTrader does it.

As I mentioned in my original post, I keep track of each position's volume and entry price that are added (eg, I have my own history), so I should be able to do it before the position is closed just like cTrader.

So, can't you look at cTrader's source code and tell me what formula it's using to do its live calculation? :-)

Thank you.

 


@firemyst

firemyst
20 Jun 2022, 11:37 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE:

amusleh said:

firemyst said:

amusleh said:

Hi,

Can you tell me which column you are talking about? I can't find any overall Pips column in cTrader.

The "Pips" column as per the "Positions" and "History" tabs:

Thank you.

Hi,

The method I posted will give you the same value that you see on Pips columns with some fraction error due to rounding or delay.

There is no overall Pips, each position Pips is separate and it's not related to other positions.

 

I don't want the Position's pip value. That's the point I think you're missing or I'm not explaining well.

I want to know how that calculation is done because I want to have an indicator draw other lines at various on the chart with the correct amount of pips written on the line.

The only way I can currently do that is to drag the stop loss line and it will show me the number of pips depending on the price at the location.

Using p.pips only tells me the pips at the current closing price, not at other price levels on the chart, when I have a position with multiple scaled in positions.

Example:

 

 


@firemyst

firemyst
20 Jun 2022, 10:31

RE:

amusleh said:

Hi,

Can you tell me which column you are talking about? I can't find any overall Pips column in cTrader.

The "Pips" column as per the "Positions" and "History" tabs:

Thank you.


@firemyst

firemyst
18 Jun 2022, 15:39

If you close each position synchronously, it waits until one position is closed before it closes the next... so on and so forth.

So try closing all positions asynchronously. This way, you send all the close commands, and it's just up to the server to process them as fast as it can.

Example:

foreach (Position p in Positions)
                            {
                                ClosePositionAsync(p, (TradeResult r) =>
                                {
                                    if (r.IsSuccessful)
                                    {
                                        //... do what you have to
                                    }
                                    else if (!r.IsSuccessful)
                                    {
					//... do what you have to
                                    }
                                });
                            }

 


@firemyst