Topics

Forum Topics not found

Replies

amusleh
09 Jul 2021, 16:10

Hi,

You have to shift the index of base time frame:

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 AWEMA : Indicator
    {
        private ExponentialMovingAverage _moving;

        private Bars _baseTimeFrameBars;
        // you could change default Value to Minute,Minute15,Hour2 and ...
        [Parameter("Base Timeframe", DefaultValue = "Daily")]
        public TimeFrame BaseTimeFrame { get; set; }

        [Parameter("Applied price", DefaultValue = Price.High)]
        public Price Source { get; set; }

        [Parameter("Shift:", DefaultValue = 0)]
        public int Shift { get; set; }

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



        [Output(" Moving,", LineColor = "Red", PlotType = PlotType.Line, LineStyle = LineStyle.Solid, Thickness = 2)]
        public IndicatorDataSeries Moving_Line { get; set; }



        protected override void Initialize()
        {
            _baseTimeFrameBars = MarketData.GetBars(BaseTimeFrame);

            var baseSeries = GetBaseSeries();

            _moving = Indicators.ExponentialMovingAverage(baseSeries, Period);
        }

        public override void Calculate(int index)
        {
            if (Shift < 0 && index < Math.Abs(Shift))
                return;

            var baseSeriesIndex = _baseTimeFrameBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]) - Shift;

            Moving_Line[index] = _moving.Result[baseSeriesIndex];

        }

        private DataSeries GetBaseSeries()
        {
            switch (Source)
            {
                case Price.Open:
                    return _baseTimeFrameBars.OpenPrices;

                case Price.Close:
                    return _baseTimeFrameBars.ClosePrices;

                case Price.High:
                    return _baseTimeFrameBars.HighPrices;

                case Price.Low:
                    return _baseTimeFrameBars.LowPrices;

                case Price.Median:
                    return _baseTimeFrameBars.MedianPrices;

                case Price.Typical:
                    return _baseTimeFrameBars.TypicalPrices;

                case Price.Weighted:
                    return _baseTimeFrameBars.WeightedPrices;
                default:

                    return _baseTimeFrameBars.ClosePrices;
            }
        }
    }

    public enum Price
    {
        Open,
        Close,
        High,
        Low,
        Median,
        Typical,
        Weighted
    }
}

 


@amusleh

amusleh
07 Jul 2021, 12:26

The symbol sessions gives you the time of week that you can trade the symbol not the trading session you are after. if you want to trade on specific time period of the day you can use the server time and if its in your trading range you can execute your trading operations, ex:

using cAlgo.API;
using System;
using System.Globalization;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class TradeTime : Robot
    {
        private TimeSpan _startTime, _endTime;

        [Parameter("Start Time", DefaultValue = "07:00:00", Group = "Time Filter")]
        public string StartTime { get; set; }

        [Parameter("End Time", DefaultValue = "16:00:00", Group = "Time Filter")]
        public string EndTime { get; set; }

        private DateTime CurrentTime
        {
            get { return Server.TimeInUtc.Add(-Application.UserTimeOffset); }
        }

        private bool IsTimeCorrect
        {
            get { return (_startTime > _endTime && (CurrentTime.TimeOfDay >= _startTime || CurrentTime.TimeOfDay <= _endTime)) || (_startTime < _endTime && (CurrentTime.TimeOfDay >= _startTime && CurrentTime.TimeOfDay <= _endTime)); }
        }

        protected override void OnStart()
        {
            if (!TimeSpan.TryParse(StartTime, CultureInfo.InvariantCulture, out _startTime))
            {
                Print("Invalid start time input");

                Stop();
            }

            if (!TimeSpan.TryParse(EndTime, CultureInfo.InvariantCulture, out _endTime))
            {
                Print("Invalid end time input");

                Stop();
            }
        }

        protected override void OnBar()
        {
            // Return if current time is not in start/end time range
            if (!IsTimeCorrect) return;
        }
    }
}

 


@amusleh

amusleh
02 Jul 2021, 18:50

Hi,

