The European Central Bank lowered its interest rates on Thursday, when the public lender said its internal research predicted even less growth in the year ahead.
As expected, the bank announced 25-basis point cuts for its three key interest rates, a decision that reduced the deposit rate to 3.00%. The changes are scheduled to take effect on 18 December.
ECB President Christine Lagarde said all members of the bank’s governing council backed the quarter-point reduction, but the group did discuss a so-called jumbo cut of a half-point.
Changes in the wording of this month’s monetary policy decision also forced observers and the bank to dig deeper into the jargon that peppers the language of high finance.
Analysts said the public lender had turned even more dovish after it eliminated wording about keeping “policy rates sufficiently restrictive for as long as necessary” from its statement on Thursday’s rate move.
But ECB President Christine Lagarde pushed back on this notion: “We are currently restrictive,” she told journalists at a post-decision press conference at the bank’s headquarters.
However, before staking out that position, she responded to a journalist by noting that the current environment allowed the bank to lift the “restrictive” terminology.
EUR/USD fell below 1.05 ahead of the decision only to move above that mark after the press conference.
The ECB's December euro area GDP growth forecasts (blue) came in lower than the September projections.
More downgrades for euro area growth
European economic weakness has increased, the bank said, with its staff projections estimating Eurozone GDP will only climb 0.7% this year, a reduction from 0.8% in September. The bank cut its 2025 growth estimate two-tenths of a point to 1.1%, and the 2026 forecast fell one-tenth to 1.4%. The bank said GDP will rise 1.3% in 2027, its first estimate for that year.
“The projected recovery rests mainly on rising real incomes,” the ECB noted, “which should allow households to consume more – and firms increasing investment. Over time, the gradually fading effects of restrictive monetary policy should support a pick-up in domestic demand.”
But some observers said the new growth numbers, however meagre, were still too upbeat. “Particularly, the 2025 forecast looks very optimistic, as the ECB has not taken into account Trump and France and is still banking on a return of the consumer,” ING warned. “At face value, these forecasts even look like a Goldilocks scenario. Too good to be true.”
US President-elect Donald Trump has threatened a blanket tariff of 10% on all goods exported to the US, and France is in the throes of political upheaval after Prime Minister Michel Barnier resigned last week. Additionally, the collapse of the three-party government in Germany, already one of the weakest major economies in Europe, has worsened the mood about the country’s prospects.
As inflation fades, talk turns to the neutral rate
At least the ECB seemed to be winning its main contest, maintaining price stability. Bank staff lowered annual headline inflation expectations one-tenth of a percentage point to 2.4% and 2.1% in 2024 and 2025. Researchers held the 2026 estimate at 1.9% and announced a 2.1% prediction for 2027.
Eurozone inflation rose to 2.3% last month, an increase the ECB had previously warned of. But consumer price growth has already fallen below the bank’s inflation target of 2% over the medium term this year. Lagarde said the indicator will reach that goal again next year, basing her forecast on the past six straight projections.
“The disinflation process is well on track,” Lagarde said.
Forecasts for inflation excluding energy and food, the so-called core rate, were little changed, with the 2024 rate remaining at 2.9% and 2.3% expected in the following year. The bank lowered its expectations for 2026 a tenth of a point to 1.9%, which is also the outlook for 2027.
Analysts say more rate cuts are in the offing from the Frankfurt bank. At the end of the press conference, Lagarde was again asked about the neutral rate, ie where the bank would end up this cutting cycle. She talked of numbers “flying around” in internal reports, suggesting that rate could lie between 1.75-2.50%.
Sign up for LiveSquawk and receive a discount with the code LSQEC$
/*jshint esversion: 6 */
var socket;
var assigned_server = 3001;
var distributor_server = 3010;
var publisher_channel = '';
var broadcaster_channel = '';
var remote_ip = '';
var session_info = {};
var logging_interval;
var logging_interval_time = 120000;
var socket_emits = 0;
var session_start_time;
var reconnectionDelayGrowFactor = 1.2;
var reconnection_delay = 1000;
var playing = false;
var connected_to_assigned = false;
var socket_close_timeout;
var player_disconnected_annoucement_play_delay = 1500;
var player_disconnected_annoucement_play_timeout = null;
self.onmessage = function (msg) {
switch(msg.data.action) {
case 'Reactivate': reactivate(); break;
case 'ConnectDistributor': connect_to_distributor(msg); break;
case 'SessionStaticInfo': session_static_info(msg); break;
case 'SessionInfo': update_session_info(msg.data); break;
case 'PauseLogging': clearTimeout(logging_interval); break;
case 'RestartLogging': postMessage({action: 'RequestSessionStaticInfo' }); break;
case 'JoinPublisherChannel': join_publisher_channel(msg.data); break;
case 'JoinPlayerChannel': join_player_channel(msg.data); break;
case 'CheckChannelStatus': check_channel_status(msg.data); break;
case 'PlayerLogResponse': player_log_response(msg.data); break;
case 'CloseSocket': close_socket(); break;
case 'RequestMessageSearch': request_message_search(msg.data); break;
case 'RequestMoreMessages': request_more_messages(msg.data); break;
case 'PlayerDisconnectedAnnoucementTimeoutStart': player_disconnected_annoucement_timeout_start(); break;
case 'PlayerDisconnectedAnnoucementTimeoutClear': player_disconnected_annoucement_timeout_clear(); break;
}
};
function player_disconnected_annoucement_timeout_clear() {
clearTimeout(player_disconnected_annoucement_play_timeout);
player_disconnected_annoucement_play_timeout = null;
}
function player_disconnected_annoucement_timeout_start() {
player_disconnected_annoucement_play_timeout = setTimeout(function() { send_play_disconnect_annoucement(); }, player_disconnected_annoucement_play_delay );
}
function send_play_disconnect_annoucement() {
postMessage({action: "PlayDisconnectAnnoucement"});
}
function reactivate() {
playing = false;
connect_to_assigned_server();
}
function player_log_response(data) {
var data_array = {};
data_array.type = 'PlayerLogResponse';
data_array.respond_to_socket_final = data.respond_to_socket_final;
data_array.respond_to_socket = data.respond_to_socket;
data_array.player_socket_id = data.player_socket_id;
data_array.logs = data.logs;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function request_message_search(data) {
var data_array = {};
data_array.type = 'request_message_search';
data_array.publisher_channel = data.publisher_channel;
data_array.search_term = data.search_term;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function request_more_messages(data) {
var data_array = {};
data_array.type = 'request_more_messages';
data_array.publisher_channel = data.publisher_channel;
data_array.last_record_id = data.last_record_id;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function check_channel_status(data) {
var data_array = {};
data_array.type = 'check_channel_status';
data_array.app_name = data.app_name;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1 && connected_to_assigned) { socket.send(msg_string); }
else { setTimeout(function() { check_channel_status(data); },500); }
}
function check_channel_status_response(data) {
postMessage({ action: 'CheckChannelStatusReponse', stream_status: data.stream_status.status, onair: data.stream_status.onair, connected: data.stream_status.connected });
}
function join_publisher_channel(data) {
var data_array = {};
data_array.type = 'join_publisher_channel';
if (typeof data.api_key !== 'undefined') { data_array.api_key = data.api_key; }
else {
data_array.publisher_channel = data.publisher_channel;
data_array.username = data.username;
data_array.subscriber_group = data.subscriber_group;
data_array.display_name = data.display_name;
data_array.single_sign_on = data.single_sign_on;
data_array.remote_ip = data.remote_ip;
data_array.http_referrer = data.http_referrer;
data_array.current_page = data.current_page;
data_array.php_session_id = data.php_session_id;
data_array.from_react = data.from_react;
}
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) {
socket.send(msg_string); }
postMessage({action: 'PublisherChannelJoined' });
}
function session_static_info(msg) {
set_static_session_info(msg.data);
start_log();
}
function connect_to_distributor(msg) {
publisher_channel = msg.data.publisher_channel;
remote_ip = msg.data.remote_ip;
socket = new WebSocket("wss://ws.livesquawk.com/ws"+distributor_server);
socket.onopen = function(event) { request_server_assignment(); };
socket.onmessage = function(event) {
var msg_string = event.data.toString();
var data = JSON.parse(msg_string);
switch(data.type) {
case 'server_assignment_response': server_assignment_response(data); break;
}
};
}
function session_info_interval() {
postMessage({action: 'RequestSessionInfo' });
logging_interval = setTimeout(session_info_interval,logging_interval_time);
}
function server_assignment_response(data) {
assigned_server = data.selected_server;
socket.close();
connect_to_assigned_server();
}
function request_server_assignment() {
var data_array = {};
data_array.type = 'request_server_assignment';
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function connect_to_assigned_server() {
socket = new WebSocket("wss://ws.livesquawk.com/ws"+assigned_server);
socket.onopen = function(event) {
postMessage({ action: 'VisibleConsole',console_string: "Connected to server "+assigned_server });
console.log("Connected to server "+assigned_server);
postMessage({ action: 'ConnectedToAssigned' });
connected_to_assigned = true;
if (playing) {
postMessage({ action: 'RejoinPlayerChannel' });
}
};
socket.onmessage = function(event) {
var msg_string = event.data.toString();
var data = JSON.parse(msg_string);
if (data.type != 'server_ping') { /* console.log(data.type); */ }
switch(data.type) {
case 'reconnect': postMessage({ action: 'VisibleConsole',console_string: "Reconnected" }); break;
case 'reload': postMessage({ action: 'Reload' }); break;
case 'start_log_response': start_log_response(data); break;
case 'application_refresh_start': application_refresh_start(data); break;
case 'application_refresh_stop': application_refresh_stop(data); break;
case 'player_log_request':
case 'check_channel_status_response': check_channel_status_response(data); break;
case 'PlayerLogRequest':
case 'new_tweet':
case 'new_latest_news':
case 'delete_report':
case 'add_report':
case 'add_ref_doc':
case 'calendar_change':
case 'calendar_insert':
case 'calendar_delete':
case 'new_note':
case 'AppStart':
case 'AppStop':
case 'BroadcasterStarted':
case 'BroadcasterStopped':
case 'added_cme_report':
case 'updated_cme_report':
case 'added_cme_commentary':
case 'updated_cme_commentary':
case 'server_assignment_response':
case 'initial_messages':
case 'message_categories':
case 'more_messages':
case 'matched_messages':
pass_straight_to_post_message(data);
break;
case 'output':
case 'server_ping':
case 'reconnect':
case 'disconnect':
break;
}
};
socket.onerror = function(event) {
postMessage({ action: 'VisibleConsole',console_string: "LS Socket Error" + event.type });
console.log(event);
postMessage({ action: 'LSSocketConnectionError' });
};
socket.onclose = function(event) {
console.log('Socket is closed. Reconnect will be attempted in 1 second.', event.reason);
socket_close_timeout = setTimeout(connect_to_assigned_server, reconnection_delay);
reconnection_delay = reconnection_delay*reconnectionDelayGrowFactor;
connected_to_assigned = false;
};
}
function close_socket() {
clearTimeout(socket_close_timeout);
socket_close_timeout = null;
socket.onclose = function(event) {};
socket.onmessage = function(event) {};
socket.onerror = function(event) {};
socket.close(1000);
console.log('Socket Closed');
}
function pass_straight_to_post_message(data) {
data.action = data.type;
postMessage(data);
}
function join_player_channel(data) {
var data_array = {};
data_array.type = 'join_player_channel';
data_array.player_channel = data.player_channel;
data_array.remote_ip = data.remote_ip;
data_array.username = data.username;
data_array.app_name = data.app_name;
data_array.onair_status = data.onair_status;
data_array.http_referrer = data.http_referrer;
data_array.current_page = data.current_page;
data_array.php_session_id = data.php_session_id;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
postMessage({action: 'PlayerChannelJoined' });
playing = true;
}
function start_log_response(data) {
session_info.session_id = data.log_record_id;
session_info_interval();
}
function application_refresh_start(data) {
if (data.app_name == session_info.application_name) { postMessage({action: 'ApplicationRefreshStart' }); }
}
function application_refresh_stop(data) {
if (data.app_name == session_info.application_name) { postMessage({action: 'ApplicationRefreshStop' }); }
}
function set_static_session_info(data) {
session_info.browser_codename = data.browser_codename;
session_info.browser_name = data.browser_name;
session_info.user_agent = data.user_agent;
session_info.browser_version = data.browser_version;
session_info.cookies_enabled = data.cookies_enabled;
session_info.platform = data.platform;
session_info.player_version = data.player_version;
session_info.stream = data.stream;
session_info.connection_protocol = data.protocol;
session_info.delay_target = data.delay_target;
session_info.session_email = data.session_email;
session_info.remote_ip = data.remote_ip;
session_info.php_session_id = data.php_session_id;
session_info.application_name = data.application_name;
session_info.http_referrer = data.http_referrer;
}
function start_log() {
var session_start_date = new Date();
session_start_time = session_start_date.getTime();
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var session_start_date_string = session_start_date.getDate() + " " + months[session_start_date.getMonth()] + " " + session_start_date.getFullYear();
var data_array = {};
data_array.type = 'webrtc_start_log';
data_array.remote_ip = session_info.remote_ip;
data_array.username = session_info.session_email;
data_array.php_session_id = session_info.php_session_id;
data_array.webrtc_protocol = '';
data_array.session_start_time = (session_start_time/1000).toFixed(0);
data_array.stream_name = session_info.stream;
data_array.session_start_date = session_start_date_string;
var msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
function update_session_info(data) {
var data_array = {};
var msg_string = '';
var current_date = new Date();
var current_time = current_date.getTime();
session_info.protocol = data.protocol;
session_info.curr_delay = (data.effective_latency / 1000).toFixed(2);
session_info.session_length = current_time - session_start_time;
session_info.ping_time = data.ping_time;
session_info.jitter = data.jitter;
session_info.packet_loss = data.packet_loss;
session_info.effective_latency = data.effective_latency;
session_info.mean_opinion_score = data.mean_opinion_score;
session_info.restarts = data.restarts;
if (socket_emits == 0) {
data_array = {};
data_array.type = 'webrtc_log_data_full';
data_array.connection_protocol = session_info.protocol;
data_array.threshold = 0;
data_array.curr_delay = session_info.curr_delay;
data_array.session_length = session_info.session_length;
data_array.date = current_time;
data_array.browser_codename = session_info.browser_codename;
data_array.browser_name = session_info.browser_name;
data_array.user_agent = session_info.user_agent;
data_array.browser_version = session_info.browser_version;
data_array.cookies_enabled = session_info.cookies_enabled;
data_array.platform = session_info.platform;
data_array.player_version = session_info.player_version;
data_array.stream = session_info.stream;
data_array.restarts = session_info.restarts;
data_array.delay_target = 0;
data_array.op_sys = '';
data_array.flash_version = '';
data_array.remote_ip = session_info.remote_ip;
data_array.http_referrer = session_info.http_referrer;
data_array.php_session_id = session_info.php_session_id;
data_array.user_email = session_info.session_email;
data_array.webrtc_protocol = session_info.protocol;
data_array.ping_time = session_info.ping_time;
data_array.jitter = session_info.jitter;
data_array.packet_loss = session_info.packet_loss;
data_array.effective_latency = session_info.effective_latency;
data_array.mean_opinion_score = session_info.mean_opinion_score;
data_array.session_id = session_info.session_id;
msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
else {
data_array = {};
data_array.type = 'webrtc_log_data';
data_array.session_id = session_info.session_id;
data_array.php_session_id = session_info.php_session_id;
data_array.connection_protocol = session_info.protocol;
data_array.restarts = session_info.restarts;
data_array.threshold = 0;
data_array.curr_delay = session_info.curr_delay;
data_array.session_length = session_info.session_length;
data_array.date = current_time;
data_array.webrtc_protocol = session_info.protocol;
data_array.ping_time = session_info.ping_time;
data_array.jitter = session_info.jitter;
data_array.packet_loss = session_info.packet_loss;
data_array.effective_latency = session_info.effective_latency;
data_array.mean_opinion_score = session_info.mean_opinion_score;
data_array.stream = session_info.stream;
msg_string = JSON.stringify(data_array);
if (socket.readyState == 1) { socket.send(msg_string); }
}
socket_emits++;
if (socket_emits == 100) { socket_emits = 0; }
}
- Officials reduce key rates 25bps
- Bank staff lowers growth outlook
- Political issues come to the fore
- Do we have a corridor for the neutral rate?
By Eric Culp
European Editor, LiveSquawk News
@EricCulpLS
12 December 2024 | 15:30 GMT
The European Central Bank lowered its interest rates on Thursday, when the public lender said its internal research predicted even less growth in the year ahead.
As expected, the bank announced 25-basis point cuts for its three key interest rates, a decision that reduced the deposit rate to 3.00%. The changes are scheduled to take effect on 18 December.
ECB President Christine Lagarde said all members of the bank’s governing council backed the quarter-point reduction, but the group did discuss a so-called jumbo cut of a half-point.
Changes in the wording of this month’s monetary policy decision also forced observers and the bank to dig deeper into the jargon that peppers the language of high finance.
Analysts said the public lender had turned even more dovish after it eliminated wording about keeping “policy rates sufficiently restrictive for as long as necessary” from its statement on Thursday’s rate move.
But ECB President Christine Lagarde pushed back on this notion: “We are currently restrictive,” she told journalists at a post-decision press conference at the bank’s headquarters.
However, before staking out that position, she responded to a journalist by noting that the current environment allowed the bank to lift the “restrictive” terminology.
EUR/USD fell below 1.05 ahead of the decision only to move above that mark after the press conference.
More downgrades for euro area growth
European economic weakness has increased, the bank said, with its staff projections estimating Eurozone GDP will only climb 0.7% this year, a reduction from 0.8% in September. The bank cut its 2025 growth estimate two-tenths of a point to 1.1%, and the 2026 forecast fell one-tenth to 1.4%. The bank said GDP will rise 1.3% in 2027, its first estimate for that year.
“The projected recovery rests mainly on rising real incomes,” the ECB noted, “which should allow households to consume more – and firms increasing investment. Over time, the gradually fading effects of restrictive monetary policy should support a pick-up in domestic demand.”
But some observers said the new growth numbers, however meagre, were still too upbeat. “Particularly, the 2025 forecast looks very optimistic, as the ECB has not taken into account Trump and France and is still banking on a return of the consumer,” ING warned. “At face value, these forecasts even look like a Goldilocks scenario. Too good to be true.”
US President-elect Donald Trump has threatened a blanket tariff of 10% on all goods exported to the US, and France is in the throes of political upheaval after Prime Minister Michel Barnier resigned last week. Additionally, the collapse of the three-party government in Germany, already one of the weakest major economies in Europe, has worsened the mood about the country’s prospects.
As inflation fades, talk turns to the neutral rate
At least the ECB seemed to be winning its main contest, maintaining price stability. Bank staff lowered annual headline inflation expectations one-tenth of a percentage point to 2.4% and 2.1% in 2024 and 2025. Researchers held the 2026 estimate at 1.9% and announced a 2.1% prediction for 2027.
Eurozone inflation rose to 2.3% last month, an increase the ECB had previously warned of. But consumer price growth has already fallen below the bank’s inflation target of 2% over the medium term this year. Lagarde said the indicator will reach that goal again next year, basing her forecast on the past six straight projections.
“The disinflation process is well on track,” Lagarde said.
Forecasts for inflation excluding energy and food, the so-called core rate, were little changed, with the 2024 rate remaining at 2.9% and 2.3% expected in the following year. The bank lowered its expectations for 2026 a tenth of a point to 1.9%, which is also the outlook for 2027.
Analysts say more rate cuts are in the offing from the Frankfurt bank. At the end of the press conference, Lagarde was again asked about the neutral rate, ie where the bank would end up this cutting cycle. She talked of numbers “flying around” in internal reports, suggesting that rate could lie between 1.75-2.50%.
Sign up for LiveSquawk and receive a discount with the code LSQEC$