Two Issues. 1st-ConnectionTest. 2nd-BollingerBand data giving NaN error.

Created at 09 Feb 2020, 04:43
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
TH

thoy1

Joined 15.02.2018

Two Issues. 1st-ConnectionTest. 2nd-BollingerBand data giving NaN error.
09 Feb 2020, 04:43


Hi All,

So I have two separate issues. This post is the first issue to do with the ConnectionTest bot. The response to this is the second issue to do with BollingerBands.

1st - My Bot to test Server.IsConnected doesn't seem to do anything. Why is this? The first screenshot shows the internet as connected, second screenshot shows it as disconnected. The console should be printing "Disconnected" continuously while there is no connection to the server. Is there something wrong with the coding or my understanding of how IsConnected works?? Code is below the Screen Shots. TIA

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ConnectionTest : Robot
    {

        protected override void OnStart()
        {
            // Put your initialization logic here
            System.Threading.Thread.Sleep(2500);
        }

        protected override void OnTick()
        {
            // Test connection to server
            if (Server.IsConnected == false)
            {
                Reconnection();
            }
        }

        private void Reconnection()
        {
            // Loop until IsConnected == true
            if (Server.IsConnected == false)
            {
                Print("Disconnected");
                System.Threading.Thread.Sleep(1000);
                Reconnection();
            }
            // Give ctrader time to update market changes that occured while disconnected.
            else if (Server.IsConnected == true)
            {
                System.Threading.Thread.Sleep(5000);
                Print("Reconnected");
            }
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@thoy1
Replies

thoy1
09 Feb 2020, 05:22

This is the second issue to do with Bollinger Band data.

In this Bot I am trying to find out the numerical value of the Top and Bottom bands. Both of the lines are bring up a NaN (Not a Number) error. As a result, trades are not being placed when I would expect them to be. How do I convert bb1.Top.LastValue and bb1.Bottom.LastValue into numbers? TIA

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class BollingerTest : Robot
    {
//Instrument Information------------------------------------------------------------------------------------------------------------------------------------------Instrument Information
        [Parameter("Symbol 1", DefaultValue = "AUDCAD", Group = "Instrument Info")]
        public string symbol_1 { get; set; }

//Protection Settings------------------------------------------------------------------------------------------------------------------------------------------------Protection Settings
        [Parameter("Take Profit Strength:", DefaultValue = 70, Group = "Protection Settings")]
        public double tpstrength { get; set; }
        [Parameter("Stop Loss Strength:", DefaultValue = 30, Group = "Protection Settings")]
        public double slstrength { get; set; }
        [Parameter("Range percent for order trigger:", DefaultValue = 85, Group = "Protection Settings")]
        public double range { get; set; }

//Declarations--------------------------------------------------------------------------------------------------------------------------------------------------------------Declarations
        private SimpleMovingAverage ma1;
        private Bars series1;
        private Symbol symbol1;
        private BollingerBands bb1;

//On Start//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Start
        protected override void OnStart()
        {
            if (string.IsNullOrWhiteSpace(symbol_1) == false)
            {
                Print("Symbol 1 = {0}", symbol_1);
            }
        }

//On Bar//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Bar
        protected override void OnBar()
        {
            symbol1 = Symbols.GetSymbol(symbol_1);
            series1 = MarketData.GetBars(TimeFrame.Daily, symbol_1);
            ma1 = Indicators.SimpleMovingAverage(series1.MedianPrices, 90);
            bb1 = Indicators.BollingerBands(ma1.Result, 90, 2.5, MovingAverageType.Simple);

            if (string.IsNullOrWhiteSpace(symbol_1) == false)
            {
                Print("pass");

                double s1range = (bb1.Top.LastValue - bb1.Bottom.LastValue);
                double s1sell = bb1.Bottom.LastValue + (s1range * (range / 100));
                double s1buy = bb1.Top.LastValue - (s1range * (range / 100));
                double s1sl = s1range * (slstrength / 100);
                double s1tp = s1range * (tpstrength / 100);
                double s1vol = 1000;

                Print("s1sell: {0}", s1sell);
                Print("s1buy: {0}", s1buy);
                Print("ask = {0}", symbol1);
                Print("Top: {0}", bb1.Top.LastValue);
                Print("Bottom: {0}", bb1.Bottom.LastValue);
                Print("Pos Count: {0}", Positions.Where(x => x.SymbolName == symbol_1).Count());

                if (Positions.Where(x => x.SymbolName == symbol_1).Count() < 1)
                {
                    if (symbol1.Ask >= s1sell)
                    {
                        ExecuteMarketOrder(TradeType.Sell, symbol_1, s1vol, "" + symbol_1 + "_Sell", s1sl, s1tp);
                    }
                    else if (symbol1.Bid <= s1buy)
                    {
                        ExecuteMarketOrder(TradeType.Buy, symbol_1, s1vol, "" + symbol_1 + "_Buy", s1sl, s1tp);
                    }
                }
            }
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@thoy1

PanagiotisCharalampous
10 Feb 2020, 08:48

Hi thoy1,

1) You have placed your checks in OnTick. If the server is disconnected, you will not receive any ticks hence no checks will be made. Use a timer instead.

2) I could not reproduce any NaN values with your BollingerTest. Can you provide exact steps to reproduce this problem and post some screenshots as well?

Best Regards,

Panagiotis 

Join us on Telegram

 


@PanagiotisCharalampous

thoy1
10 Feb 2020, 09:36 ( Updated at: 21 Dec 2023, 09:21 )

RE:

PanagiotisCharalampous said:

Hi thoy1,

1) You have placed your checks in OnTick. If the server is disconnected, you will not receive any ticks hence no checks will be made. Use a timer instead. 

2) I could not reproduce any NaN values with your BollingerTest. Can you provide exact steps to reproduce this problem and post some screenshots as well?