There was an issue on your code, why you were checking once if the Stochastic PercentK is below or equal to 20 and then inside next code block you have another if statement that checks if its greater than 80? how should it work? try this:

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

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

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

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

        [Parameter(DefaultValue = 100, MinValue = 1)]
        public int StopLoss { get; set; }

        [Parameter(DefaultValue = 150, MinValue = 1)]
        public int TakeProfit { get; set; }

        [Parameter("MACD LongCycle", DefaultValue = 26, MinValue = 1)]
        public int LongCycle { get; set; }

        [Parameter("MACD ShortCycle", DefaultValue = 12, MinValue = 1)]
        public int ShortCycle { get; set; }

        [Parameter("MACD Period", DefaultValue = 9, MinValue = 1)]
        public int MACDPeriod { get; set; }

        [Parameter("MA Type", DefaultValue = 6)]
        public MovingAverageType MaType { get; set; }

        [Parameter("K Periods", DefaultValue = 9)]
        public int KPeriods { get; set; }

        [Parameter("D Periods", DefaultValue = 9)]
        public int DPeriods { get; set; }

        [Parameter("K Slowing", DefaultValue = 3)]
        public int K_Slowing { get; set; }

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

        [Parameter("MA Bias", DefaultValue = 50)]
        public int MA_Bias { get; set; }

        public static TimeFrame Minute15;

        private MacdCrossOver _MACD;
        private StochasticOscillator _SOC;
        private ExponentialMovingAverage _MA_50;
        private bool MACDBuy;
        private bool MACDSell;
        private bool SOCBuy;
        private bool SOCSell;
        private bool MA_BiasBuy;
        private bool MA_BiasSell;

        protected override void OnStart()
        {
            _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
            MACDBuy = false;
            MACDSell = false;
            SOCBuy = false;
            SOCSell = false;
            MA_BiasBuy = false;
            MA_BiasSell = false;
            _MACD = Indicators.MacdCrossOver(LongCycle, ShortCycle, MACDPeriod);
            _SOC = Indicators.StochasticOscillator(KPeriods, K_Slowing, DPeriods, MaType);
            _MA_50 = Indicators.ExponentialMovingAverage(Price, MA_Bias);
        }

        protected override void OnBar()
        {
            var ActiveBuy = Positions.Find(Label, SymbolName, TradeType.Buy);
            var ActiveSell = Positions.Find(Label, SymbolName, TradeType.Sell);

            // MACD cross
            if (_MACD.MACD.Last(1) < _MACD.Signal.Last(1) && _MACD.MACD.Last(0) > _MACD.Signal.Last(0) && _MACD.Signal.Last(0) < 0)
            {
                MACDBuy = true;
            }
            else if (_MACD.MACD.Last(1) > _MACD.Signal.Last(1) && _MACD.MACD.Last(0) < _MACD.Signal.Last(0) && _MACD.Signal.Last(0) > 0)
            {
                MACDSell = true;
            }

            // Stochastic cross
            if (_SOC.PercentK.Last(1) > _SOC.PercentD.Last(1) && _SOC.PercentK.Last(2) <= _SOC.PercentD.Last(2) && _SOC.PercentK.Last(1) <= 20)
            {
                SOCBuy = true;
            }
            else if (_SOC.PercentK.Last(1) < _SOC.PercentD.Last(1) && _SOC.PercentK.Last(2) >= _SOC.PercentD.Last(2) && _SOC.PercentK.Last(1) >= 80)
            {
                SOCSell = true;
            }
            // Moving Average Bias

            if (Symbol.Bid > _MA_50.Result.LastValue)
            {
                MA_BiasBuy = true;
            }
            else if (Symbol.Bid > _MA_50.Result.LastValue)
            {
                MA_BiasSell = true;
            }

            if (MACDBuy == true && SOCBuy == true && MA_BiasBuy == true && ActiveBuy == null)
            {
                if (ActiveSell != null)
                {
                    ClosePosition(ActiveSell);
                }

                ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLoss, TakeProfit);
            }

            if (MACDSell == true && SOCSell == true && MA_BiasSell == true && ActiveSell == null)
            {
                if (ActiveBuy != null)
                {
                    ClosePosition(ActiveBuy);
                }

                ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLoss, TakeProfit);
            }
        }
    }
}

Before developing an indicator or cBot for cTrader please learn the C# basics and then read cTrader automate API references.


@amusleh

amusleh
02 Jul 2021, 18:42

Hi,

You can use Position.Pips property to get the amount of Pips of a position, you don't have to calculate it by yourself:

using cAlgo.API;
using cAlgo.API.Internals;
using System;
using System.Linq;
using System.Text;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewsRobotwithBE : Robot
    {
        [Parameter("News Hour", DefaultValue = 14, MinValue = 0, MaxValue = 23)]
        public int NewsHour { get; set; }

        [Parameter("News Minute", DefaultValue = 30, MinValue = 0, MaxValue = 59)]
        public int NewsMinute { get; set; }

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

        [Parameter("Take Profit", DefaultValue = 50)]
        public int TakeProfit { get; set; }

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

        [Parameter("Volume", DefaultValue = 1000, MinValue = 1)]
        public int Volume { get; set; }

        [Parameter("Seconds Before", DefaultValue = 10, MinValue = 1)]
        public int SecondsBefore { get; set; }

        [Parameter("Seconds Timeout", DefaultValue = 10, MinValue = 1)]
        public int SecondsTimeout { get; set; }

        [Parameter("One Cancels Other")]
        public bool Oco { get; set; }

        [Parameter("ShowTimeLeftNews", DefaultValue = false)]
        public bool ShowTimeLeftToNews { get; set; }

        [Parameter("ShowTimeLeftPlaceOrders", DefaultValue = true)]
        public bool ShowTimeLeftToPlaceOrders { get; set; }

        [Parameter("Trigger (pips)", DefaultValue = 20)]
        public int Trigger { get; set; }

        private bool _ordersCreated;

        private DateTime _triggerTimeInServerTimeZone;

        private const string Label = "News Robot";

        protected override void OnStart()
        {
            Positions.Opened += OnPositionOpened;
            Timer.Start(1);

            var triggerTimeInLocalTimeZone = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, NewsHour, NewsMinute, 0);
            if (triggerTimeInLocalTimeZone < DateTime.Now)
                triggerTimeInLocalTimeZone = triggerTimeInLocalTimeZone.AddDays(1);
            _triggerTimeInServerTimeZone = TimeZoneInfo.ConvertTime(triggerTimeInLocalTimeZone, TimeZoneInfo.Local, TimeZone);
        }

        protected override void OnTimer()
        {
            var remainingTime = _triggerTimeInServerTimeZone - Server.Time;
            DrawRemainingTime(remainingTime);

            if (!_ordersCreated)
            {
                var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize;
                ChartObjects.DrawHorizontalLine("sell target", sellOrderTargetPrice, Colors.Red, 1, LineStyle.DotsVeryRare);
                var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize;
                ChartObjects.DrawHorizontalLine("buy target", buyOrderTargetPrice, Colors.Blue, 1, LineStyle.DotsVeryRare);

                if (Server.Time <= _triggerTimeInServerTimeZone && (_triggerTimeInServerTimeZone - Server.Time).TotalSeconds <= SecondsBefore)
                {
                    _ordersCreated = true;
                    var expirationTime = _triggerTimeInServerTimeZone.AddSeconds(SecondsTimeout);

                    PlaceStopOrder(TradeType.Sell, Symbol, Volume, sellOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime);
                    PlaceStopOrder(TradeType.Buy, Symbol, Volume, buyOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime);

                    ChartObjects.RemoveObject("sell target");
                    ChartObjects.RemoveObject("buy target");
                }
            }

            if (_ordersCreated && !PendingOrders.Any(o => o.Label == Label))
            {
                Print("Orders expired");
            }
        }

        private void DrawRemainingTime(TimeSpan remainingTimeToNews)
        {
            if (ShowTimeLeftToNews)
            {
                if (remainingTimeToNews > TimeSpan.Zero)
                {
                    ChartObjects.DrawText("countdown1", "Time left to news: " + FormatTime(remainingTimeToNews), StaticPosition.TopLeft);
                }
                else
                {
                    ChartObjects.RemoveObject("countdown1");
                }
            }
            if (ShowTimeLeftToPlaceOrders)
            {
                var remainingTimeToOrders = remainingTimeToNews - TimeSpan.FromSeconds(SecondsBefore);
                if (remainingTimeToOrders > TimeSpan.Zero)
                {
                    ChartObjects.DrawText("countdown2", "Time left to place orders: " + FormatTime(remainingTimeToOrders), StaticPosition.TopRight);
                }
                else
                {
                    ChartObjects.RemoveObject("countdown2");
                }
            }
        }

        private static StringBuilder FormatTime(TimeSpan remainingTime)
        {
            var remainingTimeStr = new StringBuilder();
            if (remainingTime.TotalHours >= 1)
                remainingTimeStr.Append((int)remainingTime.TotalHours + "h ");
            if (remainingTime.TotalMinutes >= 1)
                remainingTimeStr.Append(remainingTime.Minutes + "m ");
            if (remainingTime.TotalSeconds > 0)
                remainingTimeStr.Append(remainingTime.Seconds + "s");
            return remainingTimeStr;
        }

        private void OnPositionOpened(PositionOpenedEventArgs args)
        {
            var position = args.Position;
            if (position.Label == Label && position.SymbolCode == Symbol.Code)
            {
                if (Oco)
                {
                    foreach (var order in PendingOrders)
                    {
                        if (order.Label == Label && order.SymbolCode == Symbol.Code)
                        {
                            CancelPendingOrderAsync(order);
                        }
                    }
                }
            }
        }

        protected override void OnTick()
        {
            var position = Positions.Find(Label, SymbolName);

            if (position != null && position.Pips >= Trigger && position.StopLoss != position.EntryPrice)
            {
                ModifyPosition(position, position.EntryPrice, position.TakeProfit);
            }
        }
    }
}

