Topics
Replies

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

firemyst
17 Jun 2022, 11:25

RE:

amusleh said:

Hi,

Can you tell what do you mean by overall Pips? cTrader Pips column shows the amount of Pips for your Position which you can get via Pips property of a Position.

To calculate it programmatically you can subtract the current price from Position entry price:

        private double GetPositionPips(Position position)
        {
            var symbol = Symbols.GetSymbol(position.SymbolName);

            return Math.Round((position.TradeType == TradeType.Buy ? symbol.Bid - position.EntryPrice : position.EntryPrice - symbol.Ask) / symbol.PipSize, 1);
        }

 

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

I would like to know how to calculate the overall pips value that cTrader displays in the "Pips" column. cTrader shows roughly 24.9 pips profit despite being up 35.6 pips from position 1, 20.5 pips in position #2, -86 pips for position #3.

So how does it calculate 24.9 overall pips between the 3 positions?

Hope that better helps you understand what I'm looking for?

Thank you.


@firemyst

firemyst
29 May 2022, 13:57

If you know the symbol and gave the position a unique label, you could also look for it in the "HistoricalTrade" collection.

Example:

HistoricalTrade ht = History.FindLast(p1.Label, p1.SymbolName);


@firemyst

firemyst
29 May 2022, 13:55

Not sure if it can be done, but to access a chart object in a bot that's drawn from a bot, you would do something like this example if you're looking for a horizontal line:

ChartHorizontalLine obj = (ChartHorizontalLine)Chart.FindObject("the name you gave the line when you drew it");

 


@firemyst

firemyst
23 May 2022, 12:42 ( Updated at: 24 May 2022, 03:36 )

RE: RE: RE: RE: Discontinuous outputs

genappsforex said:

firemyst said:

Because both

((double)index)/3 == index/3

is false and

((double)index)/4 == index/4

is false.

So it always has a value in Result1 and not Result2 because Switch is always > 0:

if(Switch>0) Result1[index] = Bars[index].High;

Sorry to tell you but you're wrong.
Just run the indicator code i've posted and see for yourself.

 

Perhaps you have some Windows or .Net updates that haven't taken affect yet in cTrader? Reboot?

 


@firemyst

firemyst
22 May 2022, 13:36

RE: RE: Discontinuous outputs

genappsforex said:

amusleh said:

Hi,

The lines are discontinuous:

 

Discontinuous outputs can have empty or NAN values, and those NAN values will not be displayed on the chart.

Well that was my understanding also.
So Why does not my little progam above generate discontinuous Lines?

Because both

((double)index)/3 == index/3

is false and

((double)index)/4 == index/4

is false.

So it always has a value in Result1 and not Result2 because Switch is always > 0:

if(Switch>0) Result1[index] = Bars[index].High;

@firemyst

firemyst
30 Apr 2022, 19:47

RE:

shaahin69 said:

Hi, 

 

I am trying to implement break even when order is in profit. 

Say if I have positions open with 15 contracts, I wish to close 10 contracts only once position pips is greater than 2 and move the SL to break even. Then I want to specify a new TP for the amount of 5 pips.

I have found an example related to break even in cTrader cBot examples, however, I am still unsure how to take profit partially as well as setting a new TP.

Is following correct? 

 

var TP = 2;

if (position.Pips > TP)

{
ClosePosition(position, 10); // close 10 contracts 

var newTP = ??? // how do I set new TP for 5 pips from current price?

ModifyPosition(position, roundedBreakEvenLevel, newTP);

}

double newTP = (position.TradeType == TradeType.Buy ? Symbol.Ask + (5 * Symbol.PipSize) : Symbol.Bid - (5 * Symbol.PipSize));


@firemyst

firemyst
30 Apr 2022, 19:44

@Spotware?

Thank you.


@firemyst

firemyst
26 Apr 2022, 10:16

RE:

amusleh said:

Hi,

I did understood your point, what I was trying to explain was there is no way to accurately know when a tick will result in formation of a new bar.

Regarding your issue, you can do something like this:

 

Okay. Cool. Thanks for that and your sample code. I haven't looked at the sample code, but had another question -- with cTrader shouldn't it (or is it already) programmed up to open a new bar regardless of whether or not a tick comes through?

It it takes the timing of a tick to actually open a new bar, then hypothetically bars could open up halfway through their time period, or even not at all.

If it is set to open a new bar regardless of whether a tick or not happens, then the example I provided seems to illustrate a bug where ticks happen before the bar is actually opened.

Thank you.


@firemyst

firemyst
25 Apr 2022, 10:38

RE: RE:

instylereality2 said:

firemyst said:

