Topics

Forum Topics not found

Replies

amusleh
09 Feb 2022, 09:38 ( Updated at: 10 Feb 2022, 08:26 )

RE:

ys2310 said:

CADJPY, GBPJPY data seems exactly the same between backtesting and Live data.

but SP, CL and EURUSD, volatile symbols seem different in decimal between backtesting and Live data.

Can you confirm this on your side? I see difference on my end.

Best regards,

Hi,

Please tell us which broker you are using and the start/end date for data or back test.

I will compare the normal chart data with back test data and I will let you know if there was any difference.


@amusleh

amusleh
09 Feb 2022, 09:00

Hi,

Here is the new code, it stored the covered positions IDs on a list and it will use the list to avoid re opening a new position for an already covered position.

using cAlgo.API;
using System.Collections.Generic;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        private readonly List<int> _coveredPositions = new List<int>(100);

        [Parameter("Trade Size", DefaultValue = 1000, MinValue = 0.01)]
        public double Size { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 15, MinValue = 2)]
        public int SL { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 35, MinValue = 2)]
        public int TP { get; set; }

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, Size, SymbolName, SL, TP);
        }

        protected override void OnTick()
        {
            // It iterates over all positions
            foreach (var position in Positions)
            {
                // If position is already covered, continue
                if (_coveredPositions.Contains(position.Id)) continue;

                // if position is 5 or more pips in profit
                if (position.Pips >= 5)
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, Size, SymbolName, SL, TP);

                    _coveredPositions.Add(position.Id);
                }
                // if position is 5 or more pips in lose
                else if (position.Pips <= -5)
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, Size, SymbolName, SL, TP);

                    _coveredPositions.Add(position.Id);
                }
            }
        }
    }
}

 


@amusleh

amusleh
09 Feb 2022, 08:53

RE: How many requests can be sent per second?

meeting.chegini said:

Hello
thank you,The code works fine
But I want to be able to send a message every second
is this possible?

Hi,

You can start cBot/Indicator Timer with 1 second interval, then call the send method inside OnTimer method every one second.


@amusleh

amusleh
09 Feb 2022, 08:51 ( Updated at: 09 Feb 2022, 08:52 )

RE: RE: RE: RE:

sim.bianc.gns said:

Do I have to send the Logon message in anycase in both sockets, right? Shouldn't I receive an answer if the login is done correctly? 

The fields are the same reported in the documentation, maybe in different position in respect to the example provided. Does it matter?
In addition, in the documentation the bodylenght is always 5 less than the correct value. Is there any other field which isn't included in the count? (Except for beginString, bodyLenght and checksum)

Hi,

You will receive a response back from server if your logon request was successful.

I haven't tested FIX on Python but I tested our .NET samples and everything works fine.

As I said on my previous post, most probably something is wrong with your code.

We will create a Python example for FIX API in near future and then I will be able to help you.


@amusleh

amusleh
09 Feb 2022, 08:48

RE: RE:

TheNiatpac said:

OK, thanks for the reply.  Any possible future versions to support this function?

amusleh said:

Hi,

No, you can't set/get the Output attribute properties programmatically.

 

Hi,

No, it's not planned, please create a thread under suggestions section and then we will consider it if it got enough vote from other users.


@amusleh

amusleh
09 Feb 2022, 08:47

Hi,

Your calculation doesn't match, if you copy the first one calculation part to the second then the results will match.

