Topics
Replies

firemyst
03 Sep 2020, 04:59 ( Updated at: 21 Dec 2023, 09:22 )

RE:

PanagiotisCharalampous said:

Hi firemyst,

But you just told me there's no way to accomplish the logic without having two dataseries objects to use interchangeably for the same trend:

Yes because you are using the wrong tool for the job. You are trying to display discontinuous lines with continuous data series. Why don't you use trendlines instead?

   if (Result[index] > Result[index - 1])
            {
                Chart.IndicatorAreas[0].DrawTrendLine(index.ToString(), Bars.OpenTimes[index - 1], Result[index - 1], Bars.OpenTimes[index], Result[index], Color.Green);
            }
            
            if (Result[index] < Result[index - 1])
            {
                Chart.IndicatorAreas[0].DrawTrendLine(index.ToString(), Bars.OpenTimes[index - 1], Result[index - 1], Bars.OpenTimes[index], Result[index], Color.Red);
            }

Best Regards,

Panagiotis 

Join us on Telegram

Your right in that those would work. But that kind of defeats the purpose of having an indicatordataseries with "discontinuous lines" for plotting. So developers have to add in extra parameters for line style, plot type, color, thickness, etc to chart, since the API doesn't allow for us to obtain those properties from the IndicatorDataSeries objects.

In otherwords, It would be great to be able to avoid cluttering up the parameter interface with the associated parameters users can't even see the preview of:

Unless there's another way to do it or a way from the API to get the settings from the IndicatorDataSeries settings under "Lines"?


@firemyst

firemyst
02 Sep 2020, 16:17

RE:

PanagiotisCharalampous said:

Hi firemyst,

So essentially every developed cTrader indicator that uses different data series for up/down colors will have this issue?

No. This not a problem with cTrader but with your logic. So there is nothing to resolve here. cTrader leaves gaps when there are no values in the data series. But you leave no gaps, therefore there is no way cTrader to know that you do not want a line to be drawn. If your dataseries has values then cTrader will join the dots.

Best Regards,

Panagiotis 

Join us on Telegram

"No. This not a problem with cTrader but with your logic."

But you just told me there's no way to accomplish the logic without having two dataseries objects to use interchangeably for the same trend:

"The only way I can think of to get around this is to use two IndicatorDataSeries for each case and use them interchangeably"

That means I need two separate indicator dataseries for the uptrend and two separate indicator downseries for the downtrend:

If I understand correctly, that means at least 4 Indicatordataseries objects just to draw two lines correctly?

If there's an error with my logic, are you able to post or show me an example where it works with the alternating color lines properly drawn with the data I provided in the sample code?

Thank you,

 


@firemyst

firemyst
02 Sep 2020, 12:31

RE:

PanagiotisCharalampous said:

Hi firemyst,

The only way I can think of to get around this is to use two IndicatorDataSeries for each case and use them interchangeably so that gaps are maintained. 

Best Regards,

Panagiotis 

Join us on Telegram

So essentially every developed cTrader indicator that uses different data series for up/down colors will have this issue?

Thanks for your suggestion @Panagiotis, but as I think you understand it isn't really practical to have two dataseries for "up" colors and two dataseries for "down" colors and having to interchange them..

Is this functionality something Spotware is working on to resolve?

I mean, every other platform out there allows for separate up/down colors in their indicators without this issue.

Why is it so hard to include it within cTrader?

Thank you.


@firemyst

firemyst
02 Sep 2020, 08:43 ( Updated at: 21 Dec 2023, 09:22 )

RE:

PanagiotisCharalampous said:

Hi firemyst,

You are missing the case where the values are equal :)

Best Regards,

Panagiotis 

Join us on Telegram

HI @Panagiotis:

I don't think it's that simple because I had some code for the equal scenario.

Here's why. Look at the graphic below:

Point "A" is -2; "B" is 2; "C" is 0.

So at those points ResultsDownTrend[index] is -2, 2, and 0 respectively.

A has to be -2 because it's coming down from the previous point.

B has to be 2 because it's going down to point C.

cTrader is then automatically drawing the line between values A & B because both A & B have values for the preceeding/postceeding points even though I don't want the line drawn between those two points.

