Replies

b917187
26 Mar 2020, 22:45

RE:

PanagiotisCharalampous said:

Hi b917187,

I have checked this and there is no issue. Your check seems to take place as soon as the bar changes. At that moment the LastValue will be almost identical to the previous value since the close price of both bars is the same. Maybe you intended to check Last(1) and Last(2)?

 Best Regards,

Panagiotis 

Join us on Telegram

 

Thank you. That was it - a combination of not refreshing the Watch values and not using Last(1) and Last(2)

 


@b917187

b917187
20 Mar 2020, 17:38

RE:

PanagiotisCharalampous said:

Hi b917187,

There are usually maintenance tasks in progress during weekends.

Best Regards,

Panagiotis 

Join us on Telegram

 

Thanks Panagiotis!

 

Regards,

 

/Brian


@b917187

b917187
20 Mar 2020, 11:01

Hello,

Is anyone able to help with this?

The question is really the core of all these indicators. Why do Last (1) and LastValue return unexpected values?

Thanks


@b917187

b917187
18 Mar 2020, 12:48 ( Updated at: 21 Dec 2023, 09:21 )

RE:

PanagiotisCharalampous said:

Hi b917187,

I tried this several times but I cannot reproduce such a behavior. I have also noticed that in your Watch the values are not refreshed (greyed). Can you please confirm you are comparing the latest values?

 Best Regards,

Panagiotis 

Join us on Telegram

 

Hi Panagiotis,

So maybe this will help us sync up. I am backtesting EURUSD on the 1 minute chart. The test is on 16th February 2020 as shown below and the test condition is hit immediately as soon as you start backtesting.

Thanks for the tip about the "refresh" button... I wasn't aware of that.  Its good to know but it does not solve the problem as not only were the watched variables showing a problem, but the code was also mirroring that problem - go going down the "true" path when it should have been the "false" patch and vice versa.

So here is a new test at the start of the 16th Feb.

My first question here is:

a) When Are you seeing the same values for LastValue and Last(1) when it falls into that "return true" in the "rsiOpenShortConditionsMet" method? Maybe you could post your screenshot if it shows different?

b) Are these two values meant to be the same? It seems to me they should not be the same. Looking at the rsi indicator on the chart, it seems Last(1) should be a lot lower than LastValue?

Note: I have refreshed the watched values... they are no longer grey.

Many thanks


@b917187

b917187
17 Mar 2020, 18:23

RE:

Here you go. Thanks for looking


@b917187

