Multiple Instances

02 Sep 2017, 07:41Multiple Instances#1
hungtonydangposts: 59since: 19 Jul 2017

I am trying to modify my code to handle multiple instances now and am running into a bit of trouble.

            var toppre = BB.Top.Last(1);
            var bottompre = BB.Bottom.Last(1);
            var StopLoss = BB.Main.Last(0);
            var topnow = BB.Top.Last(0);
            var bottomnow = BB.Bottom.Last(0);
            var volumeInUnits = Symbol.QuantityToVolume(Quantity);

            foreach (var position in Positions)
            {
                ModifyPositionAsync(position, StopLoss, position.TakeProfit);
                Print("New Position SL price is {0}", position.StopLoss);

That is the sample of code that has the problem so far. The cbot changes only 1 order correctly to have the right valued stop loss however for other instances the values seems very obsecure and I can't explain it.

It has set two of my other instances in which I ran the cbot to be 580 pips and 1080 pip stop loss respectively however according to the code the value should be only about 40 pips. Is this a bug or is it something in my code?

04 Sep 2017, 09:01#2
Spotwareposts: 3274since: 23 Sep 2013

Dear hungtonydang,

Can we have a complete cBot that reproduces this issue to check and advise accordingly? We cannot see anything suspicious in the code provided but information is missing, e.g. we cannot see how the StopLoss value is set.

Also note that ModifyPositionAsync() is an asynchronous function and there is no guarantee that it will be executed before Print(). Try ModifyPosition() instead and let us know if the problem still applies.

Best Regards,

cTrader Team


TRADERS FIRST™ Vote for your favorite features: http://vote.spotware.com/
05 Sep 2017, 00:18#3
hungtonydangposts: 59since: 19 Jul 2017
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Requests;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Threading;
using System.Threading.Tasks;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.None)]
    public class HunterBB : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 40, MinValue = 1)]
        public int StopLossInPips { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 28, MinValue = 1)]
        public int TakeProfitInPips { get; set; }

        [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        [Parameter("Bollinger Bands Deviations", DefaultValue = 2)]
        public double Deviations { get; set; }

        [Parameter("Bollinger Bands Periods", DefaultValue = 20)]
        public int Periods { get; set; }

        [Parameter("Bollinger Bands MA Type")]
        public MovingAverageType MAType { get; set; }

        [Parameter("Position Id", DefaultValue = "Pid")]
        public string PositionId { get; set; }

        BollingerBands BB;

        protected override void OnStart()
        {
            BB = Indicators.BollingerBands(Source, Periods, Deviations, MAType);
        }

        protected override void OnBar()
        {
            var toppre = BB.Top.Last(1);
            var bottompre = BB.Bottom.Last(1);
            var StopLoss = BB.Main.Last(0);
            var topnow = BB.Top.Last(0);
            var bottomnow = BB.Bottom.Last(0);
            var volumeInUnits = Symbol.QuantityToVolume(Quantity);
            
            foreach (var position in Positions)
            {
                ModifyPositionAsync(position, StopLoss, position.TakeProfit);
                Print("New Position SL price is {0}", position.StopLoss);
            }
                    if (_lastExecutedOrder.AddHours(CD) < DateTime.Now)
                    {
                        ExecuteMarketOrderAsync(TradeType.Buy, Symbol, volumeInUnits, PositionId, null, TakeProfitInPips);
                        _lastExecutedOrder = DateTime.Now;
                    }
            }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

Hi Ctrader team,

That is the code there, like I said when I run multiple instances of this code only 1 instance gets the Stop loss value right, do I have to manually assign a position finder and bind it to the indicator on that symbol to get the correct abdolute value? 

Thanks in advance, I may have a work around that I am testing but just wanted your opinion too.

05 Sep 2017, 09:26#4
Spotwareposts: 3274since: 23 Sep 2013

Dear hungtonydang,

Thanks for sending us the cBot. Unfortunately we cannot build it since CD and _lastExecutedOrder are not defined. Can you please send us a cBot that builds successfully so that we do not need to make any assumptions?

Best Regards,

cTrader Team


TRADERS FIRST™ Vote for your favorite features: http://vote.spotware.com/
05 Sep 2017, 16:13#5
hungtonydangposts: 59since: 19 Jul 2017

Sorry have been cutting and pasting multiple versions of the code and trying to get it work properly. Here is the code

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Requests;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Threading;
using System.Threading.Tasks;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.None)]
    public class HunterBB : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 40, MinValue = 1)]
        public int StopLossInPips { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 28, MinValue = 1)]
        public int TakeProfitInPips { get; set; }

        [Parameter("Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        [Parameter("Bollinger Bands Deviations", DefaultValue = 2)]
        public double Deviations { get; set; }

        [Parameter("Bollinger Bands Periods", DefaultValue = 20)]
        public int Periods { get; set; }

        [Parameter("Bollinger Bands MA Type")]
        public MovingAverageType MAType { get; set; }

        [Parameter("Position Id", DefaultValue = "Pid")]
        public string PositionId { get; set; }

        BollingerBands BB;
        private DateTime _lastExecutedOrder;

        protected override void OnStart()
        {
            BB = Indicators.BollingerBands(Source, Periods, Deviations, MAType);
        }

        protected override void OnBar()
        {
            var toppre = BB.Top.Last(1);
            var bottompre = BB.Bottom.Last(1);
            var StopLoss = BB.Main.Last(0);
            var topnow = BB.Top.Last(0);
            var bottomnow = BB.Bottom.Last(0);
            var volumeInUnits = Symbol.QuantityToVolume(Quantity);

            foreach (var position in Positions)
            {
                ModifyPositionAsync(position, StopLoss, position.TakeProfit);
                Print("New Position SL price is {0}", position.StopLoss);
            }
            if (_lastExecutedOrder.AddHours(8) < DateTime.Now)
            {
                ExecuteMarketOrderAsync(TradeType.Buy, Symbol, volumeInUnits, PositionId, null, TakeProfitInPips);
                _lastExecutedOrder = DateTime.Now;
            }
        }

        protected override void OnStop()
        {
            Stop();
        }
    }
}

 