This one EHMA output matches with first one HMA output:

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MATest2 : Indicator
    {
        [Parameter("Periods", DefaultValue = 14, MinValue = 1)]
        public int Periods { get; set; }

        [Output("Avg. Price")]
        public IndicatorDataSeries AP { get; set; }

        [Output("EMA")]
        public IndicatorDataSeries EMA { get; set; }

        [Output("EMAH")]
        public IndicatorDataSeries EMAH { get; set; }

        [Output("EMAI")]
        public IndicatorDataSeries EMAI { get; set; }

        [Output("EHMA", LineColor = "Red")]
        public IndicatorDataSeries EHMA { get; set; }

        private double exp;
        private double expH;
        private double expSR;

        protected override void Initialize()
        {
            exp = 2.0 / (Periods + 1.0);
            expH = 2.0 / (Periods / 2.0 + 1.0);
            expSR = 2.0 / (Math.Sqrt(Periods) + 1.0);
        }

        public override void Calculate(int index)
        {
            double p = Bars.ClosePrices[index];

            AP[index] = p;

            if (index <= 0)
            {
                EMA[0] = p;
                EMAH[0] = p;
                EMAI[0] = p;
                EHMA[0] = p;

                return;
            }

            int pi = index - 1;

            double pma1 = EMA[pi];
            double d1 = p - pma1;
            double ma1 = pma1 + exp * d1;
            EMA[index] = ma1;

            double pma4 = EMAH[pi];
            double d4 = p - pma4;
            double ma4 = pma4 + expH * d4;
            EMAH[index] = ma4;

            double ma5 = 2 * ma4 - ma1;
            EMAI[index] = ma5;

            double phma = EHMA[pi];
            double dh = ma5 - phma;
            double hma = ma5 + expSR * dh;
            EHMA[index] = hma;
        }
    }
}

 


@amusleh

amusleh
09 Feb 2022, 08:25 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE:

waym77 said:

Hi Amusleh,

 

Thanks so much for your help so far.

However, I'm still having problems with the same thing.

Please see my example below:

The purple line is where the entry is supposed to be. I'm not sure how to fix this.

Thanks in advance,

Hi,

You used global variables for saving results of some functions instead of local variables, that was the issue.