b917187
17 Mar 2020, 18:22

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class RSITest : Robot
    {
        #region User defined parameters


        // ************************************************************
        // Debug Mode
        [Parameter("Debug Mode", DefaultValue = false)]
        public bool DebugMode { get; set; }
        // ************************************************************

        // ************************************************************
        // Used by Main Functional Elements
        [Parameter("RSI Open Active", DefaultValue = true)]
        public bool rsiOpenParamActive { get; set; }
        [Parameter("RSI Close Active", DefaultValue = true)]
        public bool rsiCloseParamActive { get; set; }
        [Parameter("RSI Overbought", DefaultValue = 70, MinValue = 1, MaxValue = 200)]
        public int _rsi_overbought_val { get; set; }
        [Parameter("RSI Oversold", DefaultValue = 30, MinValue = 1, MaxValue = 200)]
        public int _rsi_oversold_val { get; set; }


        // ************************************************************


        [Parameter("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }
        [Parameter("Lot Size", DefaultValue = 0.1)]
        public double LotSize { get; set; }
        [Parameter("Calculate OnBar", DefaultValue = true)]
        public bool CalculateOnBar { get; set; }

        // ************************************************************
        // Used by Built-in RSI Indicator

        [Parameter("Period RSI #1", DefaultValue = 14, MinValue = 1, MaxValue = 100)]
        public int PeriodRsi1 { get; set; }
        [Parameter("Source RSI #1")]
        public DataSeries SourceRsi1 { get; set; }
        // ************************************************************

        #endregion

        #region Indicator declarations
        private double rsilast1;
        private double rsilastvalue;
        // ************************************************************
        // Used by Built-in RSI Indicator
        private RelativeStrengthIndex _rsi { get; set; }
        private bool _rsiOversold { get; set; }
        private bool _rsiOverbought { get; set; }

        // ************************************************************

        #endregion

        #region cTrader events


        /// <summary>
        /// This is called when the robot first starts, it is only called once.
        /// </summary>
        protected override void OnStart()
        {
            // construct the indicators

            // ************************************************************
            // Used by Built-in RSI Indicator
            _rsi = Indicators.RelativeStrengthIndex(SourceRsi1, PeriodRsi1);
            // ************************************************************
        }

        /// <summary>
        /// This method is called every time the price changes for the symbol
        /// </summary>
        protected override void OnTick()
        {

            if (CalculateOnBar)
            {
                return;
            }
            else
            {
                ManagePositions();
            }

        }

        /// <summary>
        /// This method is called at every candle (bar) close, when it has formed
        /// </summary>
        protected override void OnBar()
        {
            if (!CalculateOnBar)
            {
                return;
            }
            else
            {
                ManagePositions();
            }
        }

        /// <summary>
        /// This method is called when your robot stops, can be used to clean-up memory resources.
        /// </summary>
        protected override void OnStop()
        {
            // unused
        }

        #endregion

        #region Position management

        private void ManagePositions()
        {
            ManageBuyPositions();
            ManageSellPositions();

        }

        private void ManageBuyPositions()
        {
            setRSIOverboughtOversold();
            if (!IsPositionOpenByType(TradeType.Buy) && rsiOpenLongConditionsMet())
            {
                if (!DebugMode)
                {
                    OpenPosition(TradeType.Buy);
                    _rsiOversold = false;
                }
                else
                {
                }
            }
            // if there is a BUY position open            
            else if (IsPositionOpenByType(TradeType.Buy) && (!DebugMode))
            {
                if (rsiCloseLongConditionsMet())
                {
                    ClosePosition(TradeType.Buy);
                    return;
                }
            }
            else
            {
            }
        }

        private void ManageSellPositions()
        {

            if (!IsPositionOpenByType(TradeType.Sell) && rsiOpenShortConditionsMet())
            {
                if (!DebugMode)
                {
                    OpenPosition(TradeType.Sell);
                    _rsiOverbought = false;
                }
                else
                {
                }
            }
            else if (IsPositionOpenByType(TradeType.Sell) && !DebugMode)
            {
                if (rsiCloseShortConditionsMet())
                {
                    ClosePosition(TradeType.Sell);
                    return;
                }
            }
            else
            {
            }

        }


        private void setRSIOverboughtOversold()
        {
            if (_rsiOverbought == false)
            {
                if (_rsi.Result.Last(0) > _rsi_overbought_val)
                {
                    _rsiOverbought = true;
                }
            }
            else if (_rsiOversold == false)
            {
                if (_rsi.Result.Last(0) < _rsi_oversold_val)
                {
                    _rsiOversold = true;
                }
            }
            else
            {
                //do nothing
            }
        }

        //*******************************************************************************************************
        private bool rsiOpenLongConditionsMet()
        {
            if (rsiOpenParamActive == false)
            {
                return true;
            }
            else
            {
                if (_rsiOversold && _rsi.Result.Last(1) < _rsi.Result.LastValue)
                {
                    return true;
                }

                else
                {
                    return false;
                }
            }
        }


        private bool rsiOpenShortConditionsMet()
        {
            if (rsiOpenParamActive == false)
            {
                return true;
            }
            else
            {

                // Going down
                if (_rsiOverbought && _rsi.Result.Last(1) > _rsi.Result.LastValue)
                {
                    return true;
                }

                else
                {
                    return false;
                }
            }
        }
        //*******************************************************************************************************

        private bool rsiCloseLongConditionsMet()
        {
            calclatestrsivalues();
            if (rsiCloseParamActive == false)
            {
                return false;
            }
            else
            {
                // going down
                if (rsilast1 > rsilastvalue)
                {
                    return true;
                }

                else
                {
                    return false;
                }
            }
        }


        private bool rsiCloseShortConditionsMet()
        {
            calclatestrsivalues();
            if (rsiCloseParamActive == false)
            {
                return false;
            }
            else
            {
                // going up
                if (rsilast1 < rsilastvalue)
                {
                    return true;
                }

                else
                {
                    return false;
                }
            }
        }


        //*******************************************************************************************************

        public void calclatestrsivalues()
        {
            rsilast1 = _rsi.Result.Last(1);
            rsilastvalue = _rsi.Result.LastValue;
        }

        //*******************************************************************************************************

        private void OpenPosition(TradeType type)
        {
            // calculate volume from lot size.
            double volume = Symbol.QuantityToVolumeInUnits(LotSize);

            // open a new position
            ExecuteMarketOrder(type, this.Symbol.Name, volume, InstanceName, null, null);
        }

        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName, this.Symbol.Name, type);

            if (p != null)
            {
                ClosePosition(p);
            }
        }

        #endregion

        #region Position Information


        private bool IsPositionOpenByType(TradeType type)
        {
            var p = Positions.FindAll(InstanceName, Symbol.Name, type);

            if (p.Count() >= 1)
            {
                return true;
            }

            return false;
        }

        #endregion
    }
}
 


@b917187

b917187
17 Mar 2020, 00:17

Hi firemyst,

Thank you.

So I created a small function as follows to get a fresh copy of the indicator values:

 

 

But the results still seem to be incorrect even though I call this function just prior to testing the values:

 

See how the rsi in the chart is visually sloping upwards, yet the last1 is higher than LastValue, which means the variables see it as going downwards, right? It returns false instead of true

 

Many thanks,


@b917187

b917187
04 Mar 2020, 11:00

RE:

PanagiotisCharalampous said:

Hi b917187,

If the developer built the indicator without source code then you will not be able to see it or use the indicator in other project. You should contact the developer directly.

Best Regards,

Panagiotis 

Join us on Telegram

Thanks Panagiotis!

Appreciate your help.

Regards,


@b917187

b917187
28 Feb 2020, 15:25 ( Updated at: 21 Dec 2023, 09:21 )

RE:

PanagiotisCharalampous said:

Hi b917187,

The indicator seems to inherit from another indicator called Divergence. You need to include this indicator to your project.

Best Regards,

Panagiotis 

Join us on Telegram

 

 

Thank you Panagiotis,

Understood. Thanks that helps. I have the Divergence Indicator here that it inherits. The indicator installs ok, but seems to have no code and cannot be built. Is that normal?

 

Many thanks,


@b917187