06 Sep 2017, 11:03#6
Spotwareposts: 3274since: 23 Sep 2013

Dear hungtonydang,

Thanks for the cBot. Can you please also verify that with "multiple instances" you mean that you run the cBot on different charts at the same time? If this is the case, is it running on charts of the same symbol? Is it possible to provide us with charts that you run the instances as well as exact cBot parameters? We need you to provide us as much information as possible so that we can reproduce you problem.

Best Regards,

cTrader Team


TRADERS FIRST™ Vote for your favorite features: http://vote.spotware.com/
06 Sep 2017, 12:06#7
hungtonydangposts: 59since: 19 Jul 2017

Hi there Ctrader team,

I had this one cbot code running on 4 different charts at the time I came across the error. It was running on eurusd gbpusd usdcad and usdyen. All trades triggered as per logic however only 1 trade had the correct value for the stoploss and all others were off by 1000 or so pips. All the input parameters I kept as default, but would like to adjust these as I like the feature of running the same cbot across multiple instances and changing these parameters to suit. 

My initial thought is you have to bind the variable I have set for the stoploss to the symbol, but then shouldn't that already be the case when I declared the source or do I need to declare the symbol as a parameter too?

Much appreciated help on this as I would like to run the cbot across multiple currency pairs. 

06 Sep 2017, 12:23#8
Spotwareposts: 3274since: 23 Sep 2013

Hi hungtonydang,

If you are running multiple instances of the cBot on different symbols, then you should reconsider your logic, since in the OnBar() function you are altering not only the positions related to the symbol that the cBot is running but all open positions for all symbols. Probably this is the reason of the weird stop losses. You seem to be changing the stop loss of a position based on a Bollinger Band of another symbol.

Can you please check it and let us know?

Best Regards,

cTrader Team


TRADERS FIRST™ Vote for your favorite features: http://vote.spotware.com/
06 Sep 2017, 12:42#9
hungtonydangposts: 59since: 19 Jul 2017

Thanks ctrader team that was my guess. I am going to run some more tests tonight including the following but would like your thoughts. 

Rather than multiple instances on the one cbot would the code run right if it was an individual cbot run across multiple instances with the same logic. ie gpbusd eurusd usdyen but each has its own cbot of cbot1 cbot2 cbot3 but all 3 cbots have the same code logic. Would this scenario make the parameters work right?

06 Sep 2017, 16:11#10
Spotwareposts: 3274since: 23 Sep 2013

Hi hungtonydang,

No this would not work since the problem is that you execute your code considering all open Positions each time. What you need to do is to consider the positions that have the same Symbol as the chart on which the Symbol is running on. Try adding the following condition before modifying your position

if (Symbol.Code == position.SymbolCode)

Best Regards,

cTrader Team


TRADERS FIRST™ Vote for your favorite features: http://vote.spotware.com/