How to visually identify days of the week on intraday charts? Background color change for each separate day

thanks
day change does solve my query!

thanks milosz

vertical line query is solved for day change

but backcolor not working for daychange
i am attaching the chart pic too, please recheck the code

{//firstbar
FirstBar = DateNum() != Ref( DateNum(), -1 );
RibbonColor1 = ColorBlend( colorBlack, colorAqua, 0.1 );
RibbonColor2 = ColorBlend( colorBlack, colorAqua, 0.1 );
RibbonColor = IIf( Cum( FirstBar ) % 2 == 0, RibbonColor1, RibbonColor2 );
//Plot( Close, "Close", colorDefault, styleCandle );
Plot( FirstBar, "", colorAqua, styleHistogram | styleOwnScale | styleNoLabel, 1, 0, 0, -1, 2 );
Plot( 1, "", RibbonColor, styleArea | styleOwnScale | styleNoLabel, 0, 1, 0, -1 );
////If you don't need vertical lines marking first bar of each session, you can comment the line with Plot(FirstBar ...
}
image

@n_bagadia my code just works.

  1. Try changing the colors. My above example used very low contrast - so it might have been difficult to spot the difference on some displays, but as you can see below it really works:

Ribbon%204

Ribbon%203

  1. Try changing the Z-order parameter from -1 (minus one) from my example to a bigger value - for example 0, 1, 2 or 5. I can't see the grid lines on your chart, so there is a big chance, that the black background on your chart is drawn on top of my ribbon and that's why you can't see it. Or just test it on some different/default chart to find out what the reason of your problem is.

https://www.amibroker.com/guide/afl/plot.html

  1. Besides I've just noticed, that your modification of my code is wrong:
RibbonColor1 = ColorBlend( colorBlack, colorAqua, 0.1 );
RibbonColor2 = ColorBlend( colorBlack, colorAqua, 0.1 );
RibbonColor = IIf( Cum( FirstBar ) % 2 == 0, RibbonColor1, RibbonColor2 );

It doesn't make sense to use the same color here. It's illogical.

1 Like

@n_bagadia I think there is a high chance, that your only problem was using the same (almost black) color for all consecutive days - which (by the way) in the context of your initial request, seems illogical :wink: As a result, you ended up with one almost black rectangle in the background. If you (for instance) try this code:

dn = DateNum();
FirstBar = dn != Ref( dn, -1 );
RibbonColor1 = ColorBlend( colorWhite, colorGold, 0.3 );
RibbonColor2 = colorWhite;
RibbonColor = IIf( Cum( FirstBar ) % 2 == 0, RibbonColor1, RibbonColor2 );
Plot( Close, "Close", colorDefault, styleCandle );
//Plot( FirstBar, "", colorGold, styleHistogram | styleOwnScale | styleNoLabel, 1, 0, 0, -1, 2 );
Plot( 1, "", RibbonColor, styleArea | styleOwnScale | styleNoLabel, 0, 1, 0, -1 );

... you should see a chart similar to this one:

Ribbon%205

2 Likes

I thought, that sometimes when browsing historical charts, it might be useful to be able to tell what day of the week it was. Below code not only separates consequtive days, but helps spotting some patterns that are likely to occure on Mondays, Fridays etc. In this example the ribbon in the lower part of the screen is the darkest on Mondays and the brightest on Fridays. Additionally there are numbers - from 1 (Monday) to 5 (Friday), which allow to precisely identify each day of the week. Ribbon's and numbers' colors, can be changed via chart parameters.

DaysOfweek%201

DaysOfweek%202

