need help to run my first bot

Created at 24 Aug 2019, 23:29
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!
AL

alisalehicontact

Joined 24.08.2019

need help to run my first bot
24 Aug 2019, 23:29


hello everyone

I have been interested in coding bot in calgo recently since i found it way more easier to learn than mql but i have no background at coding at all and by watching some tutorial this is my frist 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 NewcBot : Robot
    {
        [Parameter("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

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

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

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

        [Parameter("Period Dema", DefaultValue = 5, MinValue = 5, MaxValue = 100)]
        public int PeriodDema { get; set; }

        [Parameter("Period Tema", DefaultValue = 5, MinValue = 5, MaxValue = 100)]
        public int PeriodTema { get; set; }

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


        private DEMA Dema { get; set; }

        private TEMA Tema { get; set; }


        protected override void OnStart()
        {
            Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema);
            Tema = Indicators.GetIndicator<TEMA>(SourceTema, PeriodTema);

            // Put your initialization logic here
        }


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

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

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

        private void ManagePostions()
        {
            if (Tema.Result.LastValue > Dema.Result.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Buy))
                {
                    OpenPosition(TradeType.Buy);
                }
                ClosePosition(TradeType.Sell);
            }


            if (Tema.Result.LastValue < Dema.Result.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Sell))
                {
                    OpenPosition(TradeType.Sell);
                }
                ClosePosition(TradeType.Buy);
            }
        }


        private void OpenPosition(TradeType type)
        {
            long Volume = Symbol.QuantityToVolume(LotSize);
            ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null);
        }

        private void ClosePosition(TradeType type)
        {
            var P = Positions.Find(InstanceName, this.SymbolName, type);
            if (P != null)
            {
                ClosePosition(P);
            }
        }

        private bool IsPositionOpenByType(TradeType type)
        {
            var P = Positions.FindAll(InstanceName, SymbolName, type);
            if (P.Count() >= 1)
            {
                return true;
            }
            return false;
        }

    }
}

and these are the errors i get when building:

Error CS1061: 'cAlgo.Indicators.TEMA' does not contain a definition for 'Result' and no extension method 'Result' accepting a first argument of type 'cAlgo.Indicators.TEMA' could be found (are you missing a using directive or an assembly reference?)

Error CS1061: 'cAlgo.Indicators.DEMA' does not contain a definition for 'Result' and no extension method 'Result' accepting a first argument of type 'cAlgo.Indicators.DEMA' could be found (are you missing a using directive or an assembly reference?)

Error CS0618: 'cAlgo.API.Internals.Symbol.QuantityToVolume(double)' is obsolete: 'Use QuantityToVolumeInUnits instead'

Can anyone please teach me how to fix this?


@alisalehicontact
Replies

Tatsuya
25 Aug 2019, 10:58

You don't need get set for variables,try this one instead:

private DEMA Dema;
private TEMA Tema;

I'd like to see the DEMA and TEMA code if the code above doesn't work.

 

Also the last error is just telling you that there is a newer API that does the same thing.

You can simply replace QuantityToVolume with QuantityToVolumeInUnits.

 


@Tatsuya

alisalehicontact
25 Aug 2019, 12:20

RE:

Tatsuya said:

You don't need get set for variables,try this one instead:

private DEMA Dema;
private TEMA Tema;

I'd like to see the DEMA and TEMA code if the code above doesn't work.

 

Also the last error is just telling you that there is a newer API that does the same thing.

You can simply replace QuantityToVolume with QuantityToVolumeInUnits.

Thanks for your reply,that didnt work,this is the code for DEMA:

using System;
using cAlgo.API;
using cAlgo.API.Indicators;
 
namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class DEMA : Indicator
    {
        [Parameter]
        public DataSeries DataSource { get; set; }
         
        [Output("DEMA",Color = Colors.Yellow)]
        public IndicatorDataSeries dema { get; set; }
 
        [Parameter(DefaultValue = 14)]
        public int Period { get; set; }
 
        private ExponentialMovingAverage ema;
        private ExponentialMovingAverage ema2;
         
        protected override void Initialize()
        {
            ema = Indicators.ExponentialMovingAverage(DataSource,Period);//i need the correct DataSeries
            ema2 = Indicators.ExponentialMovingAverage(ema.Result,Period);
        }
         
        public override void Calculate(int index)
        {
           dema[index] = (2* ema.Result[index] - ema2.Result[index]);
        }
    }

