Topics

Forum Topics not found

Replies

amusleh
18 Mar 2021, 10:49

RE: RE: thank. And what needs to be written so that the direction changes with each new order?

shop.n33 said:

PanagiotisCharalampous said:

Hi shop.n33,

Your cBot is still executing random orders. See here

            if (position.GrossProfit > 0)
            {
                ExecuteOrder(InitialVolume, GetRandomTradeType());
            }
            else
            {
                ExecuteOrder((int)position.Volume * 2, position.TradeType);
            }

Best Regards,

Panagiotis 

Join us on Telegram

 

Hi,

Here is the code that will change the trade type to opposite trade type of previous position:

using cAlgo.API;
using System;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MartingaleRobot : Robot
    {
        [Parameter("Initial Volume", DefaultValue = 10000, MinValue = 0)]
        public int InitialVolume { get; set; }

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

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

        private Random random = new Random();

        protected override void OnStart()
        {
            Positions.Closed += OnPositionsClosed;

            ExecuteOrder(InitialVolume, TradeType.Buy);
        }

        private void ExecuteOrder(long volume, TradeType tradeType)
        {
            var result = ExecuteMarketOrder(tradeType, Symbol, volume, "Martingale", StopLoss, TakeProfit);

            if (result.Error == ErrorCode.NoMoney)
                Stop();
        }

        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            Print("Closed");

            var position = args.Position;

            if (position.Label != "Martingale" || position.SymbolCode != Symbol.Code) return;

            var nextOrderTradeType = position.TradeType == TradeType.Buy ? TradeType.Sell : TradeType.Buy;

            if (position.GrossProfit > 0)
            {
                ExecuteOrder(InitialVolume, nextOrderTradeType);
            }
            else
            {
                ExecuteOrder((int)position.Volume * 2, nextOrderTradeType);
            }
        }

        private TradeType GetRandomTradeType()
        {
            return random.Next(2) == 0 ? TradeType.Buy : TradeType.Sell;
        }
    }
}

 


@amusleh

amusleh
17 Mar 2021, 13:34

cTrader Automate API is written in C# language, you have to know C# first.

There are lots of free resources available on internet for learning C#, after you got some basic C# knowledge you can start from API references and sample indicators/cBots that came with cTrader.


@amusleh

amusleh
17 Mar 2021, 13:31

Hi,

Unfortunately it's not possible now, the cloud color is set from output color, you can't change or even access it via code.


@amusleh

amusleh
17 Mar 2021, 10:18

RE:

budda_dan2020 said:

Hi,

I am running an c# program which uses Open API.

As far as I know, the access token is valid for a given time being.

When the access token is no longer valid, I should use the refresh token in order to get a new valid token.

1) Which API message should I use and how?

2) If I get new access token and new refresh token thru this message response, am I able to still operate trading action?

3) How can I know if the current access token is no longer valid?

I am looking forward to reply.

Thanks in advance.

1. For refreshing token you have to use the ProtoOARefreshTokenReq message

2. After updating the refresh token you have to re-authorize the trading accounts by sending new ProtoOAAccountAuthReq message and you have to use the new token for all future requests

3. You can use the token expiry time to check for expiry, and if your token expired you will receive a ProtoOAAccountsTokenInvalidatedEvent message


@amusleh

amusleh
17 Mar 2021, 10:14

RE:

budda_dan2020 said:

Hi,

I want to use demo account AND live account in a c# trading program using Open API.

Should I create 2 ssl stream for demo and live accounts respectively because demo.ctraderapi.com for demo accounts and live.ctraderapi.com is for live accounts?

Can I use demo.ctraderapi.com for live account transactions?

It will make the programing a lot easier.

Thanks in advance.

Hi,

Open API uses two different hosts for demo and live trading accounts, all API calls of those two different account types are separate and you must create two client connection for each.

You can't use demo connection for live account operations or vice versa.

I strongly recommend you to use our OpenAPI.NET library if you are using Open API on a .NET application.

Our library allows you to send and receive API requests/responses with just few lines of code, also take a look on library console demo app in its repo.


