Replies

sajad.nazari.1996
01 Feb 2022, 18:51

RE:

amusleh said:

Hi,

To use a custom indicator on your cBot you have to use the Indicators.GetIndicator generic method: Method GetIndicator | API reference | cTrader Community

But your indicator uses some native Win32 API for showing a message box, you have to remove it:

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SuperProfit : Indicator
    {
        [Parameter(DefaultValue = 35)]
        public int DllPeriod { get; set; }

        [Parameter(DefaultValue = 1.7)]
        public double Period { get; set; }

        [Parameter(DefaultValue = MovingAverageType.Weighted)]
        public MovingAverageType MaType { get; set; }

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

        [Parameter(DefaultValue = 5)]
        public int StopLoss { get; set; }

        [Parameter(DefaultValue = 20)]
        public int TakeProfit { get; set; }

        [Output("Up", PlotType = PlotType.Points, Thickness = 4)]
        public IndicatorDataSeries UpSeries { get; set; }

        [Output("Down", PlotType = PlotType.Points, Color = Colors.Red, Thickness = 4)]
        public IndicatorDataSeries DownSeries { get; set; }

        private DateTime _openTime;

        private MovingAverage _movingAverage1;
        private MovingAverage _movingAverage2;
        private MovingAverage _movingAverage3;
        private IndicatorDataSeries _dataSeries;
        private IndicatorDataSeries _trend;

        protected override void Initialize()
        {
            _dataSeries = CreateDataSeries();
            _trend = CreateDataSeries();

            var period1 = (int)Math.Floor(DllPeriod / Period);
            var period2 = (int)Math.Floor(Math.Sqrt(DllPeriod));

            _movingAverage1 = Indicators.MovingAverage(Price, period1, MaType);
            _movingAverage2 = Indicators.MovingAverage(Price, DllPeriod, MaType);
            _movingAverage3 = Indicators.MovingAverage(_dataSeries, period2, MaType);
        }

        public override void Calculate(int index)
        {
            if (index < 1)
                return;

            _dataSeries[index] = 2.0 * _movingAverage1.Result[index] - _movingAverage2.Result[index];
            _trend[index] = _trend[index - 1];

            if (_movingAverage3.Result[index] > _movingAverage3.Result[index - 1])
                _trend[index] = 1;
            else if (_movingAverage3.Result[index] < _movingAverage3.Result[index - 1])
                _trend[index] = -1;

            if (_trend[index] > 0)
            {
                UpSeries[index] = _movingAverage3.Result[index];

                if (_trend[index - 1] < 0.0)
                {
                    UpSeries[index - 1] = _movingAverage3.Result[index - 1];

                    if (IsLastBar)
                    {
                        var stopLoss = MarketSeries.Low[index - 1] - StopLoss * Symbol.PipSize;
                        var takeProfit = MarketSeries.Close[index] + TakeProfit * Symbol.PipSize;
                        var entryPrice = MarketSeries.Close[index - 1];

                        if (MarketSeries.OpenTime[index] != _openTime)
                        {
                            _openTime = MarketSeries.OpenTime[index];
                        }
                    }
                }

                DownSeries[index] = double.NaN;
            }
            else if (_trend[index] < 0)
            {
                DownSeries[index] = _movingAverage3.Result[index];

                if (_trend[index - 1] > 0.0)
                {
                    DownSeries[index - 1] = _movingAverage3.Result[index - 1];

                    if (IsLastBar)
                    {
                        var stopLoss = MarketSeries.High[index - 1] + StopLoss * Symbol.PipSize;
                        var takeProfit = MarketSeries.Close[index] - TakeProfit * Symbol.PipSize;
                        var entryPrice = MarketSeries.Close[index - 1];

                        if (MarketSeries.OpenTime[index] != _openTime)
                        {
                            _openTime = MarketSeries.OpenTime[index];
                        }
                    }
                }

                UpSeries[index] = double.NaN;
            }
        }
    }
}

Then right click on your cBot, select reference manager, and inside indicators tab fine the "SuperProfit", reference it by checking its checkbox and then click on Ok button.

After referencing the indicator, rebuild your cBot, then you will be able to use the indicator inside your cBot, ex:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class sajad : Robot
    {
        private double _volumeInUnits;

        private SuperProfit _superProfit;

        [Parameter("Volume (Lots)", DefaultValue = 0.05)]
        public double VolumeInLots { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 100)]
        public double StopLossInPips { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 100)]
        public double TakeProfitInPips { get; set; }

        [Parameter("Label", DefaultValue = "superprofit")]
        public string Label { get; set; }

        public Position[] BotPositions
        {
            get { return Positions.FindAll(Label); }
        }

        protected override void OnStart()
        {
            // You have to pass each indicator parameter value in order
            // I used the default values but you can change them if you want to
            // Or use cBot parameters and then use their values
            _superProfit = Indicators.GetIndicator<SuperProfit>(35, 1.7, MovingAverageType.Weighted, Bars.ClosePrices, 5, 20);

            _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
        }

        protected override void OnBar()
        {
            if (_superProfit.UpSeries.LastValue == double.NaN)
            {
                ClosePositions(TradeType.Sell);
                ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
            }
            else if (_superProfit.DownSeries.LastValue == double.NaN)
            {
                ClosePositions(TradeType.Buy);
                ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
            }
        }

        private void ClosePositions(TradeType tradeType)
        {
            foreach (var position in BotPositions)
            {
                if (position.TradeType != tradeType)
                    continue;
                ClosePosition(position);
            }
        }
    }
}

And next time you post code please use the editor "Insert code snippet" option like I did.

thank you so much


@sajad.nazari.1996