Replies

Prospect
03 May 2022, 19:29

RE:

Prospect said:

Is it possible to programmatically start/stop bots from another bot? 

It might be nice to have a watcher/manager that starts/stops bots based on different market conditions, perhaps even based on monitored profitability, maybe programmatically ran optimisation when required. 

I get that you could write all of this into one bot (less the optimisation part), but I'm interested if anyone has explored this "manager bot" idea? 

Just found conversations going back to 2015 asking for this functionality, would delete my original post if I could....


@Prospect

Prospect
14 Apr 2022, 12:42

RE:

amusleh said:

Hi,

The convergence and divergence are two very broad topics and subjective.

But I will give you an example that might help you:

using System;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo.Indicators

{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        private MovingAverage _fastMa, _slowMa;

        [Parameter("Convergence", DefaultValue = 10, Group = "Thresholds (Pips)")]
        public double ConvergenceThresholds { get; set; }

        [Parameter("Divergence", DefaultValue = 20, Group = "Thresholds (Pips)")]
        public double DivergenceThresholds { get; set; }

        [Parameter("Periods", DefaultValue = 10, Group = "Fast MA")]
        public int FastMaPeriods { get; set; }

        [Parameter("Source", Group = "Fast MA")]
        public DataSeries FastMaSource { get; set; }

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

        [Parameter("Periods", DefaultValue = 20, Group = "Slow MA")]
        public int SlowMaPeriods { get; set; }

        [Parameter("Source", Group = "Slow MA")]
        public DataSeries SlowMaSource { get; set; }

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

        [Output("Convergence", LineColor = "Green", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Convergence { get; set; }

        [Output("Divergence", LineColor = "Red", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Divergence { get; set; }

        [Output("Normal", LineColor = "Yellow", PlotType = PlotType.Histogram)]
        public IndicatorDataSeries Normal { get; set; }

        protected override void Initialize()
        {
            _fastMa = Indicators.MovingAverage(FastMaSource, FastMaPeriods, FastMaType);
            _slowMa = Indicators.MovingAverage(SlowMaSource, SlowMaPeriods, SlowMaType);

            ConvergenceThresholds *= Symbol.PipSize;
            DivergenceThresholds *= Symbol.PipSize;
        }

        public override void Calculate(int index)
        {
            var distance = _fastMa.Result[index] - _slowMa.Result[index];
            var distanceAbs = Math.Abs(distance);

            Convergence[index] = double.NaN;
            Divergence[index] = double.NaN;
            Normal[index] = double.NaN;

            if (distanceAbs <= ConvergenceThresholds)
            {
                Convergence[index] = distance;
            }
            else if (distanceAbs >= DivergenceThresholds)
            {
                Divergence[index] = distance;
            }
            else
            {
                Normal[index] = distance;
            }
        }
    }
}

 

Thanks, there's some stuff in there I can research further/work with!


@Prospect

Prospect
14 Apr 2022, 09:24

RE:

I can find lots of references for when indicators have crossed, but nothing for when they're starting to converge and therefore might cross, or conversely when they start diverging. I have no idea whether this is actually useful, but it's a decent learning exercise. 

So for example, if you have MA's for two different periods, is it as simple as creating a new data series or array to contain the differences between the MA's, then looping through the last n indexes to see if the values are progressively bigger/smaller? 

 


@Prospect

Prospect
13 Apr 2022, 18:23

RE:

Prospect said:

Hi,

Symbol.PipValue for GBPUSD returns 7.66...........E-05, but in the "New Order" dialogue in the GUI it shows the Pip Value as £0.07, is this because the minimum tradable amount (Symbol.VolumeInUnitsMin) is 1000? Confused!

Thanks.

Ahh, the pip value is based on the volume I enter. Got it!


@Prospect

Prospect
12 Apr 2022, 10:51

RE: RE: RE:

amusleh said:

Prospect said:

xabbu said:

Thank you very much, Panagiotis - I think I have found a way to prevent multiple execution due to the speed of the ...async functionality. 

Do you mind sharing your solution to this?

Hi,

This might help you:

using cAlgo.API;

namespace NewcBot
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        private TradeOperation _operation;

        protected override void OnStart()
        {
            // Execute a new market order only if there is no ongoing operation
            if (_operation == null)
            {
                _operation = ExecuteMarketOrderAsync(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin, ExecuteMarketOrderCallback);
            }
        }

        private void ExecuteMarketOrderCallback(TradeResult result)
        {
            _operation = null;

            // use result for getting the opened position
            // or error if there was any
        }
    }
}

 

Thank you


@Prospect

Prospect
11 Apr 2022, 23:11

RE:

xabbu said:

Thank you very much, Panagiotis - I think I have found a way to prevent multiple execution due to the speed of the ...async functionality. 

Do you mind sharing your solution to this?


@Prospect

Prospect
09 Apr 2022, 08:52

RE:

amusleh said:

Hi,

You will be able to use any .NET IDE for developing cBots/Indicators after cTrader 4.2, you can try it by using Spotware cTrader Beta.

cTrader 4.2 is not released yet for brokers.

Thanks for the info.


@Prospect

Prospect
25 Nov 2014, 15:42

RE: RE:

jobenb said:

badmonkeyface said:

Hi All,

Is it possible to download the backtest data to an external format through the platform?

Essentially I'm trying to get the backtest data in a format such as CSV to run through an external system to then feed back into an indicator.

Thanks.

There is unfortunately no such function within the platform.

One option would be to write a cBot that writes every tick in OnTick to a file and then run a backtest with the historical tick data that you want to export.

Good idea, I hadn't thought of that!

I had resorted to historical data from dukascopy although there seems to be much debate around the completeness of the data.

Thanks.


@Prospect

Prospect
14 Oct 2014, 20:40

RE:

Yep, that worked. It's under HKCU for anyone else reading this.

Spotware said:

You can try to remove the following registry key: Software\\Microsoft\\VisualStudio\\10.0\\ExtensionManager\\EnabledExtensions\\2c72cc50-6c69-4b16-b1f4-ab470673f284,1.4

 

 


@Prospect

Prospect
13 Oct 2014, 21:33

I was able to install the extension using the above process however still nothing happens when I click edit in visual studio.

Any clues?

Thanks.


@Prospect

Prospect
13 Jun 2014, 12:26

That's looking better now. Thanks.


@Prospect

Prospect
13 Jun 2014, 12:14

RE: RE:

badmonkeyface said:

Spotware said:

You can try to use OnBar method instead of OnTick. Please don't forget that last bar is not formed in OnBar method and you need to take values from previous index.

OK, that makes sense, I'll give it ago with something like this?


            int lastIndex = MarketSeries.Close - 2;
            int prevIndex = MarketSeries.Close - 3;

Thanks.

This is what I meant:

            int lastIndex = MarketSeries.Close.Count - 2;
            int prevIndex = MarketSeries.Close.Count - 3;

 


@Prospect

Prospect
13 Jun 2014, 12:13

RE:

Spotware said:

You can try to use OnBar method instead of OnTick. Please don't forget that last bar is not formed in OnBar method and you need to take values from previous index.

OK, that makes sense, I'll give it ago with something like this?


            int lastIndex = MarketSeries.Close - 2;
            int prevIndex = MarketSeries.Close - 3;

Thanks.


@Prospect

Prospect
09 Jun 2014, 23:36

Well I guess the lack of responses means it wasn't a stupid question.

I found the solution anyway for anyone reading this.

            if (previousSignalval > previousMDval && currentSignalval < currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine", index, Colors.Red, 1, LineStyle.Dots);
            }
 
            if (previousSignalval < previousMDval && currentSignalval > currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine2", index, Colors.Green, 1, LineStyle.Dots);
            }

The above creates only two instances of vertical lines vLine and vline2, fairly obviously really, so you only ever see two lines which move with new data. Again, obvious during open trading as you see them move, not so otherwise. Suffixing the vLine strings with +index had the desired effect.

 


@Prospect

Prospect
07 Jun 2014, 20:19

My mistake, index 0 is at the beginning of the chart where I expected it to be, I still have no idea why more vertical lines weren't plotted.


@Prospect

Prospect
07 Jun 2014, 15:07

I'm still interested in peoples thoughts on the above as it'll help me better understand the platform, but I have also tried a different approach to this:

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;


namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC)]
    public class NewIndicator : Indicator
    {
        [Parameter()]
        public DataSeries Source { get; set; }

        [Parameter(DefaultValue = 100)]
        public int percentPeriod { get; set; }

        [Parameter(DefaultValue = 9)]
        public double EMAperiod { get; set; }

        [Output("MDMACD", Color = Colors.Blue)]
        public IndicatorDataSeries MDResult { get; set; }

        [Output("MDEMA", Color = Colors.Red)]
        public IndicatorDataSeries SignalResult { get; set; }

        MDCD mdcd;


        protected override void Initialize()
        {
            mdcd = Indicators.GetIndicator<MDCD>(Source, percentPeriod, EMAperiod);
        }

        public override void Calculate(int index)
        {

            double previousSignalval = mdcd.MDEMAResult[index - 1];
            double currentSignalval = mdcd.MDEMAResult[index];

            double previousMDval = mdcd.MDMACD[index - 1];
            double currentMDval = mdcd.MDMACD[index];


            if (previousSignalval > previousMDval && currentSignalval < currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine", index, Colors.Red, 1, LineStyle.Dots);
            }

            if (previousSignalval < previousMDval && currentSignalval > currentMDval)
            {
                ChartObjects.DrawVerticalLine("vLine2", index, Colors.Green, 1, LineStyle.Dots);
            }

            MDResult[index] = mdcd.MDMACD[index];
            SignalResult[index] = mdcd.MDEMAResult[index];
        }
    }
}

What I have found is that it produces something that looks like this:

I was expecting to see those green and red vertical lines all the way back through the chart. When I only saw them at the end I started printing the indexes and some other info to the log, I can see that index 0 is reached on the 6th June so is this why I don't have vertical lines plotted further back? Is this just the way that the platform works or is there something I need to do differently?


@Prospect

Prospect
26 Mar 2014, 12:04

RE:

Spotware said:

        public override void Calculate(int index)
        {
            spread1[index] = Math.Round(symbol1.Spread / symbol1.PipValue, 1);

Such expression is not correct, because Symbol.Spread is a current value of Spread. You can not match historical index with current value of spread. Probably you will see line with the same value in every point.

Perfect, that's what I needed to know thanks. Seems obvious now in the API reference "The current spread of this symbol", as opposed to something like "Open price series of historical trendbars".


@Prospect