_SECTION_BEGIN( "Days of week" );
// by Miłosz Mazurkiewicz
/// @link https://forum.amibroker.com/t/background-color-change-for-each-separate-day-in-intraday-charts-how-to-visually-identify-days-of-the-week-on-the-chart/6881/10
dn = DateNum(); dw = DayOfWeek();
FirstBarOfDay = dn != Ref( dn, -1 );
Color1 = ParamColor( "Ribbon's color", colorLightYellow );
Color2 = ParamColor( "Numbers' color", colorBlack );
RibbonHeight = 5; // Percent of chart height
for( i = 1; i <= 5; i++ ) VarSet( "C" + i, ColorBlend( colorBlack, Color1, i / 5 ) );
RibbonColor = IIf( DW == 1, C1, IIf( dw == 2, C2, IIf( dw == 3, C3, IIf( dw == 4, C4, IIf( dw == 5, C5, colorDefault ) ) ) ) );
//Plot( Close, "Close", colorDefault, styleCandle );
Plot( FirstBarOfDay, "", Color1, styleHistogram | styleOwnScale | styleNoLabel, 1, 0, 0, -1, 2 );
Plot( RibbonHeight, "", RibbonColor, styleArea | styleOwnScale | styleNoLabel, 0, 100, 0, -1 );
PlotShapes( FirstBarOfDay * ( 33 + dw * 2 ), Color2, 0, LowestVisibleValue( L ), 6, 5 );
if (Interval() >= inDaily) Error("Change interval to Intraday");
_SECTION_END();

The main part of the code uses only Arrays and PlotShapes. To be able to display names of days instead of numbers, I would need to use loop to iterate through all visible bars. Later I I'm going to add such modified code.

1 Like

OK, here is the example of such modified code:

_SECTION_BEGIN( "Days of the week with Names" );
// by Miłosz Mazurkiewicz
/// @link https://forum.amibroker.com/t/how-to-visually-identify-days-of-the-week-on-intraday-charts-background-color-change-for-each-separate-day/6881/11

Color1 = ParamColor( "Ribbon color", colorLightYellow );
Color2 = ParamColor( "Text color", colorBlack );

if (Interval() >= inDaily) Error("This code should be used on intraday charts. Change interval.");
dn = DateNum(); dw = DayOfWeek(); bi = BarIndex();
fvbi = Status( "firstvisiblebarindex" ); lvbi = Status( "lastvisiblebarindex" ); pxchb = Status( "pxchartbottom" );
FirstBarOfDay = dn != Ref( dn, -1 );
RibbonHeight = 5; // Percent of chart height
for( i = 1; i <= 5; i++ ) VarSet( "C" + i, ColorBlend( colorBlack, Color1, i / 5 ) );
RibbonColor = IIf( DW == 1, C1, IIf( dw == 2, C2, IIf( dw == 3, C3, IIf( dw == 4, C4, IIf( dw == 5, C5, colorDefault ) ) ) ) );

GfxSetZOrder(1); GfxSetCoordsMode(3);
GfxSetTextColor(Color2); GfxSelectFont( "Arial", 9, 700 ); // Or for example "Arial Narrow"

DaysOfWeek = ", Monday, Tuesday, Wednesday, Thursday, Friday";
for( j = fvbi; j <= Min( lvbi, BarCount - 1 ) ; j++ ) if (FirstBarOfDay[j]) GfxTextOut(StrExtract(DaysOfWeek, dw[j]), bi[j] + 1, pxchb - RibbonHeight*5);

//Plot( Close, "Close", colorDefault, styleCandle );
Plot( FirstBarOfDay, "", Color1, styleHistogram | styleOwnScale | styleNoLabel, 1, 0, 0, -1, 2 );
Plot( RibbonHeight, "", RibbonColor, styleArea | styleOwnScale | styleNoLabel, 0, 100, 0, -1 );
_SECTION_END();

DaysOfweek%203

DaysOfweek%204

9 Likes

hi milosz
thanks a lot for taking so much effort.

my backgrd color is white , in the code because black is mentioned the system is painting the background black,
i tried diff combinations, in all cases the color is the one instead of black.

i tried changing z order but the problem still exists.

your other alternate codes are fine and dau no and week day name are working perfect
thanks once again

regards
nitin bagadia

I consider it pointless to use the code because on intraday chart by default days are colored in different shades if only zoom level makes it aesthetically pleasing1) to do so. It is built-in functionality an it does NOT require ANY code at all.

That is default look of background with 5-minute data. Notice that background of each day is filled with nice gradient of alternate colors.

image

This is controlled by Preferences

image

1) Custom codes like presented in this thread have one big problem: they don't behave correctly with extreme zoom levels. AmiBroker internal axis / background drawing is super-flexible and dynamically adopts to extremes well. Try zooming out intraday chart to multiple years. AmIBroker internal code would present beautiful, clean output with proper X axis and proper background changes that are best looking for given zoom level. Custom drawn "vertical line each day" will not only be slow but also unreadable as lines will be plotted every pixel (or even more frequently), not even mentioning overlapping day names.

2 Likes

Tomasz, I have tested this solution before and found out that "alternate background fill" match up with days only in certain zoom levels. For example:

C1

C2

C3

So either I am missing something (which is possible), or it doesn't give the same results...


Of course I agree. My codes are not intended to replace any of the inbuilt solutions because they will always be worse. The above ones are made almost on the go and will definitely need a lot of additional work to behave well in all possible situations. These are just example codes. Everyone is free to modify them according to one's needs.

Sometimes (depending on the zoom level and other factors) I find it difficult to differentiate between consecutive trading days - that's why I proposed the first solution and I don't know any other way (than using custom code) of displaying names of the days on the chart (which sometimes - especially when browsing historical charts, is really useful) - that's why I proposed another one.

Regards.

3 Likes

@Milosz - I already addressed everything in my previous post. The way AmiBroker works is designed FOR PURPOSE to produce beautiful chart with ANY zoom level, unlike codes presented here. As I wrote: zoom OUT to multi year range and you will see why fixed per-day subdivision isn't working well.

In the UPPER pane of screenshot below you can see what is produced by the code you posted when chart is zoomed out to multi-year range:

image

Built-in axis and background does not suffer from this because it does not use fixed subdivision - see LOWER pane. Built-in chart uses day subdivision only when it makes sense (i.e. when it would produce good looking chart). If there are too many days or too few days it intelligently chooses other subdivision to make sure that visual result is the most readable / clean one. Also there is a concept of primary (solid) and secondary (dotted) grid lines. In the screenshot above primary X grid is year and secondary is quarter, but it is all dynamic depending on zoom factor. For example, say there are only three days displayed in a chart. Then the primary grid is day (solid line and bold font on axis) and secondary grid is 6 hours. To get clearer day subdivision you can edit "Axes / Grid" look in the preferences - you can for example choose to have different color and/or pattern for primary grid. This part of the program's functionality is mostly overlooked by the users.

image

As I wrote already a couple of times, you underestimate amount of thought that is put into AmiBroker. Even things that seemingly are so "obvious" like X axis aren't that obvious when you take into consideration that charts must scale from microseconds upto centuries and still look good.

3 Likes

Tomasz, thank you for all additional (and as always) useful information, but I think there is a misunderstanding here. My objective was not to make one universal code working great in all circumstances.

Tomasz, yes I understand that. I fully agree, that AmiBroker's charting possibilities are imense and allow to produce really beautiful charts - no doubt about it - but that's not the point here. The original poster asked:

@beppe and I have shown in this thread several codes meeting and expanding this criteria.

It is not an alternative, because the inbuilt "alternate background fill" divides the days only in some circumstances. For this reason my solution is not pointless, because It allows the user to be able to easily separate each session no matter what the zoom level is. I have shown the discrepancies between my code and "alternate background fill" method.

