This story features WOOLWORTHS GROUP LIMITED, and other companies. For more info SHARE ANALYSIS: WOW
In the wake of March quarter sales numbers, which is the better investment, Woolworths or Coles? Brokers are polarised not between them, but on both.
-Sales growth surprised, but barely beat inflation
-Woolworths ahead in online, but maybe not for long
-Shoppers trading down to cheap brands
-Ratings equally split on both
By Greg Peel
The battle between Woolworths ((WOW)) and Coles ((COL)) is not akin to the battle between Holden and Ford at Bathurst in days gone by, except between managements. There may be some shoppers fiercely loyal to one or the other but other than which supermarket is closer to home or more convenient, shoppers have shown in the past they’re willing to shop at one or the other when it suits them.
Over the decades one has always enjoyed a period of outperformance over the other, before that quietly switches around into a new phase, back and forth. Over the years we’ve seen one winning on being first to offer petrol discounts for example, who is offering the most attractive pricing (down, down; $2 milk), who is offering the best pester-power toy handout (Little Shop), or who has the most efficient online delivery service or click & collect in more recent times.
There appears no great loyalty.
And typically a period of one finding itself superior over the other is accompanied by analysts pointing out why, and largely agreeing. But in the wake of recent March quarter sales updates from both, currently there is no agreement at all.
If there is agreement on anything, it’s that food inflation generally remains elevated and that shoppers facing cost of living pressures are “trading down” to cheaper own-brand lines from premium well-known brands. This introduces a battle between the two to provide the greatest range of own-brands, but analysts agree the leader in this field is competitor Aldi.
Aldi has never put a huge dent in what is still seen as a supermarket duopoly in this country, but perhaps its discount offerings are about to make a real difference, and analysts see this as a threat.
Inflation
In the March quarter, Woolworths reported 6.6% like-for-like supermarket sales growth, beating expectations but aligning with Coles on 6.5%.
Yet the key driver of sales growth at both, notes Ord Minnett, was still “extraordinarily” high price inflation. Food shelf prices (ie wholesale cost) rose 6% at both supermarkets, which rather puts 6.6% and 6.5% retail sales growth into perspective. Ord Minnett notes this sub-1% margin lagged population growth in the period.
Aside from lower income shoppers trading down to own-brands, Woolworths highlighted shoppers higher up the income scale are also trading down, from out-of-home eating back to home cooking, and still buying the premium brands. Coles, on the other hand, did not see much of a shift in the quarter.
If the breakdown of the March quarter headline CPI is anything to go by, eating out is still thriving – it’s “things” we’ve stopped buying, because we loaded up in lockdowns.
Lockdowns also forced many to shift to online shopping, and click & collect (for which one would stand in a queue of other click & collectors being covid invested while waiting – never quite got the point of that one), and appears that trend is remaining “sticky”.
UBS notes Woolworths’ online growth surprised at 8.0%, above in-store growth of 7.4%, but this also includes a “direct to boot” option rather than expensive delivery, which makes a lot more sense when parents have an overflowing trolley, a couple of toddlers at hand and a sloping parking lot.
Online sales of 8% and a lift in online penetration from 9.3% to 9.9% sequentially is consistent with ongoing improvements to customers’ perception of Woolworths’ online, suggests Citi.
So there’s one distinction. Of course as a group, the two differ beyond supermarkets. Coles still sells liquor, while Woolworths has Big W, for example. But on the online front, Coles has teamed up with Ocado.
Ocado is providing Coles with a “comprehensive and customised suite of support and engineering services to enable a smooth launch and sustainable e-commerce operations”.
“The improvements and experience and efficiency they have achieved thus far further validates our decision made in 2019 to partner strategically with Ocado. We look forward to bringing Ocado’s leading technology and differentiated service to the Australian market very soon,” boasts Coles. Analysts are waiting with anticipation.
So, from an investment point of view, which is preferred?
No Consensus
The short answer to that is neither. The FNArena broker database shows one Buy (or equivalent) rating for Woolworths, three Hold and two Sells. Coles is marginally better on three Buys, one Hold and two Sells.
Coles also scores marginally better on range of target prices, which range from $14.00 (Ord Minnett; Sell) to $20.20 (Citi; Buy) for a consensus of $17.76 (last $18.06).
Woolworths’ targets range from $27.00 (Ord Minnett; Sell) to $42.20 (Citi; Buy) for a consensus of $35.86 (last $38.33).
I sense a trend, and we note both consensus targets are below the last trading price.
On a market basis, Macquarie draws on the “we all have to eat” theme of staples offering relative safety at a time of high cost of living. This theme is quite clear in both supermarkets growing sales, but only marginally above food inflation. Macquarie has an Outperform on Coles and is Neutral on Woolworths.
Looking forward, UBS notes food inflation is expected to moderate but to remain the primary driver of sales growth in 2023, highlighting ongoing supply chain and input cost pressures in dry grocery, although volume growth should continue to increase due to the shift from out-of-home and immigration. UBS is Neutral on both.
Looking further forward, most positive is Citi, unsurprisingly (Buy on both), who believes the market’s FY24 sales growth forecast of 3.5% looks too low given the benefits from around 2% population growth and food inflation still likely to be in the mid-single digits.
In the shorter term, Ord Minnett (Sell on both) expects June quarter sales to continue to benefit from food price hikes, albeit less meaningfully than in the first half, but in the first half of FY24 forecasts the inflation rate to drop significantly as the supermarkets cycle near 8% inflation in the first half FY23.
Despite considering both groups to be currently overvalued, Ords expects the market shares of the “big three” chains to remain stable over the next decade, and estimates Woolworths’ share at 36%, Coles at 28% and Aldi at 9%.
Find out why FNArena subscribers like the service so much: “Your Feedback (Thank You)” – Warning this story contains unashamedly positive feedback on the service provided.
FNArena is proud about its track record and past achievements: Ten Years On
Click to view our Glossary of Financial Terms
var fn_do_fb_login; var fn_check_login_state; var fn_get_fb_login_button; var fn_remove_fb_loading_btn; var fn_status_change_callback;
jQuery(document).ready(function(e){
window.fbAsyncInit = function() { FB.init({ appId : '2003222569780759', // dev version: 500318794096450 cookie : true, // Enable cookies to allow the server to access the session. xfbml : true, // Parse social plugins on this webpage. version : 'v4.0' // Use this Graph API version for this call. });
//check if all fb elements done rendering //========== fn_get_fb_login_button();
FB.Event.subscribe('xfbml.render', function(response) { fn_remove_fb_loading_btn(); }); //==========
FB.getLoginStatus(function(response) { // Called after the JS SDK has been initialized.
var fb_r = response;
if (fb_r && fb_r.status === 'connected') {
get_detail_data(fb_r.authResponse.userID); // Returns the login status.
// logout function // FB.logout(function(response) { // console.log('do logout'); // }); } }); };
(function(d, s, id){ var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) {return;} js = d.createElement(s); js.id = id; js.src = " fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));
//fb functionality //======================================================= fn_check_login_state = function check_login_state() { // Called when a person is finished with the Login Button.
//everytime event login triggered, reset the form fn_reset_form();
FB.getLoginStatus(function(response) {
var status_change_callback = fn_status_change_callback(response);
if (status_change_callback) {
FB.api('/me', function(response) {
console.log(response);
});
}
});
}
//new function to do fb login - since might need a separate function //between checking and login fn_do_fb_login = function do_fb_login() { // Called when a person is finished with the Login Button.
//everytime event login triggered, reset the form fn_reset_form();
FB.getLoginStatus(function(response) {
e('.form_loading').show();
var status_change_callback = fn_status_change_callback(response);
if (status_change_callback) {
FB.api('/me', function(response) {
console.log(response); set_detail_data_to_form_and_submit(response.id);
});
} else {
FB.login(function(fb_l_r) {
if (fb_l_r.authResponse && fb_l_r.status == 'connected') {
console.log(fb_l_r.authResponse.userID); set_detail_data_to_form_and_submit(fb_l_r.authResponse.userID);
} else { e('.form_loading').hide(); }
});
}
});
}
fn_status_change_callback = function status_change_callback(response) { // Called with the results from FB.getLoginStatus().
var check_status;
console.log('status_change_callback'); console.log(response); // The current login status of the person.
if (response.status === 'connected') { // Logged into your webpage and Facebook.
get_detail_data(response.id); check_status = true;
} else { // Not logged into your webpage or we are unable to tell.
console.log('facebook is not logged in'); check_status = false;
}
return check_status;
}
function get_detail_data(fb_id) {
FB.api( '/'+fb_id+'/', {fields: 'id,first_name,last_name,email'}, function (fb_r) {
var fb_data_json = JSON.stringify(fb_r);
if (fb_r && !fb_r.error) {
e('#fb_data').html(fb_data_json);
}
} );
}
//it's kinda silly, but since fb is an async, cannot use passing parameter on a function like jquery //so instead put it on FB.api function set_detail_data_to_form_and_submit(fb_id) {
e('.form_loading').show();
FB.api( '/'+fb_id+'/', {fields: 'id,first_name,last_name,email'}, function (fb_r) {
var fb_data_json = JSON.stringify(fb_r);
if (fb_r && !fb_r.error) {
var fb_id = fb_r.id; var fb_firstname = fb_r.first_name; var fb_lastname = fb_r.last_name; var fb_email = fb_r.email;
e('.sns_facebook').val(1); e('.sns_facebook_id').val(fb_id);
e('#fb_data').html(fb_data_json); do_submit_form();
//no form_loading hide - we gonna lock the form IF it's success
} else {
e('.form_loading').hide();
}
} );
}
fn_get_fb_login_button = function get_fb_login_button() {
var html="'+ ' '+ 'Login'+ ''+ ''; e('.fb_button_placeholder').html(html);
'+ ''+ '}
fn_remove_fb_loading_btn = function remove_fb_loading_btn() {
e('.fb_loading_btn').hide(); e('.fb_login_wrapper').show();
}
fn_reset_form = function reset_form() {
e('.sns_facebook').val(''); e('.sns_facebook_id').val(''); e('.form_loading').hide();
}
function do_submit_form() {
var the_form = e('.formLogin:visible');
if (the_form.length) {
var target_form = the_form[0]; target_form.submit();
} else {
console.log('form not exist');
}
} //=======================================================
//initialize fn_reset_form();
});