Please read the API references and take a look on examples.


@amusleh

amusleh
02 Jul 2021, 10:35

Hi,

Change your OnTick method to:

        protected override void OnTick()
        {
            var position = Positions.Find(Label, SymbolName);

            if (position == null) return;

            var entryPrice = position.EntryPrice;
            var distance1 = Symbol.Bid - entryPrice;
            var distance2 = entryPrice - Symbol.Ask;

            if (distance1 >= Trigger * Symbol.PipSize)
            {
                ModifyPosition(position, entryPrice, position.TakeProfit);
                Print("Stop Loss to Break Even set for position {0}", position.Id);
                Stop();
            }
            if (distance2 >= Trigger * Symbol.PipSize)
            {
                ModifyPosition(position, entryPrice, position.TakeProfit);
                Print("Stop Loss to Break Even set for position {0}", position.Id);
                Stop();
            }
        }

Position.Find can return null, and if you don't check for null it will throw null reference exception and the rest of your code will not execute.


@amusleh

amusleh
01 Jul 2021, 11:37

Hi,

I don't see any issue on your code, it should work fine if there is any position that has less than 10 gross profit, it might not working because the OnTick method is called only for chart symbol ticks, not all position ticks, if you want to manage multiple symbols positions then try this:

        protected override void OnStart()
        {
            foreach (var symbol in Symbols.GetSymbols())
            {
                symbol.Tick += SymbolTick;
            }
        }

        private void SymbolTick(SymbolTickEventArgs obj)
        {
            foreach (var position in Positions)
            {
                if (position.SymbolName.Equals(obj.SymbolName, StringComparison.OrdinalIgnoreCase) && position.GrossProfit <= -10)
                {
                    ClosePosition(position);
                    Stop();
                }
            }
        }

 


@amusleh

amusleh
01 Jul 2021, 11:31

Hi,