Best Regards,

Panagiotis 

Join us on Telegram

 

Hi Panagiotis, 

1) Ahh yes, an oversight of mine. That makes sense, thanks.

2) I have added a screen-shot. The Print lines in the above code are for troubleshooting. In the shot below you can see that both the 'Top Value' and 'Bottom Value' are giving NaN, this is causing 's1range' to produce a NaN error also, and subsequently both 's1buy' and 's1sell' (entry positions) are showing NaN too.


@thoy1

gennimatas
11 Feb 2020, 13:44

RE:

PanagiotisCharalampous said:

Hi thoy1,

1) You have placed your checks in OnTick. If the server is disconnected, you will not receive any ticks hence no checks will be made. Use a timer instead.

2) I could not reproduce any NaN values with your BollingerTest. Can you provide exact steps to reproduce this problem and post some screenshots as well?

Best Regards,

Panagiotis 

Join us on Telegram

 

I saw this some days ago and forced it out with the line PlusMinusColors(true) 

Server.IsConnected and events OnServerConnected, OnServerDisconnected do not work.

The way i use them:

        Color clrPlus = Color.Gray;
        Color clrMinus = Color.Gray;

        protected override void Initialize()
        {
            Server.Connected += OnServerConnected;
            Server.Disconnected += OnServerDisconnected;
            PlusMinusColors(Server.IsConnected);
            //PlusMinusColors(true);

 

        void OnServerConnected()
        {
            PlusMinusColors(true);
        }

        void OnServerDisconnected()
        {
            PlusMinusColors(false);
        }

        void PlusMinusColors(bool plus)
        {
            if (plus)
            {
                clrPlus = Color.Lime;
                clrMinus = Color.Tomato;
            }
            else
            {
                clrPlus = Color.Gray;
                clrMinus = Color.Gray;
            }
        }

 


@gennimatas

thoy1
11 Feb 2020, 20:39

RE: RE:

Takis Genn said:

I saw this some days ago and forced it out with the line PlusMinusColors(true) 

Server.IsConnected and events OnServerConnected, OnServerDisconnected do not work.

The way i use them:

        Color clrPlus = Color.Gray;
        Color clrMinus = Color.Gray;

        protected override void Initialize()
        {
            Server.Connected += OnServerConnected;
            Server.Disconnected += OnServerDisconnected;
            PlusMinusColors(Server.IsConnected);
            //PlusMinusColors(true);

 

        void OnServerConnected()
        {
            PlusMinusColors(true);
        }

        void OnServerDisconnected()
        {
            PlusMinusColors(false);
        }

        void PlusMinusColors(bool plus)
        {
            if (plus)
            {
                clrPlus = Color.Lime;
                clrMinus = Color.Tomato;
            }
            else
            {
                clrPlus = Color.Gray;
                clrMinus = Color.Gray;
            }
        }

 

Hi Takis,

You legend! I had tried so many OnTimer options and none of them seemed to register the re-connections. Your version works beautifully!

For anybody else reading this thread I have completed the code to have the Thread.Sleep included. The reason for this script is upon reconnecting, the server at times sends a false Bid/Ask price and my bot likes to trade on it - creating a label which is well out of the array my bot runs. This delay allows ctrader to fully catch-up and have accurate Bid/Ask prices.

 

Now I just need to solve my BollingerBand issue.

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ConnectionTest : Robot
    {

        Color clrPlus = Color.Gray;
        Color clrMinus = Color.Gray;

        protected override void OnStart()
        {
            // Put your initialization logic here
            Server.Connected += OnServerConnected;
            Server.Disconnected += OnServerDisconnected;
            PlusMinusColors(Server.IsConnected);
        }

        void OnServerConnected()
        {
            PlusMinusColors(true);
        }


        void OnServerDisconnected()
        {
            PlusMinusColors(false);
        }

        void PlusMinusColors(bool plus)
        {
            if (plus)
            {
                clrPlus = Color.Lime;
                clrMinus = Color.Tomato;
                Print("Connected, pausing trades for 15 seconds.");
                System.Threading.Thread.Sleep(15000);
                Print("Trading active again.");
            }
            else
            {
                clrPlus = Color.Gray;
                clrMinus = Color.Gray;
                Print("Disconnected");
            }
        }

        protected override void OnTick()
        {
            Print("Tick");
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@thoy1

gennimatas
12 Feb 2020, 16:10

RE: RE: RE:

thoy1 said:

Takis Genn said:

I saw this some days ago and forced it out with the line PlusMinusColors(true) 

Server.IsConnected and events OnServerConnected, OnServerDisconnected do not work.

The way i use them:

        Color clrPlus = Color.Gray;
        Color clrMinus = Color.Gray;

        protected override void Initialize()
        {
            Server.Connected += OnServerConnected;
            Server.Disconnected += OnServerDisconnected;
            PlusMinusColors(Server.IsConnected);
            //PlusMinusColors(true);

 

        void OnServerConnected()
        {
            PlusMinusColors(true);
        }

        void OnServerDisconnected()
        {
            PlusMinusColors(false);
        }

        void PlusMinusColors(bool plus)
        {
            if (plus)
            {
                clrPlus = Color.Lime;
                clrMinus = Color.Tomato;
            }
            else
            {
                clrPlus = Color.Gray;
                clrMinus = Color.Gray;
            }
        }

 

Hi Takis,

You legend! I had tried so many OnTimer options and none of them seemed to register the re-connections. Your version works beautifully!

For anybody else reading this thread I have completed the code to have the Thread.Sleep included. The reason for this script is upon reconnecting, the server at times sends a false Bid/Ask price and my bot likes to trade on it - creating a label which is well out of the array my bot runs. This delay allows ctrader to fully catch-up and have accurate Bid/Ask prices.

 

Now I just need to solve my BollingerBand issue.

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ConnectionTest : Robot
    {

        Color clrPlus = Color.Gray;
        Color clrMinus = Color.Gray;

        protected override void OnStart()
        {
            // Put your initialization logic here
            Server.Connected += OnServerConnected;
            Server.Disconnected += OnServerDisconnected;
            PlusMinusColors(Server.IsConnected);
        }

        void OnServerConnected()
        {
            PlusMinusColors(true);
        }


        void OnServerDisconnected()
        {
            PlusMinusColors(false);
        }

        void PlusMinusColors(bool plus)
        {
            if (plus)
            {
                clrPlus = Color.Lime;
                clrMinus = Color.Tomato;
                Print("Connected, pausing trades for 15 seconds.");
                System.Threading.Thread.Sleep(15000);
                Print("Trading active again.");
            }
            else
            {
                clrPlus = Color.Gray;
                clrMinus = Color.Gray;
                Print("Disconnected");
            }
        }

        protected override void OnTick()
        {
            Print("Tick");
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 

I didn't post the whole thing as it is more than 700 lines of code

Glad it helped you

Still the Server connection state and the events do not work for me

Takis


@gennimatas

PanagiotisCharalampous
12 Feb 2020, 16:17

Hi Takis,

Your code works fine for me. How do you test it?

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

gennimatas
12 Feb 2020, 16:46

RE:

PanagiotisCharalampous said:

Hi Takis,

Your code works fine for me. How do you test it?

Best Regards,

Panagiotis 

Join us on Telegram

Hi Panagioti,

I wrote a separate indi to test it, didn't work and deleted it.

The code is part of another indi. Will test it again and let you know.

Thanks and regards


@gennimatas

PanagiotisCharalampous
12 Feb 2020, 16:48

Hi Takis,

Just use the code you posted and enable/disable your network adapter. You should see the events registering in the log.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

thoy1
13 Feb 2020, 09:06

RE:

PanagiotisCharalampous said:

Hi Takis,

Just use the code you posted and enable/disable your network adapter. You should see the events registering in the log.

Best Regards,

Panagiotis 

Join us on Telegram

Hi Panagiotis,

This is also how I tested Takis' work and found it to work well.

I have also sorted out my NaN issue. For some reason it didn't like me using moving average for the BB data series. Possibly because I was asking the BB to have 90 results after the MA had its 90 results, so my backtesting probably needed to wait for 180 days of data to be loaded befor the NaN became a decimal. I have removed the MA from the code and it works well now :)

I have run into another issue though. I can't seem to extract the SymbolName from position info in order to find the Ask/Bid price of said symbol. I am aware position.SymbolName is in string format, where I need to use it in Symbol format. Please see the code below, cheers :) The aim here is to move the SL protection to an 'in-profit' position when the Ask/Bid has moved enough.

foreach (var position in Positions)
           {
                Symbol symbol = position.SymbolName; //Need to convert to Symbol, not string.
                TradeType tradetype = position.TradeType;
                double entry = position.EntryPrice;
                double? tp = position.TakeProfit;
                double? newsl = (tp + entry) / 2;

                //Print("entry is: {0} TP is: {1}", entry, tp); //Testing how data got extracted

                if (tradetype == TradeType.Buy)
                {
                    if (symbol.Ask >= newsl + ((tp - entry) * 0.1))
                    {
                        ModifyPosition(position, newsl, tp);
                    }
                }
                else
                {
                    if (symbol.Bid <= newsl - ((entry - tp) * 0.1))
                    {
                        ModifyPosition(position, newsl, tp);
                    }
                }
            }

 


@thoy1

PanagiotisCharalampous
13 Feb 2020, 09:16

Hi thoy1,

See below

  Symbol symbol = Symbols.GetSymbol(position.SymbolName);

Best Regards,

Panagiotis 

Join us on Telegram

 


@PanagiotisCharalampous

thoy1
13 Feb 2020, 09:22

RE:

PanagiotisCharalampous said:

Hi thoy1,

See below

  Symbol symbol = Symbols.GetSymbol(position.SymbolName);

Best Regards,

Panagiotis 

Join us on Telegram

 

Oh wow I'm noob. I should have seen that coming :D

Thanks again!


@thoy1

thoy1
13 Feb 2020, 12:43 ( Updated at: 21 Dec 2023, 09:21 )

RE:

PanagiotisCharalampous said:

Hi thoy1,

See below

  Symbol symbol = Symbols.GetSymbol(position.SymbolName);

Best Regards,

Panagiotis 

Join us on Telegram

 

Hi Pangiotis,

So I have managed to get my full bot working which is programmed quite clunky (lots of repetition for multiple symbols etc. I have done my best to get it to process each symbol with a loop but the looped version crashes in OnBar. Any ideas on why this might be? My settings to leave a couple of Symbols empty is deliberate for testing functionality. Cheers :)

EDIT: I have since done another backtest with all the symbol info entered, and found that it works 100%. So the issue has to do with MySymbols not processing the nullorwhitespace correctly. I have assumed that it would still test this against the initial 'if' statement, but this appears to be where it is crashing. I have removed all the code that isn't required for testing this behavior.

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
//Instrument Information------------------------------------------------------------------------------------------------------------------------------------------Instrument Information
        [Parameter("Number of Instruments", DefaultValue = 12, Group = "Instrument Info")]
        public double instruments { get; set; }
        [Parameter("Symbol 1", DefaultValue = "AUDCAD.spa", Group = "Instrument Info")]
        public string symbol_1 { get; set; }
        [Parameter("Symbol 2", DefaultValue = "AUDCHF.spa", Group = "Instrument Info")]
        public string symbol_2 { get; set; }
        [Parameter("Symbol 3", DefaultValue = "AUDNZD.spa", Group = "Instrument Info")]
        public string symbol_3 { get; set; }
        [Parameter("Symbol 4", DefaultValue = "CADCHF.spa", Group = "Instrument Info")]
        public string symbol_4 { get; set; }
        [Parameter("Symbol 5", DefaultValue = "GBPAUD.spa", Group = "Instrument Info")]
        public string symbol_5 { get; set; }
        [Parameter("Symbol 6", DefaultValue = "GBPCAD.spa", Group = "Instrument Info")]
        public string symbol_6 { get; set; }
        [Parameter("Symbol 7", DefaultValue = "GBPCHF.spa", Group = "Instrument Info")]
        public string symbol_7 { get; set; }
        [Parameter("Symbol 8", DefaultValue = "GBPNZD.spa", Group = "Instrument Info")]
        public string symbol_8 { get; set; }
        [Parameter("Symbol 9", DefaultValue = "NZDCAD.spa", Group = "Instrument Info")]
        public string symbol_9 { get; set; }
        [Parameter("Symbol 10", DefaultValue = "NZDUSD.spa", Group = "Instrument Info")]
        public string symbol_10 { get; set; }
        [Parameter("Symbol 11", DefaultValue = "USDCAD.spa", Group = "Instrument Info")]
        public string symbol_11 { get; set; }
        [Parameter("Symbol 12", DefaultValue = "USDZAR.spa", Group = "Instrument Info")]
        public string symbol_12 { get; set; }

//Declarations--------------------------------------------------------------------------------------------------------------------------------------------------------------Declarations
        private Symbol sym;
        public Symbol[] MySymbols;

        Color clrPlus = Color.Gray;
        Color clrMinus = Color.Gray;

//On Start//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Start
//On Start//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Start
        protected override void OnStart()
        {
            if (string.IsNullOrWhiteSpace(symbol_1) == true && string.IsNullOrWhiteSpace(symbol_2) == true && string.IsNullOrWhiteSpace(symbol_3) == true && string.IsNullOrWhiteSpace(symbol_4) == true && string.IsNullOrWhiteSpace(symbol_5) == true && string.IsNullOrWhiteSpace(symbol_6) == true && string.IsNullOrWhiteSpace(symbol_7) == true && string.IsNullOrWhiteSpace(symbol_8) == true && string.IsNullOrWhiteSpace(symbol_9) == true && string.IsNullOrWhiteSpace(symbol_10) == true && string.IsNullOrWhiteSpace(symbol_11) == true && string.IsNullOrWhiteSpace(symbol_12) == true)
            {
                Print("No active instruments, Bot has stopped running.");
                Stop();
            }
        }

//On Bar//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Bar
//On Bar//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Bar
        protected override void OnBar()
        {
            double riskvol = Account.Equity / instruments;

            MySymbols = Symbols.GetSymbols("" + symbol_1, "" + symbol_2, "" + symbol_3, "" + symbol_4, "" + symbol_5, "" + symbol_6, "" + symbol_7, "" + symbol_8, "" + symbol_9, "" + symbol_10,
            "" + symbol_11, "" + symbol_12);

            foreach (var symbol in MySymbols)
            {
                Print("{0}", symbol.Name);
                //for testing
                if (string.IsNullOrWhiteSpace(symbol.Name) == false)
                {
                    sym = Symbols.GetSymbol(symbol.Name);
                    Print("{0} Passed", sym);
                }
            }
        }

//On Stop////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Stop
//On Stop////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////On Stop
        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@thoy1

thoy1
27 Feb 2020, 07:02

RE: RE:

Hi All, 

I have found the solution to my issue. Will leave this here for everyone's reference.

Kind regards,

~Thoy

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Symbols:", DefaultValue = "AUDNZD GBPCAD EURUSD", Group = "Separate symbols with a space.")]
        public string symbolList { get; set; }
        // Make sure this is set to string
        public Symbol[] MySymbols;

        char[] delimiters = 
        {
            ' '
        };

        protected override void OnStart()
        {
            MySymbols = Symbols.GetSymbols(symbolList.Split(delimiters, StringSplitOptions.RemoveEmptyEntries));

            foreach (var symbol in MySymbols)
            {
                Print("Using {0}", symbol.Name);
            }
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@thoy1