Replies

ctid418503
27 Jul 2018, 13:59

Hi weiss_omi,

Can you say whether you are backtesting with M1 or tick data?  You would not see the effect I am talking about in backtesting if you are using M1 data, but you would see it if you are using Tick Data.  Interestingly my broker is also Pepperstone.


@ctid418503

ctid418503
18 Jul 2018, 23:34

Actually, just making sure that only one position can be open at a time would not work because your SL/TP could be hit again and again within the same second too.  You just need to get out of the market when price is acting like that.


@ctid418503

ctid418503
18 Jul 2018, 23:32

Hi 1001606,

Sometimes I see (fairly regularly actually - every few months) in my broker's tick data massive swings up to 50 pips one way and 50 pips back many times within the same second.  I've always wondered if this was genuine or not.  But anyway, because of this I now never code anything which can be affected by that because it can wipe out a real account balance in a few seconds.

Consider adding a time spacing as well/instead of a pip spacing rule, or literally just make it so only one position can be open at one time for that Symbol & Cbot Label.

It seems impossible for this to happen so I suspected the broker's tick data was manipulated or corrupted, however, I have seen some realtime price movements swinging wildly one way and the other within the same second, so I am not sure.

ZZ


@ctid418503

ctid418503
04 Jul 2018, 17:09

I won't have done because the red asterisk thing which appears when the Cbot needs rebuilding doesn't appear if the indicator is changed.

I have tried that now, and it does work.  I needed to add a character to the Cbot and then delete it to make it think it has changed for the Build icon to become active.

Thanks a lot!


@ctid418503

ctid418503
04 Jul 2018, 14:45

It seems really difficult to make a Cbot react to a change in code in an indicator which I think has lead to alot of the confusion.  If I recompile an indicator I see the change reflected immediately after in the chart window but the Cbot still uses the old version.  I tried without succes:

  • Removing the Cbot instance and re-adding it
  • Closing and restarting Ctrader/Calgo
  • Rebooting the computer

None of these actually did anything.  I finally got it to react to the changes by deleting the Cbot and creating a new one, pasting the Cbot code in and recompiling.  Is there an easier way?

Thanks


@ctid418503

ctid418503
04 Jul 2018, 11:51

I'm sorry.  I think that there was some kind of refresh issue.  When I tried again after setting both the indicator and the Cbot to GMT and rebooted my computer I no longer see a difference between the chart and what the Cbot is reading.  Normally when I recompile an indicator already on a chart I see the changes reflected immediately, however I think it must be hanging onto the timezone even after a recompile so perhaps removing the indictor from the chart and re-adding it will work or restarting CTrader.


@ctid418503

ctid418503
03 Jul 2018, 18:33

indicators referenced from a cBot take the timezone of the cBot

Ok, understood.  I didn't know that.  

But..

If you want your indicator in the cBot to yield the same results to the indicator of the chart, then the cBot should operate on the same timezone as the indicator on the chart

Why did it show the same issue when I had both the Cbot and the Indicator set to GMT?  So in that case, if I understood, the Indicator used in the Cbot will use GMT because it inherited it from the Cbot, and the indicator on the chart will also use GMT because won't it use use the Timezone declared in the indicator (also GMT)?


@ctid418503

ctid418503
03 Jul 2018, 12:52

Thanks for your support.  I didn't indend to sound pushy.  It's just that I have a lot of cBots which work with different session start and end times and I'm not sure whether I should set them all to UTC and then do a lot of coding work to manually handle DST or wait for a fix.


@ctid418503

ctid418503
03 Jul 2018, 12:40

Hi,

Setting both to UTC removes the discrepancy between the chart and what the Cbot reads programmatically.  However, as I am sure you appreciate, this is not a complete solution.  We don't want to have to manually code the Cbots and indicators to take care of all the different dates for Daylight Saving Time and adjust accordingly.  This is what the Timezone setting should do for us isn't it?  It seems that this is quite a dangerous bug.

I am assuming this only affects custom indicators - are all the standard ones using only UTC?

Please keep us updated on when a permanent fix will be available.

Thanks


@ctid418503

ctid418503
03 Jul 2018, 11:32

Hi Panagiotis,

