Topics
14 Dec 2019, 23:09
 1
 1386
 1
14 Dec 2019, 15:02
 3
 1328
 1
14 Dec 2019, 14:57
 5
 1282
 2
29 Nov 2019, 11:59
 1
 1250
 1
17 Nov 2019, 01:49
 7
 1888
 1
17 Nov 2019, 01:46
 6
 1509
 1
17 Nov 2019, 01:43
 4
 1215
 1
Add-ons

cTrader Automate

Suggestions
17 Nov 2019, 01:34
 3
 1524
 1
17 Nov 2019, 01:32
 3
 1336
 1
17 Nov 2019, 01:31
 6
 1274
 1
17 Nov 2019, 01:29
 2
 1238
 1
20 Feb 2019, 19:23
 1387
 4
21 Jan 2018, 16:53
 0
 1780
 1
Replies

whis.gg
17 Nov 2019, 02:06

Corner radius doesn't work on TextBlock and TextBox? I haven't tested other controls so it might be totally broken as well.


@whis.gg

whis.gg
17 Nov 2019, 01:23

RE:

Panagiotis Charalampous said:

Hi Xavier R,

This is a bug. We will fix it in an update.

Best Regards,

Panagiotis

Please, leave it as a feature so we can render custom price markers in the axis.


@whis.gg

whis.gg
17 Nov 2019, 01:20

Hi,

Would it be possible to add Z-order/index property? If we would be able to render controls behind bars that would be great too.

Thanks,
Jiri


@whis.gg

whis.gg
21 Feb 2019, 11:59

Hi Panagiotis,

For example, if I have an indicator that overrides chart colour, or setting (showing grid let's say) I would like to revert to default state once the indicator is detached from the chart. Or let's say I have something more complex, like an indicator which uses multiple threads, right now I have to make it check if parent thread is still alive, instead I could simply kill them when it's being detached.


@whis.gg

whis.gg
24 Jan 2019, 01:52

Just a friendly follow-up, is this going to be fixed any time soon?


@whis.gg

whis.gg
24 Jan 2019, 01:51

Might I get an answer on this, please?


@whis.gg

whis.gg
04 Mar 2018, 00:04

RE:

tmc. said:

Backtesting is much slower than before. Is this going to be improved when it's officially released?

Results of speed test with m1 bars from a server for last 7 years:

cAlgo 2.01  : Backtest duration:  4.798 seconds, 2558195 ticks, 43056 bars
cTrader 3.0 : Backtest duration: 88.014 seconds, 2541006 ticks, 42878 bars

The code used for testing:

using System;
using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SpeedTest : Robot
    {
        private DateTime _startTime;
        private int _processedTicks, _processedBars;

        protected override void OnStart()
        {
            _startTime = DateTime.Now;
        }

        protected override void OnBar()
        {
            _processedBars++;
        }

        protected override void OnTick()
        {
            _processedTicks++;
        }

        protected override void OnStop()
        {
            var duration = DateTime.Now.Subtract(_startTime);

            Print("Backtest duration: {0:0.###} seconds, {1} ticks, {2} bars", duration.TotalSeconds, _processedTicks, _processedBars);
        }
    }
}

 


@whis.gg

whis.gg
03 Mar 2018, 23:32

Backtesting is much slower than before. Is this going to be improved when it's officially released?


@whis.gg

whis.gg
20 Feb 2018, 21:57

It's happening inside of robot as well, which makes it really annoying since the robot hasn't IsRealTime property which I could pass to the referenced indicator. Please fix it!


@whis.gg

whis.gg
20 Feb 2018, 21:19

Any update?


@whis.gg

whis.gg
13 Feb 2018, 00:45

Or I should rather ask if the API is ever going to be updated or am I supposed to write my own methods to calculate basic stuff and do not rely on the API at all?


@whis.gg

whis.gg
09 Feb 2018, 20:44

Not sure how this is a workaround but thanks for the information about the messages being sent later. I have applied this logic which seems to work.

private void Positions_Opened(PositionOpenedEventArgs e)
{
    if (e.Position.Label != "label")
    {
        return;
    }

    if (IsBacktesting)
    {
        Print("{0} filled (TP: {1} SL: {2})", e.Position.Comment, e.Position.TakeProfit, e.Position.StopLoss);
    }
    else
    {
        var task = new Task(() =>
        {
            Thread.Sleep(50);
            BeginInvokeOnMainThread(() => Print("{0} filled (TP: {1} SL: {2})", e.Position.Comment, e.Position.TakeProfit, e.Position.StopLoss));
        });

        task.Start();
    }
}

 


@whis.gg

whis.gg
09 Feb 2018, 15:45

Any progress? I find it as a critical bug since I can't get TP and SL values of filled pending orders on the position opened event using the API.


@whis.gg

whis.gg
09 Feb 2018, 15:35

RE: RE:

itmfar said:

you are genius . thank you so much. it really saves my time :)

You're welcome.


@whis.gg