Your cBot code had few bugs that were causing it to crash, I fixed it but there is still no trade because your entry logic is very strict:

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

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

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

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

        [Parameter(DefaultValue = 100, MinValue = 1)]
        public int StopLoss { get; set; }

        [Parameter(DefaultValue = 150, MinValue = 1)]
        public int TakeProfit { get; set; }

        [Parameter("MACD LongCycle", DefaultValue = 26, MinValue = 1)]
        public int LongCycle { get; set; }

        [Parameter("MACD ShortCycle", DefaultValue = 12, MinValue = 1)]
        public int ShortCycle { get; set; }

        [Parameter("MACD Period", DefaultValue = 9, MinValue = 1)]
        public int MACDPeriod { get; set; }

        [Parameter("MA Type", DefaultValue = 6)]
        public MovingAverageType MaType { get; set; }

        [Parameter("K Periods", DefaultValue = 9)]
        public int KPeriods { get; set; }

        [Parameter("D Periods", DefaultValue = 9)]
        public int DPeriods { get; set; }

        [Parameter("K Slowing", DefaultValue = 3)]
        public int K_Slowing { get; set; }

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

        [Parameter("MA Bias", DefaultValue = 50)]
        public int MA_Bias { get; set; }

        public static TimeFrame Minute15;

        private MacdCrossOver _MACD;
        private StochasticOscillator _SOC;
        private ExponentialMovingAverage _MA_50;
        private bool MACDBuy;
        private bool MACDSell;
        private bool SOCBuy;
        private bool SOCSell;
        private bool MA_BiasBuy;
        private bool MA_BiasSell;

        protected override void OnStart()
        {
            _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
            MACDBuy = false;
            MACDSell = false;
            SOCBuy = false;
            SOCSell = false;
            MA_BiasBuy = false;
            MA_BiasSell = false;
            _MACD = Indicators.MacdCrossOver(LongCycle, ShortCycle, MACDPeriod);
            _SOC = Indicators.StochasticOscillator(KPeriods, K_Slowing, DPeriods, MaType);
            _MA_50 = Indicators.ExponentialMovingAverage(Price, MA_Bias);
        }

        protected override void OnBar()
        {
            var ActiveBuy = Positions.Find(Label, SymbolName, TradeType.Buy);
            var ActiveSell = Positions.Find(Label, SymbolName, TradeType.Sell);

            // MACD cross
            if (_MACD.MACD.Last(1) < _MACD.Signal.Last(1) && _MACD.MACD.Last(0) > _MACD.Signal.Last(0) && _MACD.Signal.Last(0) < 0)
            {
                MACDBuy = true;
            }
            else if (_MACD.MACD.Last(1) > _MACD.Signal.Last(1) && _MACD.MACD.Last(0) < _MACD.Signal.Last(0) && _MACD.Signal.Last(0) > 0)
            {
                MACDSell = true;
            }

            // Stochastic cross
            if (_SOC.PercentK.HasCrossedAbove(_SOC.PercentD, 0) && _SOC.PercentK.Last(1) <= 20)
            {
                if (_SOC.PercentK.Last(1) > 80)
                {
                    SOCBuy = true;
                }
            }
            else if (_SOC.PercentK.HasCrossedBelow(_SOC.PercentD, 0) && _SOC.PercentK.Last(1) >= 80)
            {
                if (_SOC.PercentK.Last(1) < 20)
                {
                    SOCSell = true;
                }
            }
            // Moving Average Bias

            if (Symbol.Bid > _MA_50.Result.LastValue)
            {
                MA_BiasBuy = true;
            }
            else if (Symbol.Bid > _MA_50.Result.LastValue)
            {
                MA_BiasSell = true;
            }

            if (MACDBuy == true && SOCBuy == true && MA_BiasBuy == true && ActiveBuy == null)
            {
                if (ActiveSell != null)
                {
                    ClosePosition(ActiveSell);
                }

                ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLoss, TakeProfit);
            }

            if (MACDSell == true && SOCSell == true && MA_BiasSell == true && ActiveSell == null)
            {
                if (ActiveBuy != null)
                {
                    ClosePosition(ActiveBuy);
                }

                ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLoss, TakeProfit);
            }
        }
    }
}

If you remove some of the entry conditions you will see trades on back test, also please don't user the Last(0) or LastValue on your cBot, it gives you the latest not closed value of a data series, which can be non deterministic, instead use Last(1) and Last(2).

If you couldn't figure out how to develop the cBot based on your requirements you can post a job request or ask one of our consultants to do it for you.


@amusleh

amusleh
01 Jul 2021, 11:06

Hi,

Try this:

using cAlgo.API;
using System.Linq;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class HeavyweightBot : Robot
    {
        [Parameter("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

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

        //Selecting Indicator
        private ConvertedIndicator heavy;

        protected override void OnStart()
        {
            Print("Hello World!");
            //Load Indicators on startup
            heavy = Indicators.GetIndicator<ConvertedIndicator>(14, 3);
        }

        protected override void OnBar()
        {
            //Trade Amounts
            var TradeAmount = 1000;

            //Zero line cross example
            var HeavyUp = heavy.ExtMapBuffer2_AlgoOutputDataSeries.Last(1);
            var PrevHeavyUp = heavy.ExtMapBuffer2_AlgoOutputDataSeries.Last(2);
            var HeavyDown = heavy.ExtMapBuffer1_AlgoOutputDataSeries.Last(1);
            var PrevHeavyDown = heavy.ExtMapBuffer1_AlgoOutputDataSeries.Last(2);
            var Flat = heavy.ExtMapBuffer3_AlgoOutputDataSeries.Last(2);

            //Check for trade signal
            if (HeavyUp > PrevHeavyDown && !IsPositionOpenByType(TradeType.Buy))
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, TradeAmount, InstanceName, 20, 20);
            }
            else if (HeavyDown < PrevHeavyUp && !IsPositionOpenByType(TradeType.Sell))
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, TradeAmount, InstanceName, 20, 20);
            }
        }

        protected override void OnStop()
        {
            Print("Cya Later!");
        }

        private bool IsPositionOpenByType(TradeType type)
        {
            return Positions.FindAll(InstanceName, SymbolName, type).Length > 0;
        }
    }
}

 


@amusleh

amusleh
28 Jun 2021, 11:46

Hi,

Your question is not related to cTrader Automate API, you have to Google these types of questions or post your question on Stackoverflow.

Your object and Json have invalid format, try this:

using cAlgo.API;
using Newtonsoft.Json;
using System;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class JsonDeserializeTest : Indicator
    {
        private string _json = @"{
success: true,
data:
{
id: 14,
orderId: 21,
productId: 20,
userId: 1,
licenseKey: 'RS-KH-0G-6B-FD-A7-CS-W7',
expiresAt: '2021-07-26 00:00:00'
}
}";

        protected override void Initialize()
        {
            var licence = JsonConvert.DeserializeObject<Licence>(_json);

            Print(licence.Data.ExpiresAt);
        }

        public override void Calculate(int index)
        {
        }
    }

    public class Licence
    {
        public string Success { get; set; }
        public Data Data { get; set; }
    }

    public class Data
    {
        public int Id { get; set; }
        public int OrderId { get; set; }
        public int ProductId { get; set; }
        public int UserId { get; set; }
        public string LicenseKey { get; set; }
        public DateTime ExpiresAt { get; set; }
    }
}

It works fine on my system, I removed some of your data object properties for brevity.


@amusleh

amusleh
25 Jun 2021, 17:22

Hi,

Yes, you can use CheckBox and RadioButton chart controls, there are some examples on API references, please check the links.


@amusleh

amusleh
23 Jun 2021, 16:50

Hi,

Use IndicatorArea instead of Chart for drawing:

IndicatorArea.DrawStaticText("text", indicator_output, VerticalAlignment.Center, HorizontalAlignment.Center, Color.Black);

 


@amusleh

amusleh
23 Jun 2021, 16:48

RE: RE:

Hi,

The problem is you are creating two new chart controls on each tick, and you plot the new ones on top of old ones, please use the below code instead:

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class DrawSpread : Indicator
    {
        private TextBlock _spreadTextBox, _candleTextBox;

        [Parameter("Spread Color", DefaultValue = "Yellow")]
        public string SpreadColor { get; set; }

        [Parameter("Candle Color", DefaultValue = "White")]
        public string CandleColor { get; set; }

        protected override void Initialize()
        {
            _spreadTextBox = new TextBlock
            {
                BackgroundColor = Color.Red,
                ForegroundColor = Color.White,
                Padding = "8, 4",
                VerticalAlignment = VerticalAlignment.Top,
                HorizontalAlignment = HorizontalAlignment.Left,
                Margin = "5, 40, 0, 0",
                Width = 100,
            };

            Chart.AddControl(_spreadTextBox);

            _candleTextBox = new TextBlock
            {
                BackgroundColor = Color.Blue,
                ForegroundColor = Color.White,
                Padding = "8, 4",
                VerticalAlignment = VerticalAlignment.Top,
                HorizontalAlignment = HorizontalAlignment.Left,
                Margin = "5, 65, 0, 0",
                Width = 100,
            };

            Chart.AddControl(_candleTextBox);
        }

        public override void Calculate(int index)
        {
            if (IsLastBar)
                DisplayOnChart();
        }

        private void DisplayOnChart()
        {
            var close = Bars.ClosePrices.Last(0);
            var open = Bars.OpenPrices.Last(0);

            double size;

            if (close < open)
            {
                size = Math.Round((open - close) / Symbol.PipSize, 2);
            }
            else
            {
                size = Math.Round((close - open) / Symbol.PipSize, 2);
            }

            _spreadTextBox.Text = string.Format("Spread: {0:f2}", Symbol.Spread / Symbol.PipSize);
            _candleTextBox.Text = string.Format("Candle: {0}", size);
        }
    }
}
 