How do we get around this?

 


@firemyst

firemyst
02 Sep 2020, 08:24 ( Updated at: 21 Dec 2023, 09:22 )

RE:

PanagiotisCharalampous said:

Hi firemyst,

Yes it is. I don't see anything wrong. Can you elaborate?

Best Regards,

Panagiotis 

Join us on Telegram

 

Hi @Panagiotis:

In the sample screen capture above, the expected output is that all lines going up should be green, all the lines going down should be red as shown below:

However, I'm unable to get the simple code above to do what I want.

What am I missing?

Thank you.


@firemyst

firemyst
01 Sep 2020, 17:55

RE:

luca.tocchi said:

how do i check the direction of the moving averages in real time and if they go high i go buy if they go low i sell?

Thanks a lot

You get the current value of the MA and can compare it to the previous value to see if it's increasing or decreasing.

//example pseudo-code
if (ma.Result.Last(0) > ma.Result.Last(1))
    //open long position 
else if (ma.Result.Last(0) < ma.Result.Last(1))
    //open short position
else
   //the ma values are equal. What do you want to do?

 


@firemyst

firemyst
01 Sep 2020, 17:51

I don't know if there's an indicator for it, but you'll need C# code to find "peaks and troughs".

Doing a Google search will yield results for you.


@firemyst

firemyst
31 Aug 2020, 16:23

RE:

patrock333 said:

I was wondering if anyone knows how to pass data between two or more running cBots.

Eg. One cBot running on the AUDUSD symbol passing data to another cBot on NZDUSD to help in triggering an event.

 

Thanks.

Static variables would work wonders for you.

Static variables are shared across multiple instances of the same indicator on different charts, so hopefully they would also be shared between bot instances of the same bot.

However, they probably won't be shared between different bots.

It'll save the hassle and slowness of reading/writing files to/from the file system.


@firemyst

firemyst
31 Aug 2020, 15:56

RE:

jeanmarc.cds said:

Hello everybody.

 

I am looking for a good cTrader broker with a good spread on AUDSGD pair. ICmarkets seems very good but they dont accept Canadian citizens. Most of brokers I checked dont offer AUDSGD or have quite high spreads on this pair.

 

THANKS FOR YOUR HELP

AUDSGD and USDSGD are offered by Pepperstone:

They also use cTrader.

Not 100% sure about them accepting Canadians though.

 


@firemyst

firemyst
30 Aug 2020, 16:06

RE: RE: RE: RE: Example code for quick tip:

.

 


@firemyst

firemyst
30 Aug 2020, 14:55

RE: RE: Example code for quick tip:

voldemort said:

Only difference is I used Bars instead of MarketSeries. Will give this a go. Thanks :)

that should have been "Bars" and not MarketSeries.

I've updated the code in the example.

If it's still not working, it's something else with your code or what you're doing, so you'll need to post some sample code.


@firemyst

firemyst
30 Aug 2020, 12:54

What you need to do is:

1) get the position open time

2) create a timer object

3) when 15 minutes has passed on the timer object, trigger it to call a method. That method could be the close method, which closes your position.

Examples for the C# timer object:

https://docs.microsoft.com/en-us/dotnet/api/system.timers.timer?view=netcore-3.1

and

https://stackoverflow.com/questions/12535722/what-is-the-best-way-to-implement-a-timer


@firemyst

firemyst
30 Aug 2020, 12:43

Example code for quick tip:

 public override void Calculate(int index)
        {
            int altIndex = index;

            altIndex = Bars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            //Reference any values from a different timeframe with the altIndex
            double median = (Bars.HighPrices[altIndex] + Bars.LowPrices[altIndex]) / 2;

	   Result[index] = median;
	}

 

Hope this helps :-)

 

 


@firemyst

firemyst
30 Aug 2020, 12:36

In Visual Studio:

  • Right Click on your project and select 'Add reference'

  • Select 'Assemblies->Framework' in 'Reference Manager' window.

  • Add select Microsoft.CSharp.dll and click on add

 

You might also try this link:

https://stackoverflow.com/questions/13566887/dynamic-in-the-immediate-window-causes-microsoft-csharp-runtimebinder-binder-i?lq=1

 


@firemyst

