Topics

Forum Topics not found

Replies

amusleh
08 Apr 2022, 10:40

Hi,

You can separate each instance orders by using the Symbol name, example:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class DemoBot : Robot
    {
        [Parameter("Name", Group = "Global Settings", DefaultValue = "DemoBot")]
        public string _name { get; set; }

        [Parameter("High/Low Timeframe", Group = "Global Settings", DefaultValue = "Daily")]
        public TimeFrame _hltf { get; set; }

        [Parameter("Take Profit", Group = "Risk", DefaultValue = 15.0, MinValue = 0.1, MaxValue = 1000000.0)]
        public double _takeprofit { get; set; }

        [Parameter("Risk %", Group = "Risk", DefaultValue = 1.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _riskpercent { get; set; }

        [Parameter("Stop Loss", Group = "Risk", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 1000000.0)]
        public double _stoploss { get; set; }

        [Parameter("Safety (Pips)", Group = "Risk", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 10000.0)]
        public double _safety { get; set; }

        private Bars _hlbars;
        private double _previoushigh, _previouslow, _volume;
        private bool _todaybuyhappened, _todaysellhappened;

        public IEnumerable<PendingOrder> BotPendingOrders
        {
            get
            {
                return PendingOrders.Where(order => order.SymbolName.Equals(SymbolName, StringComparison.Ordinal) && order.Label.Equals(_name, StringComparison.Ordinal));
            }
        }

        protected override void OnStart()
        {
            _hlbars = MarketData.GetBars(_hltf);

            _hlbars.BarOpened += _hlbars_BarOpened;
            _safety *= Symbol.PipSize;

            Positions.Closed += PositionsOnClosed;

            _todaybuyhappened = true;
            _todaysellhappened = true;
        }

        private void _hlbars_BarOpened(BarOpenedEventArgs obj)
        {
            _todaybuyhappened = false;
            _todaysellhappened = false;

            foreach (var _PendingOrders in BotPendingOrders)
            {
                CancelPendingOrder(_PendingOrders);
            }

            if (_hlbars.OpenPrices.Last(0) > _hlbars.HighPrices.Last(1))
            {
                _todaybuyhappened = true;
            }

            if (_hlbars.OpenPrices.Last(0) < _hlbars.LowPrices.Last(1))
            {
                _todaysellhappened = true;
            }

            _volume = GetVolume();

            _previoushigh = Math.Abs(_hlbars.HighPrices.Last(1) + _safety);
            _previouslow = Math.Abs(_hlbars.LowPrices.Last(1) - _safety);

            if (!_todaybuyhappened)
            {
                PlaceStopOrder(TradeType.Buy, Symbol.Name, _volume, _previoushigh, _name, _stoploss, _takeprofit);
                _todaybuyhappened = true;
            }

            if (!_todaysellhappened)
            {
                PlaceStopOrder(TradeType.Sell, Symbol.Name, _volume, _previouslow, _name, _stoploss, _takeprofit);
                _todaysellhappened = true;
            }
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            _volume = GetVolume();

            foreach (var _PendingOrders in BotPendingOrders)
            {
                if (_PendingOrders.VolumeInUnits != _volume)
                {
                    _PendingOrders.ModifyVolume(_volume);
                }
            }
        }

        private double GetVolume()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;

            double baseNumber = Account.Balance;

            double sizeInLots = Math.Round((baseNumber * _riskpercent / 100) / (_stoploss * costPerPip), 2);

            var result = Symbol.QuantityToVolumeInUnits(sizeInLots);

            if (result > Symbol.VolumeInUnitsMax)
            {
                result = Symbol.VolumeInUnitsMax;
            }
            else if (result < Symbol.VolumeInUnitsMin)
            {
                result = Symbol.VolumeInUnitsMin;
            }
            else if (result % Symbol.VolumeInUnitsStep != 0)
            {
                result = result - (result % Symbol.VolumeInUnitsStep);
            }
            return result;
        }
    }
}

The BotPendingOrders enumerable will give you only those orders that are from same symbol and with same Label.


@amusleh

amusleh
08 Apr 2022, 10:31

Hi,

Do you mean adding categories/folder support on cTrader automate cBots/Indicators list? Or showing the .NET solution projects hierarchy like Visual Studio? If you mean the later then you can use Visual Studio or any other .NET IDE (after 4.2 release) for it, in case of the former please create a new thread under suggestions section.


@amusleh

amusleh
08 Apr 2022, 10:26

Hi,

There is no need to create a new data series for that, you can work on a split of a data series, ex:

        /// <summary>
        /// Returns the minimum value between start and end (inclusive) index in a DataSeries
        /// </summary>
        /// <param name="dataSeries"></param>
        /// <param name="startIndex">Start index Inclusive (Ex: 1)</param>
        /// <param name="endIndex">End index Inclusive (Ex: 10)</param>
        /// <returns>double</returns>
        private double Minimum(DataSeries dataSeries, int startIndex, int endIndex)
        {
            var min = double.PositiveInfinity;

            for (var i = startIndex; i <= endIndex; i++)
            {
                min = Math.Min(dataSeries[i], min);
            }

            return min;
        }


        /// <summary>
        /// Returns the maximum value between start and end (inclusive) index in a DataSeries
        /// </summary>
        /// <param name="dataSeries"></param>
        /// <param name="startIndex">Start index Inclusive (Ex: 1)</param>
        /// <param name="endIndex">End index Inclusive  (Ex: 10)</param>
        /// <returns>double</returns>
        private double Maximum(DataSeries dataSeries, int startIndex, int endIndex)
        {
            var max = double.NegativeInfinity;

            for (var i = startIndex; i <= endIndex; i++)
            {
                max = Math.Max(dataSeries[i], max);
            }

            return max;
        }

 