Try this:

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

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

    {
        [Parameter("Name", Group = "General", DefaultValue = "MACD Bot")]
        public string _Label { get; set; }

        [Parameter("MACD Long", Group = "MACD", DefaultValue = 26, MaxValue = 100, MinValue = 1)]
        public int _macdlong { get; set; }

        [Parameter("MACD Short", Group = "MACD", DefaultValue = 12, MaxValue = 100, MinValue = 1)]
        public int _macdshort { get; set; }

        [Parameter("MACD Signal", Group = "MACD", DefaultValue = 9, MaxValue = 100, MinValue = 1)]
        public int _macdsig { get; set; }

        [Parameter("MA Type", Group = "Moving Average", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType _matype { get; set; }

        [Parameter("MA Period", Group = "Moving Average", DefaultValue = 200, MaxValue = 1000, MinValue = 1)]
        public int _maperiod { get; set; }

        [Parameter("Reward", Group = "Risk", DefaultValue = 1.5, MaxValue = 10.0, MinValue = 0.1, Step = 0.1)]
        public double _reward { get; set; }

        [Parameter("Pip Limiter", Group = "Risk", DefaultValue = 8.0, MaxValue = 50.0, MinValue = 0.1, Step = 0.1)]
        public double _limiter { get; set; }

        [Parameter("Position Size", Group = "Risk", DefaultValue = 1.0, MaxValue = 100.0, MinValue = 0.01, Step = 0.01)]
        public double _size { get; set; }

        [Parameter("Stop Loss Buffer", Group = "Risk", DefaultValue = 1.0, MaxValue = 50.0, MinValue = 0.01, Step = 0.01)]
        public double _slbuffer { get; set; }

        public MacdCrossOver _macd;
        public MovingAverage _ma;

        protected override void OnStart()
        {
            _macd = Indicators.MacdCrossOver(_macdlong, _macdshort, _macdsig);
            _ma = Indicators.MovingAverage(Bars.ClosePrices, _maperiod, _matype);
            _slbuffer = 1.0;
        }

        protected override void OnBar()
        {
            var _activebuy = Positions.Find(_Label, SymbolName, TradeType.Buy);
            var _activesell = Positions.Find(_Label, SymbolName, TradeType.Sell);

            var _volume = Symbol.QuantityToVolumeInUnits(_size);
            var _distance = Math.Abs((_ma.Result.LastValue - Bars.ClosePrices.LastValue) / Symbol.PipSize);

            var _maq = Bars.ClosePrices.Last(1) > _ma.Result.Last(1) ? true : false;
            var _distanceq = _distance < _limiter ? true : false;

            var _macdbuy = false;
            var _macdsell = false;

            if (_macd.MACD.Last(1) > _macd.Signal.Last(1) && _macd.MACD.Last(2) < _macd.Signal.Last(2) && _macd.MACD.Last(1) < 0)
            {
                _macdbuy = true;
            }

            if (_macd.MACD.Last(1) < _macd.Signal.Last(1) && _macd.MACD.Last(2) > _macd.Signal.Last(2) && _macd.MACD.Last(1) > 0)
            {
                _macdsell = true;
            }

            if (_activebuy == null && _maq && _distanceq && _macdbuy)
            {
                var _getsl = GetStopLoss();
                var _gettp = GetTakeProfit(_getsl);

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

                ExecuteMarketOrder(TradeType.Buy, Symbol.Name, _volume, _Label, _getsl, _gettp);
            }

            if (_activesell == null && !_maq && _distanceq && _macdsell)
            {
                var _getsl = GetStopLoss();
                var _gettp = GetTakeProfit(_getsl);

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

                ExecuteMarketOrder(TradeType.Sell, Symbol.Name, _volume, _Label, _getsl, _gettp);
            }
        }

        private double GetStopLoss()
        {
            return Math.Abs((_ma.Result.Last(1) - Bars.ClosePrices.Last(1)) / Symbol.PipSize) + _slbuffer;
        }

        private double GetTakeProfit(double stopLoss)
        {
            return stopLoss * _reward;
        }
    }
}

 


@amusleh

amusleh
09 Feb 2022, 08:14

RE:

ys2310 said:

Hello amusleh, LoadMoreHistory method solved my problem.

though, I see there are small discrepancies in data obtained from backtesting and data obtained from Live.

Is there any method for this problem? backtesing results are different from Live results because of this data gap.

Best regards,

 

Hi,

You get the same data, if you are back testing and running your cBot on same broker then the data you get must be same.

And you should back test your cBot on tick data to get the most accurate results.


@amusleh

amusleh
08 Feb 2022, 12:06

Hi,

Your question is not clear, In case you want to link a position/order with a bar you can use bar OpenTime as comment for position/order.

Please stop creating multiple threads for same question, otherwise you will be banned from forum.


@amusleh

amusleh
08 Feb 2022, 10:06

RE: RE:

boris_k said:

"Can you please post the full logout message response you received?"
You see the body of the Logout message  in my first post.
The field 58 is missed in the message the server sends if an another session is active.
It is easy to replicate:
1.Connect to the session
2. Try to connect to the session with the same credentials.
You will receive the Logout message without the body. There is no info about the reason of logout.
 

Hi,

I tried this but it doesn't result on a logout message from server, instead it gets disconnected so nothing comes from server side on second logon attempt with same credentials.


@amusleh

amusleh
08 Feb 2022, 09:58

RE: RE:

sim.bianc.gns said:

amusleh said:

Hi,

Did you tried on our FIX samples? and you can't have two FIX session at the same time, you can only have one active connected FIX session.

I didn't try it because I'm using python. I don't have any FIX session because I've never received any answer from the server (even in my personal area they are not registered).

The flow is that I connect through the module socket to the host name and port reported in the first message and then I send the Logon message in both socket. Is there anything else that I must do first?
 

Hi,

If you are using plain text host/port you can start sending messages after connection, only for SSL you need an extra authentication step before you start to send any message.

Most probably your message is not formatted correctly, that's why server is not returning any message back.


@amusleh

amusleh
08 Feb 2022, 08:36

RE: RE: RE:

danieleyube said:

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("Trade Size", DefaultValue = 1000, MinValue = 0.01)]
        public double Size { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 15, MinValue = 2)]
        public int SL { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 35, MinValue = 2)]
        public int TP { get; set; }

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, Size, SymbolName, 10, 10);
        }

        protected override void OnTick()
        {
            // It iterates over all positions
            foreach (var position in Positions)
            {
                // if position is 5 pips in profit
                if (Positions[0].Pips == 5)
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, Size, SymbolName, 0, 10);
                }
                // if position is 5 pips in lose
                else if (Positions[0].Pips == -5)
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, Size, SymbolName, 0, 10);
                }
            }
        }

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

 