I'm not sure your idea will work, as I believe the "OnTick" events only occur after OnStart has completed.

Obviously Spotware can confirm, but if that's the case, you'll have to redo your logic.

Yeah, I was feeling that this would be the case. A confirmation is needed on this for sure.

Any idea about how this could be achieved? Or isn't possible at all to have a live price checking mechanism in OnTick() that would be combined with OnStart() to complete a continues checking cycle??

Thank you! 

Why do you even need to wait in OnStart until something happens?

Just set a flag to false, and when it occurs in OnTick, set the flag to true.

Then check the flag in OnTick and when it's true, go through another branch of code.


@firemyst

firemyst
25 Apr 2022, 09:15

I'm not sure your idea will work, as I believe the "OnTick" events only occur after OnStart has completed.

Obviously Spotware can confirm, but if that's the case, you'll have to redo your logic.


@firemyst

firemyst
25 Apr 2022, 09:12

RE:

budda_dan2020 said:

Hi,

is the IAccount.StopoutLevel in % or just a proportion?

E.g. if my account has a stop out level as 30%, is the value of IAccountStopOutLevel 30 or 0.3?

 

kind Regards

Why not just print it out to see for yourself?

Eg:

Print("Stop out level: {0}", IAccount.StopoutLevel);

and then check the log tab to see what it says.


@firemyst

firemyst
25 Apr 2022, 09:11

Yes.

In your code set a boolean flag to indicate that you've done your modification on the position. For example, "alreadyModifiedPosition = true;"

Every time you go through your code, only enter into the part that does the position modification if the flag is set to false.

Eg:

if (!alreadyModifiedPosition)

{

   /// do your position modification

   alreadyModifiedPosition = true;

}

 

Then you just have to figure out the logic when you reset alreadyModifiedPosition back to false. Every time you start your bot? When the position is closed? Something else?

Good luck! :-)


@firemyst

firemyst
22 Apr 2022, 04:20 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

There is no way to know when  a tick results on opening of a new bar, you can use a timer to count the remaining time of a bar but that works only for time based bars not for Tick, Renko, and range bars, you have to know the time period of a time frame bar as there is no way for now to know how much is a time based time frame bar time period programmatically.

I recommend you to change the way you designed your bot, instead of using the timer, as it would be not 100% accurate.

cBots OnTick method is called before OnBar, and by a single thread, so they will never be called concurrently.

These types of issues are more related to the way you design your Bot than API limitations.

I don't think you fully understand what I'm trying to describe or I'm not being clear enough.

I do not use a timer in the algorithm. The timings you see in the log statements are from the "Log" tab in cTrader.

I use the "OnTick" and "OnBar" methods with a boolean flag. The code is structured as per my first post.

The bot checked to increase the position size. Since it hadn't already done so that bar, it increased by 0.1 lots, and then set the flag "_enteredPositionThisBar" to true so the bot would not enter another position in the current bar.

That was on the tick called just before the OnBar, but the clock had already ticked over to the next minute, so it should have occurred during the 21.00.00 bar and not the bar opened at 20.59.00.

Then the next bar is opened, and since the flag "_enteredPositionThisBar" was set to false in the "OnBar" method, the bot immediately increased the position size again during the 21.00.00 bar as you can see from the screen capture. Note I do NOT use any asynchronous calls when placing orders.

20/04/2022 20:51:39.729 | cBot "BugBot" was started successfully for NAS100, m1.

20/04/2022 20:51:54.348 | OnTick

:
20/04/2022 21:00:00.775 | OnTick --> it increased the size here, adding 0.1 lots. "_enteredPositionThisBar" set to true.
20/04/2022 21:00:00.909 | OnBar     --> "_enteredPositionThisBar" set to false.
20/04/2022 21:01:00.313 | OnTick --> it increased the size again here by 0.1 lots and reset the flag the true.   
20/04/2022 21:00:00.418 | OnTick
 

So because the "OnBar" even occurs _after_ the first tick event in that new bar, it opens a position twice during the same bar when technically it shouldn't since the new bar hadn't been opened yet. With the log above and screen captures below, do you see what I'm saying?

Since boolean flags won't work since tick events for a new bar's timeframe occur _before_ the "OnBar" event actually occurs, and we can't use the Bars.OpenTimes.Count to check if the number of bars have increased (because on the first tick in the new M1 bar, the new bar hasn't been formed yet), would you be able to provide sample code to get around this issue?

Here's what happened. Note the deal map and compare against the logs. cTrader shows BOTH orders being displayed in the same bar even though the first one happened during the tick event _before_ the "OnBar" event:

Thank you.

 


@firemyst