@amusleh

amusleh
16 Mar 2021, 14:08

The team were able to reproduce this issue and it will be fixed in future releases, thanks.


@amusleh

amusleh
16 Mar 2021, 11:11

RE:

andurei said:

Some mql4/mql5 codes in my opinion are pretty hard to convert to cAlgo because of this function. How can i get a similar alternative to prev_calculated (for mql5) or IndicatorCounted (for mql4)?  Thanks in advance. 

See the example below: ( in mql4)

int counted_bars=IndicatorCounted();
   int i,j,k,limit;

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
           limit=MathMin(Bars-1,MathMax(Bars-counted_bars,HalfLength));

   //
   //
   //
   //
   //
   
   for (i=counted_bars; i>=0; i--)
   {
      // code example
   }

   

 

 

 

 

Hi,

Its very easy to convert other platforms code to cTrader Automate C# code, you just have to know the API.

There is no IndicatorCounted equivalent function in Automate API, and the indicator is refreshed and reinitialized whenever the chart data is updated or indicator parameters change, you can't access the previous indicator instance data.

So basically you don't need this function in cTrader automate as it works differently in comparison to MT 4/5, cTrader is not new version of MetaTrader and they work differently.

If you want to have access to previous indicator instance data you can save the current instance data in a file and when the indicator reinitialized you can read from that file your data and fill the indicator data series outputs with it instead of recalculating.

 


@amusleh

amusleh
15 Mar 2021, 17:39 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE: RE:

matthewgrayiveta said:

amusleh said:

matthewgrayiveta said:

amusleh said:

Please use cTrader pattern drawing indicator: 

 

is not working your indicator  and is not this what i suggest  si simple tool that let you draw Eliot wave 12345 and ABC  we need what be in ctrader by default and we have trend lines and other tools  

This indicator works on cTrader 4.0 and later versions, it looks like your broker cTrader is not updated ye

Pattern drawing indicator works like a cTrader built-in drawing tool:

Once your broker updated to cTrader 4.0 you can start using it.

can you text me to me in my email to make this indicator work or my chart my email matthewgrayiveta@gmail.com 

Please wait for your broker cTrader to update, once your broker cTrader updated to 4.0 then you can start to use the indicator.


@amusleh

amusleh
15 Mar 2021, 14:30

I tried in Skilling cTrader, it returns 19.9 for down and 20 for up and nearest rounding, I will verify this with the team if this is the expected behavior or not.

In Spotware beta it returns 20 for all rounding modes, and if there was a bug it might be already fixed, I will report this and I will update you.

Thanks for reporting this issue.


@amusleh

amusleh
15 Mar 2021, 14:13

RE: RE:

matthewgrayiveta said:

amusleh said:

Please use cTrader pattern drawing indicator: 

 

is not working your indicator  and is not this what i suggest  si simple tool that let you draw Eliot wave 12345 and ABC  we need what be in ctrader by default and we have trend lines and other tools  

This indicator works on cTrader 4.0 and later versions, it looks like your broker cTrader is not updated yet.

Pattern drawing indicator works like a cTrader built-in drawing tool:

Once your broker updated to cTrader 4.0 you can start using it.


@amusleh

amusleh
15 Mar 2021, 12:50

RE:

rsoudani said:

Hi, i'm working on my own strategy, looks good on demo account and on firts live tests, but i can not backtest it because i need low spreads, and i have raw spread account on icmarkets, but for backtesting in cTrader i can only get tickdata from server where i cant choose spread and it seems to be much to high (i need tick data not bar data). Do you have any suggestions?

Hi,

The tick data is from your broker price feed, you can try other brokers cTrader for backtesting and using their tick data. 


@amusleh

amusleh
15 Mar 2021, 09:46

RE:

duketv said:

Hi guys,

Working on a new idea and trying a very simple crossover but do not seem to able to get it to work consistenly in my backtest, perhaps you can spot the error?

My goal is to:

1. return true when price crosses and closes above MA for buy signal (and opposite for sell)

2. Return true for this instance for the next three bars or so (in case no direct overlap with other indicators)

 

