Calculate a value based on its old value

Created at 17 Mar 2020, 00:16
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!
PA

patrickzberg

Joined 04.02.2020

Calculate a value based on its old value
17 Mar 2020, 00:16


Hi all

I try to program a method, that is calling its own return value and calculate further after a new bar is built.

The idea is, that MyValue is calculated new on every bar. The calculation is based on MyValue of the bar before.

In Detail the code should do this. When the ClosePrice and ClosePrice are both higher than MyValue of the candle before then it should set MyValue either with the old value or the value "alternate".

The code below does compile but it does not do any trades. I guess this is because there is not start value for MyValue defined (this is really a guess, I only know that this part of the code is the problem. When I replace it with a simple value it does do trades...). A potential start value could be 0

 

       public double MyMethod(double loss)
        {
            double ClosePrice = Bars.ClosePrices.Last(1);
            double ClosePrice2 = Bars.ClosePrices.Last(2);

            double alternate = ClosePrice - loss;
            double alternate2 = ClosePrice + loss;


            if ((ClosePrice > MyValue) && (ClosePrice2 > MyValue))
            {
                if (MyValue> alternate)
                {
                    MyValue= MyValue;
                }

                else
                {
                    MyValue= alternate;
                }

            }
     

            return MyValue;
        } 

 

I hope somebody has a solution to this. Thank you in advance


@patrickzberg
Replies

firemyst
18 Mar 2020, 15:43

RE:

patrickzberg said:

Hi all

I try to program a method, that is calling its own return value and calculate further after a new bar is built.

The idea is, that MyValue is calculated new on every bar. The calculation is based on MyValue of the bar before.

In Detail the code should do this. When the ClosePrice and ClosePrice are both higher than MyValue of the candle before then it should set MyValue either with the old value or the value "alternate".

The code below does compile but it does not do any trades. I guess this is because there is not start value for MyValue defined (this is really a guess, I only know that this part of the code is the problem. When I replace it with a simple value it does do trades...). A potential start value could be 0

 

       public double MyMethod(double loss)
        {
            double ClosePrice = Bars.ClosePrices.Last(1);
            double ClosePrice2 = Bars.ClosePrices.Last(2);

            double alternate = ClosePrice - loss;
            double alternate2 = ClosePrice + loss;


            if ((ClosePrice > MyValue) && (ClosePrice2 > MyValue))
            {
                if (MyValue> alternate)
                {
                    MyValue= MyValue;
                }

                else
                {
                    MyValue= alternate;
                }

            }
     

            return MyValue;
        } 

 

I hope somebody has a solution to this. Thank you in advance

Well, for starters you haven't said if this is an indicator or bot.

If it's the former, what's the value of "MyValue" at the end of the calculate method when it runs through and calculates the history? Or do you initialize it in the "Initialize" method?

Otherwise, we have no idea why an order might not be placed with the given code snippet you've provided since you don't actually provide the code too that places the order or how MyMethod is called in between.

I would also edit your code as follows:

if (MyValue> alternate)
                {
                    MyValue= MyValue;
                }

                else
                {
                    MyValue= alternate;
                }

//Change the above to:
if (MyValue <= alternate)
                {
                    MyValue = alternate;
                }

//because it's pointless to set MyValue = MyValue.
//That takes unnecessary CPU and memory assignment time, which will slow down by nanoseconds whatever it is you're writing.

 


@firemyst

patrickzberg
18 Mar 2020, 18:20

RE: RE:

firemyst said:

patrickzberg said:

Hi all

I try to program a method, that is calling its own return value and calculate further after a new bar is built.

The idea is, that MyValue is calculated new on every bar. The calculation is based on MyValue of the bar before.

In Detail the code should do this. When the ClosePrice and ClosePrice are both higher than MyValue of the candle before then it should set MyValue either with the old value or the value "alternate".

The code below does compile but it does not do any trades. I guess this is because there is not start value for MyValue defined (this is really a guess, I only know that this part of the code is the problem. When I replace it with a simple value it does do trades...). A potential start value could be 0

 

       public double MyMethod(double loss)
        {
            double ClosePrice = Bars.ClosePrices.Last(1);
            double ClosePrice2 = Bars.ClosePrices.Last(2);

            double alternate = ClosePrice - loss;
            double alternate2 = ClosePrice + loss;


            if ((ClosePrice > MyValue) && (ClosePrice2 > MyValue))
            {
                if (MyValue> alternate)
                {
                    MyValue= MyValue;
                }

                else
                {
                    MyValue= alternate;
                }

            }
     

            return MyValue;
        } 

 