@amusleh

amusleh
07 Apr 2022, 14:02

Hi,

Visual studio 2022 and .NET 6 support is added to cTrader 4.2 which is in beta testing now, you can try it by downloading Spotware cTrader Beta.


@amusleh

amusleh
07 Apr 2022, 10:47

Hi,

Can you please send us the ".algo" files and project folders of these indicators/robot via email?

Our Email: connect@spotware.com


@amusleh

amusleh
07 Apr 2022, 09:16 ( Updated at: 21 Dec 2023, 09:22 )

Hi,

The Chart drawings are working fine in Visual back test mode, ex:

using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TestDrawing : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Price { get; set; }

        protected override void OnStart()
        {
            var line = Chart.DrawHorizontalLine("1", Price, Color.Red);
            
            line.IsInteractive = true;
        }
    }
}

Result:

If you set the IsInteractive property of a chart object to True then it will remain on chart even if back test stop, otherwise the objects will be removed from the chart on back test stop.

In non visual mode the chart drawings will not show up.


@amusleh

amusleh
07 Apr 2022, 09:06

Hi,

All cTrader services use cTrader Proxy cloud, please read: cTrader Proxy Cloud | Solving Last Mile Latency | Spotware Systems Ltd


@amusleh

amusleh
07 Apr 2022, 09:02

Hi,

If your cBot/Indicator is built with previous version of cTrader then you need Visual Studio 2019 for opening it.

For cBots/Indicators that are built with cTrader 4.2 you need Visual Studio 2022.

Installing Visual Studio 2019 might solve this issue, you can install both Visual Studio 2019 and 2022.


@amusleh

amusleh
07 Apr 2022, 08:00

Hi,

Check the API references for a sample: Event Closed | API reference | cTrader Community


@amusleh

amusleh
06 Apr 2022, 09:56 ( Updated at: 06 Apr 2022, 09:58 )

Hi,

Multi symbol optimization is added on version 4.2 of cTrader, it's on beta and it will be released for brokers very soon.

You can use multi symbol optimization on Spotware cTrader Beta 4.2.


@amusleh

amusleh
06 Apr 2022, 09:53

Hi,

I'm not sure exactly what kind of problem you are facing, I just tested Visual back test with some indicators, it works fine.

Please record a video from the issue you are facing and post it here.


@amusleh

amusleh
06 Apr 2022, 09:50

Hi,

I think you have to re-write the Bot based on new cTrader Automate API, specifically those Trade calls.


@amusleh

amusleh
05 Apr 2022, 14:17 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE:

hejnekem said:

firemyst said:

> Hi, I would like to run this bot on different instances, but I couldnt do it. I tried label and symbol too.

 

What do you mean?

To run multiple instances of a bot, just add more "instances" under the bot and choose the symbol you want to run it against.

Example:

In teh above, one instance will run on EURUSD H1 timeframe, the other bot will run under the US30 symbol.

It doesnt work, because when I start a second instance it doesnt start, other times the first instance closes the second one.

Hi,

Are you sure it's a cTrader cBot code? It uses some APIs that is not part of cTrader automate API.

 


@amusleh

amusleh
05 Apr 2022, 09:54

Hi,

When you are using Nuget packages on your Indicators/cBots that target .NET framework you have to use the .NET SDK compiler, you can't use embedded compiler for those types of Indicators/cBots.

You can change the .NET compiler from your cTrader settings -> Automate tab.


@amusleh

amusleh
05 Apr 2022, 09:52

Hi,

The account balance is updated when you close a position, or you deposit/withdraw funds, for later two there is no way to know that but for position close you can use the Positions Closed event.

So what you need to do is first subscribe to Positions.Closed event and then move your calculation logic to Positions closed event handler.


@amusleh

amusleh
05 Apr 2022, 09:49

Hi,

It happens because of spread between bid and ask price levels, the bars are created based on bid price.


@amusleh

amusleh
05 Apr 2022, 09:45

RE:

Jobauma said:

Reloading equal to loading the 1st time after applying.

Thanks.

Best regards,

Johannes Hillestad Baumann

Hi,

Do you mean when you attach an indicator on a backtest chart it's not appearing?


@amusleh

amusleh
05 Apr 2022, 09:44

RE: RE: RE: Code to make this work?

william@hallsdesign.co.uk said:

 

Hi,

 

I have been going round in circles with this, and all I want is the current price of a pair I have. I have everything, all my code is placing a trade etc.. But only if I manually add the price in for my pair and run my code.

I have tried all the subscribing and ProtoOASpotEvent stuff. If you wouldnt mind helping me out with the exact code you did, that would be greatly appreciated. I just wish they would allow you to place a market order with a stopLoss and takeProfit without having to faff with all of this!!

Thanks in advance

 

William

Hi,

To receive live quotes of a symbol you have to send a ProtoOASubscribeSpotsReq, after that you will keep receiving ProtoOASpotEvent(s) which will contain the latest symbol bid/ask prices.

For code example please check the console sample of OpenApiPy: OpenApiPy/main.py at main · spotware/OpenApiPy (github.com)

For creating a new market order you have to send a ProtoOANewOrderReq: OpenApiPy/main.py at 50b00db0a2570d4cb62ab0a191501f49aa5ea191 · spotware/OpenApiPy (github.com)

You can set the stop loss and take profit in relative: Messages - cTrader Open API (spotware.github.io)


@amusleh

amusleh
05 Apr 2022, 09:39

Hi,

Can you please provide the steps to reproduce the doubling issue? we tried but we were not able to reproduce this issue.


@amusleh

amusleh
05 Apr 2022, 09:37

Hi,

You can use the trendbar utcTimestampInMinutes fields, if it changes then it means a new bar is opened.

If there is no activity then there will be no bars.


@amusleh