I previously did this with: 

if (Bars.Last(1).Open < Sma.Result.LastValue && Bars.Last(1).Close > Sma.Result.LastValue)

{ //buy

or with:

if (Sma.Result.HasCrossedBelow(Symbol.Bid, 3));

{ //buy

but neither gives me the consistent desired result..

Any ideas are much appreciated :)

Hi,

The code above checks last MA value which is not closed yet and can change, so it can go above or below last closed bar price.

You should use Last(1) not LastValue:

if (Bars.Last(1).Open < Sma.Result.Last(1) && Bars.Last(1).Close > Sma.Result.Last(1))
{

​}

Last(1) gives you the latest closed value, and LastValue gives you the last value of series which is not closed yet and can change which will give you inconsistent results both in backtest and live.

You can use Last(2) to get the last second closed value of a series.


@amusleh

amusleh
15 Mar 2021, 09:40

Please use cTrader pattern drawing indicator: 

 


@amusleh

amusleh
14 Mar 2021, 12:29

I see you load more historical bars data on your cBot, and indicators, which might cause this issue, please follow this:

1. Use only one indicator instance on your cBot not an array of indicator instances as it will make testing hard

2. Remove load bars data from all three, and check again, if the data matches then the issue is with new loaded bars

3. If the data didn't match then post the new code here without load historical bars data code and I will check (only if you do the two above steps first)

The difference in indicator data can happen if the data is different in your cBot and indicator, to solve it you can call each indicator calculate method inside a for loop manually from your cBot.

Your code amount is very large and missy, if you couldn't solve the issue you can ask a consultant to develop your cBot for you. 


@amusleh

amusleh
12 Mar 2021, 15:05

RE: Number of Subscripted symbols

BenjaminR said:

Hi Panagiotis,

I have same problem.

We monitor many accounts by OpenAPI and when users open a new positions with different symbols  our app subscripts for that symbols and waits for prices. Sometimes the price do not arrive and  our app waits and do nothing for many seconds or minutes...

This time the program logic is the following:

- when the user opens a position with new (not subscripted) symbol: our app subscribes to this symbol and waits for prices. 

- if the user close the position: our app unsubscribe from that symbol.

Can we have a problem if we subscribe to all symbols at program start  instead of subscribe to symbol on the fly one by one as the users use them?

Thanks, Beri

Hi BenjaminR,

You can subscribe to all account symbols after account authorization, there will be no problem.

Regarding not receiving the price quotes, did you received any error message from API? and when it happened?


@amusleh

amusleh
11 Mar 2021, 15:54

Try this:

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

namespace cAlgo
{
    [Cloud("Top", "Bottom", Opacity = 0.2)]
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class BollingerBandsMTF : Indicator
    {
        private BollingerBands _bollingerBands;

        private Bars _baseBars;

        [Parameter("Base TimeFrame", DefaultValue = "Daily")]
        public TimeFrame BaseTimeFrame { get; set; }

        [Parameter("Source", DefaultValue = DataSeriesType.Close)]
        public DataSeriesType DataSeriesType { get; set; }

        [Parameter("Periods", DefaultValue = 14, MinValue = 0)]
        public int Periods { get; set; }

        [Parameter("Standard Deviation", DefaultValue = 2, MinValue = 0)]
        public double StandardDeviation { get; set; }

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

        [Output("Main", LineColor = "Yellow", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Main { get; set; }

        [Output("Top", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Top { get; set; }

        [Output("Bottom", LineColor = "Red", PlotType = PlotType.Line, Thickness = 1)]
        public IndicatorDataSeries Bottom { get; set; }

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

            var baseSeries = GetBaseSeries();

            _bollingerBands = Indicators.BollingerBands(baseSeries, Periods, StandardDeviation, MaType);
        }

        public override void Calculate(int index)
        {
            var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

            Main[index] = _bollingerBands.Main[baseIndex];
            Top[index] = _bollingerBands.Top[baseIndex];
            Bottom[index] = _bollingerBands.Bottom[baseIndex];
        }

        private DataSeries GetBaseSeries()
        {
            switch (DataSeriesType)
            {
                case DataSeriesType.Open:
                    return _baseBars.OpenPrices;

                case DataSeriesType.High:
                    return _baseBars.HighPrices;

                case DataSeriesType.Low:
                    return _baseBars.LowPrices;

                case DataSeriesType.Close:
                    return _baseBars.ClosePrices;

                default:
                    throw new ArgumentOutOfRangeException("DataSeriesType");
            }
        }
    }

    public enum DataSeriesType
    {
        Open,
        High,
        Low,
        Close
    }
}

 


@amusleh

amusleh
11 Mar 2021, 13:57

Please try this new indicator code on your cBot:

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

namespace cAlgo.Indicators
{
    [Indicator("ATR Trailing Stop", AutoRescale = false, IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
    public class ATR_Stops_time_MarketData_History : Indicator
    {
        [Parameter("Timeframe", DefaultValue = 0.0)]
        public TimeFrame TF { get; set; }

        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Parameter("Period", DefaultValue = 10, MinValue = 2, MaxValue = 50000)]
        public int Period { get; set; }

        [Parameter("Weight", DefaultValue = 4.0, MinValue = 0.1, MaxValue = 400.0)]
        public double Weight { get; set; }

        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { get; set; }

        [Parameter(DefaultValue = 16000)]
        public int LoadHistory_for_ind { get; set; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }

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

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

        private ATRMTF_time_History _atr;
        public bool _isLong;

        private MarketSeries _marketSeries;

        //private AverageTrueRange_Cust_lag[,] stop_ind = new ATRStops[perCount, weightCount];
        private Bars Bars2;

        public StreamWriter file3;

        protected override void Initialize()
        {
            Print("Start");

            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            Print("{0} bar on the chart. Loading 2.000.000 bars", Bars2.Count);

            if (LoadIndHist == true)
            {
                while (Bars2.Count < LoadHistory_for_ind)
                {
                    var loadedCount = Bars2.LoadMoreHistory();

                    if (loadedCount == 0)
                        break;
                }
                Print("Finished, total bars {0}", Bars2.Count);
            }

            Print("1");

            _atr = Indicators.GetIndicator<ATRMTF_time_History>(Period, TF, LoadHistory_for_ind, LoadIndHist);

            _marketSeries = MarketData.GetSeries(MarketData.GetSymbol(Symbol.Name), TF);

            //else
            //Print("Не загружено {0} баров", BarCount_set);
        }

        public override void Calculate(int index)
        {
            var currentAtr = Weight * _atr.Result[index];

            if (double.IsNaN(currentAtr))
                return;

            if (double.IsNaN(Result[index - 1]) && !double.IsNaN(_atr.Result[index - 1]))
            {
                var previousATR = Weight * _atr.Result[index - 1];

                _isLong = MarketSeries.Close.IsRising();

                var previous = UseHighAndLow ? (_isLong ? this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])] : this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])]) : this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])];

                Result[index] = _isLong ? previous - previousATR : previous + previousATR;
            }
            else
            {
                var current = this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];

                if (_isLong)
                {
                    if (current >= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Max(Result[index - 1], current - currentAtr);
                    }
                    else
                    {
                        _isLong = false;
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current + currentAtr;
                    }
                }
                else
                {
                    if (current <= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Min(Result[index - 1], current + currentAtr);
                    }
                    else
                    {
                        _isLong = true;
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current - currentAtr;
                    }
                }
            }

            if (_isLong)
                _myIsLong[index] = 2;
            else
                _myIsLong[index] = 1;
        }
    }
}