Thanks for looking into this.  The Indicator and the cBot using different time zones was also my initial thought and I've tried that and it still shows the same effect.  Has someone actually tested that?

If you set the Indicator to use  TimeZones.GMTStandardTime and change the line:

if (MarketSeries.OpenTime[ii].Hour == 0 && MarketSeries.OpenTime[ii].Minute == 0)

to

if (MarketSeries.OpenTime[ii].Hour == 5 && MarketSeries.OpenTime[ii].Minute == 5)

So that the indicator is working with GMT but resetting the calculation at 5am (simulating EST) and rerun the same test I outlined above you will get the same difference between the chart and what the Cbot reads programmatically.  So it doesn't seem to be that.  I've just repeated this test now incase I was mistaken and it does the same thing.

Cheers


@ctid418503

ctid418503
29 Jun 2018, 11:41

Sure.  The parameters are:

[ChartParameters]
Symbol = GBPUSD
Timeframe = m5

[cBotParameters]
SessionStart = 8
SessionLen = 8

  • 10,000 starting capital
  • Tick Data from Server
  • Commision: 35

You can see that order in the picture from the 26th December if you use 25/12/2014 as the start date and 27/12/2014 as the end date assuming your tick data is roughly similar to that from my broker.  But the issue happens throughout the backtesting if you use a longer period.  You would have to install that indicator I linked to above.  Code for the CBot:

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.GMTStandardTime, AccessRights = AccessRights.None)]
    public class VWAPBreakout : Robot
    {

        [Parameter("Session Start Hour", DefaultValue = 8, MinValue = 0, Step = 1)]
        public int SessionStart { get; set; }

        [Parameter("Session Length (Hours)", DefaultValue = 5, MinValue = 0, Step = 1)]
        public int SessionLen { get; set; }

        private MarketSeries seriesD1;

        private TrueRange tr;
        private AverageTrueRange atr;
        private VWAP vwap;
        bool buy_tradeflg = true;
        bool sell_tradeflg = true;

        protected override void OnStart()
        {
            // Put your initialization logic here
            seriesD1 = MarketData.GetSeries(TimeFrame.Daily);
            tr = Indicators.TrueRange(seriesD1);
            atr = Indicators.AverageTrueRange(seriesD1, 14, MovingAverageType.Simple);
            vwap = Indicators.GetIndicator<VWAP>(0, false);
            //Print("VWAP = {0}", vwap.Result[vwap.Result.Count - 1]);
        }

        protected override void OnBar()
        {
            // Put your core logic here
            double ATRange = atr.Result.LastValue;
            double DayRange = tr.Result.LastValue;
            //Print("ATR Range = {0}, Day Range = {1}", ATRval, DayRange);

            double totcnt = 0;
            double belowcnt = 0;
            double abovecnt = 0;

            for (int ii = 0; MarketSeries.OpenTime.Last(ii).Hour > SessionStart || MarketSeries.OpenTime.Last(ii).Minute != 0; ii++)
            {
                //Print("MarketSeries.Close.Last {0} vwap.Result.Last {1}", MarketSeries.Close.Last(ii), vwap.Result.Last(ii));
                if (MarketSeries.Close.Last(ii) < vwap.Result.Last(ii))
                {
                    belowcnt++;
                    //Print("VWAP was above price {0}", MarketSeries.OpenTime.Last(ii).Minute);
                }
                else
                {
                    abovecnt++;
                }

                totcnt++;

            }
            //Print("below count: {0}, total count: {1} --- {2}", belowcnt, totcnt, (belowcnt / totcnt) * 100);
            double abv_percent = 0;
            double blw_percent = 0;
            if (totcnt > 0)
            {
                blw_percent = (belowcnt / totcnt) * 100;
                abv_percent = (abovecnt / totcnt) * 100;
            }

            // Buy logic

            //if (blw_percent > 70 && DayRange < (ATRange * 1.3))
            //    Print("Price below VWAP {0} percent of time", blw_percent);

            if (blw_percent > 70 && Time.Hour > SessionStart + 1 && Time.Hour < SessionStart + SessionLen - 1 && DayRange < (ATRange * 1.3))
            {
                if (buy_tradeflg == true && Positions.Count == 0 && MarketSeries.Close.Last(1) > vwap.Result.Last(1) && MarketSeries.Low.Last(1) < vwap.Result.Last(1))
                {
                    Print("MarketSeries.Close.Last(1) {0} MarketSeries.Low.Last(1) {1} vwap.Result.Last(1) {2}", MarketSeries.Close.Last(1), MarketSeries.Low.Last(1), vwap.Result.Last(1));
                    double StopLoss = (Math.Abs(MarketSeries.Low.Last(1) - MarketSeries.High.Last(1)) / Symbol.PipSize) * 3;

                    TradeResult tres = ExecuteMarketOrder(TradeType.Sell, Symbol, 100000, "VB", StopLoss, 9999);
                    if (tres.IsSuccessful != true)
                        Print("Error executing market order");
                    buy_tradeflg = false;
                }
            }
            if (MarketSeries.Close.Last(0) < vwap.Result.Last(0))
                buy_tradeflg = true;

            // Sell logic

            // if (abv_percent > 70 && DayRange < (ATRange * 1.3))
            //     Print("Price above VWAP {0} percent of time", abv_percent);

            if (abv_percent > 70 && Time.Hour > SessionStart + 1 && Time.Hour < SessionStart + SessionLen - 1 && DayRange < (ATRange * 1.3))
            {
                if (sell_tradeflg == true && Positions.Count == 0 && MarketSeries.Close.Last(1) < vwap.Result.Last(1) && MarketSeries.Close.Last(2) > vwap.Result.Last(2))
                {

                    double StopLoss = (Math.Abs(MarketSeries.Low.Last(1) - MarketSeries.High.Last(1)) / Symbol.PipSize) * 1.5;

                    TradeResult tres = ExecuteMarketOrder(TradeType.Buy, Symbol, 100000, "VB", StopLoss, 9999);
                    if (tres.IsSuccessful != true)
                        Print("Error executing market order");
                    sell_tradeflg = false;
                }
            }
            if (MarketSeries.Close.Last(0) > vwap.Result.Last(0))
                sell_tradeflg = true;


            if (Time.Hour == SessionStart + SessionLen && Time.Minute == 0)
            {

                foreach (var position in Positions)
                {
                    if (position.Label.Equals("VB") && position.SymbolCode == Symbol.Code)
                        ClosePosition(position);
                }

            }



        }

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

 


@ctid418503

ctid418503
28 Jun 2018, 23:15

Maybe it crashed?  What does it say in the Log tab?

Or it blew the account?  You'll need to provide a bit more information I think.


@ctid418503

ctid418503
05 May 2018, 12:18

It annoys me that when you select a trade in history and it displays it on the chart, you cant scroll the chart without the trade disappearing.  Will something be done about this?


@ctid418503

ctid418503
05 May 2018, 11:56

Hi Bernard,

Yeah I'm using it and find it stable and reliable.  The interface is much more pretty and user friendly (for manual traders), and using C# for algo traders has a lot of benefits.  Admittedly there is a lot more source code available for Metatrader for EAs/bots and indicators (and also EAs you must pay for), but that can be either a good or bad thing.  I program all my stuff from scratch (I like to understand exactly what its doing and not just use someone else's Metatrader (MT4, MQ4/5) code).   

Only a few brokers offer it.  Well that's the 'free' market isn't it?


@ctid418503

ctid418503
05 May 2018, 11:34

I've noticed the thing about slider position and how far back you can backtest.  It varies between tick data and M1 prices on my broker.  When I first installed CAlgo I could only backtest with tickdata for a few days because the slider wouldn't let me put it futher back (play button was greyed out if I put it further back).  Then later I can backtest from about 2013 with tick data.  Downloading tick data takes a while, they are big files but I wish Ctrader/Calgo had more visibility of what it's doing because it doesn't instill confidence when one time you can backtest only a few days and then suddenly you can backtest for several years.  More transparancy would be good!

I'm not sure about your different backtest trading results.  Explanations in my mind are:

1. You were actually running different algorithms 

2. You were running backtest with different parameters, maybe using M1 on one and tick data on the other.

3. Your broker is manipulating the price feed.

Probably 1 or 2.  Ctrader doesn't help because there is not a lot of transparency in how it downloads historical data.  Don't get me wrong, its still better than MT in this respect.


@ctid418503