is anything Wrong with the above code?

Hi,

Why you are using Positions[0].Pips?

Here is the correct version:

using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Trade Size", DefaultValue = 1000, MinValue = 0.01)]
        public double Size { get; set; }

        [Parameter("Stop Loss (Pips)", DefaultValue = 15, MinValue = 2)]
        public int SL { get; set; }

        [Parameter("Take Profit (Pips)", DefaultValue = 35, MinValue = 2)]
        public int TP { get; set; }

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, Size, SymbolName, SL, TP);
        }

        protected override void OnTick()
        {
            // It iterates over all positions
            foreach (var position in Positions)
            {
                // if position is 5 pips in profit
                if (position.Pips >= 5)
                {
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, Size, SymbolName, SL, TP);
                }
                // if position is 5 pips in lose
                else if (position.Pips <= -5)
                {
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, Size, SymbolName, SL, TP);
                }
            }
        }
    }
}

 


@amusleh

amusleh
08 Feb 2022, 08:30 ( Updated at: 08 Feb 2022, 08:32 )

Hi,

You can access the values inside Bars data series like OpenPrices by index either from beginning or end, but I'm not sure what exactly you are trying to do?

The indices aren't same, they change based on available data on your chart or loaded data from Bars.

One index might give you a value in one chart but another on another chart or environment.

The NAN is retuned when you try to access a value on a data series by index that aren't there yet.

You can try to load more data for bars if you need more data, call Bars LoadMoreHistory method to load more data.


@amusleh

amusleh
08 Feb 2022, 08:26

Hi,

No, you can't set/get the Output attribute properties programmatically.


@amusleh

amusleh
08 Feb 2022, 08:19

RE: RE:

florent.herb said:

amusleh said:

Hi,

You can use History with Linq:

var grossProfitTotal = History.Select(trade => trade.GrossProfit).Sum();
var netProfitTotal = History.Select(trade => trade.NetProfit).Sum();

 

Hi,

 

Is it in C# langage? And would it work for total gross loss?

 

Regards

Hi,

It's C#, and you can use it on your cBots/Indicators.

You can calculate the gross loss by using history, ex:

// First it filters the losing trades, then is sum their gross return
var grossLossTotal = History.Where(trade => trade.GrossProfit < 0).Select(trade => trade.GrossProfit).Sum();

 


@amusleh

amusleh
08 Feb 2022, 08:15

RE:

sirinath said:

Can this difference be due to a bug in cTrader?

Hi,

I checked your code but it's not clear what's the exact issue you are looking to solve?

Please make clear what's the issue and then I will be able to help you.

If there is something wrong in your code first remove the other things and just post the code that has issue, that way it would be much easier for us to help you.


@amusleh

amusleh
08 Feb 2022, 06:57

RE: RE:

CTGood said:

amusleh said:

Hi,

Ranke/Renko back teste is not available right now on cTrader back tester.

It will be added on a future release.

Hi, When will Renko/Range backtest will be available?  Any approximate idea of month/year will help. 

Thanks

Hi,

Sorry, I can't give you any ETA.


@amusleh

amusleh
07 Feb 2022, 09:33

Hi,

Did you tried on our FIX samples? and you can't have two FIX session at the same time, you can only have one active connected FIX session.


@amusleh

amusleh
07 Feb 2022, 09:31

Hi,

It's the average return of all your trades.


@amusleh

amusleh
07 Feb 2022, 09:30

Hi,

You can use History with Linq:

var grossProfitTotal = History.Select(trade => trade.GrossProfit).Sum();
var netProfitTotal = History.Select(trade => trade.NetProfit).Sum();

 


@amusleh