I think, that showing my chart zoomed out that far (with garbage X axis) is unfair, because as the OP requested, my code was meant to be used on Intraday interval for the user to be able to easily differentiate between 3-5-10-15 days (not hundreds or thousands), for example to spot some price patterns etc. that are likely to occure on Mondays, Fridays etc. Besides I didn't need to do this, but I have proposed many ways how to differentiate the days: 1) full day names written in Arial, 2) full day names written in Arial Narrow, 3) using abbreviations instead of full names, 4) using PlotShapes with numbers (ranging from 1 - 5), 5) using only colors. All of those 5 ways can be utilized using my codes when someone needs compact solution. But I agree - I didn't have time to make the code working great in all circumstances.


As I wrote in another thread - I don't live of writting on the forum, but trading and additionally I have many other obligations and hear quite often from my family, that I spend too much time on the forum. Currently there are almost 2500 signed-up users and probably even more unsigned on the forum. I think there are not more than 10-15 users who regurarly provide others with ready to use codes just to help them, not to solve their own issues. I offered some solutions which are not universal and were not meant to be treated this way, but they meet the initial criteria and offer much more. Every single user is free to use any part of my codes and modify them to meet his/her criteria - for example to display 2 years of 5 minute data at once. I would gladly see lots of other, better examples so that I could learn and draw conclusions (I really encourage everyone to do that), but sadly most users prefer passive way of exploring the forum. Probably they are smarter than me. Some unknown users show up just to write a few words in SMS style request and in exchange quite often they receive long detailed replies. So, yes - for sure I could come up with better examples, but my time for helping others is also limited.

BTW - my above codes work for me. They were not meant to replace any inbuilt functionalities because there aren't such inbuilt functionalities allowing to clearly divide sessions in all circumstances and display the day names. I will probably improve some visual aspects when I have free time, but even now they are useful for me.

Regards.

5 Likes

@Milosz what I wrote is not about your coding. What I wrote is about original idea/request. The idea of using fixed subdivision by day regardless of zoom is flawed.
I understand that you just wanted to provide him with some example code and that is all great.
But my point wasn't about your code, so don't take it personally.

As to the "unfair" thing: it is not unfair. The chart I have shown is intraday chart, specifically SPY 1-minute chart. Custom axis becomes unreadable with just one month worth of data, see below:

image

You also skipped the part about primary axis that I explained that days are marked with primary grid lines. Alternate background uses secondary grid.

Yes, I'm aware of the fact, that my code will not work well as it is, when zoomed out to the extreme, but after small modification it might work well on 1 month woth of 1 minute data:

B1

... or even 2 months of 1 minute data:

B2

... but it was not meant to be used this way, because 1 or 2 months of 1 minute data displayed at once is for me completely unreadable.

Because of too many vertical lines (for every day).

Yet, without them, it is clear. That was my point from the beginning.

Viewing multi-month 1-minute charts is not uncommon: for example when you backtest on 1-minute data you usually want to see entire equity chart from backtest period and you expect X axis to be readable and clear background as well. Besides same custom code axis corruption would occur if you used hourly data.

Anyway we can agree to disagree :slight_smile: Fortunately everyone can do whatever they like.

Frankly it has never crossed my mind to analyse 1 month of 1 minute data displayed at once, because I would probably need 16K monitor to be able to see the candles :wink: I personally use 1 minute candles to analyse selected days only (one day after another) or during the session to be able to react quickly.

I agree that my upper code needs further improvements - especially to scale properly to different chart sizes and resolutions - it is far from being perfect - I like when my codes look really good and it definitely is not the case on some screenshots. I might show the enhanced version when I have some free time.

On the other hand, it might be treated only as some inspiration or starting point. If someone doesn't like it, he/she doesn't have to use it. There are 2500 users on the forum and 2500 ways of appraching the subject. Everyone is invited to join in and show alternative solutions. This one (even in its current version) works for me.

Tomasz, I have no problem with admitting, that I was wrong - and when it comes to automatic vertical dividers (or precisely Vertical Gridlines) - that is the case here. This time I have choosen a different color for Primary Vertical Lines and as a result, subdivision is working really well. This automatic method should be enough in 95% cases.

