NexusFi: Find Your Edge


Home Menu

 





Essentials of MTF (multi-time frame) indicators


Discussion in NinjaTrader

Updated
      Top Posters
    1. looks_one Fat Tails with 7 posts (75 thanks)
    2. looks_two ganamide with 3 posts (3 thanks)
    3. looks_3 rename with 2 posts (0 thanks)
    4. looks_4 Adamus with 1 posts (0 thanks)
    1. trending_up 17,711 views
    2. thumb_up 81 thanks given
    3. group 21 followers
    1. forum 15 posts
    2. attach_file 1 attachments




 
Search this Thread

Essentials of MTF (multi-time frame) indicators

  #11 (permalink)
 ganamide 
Los Angeles, CA, USA
 
Experience: Intermediate
Platform: IB TWS, TOS, Lightspeed
Broker: Interactive Brokers, Lightspeed, TD Ameritrade, Fidelity
Trading: MES, Spy Options, Penny Stocks
Posts: 105 since Sep 2013
Thanks Given: 156
Thanks Received: 86


Fat Tails View Post
I have made the observation that for historical bars the value of CurrentBars[1] already changes when the primary bars are being processed. This allows me to access the indicator value calculated from CurrentBars[1] prior to the processing of the secondary bars, and I can avoid the lag. The changed indicator architecture is now
 
Code
if (CurrentBars[1] < currentBars1)
{
    currentBars1 = CurrentBars[1];
    // calculate indicator value here
}
if (BarsInProgress == 0)
{
    // set indicator value to plot here
}

Thanks a million Fat Tails!

Can you point me to sample code that uses the currentBars1 logic? I am not sure I quite understand how the above snippet would work as future bars are processed. I am currently focused on the historical data case, but eventually will want to handle all 3 cases. In particular, I don't understand how (CurrentBars[1] < currentBars1) could keep evaluating to true on each primary bar. Or does this calculation only apply to the very last bar of the chart?

[EDIT]
I found the answer to the above question in Fat Tails' anaOpeningRangeV42MTF indicator. The comparison sign should be reversed so that it looks like this:
 
Code
if (CurrentBars[1] > currentBars1)
{
    currentBars1 = CurrentBars[1];
    // calculate indicator value here
}
if (BarsInProgress == 0)
{
    // set indicator value to plot here
}
[/EDIT]


Second Question:

I have been struggling for days trying to align my secondary data series with my first. My primary series is a renko, let's say 3 tick for the sake of argument, and my secondary is a 1 tick series. I wish to accumulate volumes on 1 tick data for swings that I plot on the primary series. It worked fine for larger renko bars, but with smaller renko bars there could be situations in fast markets where several renko bars print with the exact same timestamps. This is when my indicator has problems synchronizing with the data computed from tick data series.

I should mention that I am actually using BetterRenko bars with a brick size of 1 as my primary series for this test case, which sometimes prints bricks that are actually 2 ticks tall.

Any help greatly appreciated!

Reply With Quote
The following user says Thank You to ganamide for this post:

Can you help answer these questions
from other members on NexusFi?
ZombieSqueeze
Platforms and Indicators
My NT8 Volume Profile Split by Asian/Euro/Open
NinjaTrader
NexusFi Journal Challenge - April 2024
Feedback and Announcements
Request for MACD with option to use different MAs for fa …
NinjaTrader
 
Best Threads (Most Thanked)
in the last 7 days on NexusFi
Retail Trading As An Industry
58 thanks
Battlestations: Show us your trading desks!
55 thanks
NexusFi site changelog and issues/problem reporting
48 thanks
What percentage per day is possible? [Poll]
31 thanks
GFIs1 1 DAX trade per day journal
29 thanks

  #12 (permalink)
 ganamide 
Los Angeles, CA, USA
 
Experience: Intermediate
Platform: IB TWS, TOS, Lightspeed
Broker: Interactive Brokers, Lightspeed, TD Ameritrade, Fidelity
Trading: MES, Spy Options, Penny Stocks
Posts: 105 since Sep 2013
Thanks Given: 156
Thanks Received: 86

I printed out a bunch of statements to figure out how to work around these insane NT 7 MTF bar processing behaviors. Hopefully this could help someone understand the problem, or better yet, maybe someone can suggest a solution!

Setup:
  • Primary data series is a 1 tick BetterRenko. This is a custom bar type I got from futures.io (formerly BMT).
  • Secondary data series is 1 tick (individual trades)
  • Code is an indicator with CalculateOnBarClose=false
  • Information is printed to Output window during OnBarUpdate events

Problem Test Case:
  • A set of 3 BetterRenko bars that all have the same timestamp
  • Corresponding tick data are 5 individual tick bars all having the same timestamp and volume of 1
  • Timestamp is 9/4/15 13:47:20 PST, which does not fall on a session boundary
  • NQ 09-15 contract data from NT historical data server

Output Results in order received in OnBarUpdate:
1. First BetterRenko bar (made from 1 tick)
2. First and only Tick bar of First BetterRenko bar