Inside your "_myIsLong" series 2 means True and 1 means False.


@amusleh

amusleh
10 Mar 2021, 09:23

Hello,

Try this:

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MidasIndex : Robot
    {
        [Parameter(DefaultValue = 9)]
        public int PeriodFast { get; set; }

        [Parameter(DefaultValue = 26)]
        public int PeriodMedium { get; set; }

        [Parameter(DefaultValue = 52)]
        public int PeriodSlow { get; set; }

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

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

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

        private IchimokuKinkoHyo _ichimoku;

        protected override void OnStart()
        {
            _ichimoku = Indicators.IchimokuKinkoHyo(PeriodFast, PeriodMedium, PeriodSlow);
        }

        protected override void OnBar()
        {
            var positionsBuy = Positions.FindAll("Buy");
            var positionsSell = Positions.FindAll("Sell");

            if (positionsBuy.Length > 0 || positionsSell.Length > 0) return;

            if (Bars.OpenPrices.Last(1) <= _ichimoku.SenkouSpanA.Last(1)
                && Bars.OpenPrices.Last(1) > _ichimoku.SenkouSpanB.Last(1)
                && Bars.ClosePrices.Last(1) > _ichimoku.SenkouSpanA.Last(1)
                && _ichimoku.TenkanSen.Last(1) > _ichimoku.KijunSen.Last(1))
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, "Buy", StopLossPips, TakeProfitPips);
            }

            if (Bars.OpenPrices.Last(1) >= _ichimoku.SenkouSpanA.Last(1)
                && Bars.OpenPrices.Last(1) < _ichimoku.SenkouSpanB.Last(1)
                && Bars.ClosePrices.Last(1) < _ichimoku.SenkouSpanA.Last(1)
                && _ichimoku.TenkanSen.Last(1) < _ichimoku.KijunSen.Last(1))
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, "Sell", StopLossPips, TakeProfitPips);
            }
        }
    }
}

I backtested and it worked fine.


@amusleh

amusleh
09 Mar 2021, 12:33

RE: Re3:

travkinsm1 said:

members of the forum, and first of all amusleh, have any thoughts about my problem?

I tried to compile your code but the "ATRMTF_time_History" indicator is missing, please decrease the amount of your code and post it again so I will be able to find the issue.

Right now I don't see any specific issue on your cBot code, but your indicator might be the problem.

Regarding getting different values, it can be because cBot loads different data, not the same amount of data that indicator uses, your indicator is a multi time frame indicator and it references another multi time frame indicator, which can cause this mismatch.

I recommend you if its possible move your indicator code to your cBot, that will decrease the complexity and you will have direct access to code so you will not much easier what goes wrong.

Try to use the indicator on a small sample cBot, see if you can replicate the issue, if you were able then post that small sample cBot here and I will be able to identify the issue faster


@amusleh

amusleh
08 Mar 2021, 13:07

Try this:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TestVWAP_Bot : Robot
    {
        [Parameter("TradeType")]
        public TradeType TradeDir { get; set; }

        [Parameter("Max Buy Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxBuy { get; set; }

        [Parameter("Max Sell Positions", DefaultValue = 1, MinValue = 1)]
        public int MaxSell { get; set; }

        [Parameter("Trade Start Time", DefaultValue = 7, MinValue = 7, MaxValue = 8)]
        public double StartTime { get; set; }

        [Parameter("Trade End Time", DefaultValue = 14, MinValue = 14, MaxValue = 15)]
        public double EndTime { get; set; }

        private TestVWAP _vwap;

        protected override void OnStart()
        {
            _vwap = Indicators.GetIndicator<TestVWAP>();
        }

        protected override void OnBar()
        {
            double Time = Server.Time.TimeOfDay.TotalHours;

            if (!(StartTime <= Time && Time <= EndTime)) return;

            if (TradeDir == TradeType.Buy)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Buy).Length >= MaxBuy) return;

                if (Bars.OpenPrices.Last(1) < _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) > _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
            else if (TradeDir == TradeType.Sell)
            {
                if (Positions.FindAll("TestVWAP_Bot", Symbol.Name, TradeType.Sell).Length >= MaxSell) return;

                if (Bars.OpenPrices.Last(1) > _vwap.Result.Last(1) && Bars.ClosePrices.Last(1) < _vwap.Result.Last(1))
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 1000, "TestVWAP_Bot", 30, 60);
                }
            }
        }
    }
}

Next time please also post the custom indicator code you are using.


@amusleh