whis.gg
08 Feb 2018, 21:58

Works on my end.

using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class testRefresh : Indicator
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType maType { get; set; }

        private StochasticOscillator _stochastic;
        private readonly List<bool> _ssdRising = new List<bool>();

        protected override void Initialize()
        {
            _stochastic = Indicators.StochasticOscillator(9, 3, 9, maType);
        }

        public override void Calculate(int index)
        {
            var lastIndex = _ssdRising.Count - 1;
            if (lastIndex < index)
            {
                _ssdRising.Add(_stochastic.PercentD.IsRising());
            }
            else
            {
                _ssdRising[lastIndex] = _stochastic.PercentD.IsRising();
            }

            FindSSCrossovers(index);
            DrawLinesSSD(index);
        }

        private void FindSSCrossovers(int index)
        {
            if (_stochastic.PercentD.HasCrossedAbove(_stochastic.PercentK, 0))
            {
                ChartObjects.DrawText("MAXss1" + index, "S⮟", index, Source[index], VerticalAlignment.Top, HorizontalAlignment.Center, Colors.Yellow);
            }
            else
            {
                ChartObjects.RemoveObject("MAXss1" + index);
            }

            if (_stochastic.PercentK.HasCrossedAbove(_stochastic.PercentD, 0))
            {
                ChartObjects.DrawText("Minss1" + index, "S⮝", index, Source[index], VerticalAlignment.Bottom, HorizontalAlignment.Center, Colors.Yellow);
            }
            else
            {
                ChartObjects.RemoveObject("Minss1" + index);
            }
        }

        private void DrawLinesSSD(int index)
        {
            if (_ssdRising[index - 1] != _ssdRising[index] && _stochastic.PercentD[index] > 60 && _ssdRising[index] == false)
            {
                ChartObjects.DrawText("maxrssd" + index, "D⮟", index, Source[index], VerticalAlignment.Top, HorizontalAlignment.Center, Colors.White);
            }
            else
            {
                ChartObjects.RemoveObject("maxrssd" + index);
            }

            if (_ssdRising[index - 1] != _ssdRising[index] && _stochastic.PercentD[index] < 40 && _ssdRising[index] == true)
            {
                ChartObjects.DrawText("minrssd" + index, "D⮝", index, Source[index], VerticalAlignment.Bottom, HorizontalAlignment.Center, Colors.White);
            }
            else
            {
                ChartObjects.RemoveObject("minrssd" + index);
            }
        }
    }
}

 


@whis.gg

whis.gg
07 Feb 2018, 17:12

Sorry, there was a typo in the code.

private void Positions_Closed(PositionClosedEventArgs e)
{
    var takeProfit = e.Position.TakeProfit;
    var stopLoss = e.Position.StopLoss;
    var closingPrice = History.First(x => x.PositionId == e.Position.Id).ClosingPrice;
 
    if (e.Position.TradeType == TradeType.Buy ? closingPrice >= takeProfit : closingPrice <= takeProfit)
    {
        Print("Position {0} closed by TP", e.Position.Id);
    }
    else if (e.Position.TradeType == TradeType.Buy ? closingPrice <= stopLoss : closingPrice >= stopLoss)
    {
        Print("Position {0} closed by SL", e.Position.Id);
    }
    else
    {
        Print("Position {0} closed manually", e.Position.Id);
    }
}

 


@whis.gg

whis.gg
07 Feb 2018, 17:09

Hi,

How about this? You might need to add some tolerance due to slippage though.

private void Positions_Closed(PositionClosedEventArgs e)
{
    var takeProfit = e.Position.TakeProfit;
    var stopLoss = e.Position.StopLoss;
    var closingPrice = History.First(x => x.PositionId == e.Position.Id).ClosingPrice;

    if (e.Position.TradeType == TradeType.Buy ? closingPrice >= takeProfit : closingPrice <= takeProfit)
    {
        Print("Position {0} closed by TP", e.Position.Id);
    }
    else if (position.TradeType == TradeType.Buy ? closingPrice <= stopLoss : closingPrice >= stopLoss)
    {
        Print("Position {0} closed by SL", position.Id);
    }
    else
    {
        Print("Position {0} closed manually", position.Id);
    }
}

 


@whis.gg

whis.gg
07 Feb 2018, 14:48

Hi itmfar,

The Calculate() method is called on each bar when processing historical data and on each incoming tick when processing real-time data. You should be adding a new element to the list only on a new bar. Try this:

var lastIndex = ssdRising.Count - 1;

if (index > lastIndex)
{
    ssdRising.Add(_stochastic.PercentD.IsRising());
}
else
{
    ssdRising[lastIndex] = _stochastic.PercentD.IsRising();
}

Also, you should remove chart objects if the conditions are not met. Otherwise, it might remain there from previous tick before a bar is closed and show false results.


@whis.gg

whis.gg
26 Jan 2018, 00:42

Is it going to be fixed any time soon?


@whis.gg