I hope somebody has a solution to this. Thank you in advance

Well, for starters you haven't said if this is an indicator or bot.

If it's the former, what's the value of "MyValue" at the end of the calculate method when it runs through and calculates the history? Or do you initialize it in the "Initialize" method?

Otherwise, we have no idea why an order might not be placed with the given code snippet you've provided since you don't actually provide the code too that places the order or how MyMethod is called in between.

I would also edit your code as follows:

if (MyValue> alternate)
                {
                    MyValue= MyValue;
                }

                else
                {
                    MyValue= alternate;
                }

//Change the above to:
if (MyValue <= alternate)
                {
                    MyValue = alternate;
                }

//because it's pointless to set MyValue = MyValue.
//That takes unnecessary CPU and memory assignment time, which will slow down by nanoseconds whatever it is you're writing.

 

 

Thank you for helping me. I can provide the full code, just thought it would be too much for this question. Some day it should become a bot.

 

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 MyRobot : Robot
    {
        [Parameter("Instance Name", DefaultValue = "002")]
        public string InstanceName { get; set; }

        [Parameter("Source")]
        public DataSeries Source { get; set; }

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

        [Parameter("Lot Size", DefaultValue = 1)]
        public double LotSize { get; set; }

        [Parameter("Calculate OnBar", DefaultValue = true)]
        public bool CalculateOnBar { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 30)]
        public int tp { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 50)]
        public int sl { get; set; }


        [Parameter("sens", DefaultValue = 1.2)]
        public double sens { get; set; }

        [Parameter("c", DefaultValue = 10)]
        public int c { get; set; }

        [Parameter("MyValue", DefaultValue = 0)]
        public double MyValue { get; set; }

        public IndicatorDataSeries Result { get; set; }


        public double Sum { get; set; }
        public DataSeries Price { get; set; }

        private AverageTrueRange _atr;
        private ExponentialMovingAverage _ema1;

        protected override void OnStart()
        {

            _ema1 = Indicators.ExponentialMovingAverage(Price, 1);
            _atr = Indicators.AverageTrueRange(c, MovingAverageType.Simple);
            Sum = 1;
        }



        protected override void OnTick()
        {
            if (CalculateOnBar)
            {
                return;
            }

            ManagePositions();
        }


        protected override void OnBar()
        {
            if (!CalculateOnBar)
            {
                return;
            }

            ManagePositions();
        }


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


        private void ManagePositions()
        {

            double ClosePrice = Bars.ClosePrices.LastValue;
            ExponentialMovingAverage exponentialMovingAverage = Indicators.ExponentialMovingAverage(Price, 1);
            _ema1 = exponentialMovingAverage;

            double atr_now = _atr.Result[1];
            double nLoss = sens * atr_now;

            if (Bars.ClosePrices.LastValue > MyMethod(nLoss))
            {
                Close(TradeType.Sell);
                Open(TradeType.Buy);
            }


            if (Bars.ClosePrices.LastValue < MyMethod(nLoss))
            {
                Close(TradeType.Buy);
                Open(TradeType.Sell);
            }

        }

        private void Close(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll("MyRobot", SymbolName, tradeType))
                ClosePosition(position);
        }

        private void Open(TradeType tradeType)
        {
            var position = Positions.Find("MyRobot", SymbolName, tradeType);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);

            if (position == null)
                ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "MyRobot", sl, tp);
        }



        public double nLoss()
        {
            double atr_now = _atr.Result[1];
            double nLoss = sens * atr_now;
            return nLoss;
        }


        public double MyMethod(double nLoss)
        {
            double ClosePrice = Bars.ClosePrices.Last(1);
            double ClosePrice2 = Bars.ClosePrices.Last(2);
            double alternate = ClosePrice - nLoss;
            double alternate2 = ClosePrice + nLoss;



            if ((ClosePrice > MyValue) && (ClosePrice2 > MyValue))
            {
                if (MyValue > alternate)
                {
                    MyValue = MyValue;
                }

                else
                {
                    MyValue = alternate;
                }

            }
            else
            {
                if ((ClosePrice < MyValue) && (ClosePrice2 < MyValue))
                {
                    if (MyValue > alternate)
                    {
                        MyValue = alternate;
                    }

                    else
                    {
                        MyValue = MyValue;
                    }

                }
                else
                {
                    if (ClosePrice > MyValue)
                    {
                        MyValue = alternate;
                    }
                    else
                    {
                        MyValue = alternate2;
                    }
                }
            }

            return MyValue;
        }


    }

}

 


@patrickzberg