Summing up - if someone needs to clearly differentiate between consecutive sessions, he/she should start from choosing a differen color for Primary Vertical Lines (as described by Tomasz above ) and resort to using any custom codes only when this automatic method is (for some reason) not enough or for example wants to display the names of week days.

Thank you for describing it and drawing my (and other users') attention to this functionality.

Regards

1 Like

hi tomasz
i was not aware of this feature
thanks a lot
regards
nitin

Hi @Milosz,

I'm new to the AmiBroker community and quite enjoying the software.....as a convert from Metastock I think this program provides so much more.....kudos to @Tomasz!!
I like the code you provided for setting the different background colors for the days. Looks really clean. Using your code as a basis, I'm trying to color the background for aftermarket hours on an hourly basis for intraday charting. In other words, I'd like to be able to have a different background color (using your blended color scheme) for premarket hours and similarly a slightly different blended color scheme for aftermarket hours. Could you provide some advice on how I could set this up? I'm assuming I'd have to nest my If statements but maybe there's an easier way with a loop. But I'm also stuck on the % statement of your code as I've never used a modulus before so I'm trying to un-knot my brain on how that works. Starting with the code you provided earlier in this post, I started by creating a 3rd RibbonColor variable but trying to figure out how to set up those if statements on an hourly basis. Any advice would be greatly appreciated.

Based on your original code with some slight modifications for color schemes and using 2 new variables for pre and after market variables, this is as far as I've gotten:

dn = DateNum();
FirstBar = dn != Ref( dn, -1 );
AfterMktColor1 = ColorBlend( colorBlack, colorDarkRed, 0.1 );
RibbonColor2 = ColorBlack;
PreMktColor3 = ColorBlend( colorBlack, colorDarkBlue, 0.1);
RibbonColor = IIf( Cum( FirstBar ) % 2 == 0, RibbonColor1, AfterMktColor1 );
Plot( Close, "Close", colorDefault, styleCandle );
Plot( FirstBar, "", colorDarkBlue, styleHistogram | styleOwnScale | styleNoLabel, 1, 0, 0, -1, 2 );
Plot( 1, "", RibbonColor, styleArea | styleOwnScale | styleNoLabel, 0, 1, 0, -1 );

Please use code tags if inserting code. It is mandatory feature for inserting code.
See here.


Use TimeNum() array function for setting intraday time range(s).

tn = TimeNum();
pre_market = tn < 93000;
after_market = tn > 160000;

RibbonColor2 = ColorBlack;
PreMktColor3 = ColorBlend( colorBlack, colorDarkBlue, 0.1);
AfterMktColor1 = ColorBlend( colorBlack, colorDarkRed, 0.1 );

RibbonColor = pre_market * PreMktColor3 + 
				after_market * AfterMktColor1 + 
				(NOT(pre_market OR after_market)) * RibbonColor2;

// Add Plot below...

Alternatively

tn = TimeNum();
pre_market = tn < 93000;
after_market = tn > 160000;

PreMktColor3 = ColorBlend( colorBlack, colorDarkBlue, 0.1);
AfterMktColor1 = ColorBlend( colorBlack, colorDarkRed, 0.1 );

RibbonColor = pre_market * PreMktColor3 + 
				after_market* AfterMktColor1;

Plot( Close, "Close", colorDefault, styleCandle );
style = styleArea | styleOwnScale | styleNoLabel;
Plot( pre_market OR after_market, "", RibbonColor, style, 0, 1, 0, -1 );
2 Likes

@fxshrat
First of all, my apologies for not using the code tag button. I'll make sure to use those buttons going forward.

Secondly, and more importantly, many thanks for the code and also for providing two different ways to do it..... absolutely brilliant. Thanks again and also for the very quick response. Loving this program and the community here!!