and this is for TEMA:

using System;
using cAlgo.API;
using cAlgo.API.Indicators;
 
namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class TEMA : Indicator
    {
        [Output("TEMA")]
        public IndicatorDataSeries tema { get; set; }
         
        [Parameter("Data Source")]
        public DataSeries DataSource { get; set; }
 
        [Parameter(DefaultValue = 14)]
        public int Period { get; set; }
 
        private ExponentialMovingAverage ema1;
        private ExponentialMovingAverage ema2;
        private ExponentialMovingAverage ema3;
     
        protected override void Initialize()
        {
            ema1 = Indicators.ExponentialMovingAverage(DataSource,Period);
            ema2 = Indicators.ExponentialMovingAverage(ema1.Result,Period);
            ema3 = Indicators.ExponentialMovingAverage(ema2.Result,Period);
        }
         
        public override void Calculate(int index)
        {
            tema[index] = 3*ema1.Result[index] - 3*ema2.Result[index] + ema3.Result[index];
        }
    }

and if I replace replace QuantityToVolume with QuantityToVolumeInUnits I get this Error:

Error CS0266: Cannot implicitly convert type 'double' to 'long'. An explicit conversion exists (are you missing a cast?)

 

and by the way I havent write the code for this two indicator, TEMA & DEMA cods are for user 

qualitiedx2

 


@alisalehicontact

Tatsuya
25 Aug 2019, 21:38

Hope this code helps.

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("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

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

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

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

        [Parameter("Period Dema", DefaultValue = 5, MinValue = 5, MaxValue = 100)]
        public int PeriodDema { get; set; }

        [Parameter("Period Tema", DefaultValue = 5, MinValue = 5, MaxValue = 100)]
        public int PeriodTema { get; set; }

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


        private DEMA Dema;
        private TEMA Tema;

        protected override void OnStart()
        {
            Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema);
            Tema = Indicators.GetIndicator<TEMA>(SourceTema, PeriodTema);
        }


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

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

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

        private void ManagePostions()
        {
            // When you want to grab data from indicators you need their IndicatorDataSeries.
            // Result wasn't either in one of them,in your case you had tema and dema.

            if (Tema.tema.LastValue > Dema.dema.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Buy))
                {
                    OpenPosition(TradeType.Buy);
                }
                ClosePosition(TradeType.Sell);
            }


            if (Tema.tema.LastValue < Dema.dema.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Sell))
                {
                    OpenPosition(TradeType.Sell);
                }
                ClosePosition(TradeType.Buy);
            }
        }


        private void OpenPosition(TradeType type)
        {
            // QuantityToVolumeInUnits returns double,not long therefore you either have to put it into double or cast it to long.
            // e.g. long Volume = (long)Symbol.QuantityToVolumeInUnits(LotSize); this also works.

            double Volume = Symbol.QuantityToVolumeInUnits(LotSize);
            ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null);
        }

        private void ClosePosition(TradeType type)
        {
            var P = Positions.Find(InstanceName, this.SymbolName, type);
            if (P != null)
            {
                ClosePosition(P);
            }
        }

        private bool IsPositionOpenByType(TradeType type)
        {
            var P = Positions.FindAll(InstanceName, SymbolName, type);
            if (P.Count() >= 1)
            {
                return true;
            }
            return false;
        }

    }
}

 


@Tatsuya

alisalehicontact
26 Aug 2019, 13:49

RE:

Tatsuya said:

Hope this code helps.

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("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

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

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

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

        [Parameter("Period Dema", DefaultValue = 5, MinValue = 5, MaxValue = 100)]
        public int PeriodDema { get; set; }

        [Parameter("Period Tema", DefaultValue = 5, MinValue = 5, MaxValue = 100)]
        public int PeriodTema { get; set; }

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


        private DEMA Dema;
        private TEMA Tema;

        protected override void OnStart()
        {
            Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema);
            Tema = Indicators.GetIndicator<TEMA>(SourceTema, PeriodTema);
        }


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

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

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

        private void ManagePostions()
        {
            // When you want to grab data from indicators you need their IndicatorDataSeries.
            // Result wasn't either in one of them,in your case you had tema and dema.

            if (Tema.tema.LastValue > Dema.dema.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Buy))
                {
                    OpenPosition(TradeType.Buy);
                }
                ClosePosition(TradeType.Sell);
            }


            if (Tema.tema.LastValue < Dema.dema.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Sell))
                {
                    OpenPosition(TradeType.Sell);
                }
                ClosePosition(TradeType.Buy);
            }
        }


        private void OpenPosition(TradeType type)
        {
            // QuantityToVolumeInUnits returns double,not long therefore you either have to put it into double or cast it to long.
            // e.g. long Volume = (long)Symbol.QuantityToVolumeInUnits(LotSize); this also works.

            double Volume = Symbol.QuantityToVolumeInUnits(LotSize);
            ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null);
        }

        private void ClosePosition(TradeType type)
        {
            var P = Positions.Find(InstanceName, this.SymbolName, type);
            if (P != null)
            {
                ClosePosition(P);
            }
        }

        private bool IsPositionOpenByType(TradeType type)
        {
            var P = Positions.FindAll(InstanceName, SymbolName, type);
            if (P.Count() >= 1)
            {
                return true;
            }
            return false;
        }

    }
}

 

Thanks a lot man :) you just made my day,it works now

I did some backtest and optimization but the results were not great,then I changed it into two different Dema instead of Tema&Dema and the results were better,but I need to Add one more indicator to filter out the false signals and I think AdxVma is the right choise, this way when market is flat bot wont open a position.

This is the code for AdxVma:

using System;
using cAlgo.API;
 
namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class AdxVma : Indicator
    {
        private double _k;
 
        private IndicatorDataSeries _iSeries;
        private IndicatorDataSeries _mdiSeries;
        private IndicatorDataSeries _mdmSeries;
        private IndicatorDataSeries _pdiSeries;
        private IndicatorDataSeries _pdmSeries;
 
        [Parameter]
        public DataSeries Source { get; set; }
 
        [Parameter(DefaultValue = 6)]
        public int Period { get; set; }
 
        [Output("Rising", Color = Colors.Green, PlotType = PlotType.Points, Thickness = 2)]
        public IndicatorDataSeries Rising { get; set; }
 
        [Output("Falling", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 2)]
        public IndicatorDataSeries Falling { get; set; }
 
        [Output("Flat", Color = Colors.Gold, PlotType = PlotType.Points, Thickness = 2)]
        public IndicatorDataSeries Flat { get; set; }
 
        [Output("Result", Color = Colors.Black)]
        public IndicatorDataSeries Result { get; set; }
 
 
        protected override void Initialize()
        {
            _pdmSeries = CreateDataSeries();
            _mdmSeries = CreateDataSeries();
            _pdiSeries = CreateDataSeries();
            _mdiSeries = CreateDataSeries();
            _iSeries = CreateDataSeries();
 
            _k = 1.0/Period;
        }
 
 
        public override void Calculate(int index)
        {
            if (index < Period)
            {
                _pdmSeries[index] = 0;
                _mdmSeries[index] = 0;
                _pdiSeries[index] = 0;
                _mdiSeries[index] = 0;
                _iSeries[index] = 0;
                _pdmSeries[index] = 0;
                Result[index] = Source[index];
                return;
            }
            double pdm = Math.Max((Source[index] - Source[index - 1]), 0);
            double mdm = Math.Max((Source[index - 1] - Source[index]), 0);
 
            _pdmSeries[index] = ((1 - _k)*_pdmSeries[index - 1] + _k*pdm);
            _mdmSeries[index] = ((1 - _k)*_mdmSeries[index - 1] + _k*mdm);
 
            double sum = _pdmSeries[index] + _mdmSeries[index];
            double pdi = 0.0;
            double mdi = 0.0;
 
            if (sum > double.Epsilon)
            {
                pdi = _pdmSeries[index]/sum;
                mdi = _mdmSeries[index]/sum;
            }
 
            _pdiSeries[index] = ((1 - _k)*_pdiSeries[index - 1] + _k*pdi);
            _mdiSeries[index] = ((1 - _k)*_mdiSeries[index - 1] + _k*mdi);
 
            double diff = Math.Abs(_pdiSeries[index] - _mdiSeries[index]);
 
            sum = _pdiSeries[index] + _mdiSeries[index];
 
            if (sum > double.Epsilon)
                _iSeries[index] = ((1 - _k)*_iSeries[1] + _k*diff/sum);
 
 
            double hhv = Math.Max(_iSeries[index], _iSeries.Maximum(Period));
            double llv = Math.Min(_iSeries[index], _iSeries.Minimum(Period));
 
            diff = hhv - llv;
            double vIndex = 0;
 
            if (diff > double.Epsilon)
                vIndex = (_iSeries[index] - llv)/diff;
 
            Result[index] = (1 - _k*vIndex)*Result[index - 1] + _k*vIndex*Source[index];
 
            Rising[index] = double.NaN;
            Falling[index] = double.NaN;
            Flat[index] = double.NaN;
 
            if (Result.IsRising())
                Rising[index] = Result[index];
            else if (Result.IsFalling())
                Falling[index] = Result[index];
            else
                Flat[index] = Result[index];
        }
    }
}