firemyst
30 Aug 2020, 12:30

Hi @Vitore:

When you report bugs like this, you should include screen shots or code samples which illustrate the issue.

It will help others see what's happening, and help Spotware diagnose the issue if in fact it is an issue.

 


@firemyst

firemyst
30 Aug 2020, 12:28

Have you looked at the online guides @Spotware have posted?

https://help.ctrader.com/ctrader-automate/guides/trading_api

 

As for me, I went the cTrader route because it uses C#, which to me is easier because I already knew it. :-)

MT5 will definitely have more support and more options available though because that seems to be the standard in the industry MetaTrader.

If you plan to do any other kind of programming other than for bots/indicators (eg, writing your own Windows applications or whatever), then you should learn C#; otherwise it's up to you.


@firemyst

firemyst
26 Aug 2020, 14:33

Here's an example how. You have to get the current date in your code:

if (_currentDate.DayOfWeek != DayOfWeek.Friday && _currentDate.DayOfWeek != DayOfWeek.Saturday && _currentDate.DayOfWeek != DayOfWeek.Sunday)
{

}

 


@firemyst

firemyst
26 Aug 2020, 14:28

Have you run this code in Visual Studio or put in "Print" statements to see if the actual calls to ModifiyPosition are called?

You have quite a bit of "IF" statements, so how do you know any of those are true to execute the modifyposition method?


@firemyst

firemyst
26 Aug 2020, 14:24

This is relatively easy.

See code example below. You'll obviously have to make adjustments for it to fit in your code.

 

//you need to set this up as a parameter
StopBotWhenLossesFallBelow


double _runningTotalsGainLoss;
string _positionLabel;

        private void Positions_Closed(PositionClosedEventArgs args)
        {
            //Only run this method if it's this instance that closed.
            Position p1 = args.Position;

            if (p1.SymbolName == Symbol.Name && p1.Label == _positionLabel)
            {
                    //Now get the historical trade stuff.
                    HistoricalTrade ht = History.FindLast(p1.Label, p1.SymbolName, p1.TradeType);

                        //Running Totals
                        _runningTotalsGainLoss += p1.NetProfit;
                        Print("PC20: Running total for \"{0}\": {1}", p1.Label, String.Format("{0:$#,###.00}", _runningTotalsGainLoss));
                        if (_runningTotalsGainLoss < StopBotWhenLossesFallBelow)
                        {
                            Print("WARNING! Running total {0} has fallen below StopBotWhenLossesFallBelow {1} threshold! Stopping bot for \"{2}\"!", String.Format("{0:$#,###.00}", _runningTotalsGainLoss), String.Format("{0:$#,###.00}", StopBotWhenLossesFallBelow), p1.Label);
							Stop();
                        }
            }

        }

 


@firemyst

firemyst
17 Aug 2020, 12:43

Serialize it to JSON, save the JSON to a text file.

Then when you restart and restart your bot/indicator, in the OnStart or Initialize methods, you can read the json back in and convert it back to a 2-dimensional array.

Example code:

//In the OnStart method:

            // read saved file into a string and deserialize JSON to a type
            RobotInfoClass ric = null;
            if (System.IO.File.Exists(_savedFilePath))
            {
                ric = JsonConvert.DeserializeObject<RobotInfoClass>(System.IO.File.ReadAllText(_savedFilePath));
                System.IO.File.Delete(_savedFilePath);  //clean up since we no longer need it
            }

///////////////////////////////////////

//In the OnStop method:

using (System.IO.StreamWriter sw = new System.IO.StreamWriter(_savedFilePath))
                {
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        RobotInfoClass ric = new RobotInfoClass();
                        ric._positionEntryPricePoints = _positionEntryPricePoints;
                        ric._positionEntryPriceTimes = _positionEntryPriceTimes;
                        ric._breakEvenPoints = _breakEvenPoints;
                        ric._increasePositionSizePoints = _increasePositionSizePoints;
                        //blah blah blah
                        ric._savedTime = DateTime.Now;

                        JsonSerializer serializer = new JsonSerializer();
                        serializer.Formatting = Formatting.Indented;
                        serializer.Serialize(writer, ric);
                    }
                }

 


@firemyst