@amusleh

amusleh
22 Jun 2021, 19:57

RE:

khoshroomahdi said:

i know that. but i want dynamic time zone. when user change time zone in ctradr indicator should change.

Hi,

You can use the Application.UserTimeOffset to get the user Time zone offset, and if user change the time zone you can use the Application.UserTimeOffsetChanged event to get user new time zone offset.

Check the example code of Application on API references.


@amusleh

amusleh
22 Jun 2021, 17:38

RE: RE: RE: RE: Gratitude

falkyw said:

But, I intended to open a new buy or sell position after closing 3 candles.

Specifically on the renko chart.This mod would be for closing the position, right?

The above code is for closing a position after three bars, not for opening a new one.

Please read the API references and you will be able to do it, or post a job request.


@amusleh

amusleh
21 Jun 2021, 19:45 ( Updated at: 21 Jun 2021, 19:47 )

Hi,

Right now we don't any library for Python or C++, we only have a .NET library.

We will develop more libraries and we will have one for Python in upcoming months.

Open API uses Google Protocol Buffers protocol, its Language agnostic and you can interact with it easily, please check Open API documentation for more detail.


@amusleh

amusleh
21 Jun 2021, 14:51

RE: RE:

jumel.donatien said:

Hi amusleh,

I have another question: When I launch the robot, the form opens and if I want to change the action of the Buy Button (for example) to draw text on chart, it doesn't work.. I think, it's because when the form is launched, the chart is not activated..

Do you have a solution?

Here is the code changed in MainForm.cs:

private void BtnBuy_Click(object sender, System.EventArgs e)
        {
            _robot.ExecuteMarketOrder(TradeType.Buy, _robot.SymbolName, _robot.Symbol.VolumeInUnitsMin);

            _robot.ChartObjects.DrawText("Sample Text", "Sample Text", StaticPosition.Center);
        }

Thank you in advance!

Hi,

Invoke it on robot main thread:

        private void BtnBuy_Click(object sender, System.EventArgs e)
        {
            _robot.ExecuteMarketOrder(TradeType.Buy, _robot.SymbolName, _robot.Symbol.VolumeInUnitsMin);

            _robot.BeginInvokeOnMainThread(() => _robot.Chart.DrawStaticText("Sample Text", "Sample Text", VerticalAlignment.Bottom, API.HorizontalAlignment.Center, Color.Red));
        }

 


@amusleh

amusleh
20 Jun 2021, 10:25

You can download the algo file from here: 

 


@amusleh

amusleh
18 Jun 2021, 20:23

Hi, Its an issue, thanks for reporting, we will fix it in future versions, in meantime you can use the Automate API references.


@amusleh

amusleh
18 Jun 2021, 20:21

Hi,

When you post code please use the editor "Insert Code Snippet" option.

Regarding your issue, you can ask one of our consultants to modify your cBot code or post a job request.


@amusleh

amusleh
18 Jun 2021, 20:19

RE: RE: Gratitude

falkyw said:

amusleh said:

Hi,

You can open a buy/sell market order by using ExecuteMarketOrder method, and you can pass the stop loss/take profit in Pips.

The order will be executed based on symbol bid/ask price, check the code examples of Position.

You can use OnBar method on a Renko chart to execute your orders per bar, or use the OnTick method to count the Pips by your self.

Thank you for answering  Amusleh
Can I execute a new order after the closing of 3 candles on the renko chart of pips? (without third party indicators)
What would be the coding for this?

Hi,

Yes, you can do it, you just have to count the number of bars and if three bars were passed close the position, ex:

using cAlgo.API;
using System;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        protected override void OnBar()
        {
            var index = Bars.Count - 1;

            foreach (var position in Positions)
            {
                // if position symbol is not same as our chart symbol we skip over it
                if (!position.SymbolName.Equals(SymbolName, StringComparison.OrdinalIgnoreCase)) continue;

                // We get the bar Index of position entry time
                var positionEntryBarIndex = Bars.OpenTimes.GetIndexByTime(position.EntryTime);
                // If 3 or more bars passed since position entry time then we close it
                if (index - positionEntryBarIndex >= 3)
                {
                    ClosePosition(position);
                }
            }
        }
    }
}

 


@amusleh