3. Second BetterRenko bar (made from 2 ticks)
4. First of two Tick bars of Second BetterRenko bar

5. Third BetterRenko bar (made from 2 ticks)
6. Second of two Tick bars of Second BetterRenko bar
7. First of two Tick bars of Third BetterRenko bar (same close and timestamp as previous tick)
8. Second of two Tick bars of Third BetterRenko bar
Hopefully it is clear how this is a problem. I can't be sure if an update on a tick bar is for the BetterRenko bar that came last, or one that came before that one. I suppose I could try to keep track of volume and prices to guess which BetterRenko bar each tick belongs to, but I don't feel confident that approach would work in all cases. Maybe this would work in conjunction with aligning ticks to timestamps, meaning that there seems to be no problem when a new tick has a different time stamp compared to the previous tick. This sort of re-synchs the two data series.

Reply With Quote
  #13 (permalink)
 ganamide 
Los Angeles, CA, USA
 
Experience: Intermediate
Platform: IB TWS, TOS, Lightspeed
Broker: Interactive Brokers, Lightspeed, TD Ameritrade, Fidelity
Trading: MES, Spy Options, Penny Stocks
Posts: 105 since Sep 2013
Thanks Given: 156
Thanks Received: 86


I solved my problem after hours of toiling. In case anyone is interested, I did it by keeping two cumulative volume counts, one for the primary series and one for the secondary series. Whenever I wanted to align calculations made on the secondary series with the primary series, I would check the cumulative volumes to see which primary bar index aligned with the current secondary bar. Depending on the comparison, I would sometimes have to cycle back through the primary bar volumes to get the right index. I also wrote code to cycle forward, but I never needed to go forward more than 1 bar in my testing. At RTH session close, I had to go back 42 bars for alignment!

Now I can get back to the fun part of system development!

Reply With Quote
The following 2 users say Thank You to ganamide for this post:
  #14 (permalink)
 rename 
Россия
 
Posts: 6 since Dec 2014

Yes, you need one counter for each period of chart.

Some related example of counting bar volume by cumulating volumes on every tick by bid\ask side
(works on any timeframe min, tick, range, volume etc.)

 
Code
		protected override void OnMarketData(MarketDataEventArgs e)
		{
                        ...
 			tradeSideVolumes.TickVolume = e.Volume;
			tradeSideVolumes.CumVolume += e.Volume; 
			
			if (lastBar == CurrentBar)  
			{ // we are inside higher timeframe bar
				tradeSideVolumes.BarVolume += e.Volume;
			}
                        ...

		protected override void OnBarUpdate()
		{
			if (BarsInProgress == 0) {   // higher time frame
				lastBar = CurrentBar;  // lastBar is custom indicator class member
				
				if (FirstTickOfBar)  
				{ // new bar on chart
					// set volumes collected in OnMarketData() and just traded for a new bar
                                        // this cause OnMarketData() for new bar triggered before OnBarUpdate()
					volumes[(int)TradeSide.Ask].BarVolume = volumes[(int)TradeSide.Ask].TickVolume;
                                        ...
                                 }

                		vol = volumes[(int)TradeSide.Ask].GetDisplayVolume( BarsPeriod.Id);
		                if (vol > 0)
         			   AskVolume.Set( vol);
                                 ...


		public class Volumes
		{
			public double TickVolume;
			public double BarVolume;			// 
			public double CumVolume;            // cumulate vols for 1 or more ticks (depends on indicator logic)
                        ...

                        public double GetDisplayVolume( PeriodType period)
			{
				if (period == PeriodType.Tick)
					return CumVolume;
				else
					return BarVolume;
			}

			public void NewAskBid()
			{
				CumVolume = 0;	
			}
                        ...

Reply With Quote
  #15 (permalink)
 
Fat Tails's Avatar
 Fat Tails 
Berlin, Europe
Market Wizard
 
Experience: Advanced
Platform: NinjaTrader, MultiCharts
Broker: Interactive Brokers
Trading: Keyboard
Posts: 9,888 since Mar 2010
Thanks Given: 4,242
Thanks Received: 27,102

One of the problems here is the 1-second granularity used by NinjaTrader 7. With NinjaTrader 8 and millisecond granularity things should improve.

Also there is a difference between bar processing in real-time and on historical data. High resolution bars are not being processed correctly on historical data, when they have the same time stamp.

Started this thread Reply With Quote
  #16 (permalink)
 rename 
Россия
 
Posts: 6 since Dec 2014


Fat Tails View Post
One of the problems here is the 1-second granulatiry used by NinjaTrader 7. With NinjaTrader 8 and millisecond granularity things should improve.

Also there is a difference between bar processing in real-time and on historical data. High resolution bars are not being processed correctly on historical data, when they have the same time stamp.

in Market replay we have full data feed input with Level 2.
if you talking about msec TFs, you should use per tick processing anyway, t.i. event-driven algo.

Reply With Quote





Last Updated on October 10, 2015


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
All information is for educational use only and is not investment advice. There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts