Replies

linkersx
30 Dec 2020, 09:44

RE: So are we going to get Renko range bars or not?

gibetheridge said:

We need them in order to back test.

Back to the future episode 2 ;-)

this-> get renko and range bars in backtest ;-)

 


@linkersx

linkersx
30 Dec 2020, 06:55 ( Updated at: 30 Dec 2020, 06:58 )

RE:

PanagiotisCharalampous said:

Hi ketos.energy,

There is no specific intention behind this except the fact that it takes less space and looks cleaner. It is just that AFAIK nobody ever requested this information. If you think it is important, post a suggestion and if it gathers enough votes, we will consider it.

Best Regards,

Panagiotis 

Join us on Telegram

You mean, saving memory? wee, that's cool, however i doubt that having dedicated DataSeries for 

Weighted, Median and Typical prices is a space saver!

Once I have read on this forum, someone from cTrader support said, that the Tick has an Open, High, Close and low price.

He was talking about tick and not bar !

        //     Gets the Weighted prices data.
        DataSeries WeightedPrices { get; }
        //
        // Summary:
        //     Gets the Median prices data.
        DataSeries MedianPrices { get; }
        //
        // Summary:
        //     Gets the Typical prices data.
        DataSeries TypicalPrices { get; }


@linkersx

linkersx
29 Dec 2020, 17:33 ( Updated at: 29 Dec 2020, 17:39 )

RE: RE:

ketos.energy said:

PanagiotisCharalampous said:

Hi ketos.energy,

There is no specific intention behind this except the fact that it takes less space and looks cleaner. It is just that AFAIK nobody ever requested this information. If you think it is important, post a suggestion and if it gathers enough votes, we will consider it.

Best Regards,

Panagiotis 

Join us on Telegram

Thank you so much for your super fast answers :) For me, it was just very confusing and this gave my the input to think that in backtesting, there is only bar-data and not tick-data used. This was the reason in the first place I asked. When I do backtesting, I'd like to have the closest results to the real world. And if I compare the times, I see a difference. So in my world, I think that there is a difference. If data is here, I'd prefer having the closes look as possible. But this is just my opinion. Just confusing like this :)

 

Enjoy the holidays.

Please check out this-> 

it is trully 100% tick & event driven bar types, even minute bars are derived from ticks which normal btw,

since in the market we got only 2 things price and time, everything else is abstraction from that.,

With BarX bars there is no problem in back testing even in a mix of tick and time based bars

Fully Market profile bars.

Happy holydays


@linkersx

linkersx
29 Dec 2020, 17:33 ( Updated at: 29 Dec 2020, 17:37 )

RE: RE:

...


@linkersx

linkersx
29 Dec 2020, 01:44

RE:

mamamicka said:

For my customer, I am looking for a good scalping robot. My client has 0.2 - 0.3 pip trade cost in total, so anything above 1 pip TP is superb.

After proof that the robot is what it should be, can offer a decent reward. 

 

Thanks in advance. 

hey, HI!

This would be an example of a money making cBot running on cTrader:

//This is an example of an event driven multi barType & timeframe && multi Instrument 
//fully backtestable tick by tick cTrader Robot using LinkersX Event Driven Trading API
namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class cTrader_cBot : Robot
    {
        private TicksX gu1;
        private BarsX gum1;
        private BarsX gum5;
        private BarsX gum15;
        private BarsX gum60;
        private BarsX gum240;
        private BarsX gur10;
        private BarsX guur200;
        private SwingX gusw1; 
        private SwingX guswm5;
        //MarketProfilesX is a custom driven, memory wise unrestricted version of BarsX BarSeries container
        // for storing independent BarX Market Profile Bars
        private MarketProfilesX mpgu1; 
        
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        protected override void OnStart()
        {
            gu1 = new TicksX("GBPUSD", 1, this);
            gum1 = new BarsX(ref gu1, BarType.Minute, 1);
            gum5 = new BarsX(ref gu1, BarType.Minute, 5);
            gum15 = new BarsX(ref gu1, BarType.Minute, 15);
            gum60 = new BarsX(ref gu1, BarType.Minute, 60);
            gum240 = new BarsX(ref gu1, BarType.Minute, 240);
            
            gur10 = new BarsX(ref gu1, BarType.Range, 10);
            
            // declare ONE BarX bar starting from startTime in the Future
            // UltimateRenko BarType 200 pips in size.
            guur200 = new BarX(ref gu1, startTime, BarType.UltimateRenko, 200); 
            
            //
            gusw1 = new BarX(gum1, 1); // attach SwingX High Low algorythm to gum1 1min chart
            guswm5 = new BarX(gum5, 1);

            gum1.OnEvent += onEvent;
            gum5.OnEvent += onEvent;
            gum15.OnEvent += onEvent;
            gum60.OnEvent += onEvent;
            gum240.OnEvent += onEvent;
            gut56.OnEvent += onEvent;
            guur200.OnEvent += onEvent; // BarX will notify us when the Bar is done.
        }

         // various event types examples... All subscribed events will execute on onEvent
        public EventX onEvent(EventX e)
        {
          if(e._non_Farm_Employment_Change)
          {
           return e; // watch out! Non-Farm Employment Change event in Play! Just Do nothing
          }
         
          if(e.newBarHigh && e.id == gum15.id)
          {
           //our 15 minutes GBPUSD Bar is making new Highs x-> do something :-)
          }
                 
          if(e.dailyHigh  && e.bars.symbolName == "GBPUSD")
          {
          // if event is new daily high and symbol name is "GBPUSD" then print out new daily high
          }
          
          //my favorite money Maker ;)
          //if event is new swing high and barseries is 5min gum5 and retracement from last swing up on a 5min chart is 50 percent
          if(e.id == gum5.id && e.newSwingHigh && e.swingHigh[0].fibonacci(50)) 
          {
           // Do something
          }
          //-----------
        }
    }
}

 


@linkersx

linkersx
29 Dec 2020, 00:47 ( Updated at: 29 Dec 2020, 00:50 )

RE:

tbellicus006 said:

Is it possible to build a cBot that is based on several Range chart sizes ("timeframes") but running only in one of them, like a regular MTF bot?

This would be the example of a simple cBot running on cTrader ! It runs on 10 different Timeframes and has 2 range bars with 10 and 20 pips

The strategy is fully Event Driven

Of course this is Back to the Future of January 2021 when you could compile this strategy with the help of the LinkersX API

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

//This is an example of an event driven multi barType & timeframe && multi Instrument 
//fully backtestable tick by tick cTrader Robot using LinkersX Event Driven Trading API
namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class cTrader_cBot : Robot
    {
        private TicksX gu1;
        private BarsX gum1;
        private BarsX gum5;
        private BarsX gum15;
        private BarsX gum60;
        private BarsX gum240;
        private BarsX gurr10;
        private BarsX gut56;
        private BarsX guur200;
        private BarsX gur10;
        private BarsX gur20;
        private SwingX gusw1; 
        private SwingX guswm5;
        //MarketProfilesX is a custom driven, memory wise unrestricted version of BarsX BarSeries container
        // for storing independent BarX Market Profile Bars
        private MarketProfilesX mpgu1; 
        
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        protected override void OnStart()
        {
            gu1 = new TicksX("GBPUSD", 1, this);
            gum1 = new BarsX(ref gu1, BarType.Minute, 1);
            gum5 = new BarsX(ref gu1, BarType.Minute, 5);
            gum15 = new BarsX(ref gu1, BarType.Minute, 15);
            gum60 = new BarsX(ref gu1, BarType.Minute, 60);
            gum240 = new BarsX(ref gu1, BarType.Minute, 240);
            gurr10 = new BarsX(ref gu1, BarType.RomanRenko, 10);
            gut56 = new BarsX(ref gu1, BarType.Tick, 56);

            gur10 =  = new BarsX(ref gu1, BarType.Range, 10);
            gur20 =  = new BarsX(ref gu1, BarType.Range, 20);

            // declare ONE BarX bar starting from startTime in the Future
            // UltimateRenko BarType 200 pips in size.
            guur200 = new BarX(ref gu1, startTime, BarType.UltimateRenko, 200); 
            
            //
            gusw1 = new BarX(gum1, 1); // attach SwingX High Low algorythm to gum1 1min chart
            guswm5 = new BarX(gum5, 1);

            gum1.OnEvent += onEvent;
            gum5.OnEvent += onEvent;
            gum15.OnEvent += onEvent;
            gum60.OnEvent += onEvent;
            gum240.OnEvent += onEvent;
            gurr10.OnEvent += onEvent;
            gut56.OnEvent += onEvent;
            guur200.OnEvent += onEvent; // BarX will notify us when the Bar is done.
        }

         // various event types examples... All subscribed events will execute on onEvent
        public void onEvent(EventX e)
        {
                   
          if(e.firstTickOfBar && e.bars.barType == BarType.Tick && e.bars.barsPeriod == 56)
          {
            //we got a firstTickOfBar event from the Tick.56 object x-> do something :-)
          }
          // same just easier
          if(e.firstTickOfBar && e.id == gut56.id) // check if first tick of bar and bar object is tick.56
          {
            //we got a firstTickOfBar event from the Tick.56 object x-> do something :-)
          }
          
          if(e.id == guur200.id)
          {
           //our guur200 200pips in size Ultimate Renko BarX object declared in the future has just finished the bar object x-> do something :-)
            mpgu1.add(guur200); // add the guur200 BarX object to the MarketProfilesX DataSeries Container.
              Print("UltimateRenko 200 pips BarX object just finished!" 
                    + " Point of Control by Time Profile is:" + guur200.levels.POC_byTime() 
                    + " Point of Control by volume:" +  guur200.levels.POC_byVolume()
                    + " Point of Control by Tick Count:" +  guur200.levels.POC_byTick())
          }
          
          if(e.newBarHigh && e.id == gum15.id)
          {
           //our 15 minutes GBPUSD Bar is making new Highs x-> do something :-)
          }
          
          //if 2 bars ago on a 1 minute bar series volume at Ask was bigger than same bar Volume at Bid
          if(e.bars.id == gum1.id && e.bars[e.index-2].volumeAtAsk > e.bars[e.index-2].volumeAtBid)
          {
           e.bars[e.index-2].eraseBar(); //erase bar from chart for the market profile we gonna draw)
           e.bars[e.index-2].drawMarketProfile();  // just draw a market profile Bar to the chart instead of the erased MTF bar
          }
          
          if(e._non_Farm_Employment_Change)
          {
           // watch out! Non-Farm Employment Change event in Play!
          }
         
          if(e.id == gum5.id && e.bars[e.index -3].candlestick.doji)
          {
           //if 3 bars ago on a 5 minute BarSeries the candlestick type was Doji 
          }
          
          if(e.id == gum60.id && e.ticks[e.ticks.index -5].price > e.ticks.daily[2].high)
          {
           // if the barseries is minute60 and 5 ticks ago  the tick price was higher than daily high 2 days ago
           // Since we can access the Open, Close, High and Low Times, Ask and Bid , we gonna print high price and actual time of the tick
           //   that was of the daily high 2 days ago
           Print("High of a day 2 days ago Price:" + e.daily[2].high + " Time of the days High" + e.daily[2].highTime);
          }
          
          if(e.dailyHigh  && e.bars.symbolName == "GBPUSD")
          {
          // if event is new daily high and symbol name is "GBPUSD" then print out new daily high
          Print (e.bars.symbolName + " new Daily high :" + e.bars[e.index].ClosePrices);
          }
          
          if(e.id == gum5.id && e.newSwingHigh && e.swingHigh[0].fibonacci(50)) 
          {
           //if event is new swing high and barseries is 5min gum5 and retracement from last swing up on a 5min chart is 50 percent
           //e.swingHigh[0].fibonacci(50) returns true if the price is around 50% (+/- level size 5pips) retracement from the current SwingHigh(up) 
          }
          //-----------
        }
    }
}
© 2020 GitHub, Inc.

 


@linkersx

linkersx
29 Dec 2020, 00:33

RE:

PanagiotisCharalampous said:

Hi ketos.energy,

In general, backtesting cannot simulate latency. In backtesting, the entry time is the time at which the tick was generated on the server. In live trading, it takes some time from that moment to the moment your trade is actually executed, since the quote has to travel to your PC, the code needs to be executed, the order needs to be send and then executed on the server. However I cannot know what happens in your case, since the information you provided is very limited.

Best Regards,

Panagiotis 

Join us on Telegram

Why not? I've seen simulation of all kind of latencies in back testing. Of course these algorithms really run on 100% tick Back test!

I really don't understand what`s the big fuss about back testing in general.

 


@linkersx