But now I have an other problem adding this code to my bot, I want the logic be like  if AdxVma wasent flat open a position but this dosent work and I know mainly because my lack of knowledge in c# :( 

this is the new code:

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

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

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

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

        [Parameter("Period Dema", DefaultValue = 50, MinValue = 5, MaxValue = 100)]
        public int PeriodDema { get; set; }

        [Parameter("Period Dema1", DefaultValue = 27, MinValue = 5, MaxValue = 100)]
        public int PeriodDema1 { get; set; }

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

        [Parameter("Period AdxVma", DefaultValue = 6, MinValue = 6, MaxValue = 14)]
        public int PeriodAdxVma { get; set; }

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


        private DEMA Dema;
        private DEMA Dema1;
        private AdxVma AdxVma;

        protected override void OnStart()
        {
            Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema);
            Dema1 = Indicators.GetIndicator<DEMA>(SourceDema1, PeriodDema1);
            AdxVma = Indicators.GetIndicator<AdxVma>(SourceAdxVma, PeriodAdxVma);
        }


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

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

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

        private void ManagePostions()
        {
            // When you want to grab data from indicators you need their IndicatorDataSeries.
            // Result wasn't either in one of them,in your case you had tema and dema.

            if (Dema1.dema.LastValue > Dema.dema.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Buy))
                {
                
                if (AdxVma.adxvma.Lastvalue != Flat[index] = Result[index])
                
                    OpenPosition(TradeType.Buy);
                }
                ClosePosition(TradeType.Sell);
            }


            if (Dema1.dema.LastValue < Dema.dema.LastValue)
            {
                if (!IsPositionOpenByType(TradeType.Sell))
                {
                    OpenPosition(TradeType.Sell);
                }
                ClosePosition(TradeType.Buy);
            }
        }


        private void OpenPosition(TradeType type)
        {
            // QuantityToVolumeInUnits returns double,not long therefore you either have to put it into double or cast it to long.
            // e.g. long Volume = (long)Symbol.QuantityToVolumeInUnits(LotSize); this also works.

            double Volume = Symbol.QuantityToVolumeInUnits(LotSize);
            ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null);
        }

        private void ClosePosition(TradeType type)
        {
            var P = Positions.Find(InstanceName, this.SymbolName, type);
            if (P != null)
            {
                ClosePosition(P);
            }
        }

        private bool IsPositionOpenByType(TradeType type)
        {
            var P = Positions.FindAll(InstanceName, SymbolName, type);
            if (P.Count() >= 1)
            {
                return true;
            }
            return false;
        }

    }
}

 


@alisalehicontact