ETH Macro Engine

The ETH Macro Engine is a bespoke, lightweight analytical widget. It is engineered to provide a high-level, real-time snapshot of Ethereum market conditions, specifically tailored for long-term holders tracking macro cycles rather than intraday price fluctuations.

Core Functional Objectives

Noise Reduction: By incorporating a native "Hide Noise" feature, the widget allows for a clean view of essential data, filtering out the constant, distracting ticker updates when the user requires a focused view.

Contrarian Sentiment Integration: The widget pulls live data from the Crypto Fear and Greed Index. This provides a vital contrarian signal; when the wider market is gripped by 'Extreme Fear', the engine automatically adjusts its internal Multiplier to highlight potential accumulation opportunities.

Macro Cycle Tracking: The system monitors the Weekly RSI (14) and Market Phase. By visualising the distinction between 'Expansion' and 'Contraction' phases, it serves as a decision-support tool for executing a long-term exit strategy based on specific threshold triggers.

Network Health Diagnostics: The widget incorporates a real-time assessment of the Ethereum Gas Network. By monitoring gas prices, it identifies whether the network is in a state of 'Accumulation' or 'Topping Out', offering a technical insight into network utilisation.
 
Comparative Strength: Through the real-time ETH/BTC Ratio, the widget provides an immediate gauge of Ethereum’s relative performance compared to the wider market, assisting in understanding if capital is rotating into or out of the asset.

Macro Multiplier: This is the heart of the engine; it is a proprietary score built to cut through market noise and give a single, actionable number. Instead of trying to weigh the Fear and Greed index against the ETH/BTC ratio in my head, the multiplier does the maths for me.

It starts at a base of 1.00x (equilibrium) and dynamically shifts up or down based on a set of pre-defined technical and sentiment triggers. When the market is showing signs of extreme pessimism or 'fear', the multiplier gets a bullish boost, effectively highlighting that the market is potentially oversold. Conversely, when the system detects extreme greed, it applies a penalty, signalling that it might be time to be more cautious.

Key Data Metrics

  • Eth Pi Cycle Top: Historically accurate to within a few days of the top. 
  • Weekly RSI (14): Identifies long-term overbought/oversold conditions.
  • 14D Forecast: Projects the price trajectory based on historical 14-day performance.
  • Macro Multiplier: A weighted score (x) that synthesises sentiment, funding, and technical indicators.
  • DeFi TVL (14D): Tracks the relative health and capital flow within the Ethereum DeFi ecosystem.
  • Deriv Funding: Monitors leverage sentiment in the perpetual futures markets.

Operational Logic

The engine utilises an asynchronous, parallel fetching architecture to ensure the widget remains fast and responsive. It queries multiple distinct APIs simultaneously - including CoinGecko, Binance, Alternative.me, and DefiLlama - to compile a unified, intelligent overview.

The widget is configured to refresh every 15 minutes, maintaining a balance between data accuracy and system efficiency.

This widget provides the analytical clarity required to maintain a grounded perspective on investment targets, ensuring that daily pressures do not interfere with the long-term objective of scaling out at a high weekly RSI.

WARNING: This Macro Engine is an informational tool designed for daily macro trend analysis and must not be treated as definitive financial advice or a standalone trade execution trigger. Because the compounding calculations rely on a multi-layered matrix of daily metrics - including the weekly RSI, macro-multiplier phases, derivatives funding rates, live gas fees, DeFi TVL trends, and net validator queue impact - it is inherently a lagging macro tool that cannot capture rapid intra-day volatility or sudden, high-speed price spikes. Furthermore, the interface depends on multiple third-party aggregated historical feeds, public blockchain endpoints, and proxy-routed queue trackers that can experience API reporting latency, network throttling, or unexpected structural inconsistencies. Always verify these metrics across independent charting platforms, and use them strictly in conjunction with broader, personal risk-management strategies before making any investment decisions.

ETH Macro Engine

Synchronizing data feeds...
Weekly RSI (14) --
14D Forecast --
Macro Multiplier 1.00x
Market Phase Neutral
ETH Pi Cycle Top--
5Y Liquidity Cycle--
Daily Trend (50/200D)--
Weekly Divergence--
Market Sentiment--
ETH/BTC Ratio--
Deriv Funding--%
Gas Network State--
DeFi TVL (14D)--%
Net Impact--
Ethereum Macro Engine
<style>
    .ese-container { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #18181b; color: #f4f4f5; max-width: 480px; padding: 20px; border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.5); }
    .ese-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #3f3f46; padding-bottom: 12px; margin-bottom: 16px; }
    .ese-title { font-size: 16px; font-weight: 600; color: #a1a1aa; margin: 0; }
    .ese-controls { display: flex; align-items: center; gap: 12px; }
    .ese-toggle-lbl { font-size: 12px; color: #a1a1aa; display: flex; align-items: center; cursor: pointer; gap: 6px; }
    .ese-status { height: 10px; width: 10px; background: #00ff88; border-radius: 50%; box-shadow: 0 0 8px #00ff88; cursor: help; }
    
    .ese-price-container { margin: 10px 0 15px 0; min-height: 48px; }
    .ese-main-price { font-size: 32px; font-weight: 700; display: flex; align-items: baseline; gap: 8px; transition: filter 0.3s; }
    .ese-sub-price { font-size: 16px; color: #a1a1aa; font-weight: 400; }
    .ese-blur { filter: blur(8px); opacity: 0.6; }
    .ese-loading-text { font-size: 18px; color: #a1a1aa; font-style: italic; animation: esePulse 1.5s infinite; }

    .ese-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 20px; }
    .ese-box { background: #27272a; padding: 12px; border-radius: 8px; border-left: 4px solid #3f3f46; display: flex; flex-direction: column; justify-content: space-between; min-height: 52px; }
    .ese-box-title { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #a1a1aa; margin-bottom: 4px; display: block; }
    .ese-box-val { font-size: 18px; font-weight: 600; }
    
    .ese-data-list { background: #27272a; border-radius: 8px; padding: 12px; margin-bottom: 20px; font-size: 13px; }
    .ese-row { display: flex; justify-content: space-between; padding: 7px 0; border-bottom: 1px solid #3f3f46; }
    .ese-row:last-child { border-bottom: none; }
    
    .ese-footer { text-align: center; padding-top: 16px; border-top: 1px solid #3f3f46; font-size: 12px; font-weight: 400; min-height: 20px; color: #71717a; }
    
    .text-green { color: #00ff88; } .text-red { color: #ef4444; }
    .border-green { border-left-color: #00ff88 !important; } .border-red { border-left-color: #ef4444 !important; }

    @keyframes esePulse { 0% { opacity: 0.5; } 50% { opacity: 1; } 100% { opacity: 0.5; } }
</style>

<div class="ese-container">
    <div class="ese-header">
        <h2 class="ese-title">ETH Macro Engine</h2>
        <div class="ese-controls">
            <label class="ese-toggle-lbl">
                <input type="checkbox" id="ese-noise-toggle"> Hide Noise
            </label>
            <div id="ese-status-dot" class="ese-status"></div>
        </div>
    </div>

    <div class="ese-price-container">
        <div id="ese-price-display" class="ese-main-price">
            <span id="ese-loader" class="ese-loading-text">Synchronizing data feeds...</span>
            <span id="ese-gbp" style="display:none;">&pound;--</span>
            <span class="ese-sub-price" id="ese-usd" style="display:none;">&#36;--</span>
        </div>
    </div>

    <div class="ese-grid">
        <div class="ese-box" id="ese-box-rsi">
            <span class="ese-box-title">Weekly RSI (14)</span>
            <span class="ese-box-val" id="ese-rsi">--</span>
        </div>
        <div class="ese-box" id="ese-box-forecast">
            <span class="ese-box-title">14D Forecast</span>
            <span class="ese-box-val" id="ese-forecast">--</span>
        </div>
        <div class="ese-box">
            <span class="ese-box-title">Macro Multiplier</span>
            <span class="ese-box-val" id="ese-multiplier">1.00x</span>
        </div>
        <div class="ese-box">
            <span class="ese-box-title">Market Phase</span>
            <span class="ese-box-val" id="ese-phase">Neutral</span>
        </div>
    </div>

    <div class="ese-data-list">
        <div class="ese-row"><span>ETH Pi Cycle Top</span><span id="ese-picycle">--</span></div>
        <div class="ese-row"><span>5Y Liquidity Cycle</span><span id="ese-liquidity">--</span></div>
        <div class="ese-row"><span>Daily Trend (50/200D)</span><span id="ese-cross">--</span></div>
        <div class="ese-row"><span>Weekly Divergence</span><span id="ese-div">--</span></div>
        <div class="ese-row"><span>Market Sentiment</span><span id="ese-sentiment">--</span></div>
        <div class="ese-row"><span>ETH/BTC Ratio</span><span id="ese-ethbtc">--</span></div>
        <div class="ese-row"><span>Deriv Funding</span><span id="ese-funding">--%</span></div>
        <div class="ese-row"><span>Gas Network State</span><span id="ese-gas">--</span></div>
        <div class="ese-row"><span>DeFi TVL (14D)</span><span id="ese-tvl">--%</span></div>
        <div class="ese-row"><span>Net Impact</span><span id="ese-impact">--</span></div>
    </div>

    <div class="ese-footer" id="ese-action">Awaiting system compilation...</div>
</div>

<script>
(function() {
    async function safeFetch(url, options = {}) {
        try {
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 8000); 
            const res = await fetch(url, { ...options, signal: controller.signal });
            clearTimeout(timeoutId);
            return res.ok ? await res.json() : null;
        } catch (e) { return null; }
    }

    function calculateRSIArray(closes, period = 14) {
        if (closes.length <= period) return [];
        let rsiArr = new Array(period).fill(null);
        let gains = 0, losses = 0;
        for (let i = 1; i <= period; i++) {
            let diff = closes[i] - closes[i - 1];
            if (diff >= 0) gains += diff; else losses -= diff;
        }
        let avgGain = gains / period; let avgLoss = losses / period;
        rsiArr.push(100 - (100 / (1 + (avgGain / (avgLoss || 1e-10)))));
        for (let i = period + 1; i < closes.length; i++) {
            let diff = closes[i] - closes[i - 1];
            let gain = diff >= 0 ? diff : 0; let loss = diff < 0 ? -diff : 0;
            avgGain = ((avgGain * (period - 1)) + gain) / period;
            avgLoss = ((avgLoss * (period - 1)) + loss) / period;
            rsiArr.push(100 - (100 / (1 + (avgGain / (avgLoss || 1e-10)))));
        }
        return rsiArr;
    }

    async function executeSynthesis() {
        let m = { usd: null, gbp: null, ethbtc: null, wRsi: 50, forecast: 0, funding: 0.01, gas: 1.5, tvl: 0, cross: 'Neutral', div: 'None', phase: 'Neutral', fngVal: 50, fngText: 'Neutral' };
        
        const [spot, binance, cg200, fund, gasRes, tvlRes, fngRes, eth365] = await Promise.all([
            safeFetch('https://api.coingecko.com/api/v3/simple/price?ids=ethereum,bitcoin&amp;vs_currencies=usd,gbp'),
            safeFetch('https://api.binance.com/api/v3/klines?symbol=ETHUSDT&amp;interval=1w&amp;limit=60'),
            safeFetch('https://api.coingecko.com/api/v3/coins/ethereum/market_chart?vs_currency=gbp&amp;days=200&amp;interval=daily'),
            safeFetch('https://fapi.binance.com/fapi/v1/premiumIndex?symbol=ETHUSDT'),
            safeFetch('https://cloudflare-eth.com', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: "2.0", method: "eth_gasPrice", params: [], id: 1 }) }),
            safeFetch('https://api.llama.fi/charts/Ethereum'),
            safeFetch('https://api.alternative.me/fng/?limit=1'),
            safeFetch('https://api.coingecko.com/api/v3/coins/ethereum/market_chart?vs_currency=usd&amp;days=365&amp;interval=daily')
        ]);
        
        if (spot && spot.ethereum) { m.usd = spot.ethereum.usd; m.gbp = spot.ethereum.gbp; if (spot.bitcoin && spot.bitcoin.usd) m.ethbtc = m.usd / spot.bitcoin.usd; }
        if (binance) { const closes = binance.map(k => parseFloat(k[4])); const rsi = calculateRSIArray(closes, 14); m.wRsi = rsi[rsi.length - 1]; const recent = closes.slice(-20); const rsiRecent = rsi.slice(-20); if (recent[19] < recent[0] && rsiRecent[19] > rsiRecent[0]) m.div = 'Bullish'; else if (recent[19] > recent[0] && rsiRecent[19] < rsiRecent[0]) m.div = 'Bearish'; }
        if (cg200) { const dp = cg200.prices.map(p => p[1]); m.cross = (dp.slice(-50).reduce((a,b)=>a+b,0)/50 >= dp.slice(-200).reduce((a,b)=>a+b,0)/200) ? 'Golden Cross' : 'Death Cross'; m.forecast = ((dp[dp.length-1] - dp[dp.length-15]) / dp[dp.length-15]) * 100; }
        if (fund) m.funding = parseFloat(fund.lastFundingRate) * 100;
        if (gasRes && gasRes.result) m.gas = parseInt(gasRes.result, 16) / 1e9;
        if (tvlRes && tvlRes.length > 14) m.tvl = ((tvlRes[tvlRes.length-1].totalLiquidityUSD - tvlRes[tvlRes.length-15].totalLiquidityUSD) / tvlRes[tvlRes.length-15].totalLiquidityUSD) * 100;
        if (fngRes && fngRes.data && fngRes.data.length > 0) { m.fngVal = parseInt(fngRes.data[0].value); m.fngText = fngRes.data[0].value_classification; }
        
        // ETH Pi Cycle Top Calculation
        let piRatio = 0, piText = 'No Data', piClass = '';
        if (eth365 && eth365.prices && eth365.prices.length >= 350) {
            const ePrices = eth365.prices.map(p => p[1]);
            const sma111 = ePrices.slice(-111).reduce((a, b) => a + b, 0) / 111;
            const sma350 = ePrices.slice(-350).reduce((a, b) => a + b, 0) / 350;
            piRatio = sma111 / (sma350 * 2);

            if (piRatio >= 1.0) {
                piText = 'Crossed (TOP)'; piClass = 'text-red';
            } else if (piRatio >= 0.85) {
                piText = `Approaching (${(piRatio * 100).toFixed(1)}%)`; piClass = 'text-red';
            } else {
                piText = `Safe (${(piRatio * 100).toFixed(1)}%)`; piClass = 'text-green';
            }
        }
        
        // 5-Year Liquidity Cycle Calculation
        const msIn5Y = 5 * 365.25 * 24 * 60 * 60 * 1000;
        const timeSinceTrough = Date.now() - new Date('2022-11-20T00:00:00Z').getTime();
        const cycleProgress = (timeSinceTrough % msIn5Y) / msIn5Y;
        
        let liqState = 'Neutral', liqClass = '', liqModifier = 0;
        if (cycleProgress < 0.35) { liqState = 'Expansion'; liqClass = 'text-green'; liqModifier = 0.20; }
        else if (cycleProgress < 0.50) { liqState = 'Peak Liquidity'; liqClass = 'text-green'; liqModifier = 0.10; }
        else if (cycleProgress < 0.85) { liqState = 'Contraction'; liqClass = 'text-red'; liqModifier = -0.20; }
        else { liqState = 'Trough / Accum.'; liqClass = 'text-green'; liqModifier = 0.15; }

        let multi = 1.00;
        multi += liqModifier; 
        
        // ETH Pi Cycle Top Penalty
        if (piRatio >= 1.0) multi -= 0.50;
        else if (piRatio >= 0.90) multi -= 0.15;
        else if (piRatio < 0.60) multi += 0.10;

        if (m.funding > 0.05) multi -= 0.15; else if (m.funding < 0) multi += 0.15;
        if (m.wRsi < 40) multi += 0.20; else if (m.wRsi > 70) multi -= 0.20;
        if (m.cross === 'Golden Cross') multi += 0.10; else if (m.cross === 'Death Cross') multi -= 0.10;
        if (m.fngVal <= 25) multi += 0.10; else if (m.fngVal >= 75) multi -= 0.10;
        
        m.phase = (multi >= 1.20) ? 'Expansion' : (multi <= 0.80) ? 'Contraction' : 'Neutral';
        
        let gasText = 'Normal', gasClass = '';
        if (m.gas <= 1.0) { gasText = 'Accumulation'; gasClass = 'text-green'; } else if (m.gas >= 10.0) { gasText = 'Topping Out'; gasClass = 'text-red'; }
        
        let impactText = 'Normal', impactClass = '';
        if (m.forecast >= 2.0 && multi >= 1.1) { impactText = 'Accelerated'; impactClass = 'text-green'; } else if (m.forecast <= -2.0 && multi <= 0.9) { impactText = 'Decelerated'; impactClass = 'text-red'; }
        
        document.getElementById('ese-loader')?.remove(); document.getElementById('ese-gbp').style.display = 'inline'; document.getElementById('ese-usd').style.display = 'inline';
        document.getElementById('ese-gbp').innerHTML = m.gbp ? `&pound;${m.gbp.toLocaleString(undefined, {minimumFractionDigits:2, maximumFractionDigits:2})}` : '&pound;--';
        document.getElementById('ese-usd').innerHTML = m.usd ? `&#36;${m.usd.toLocaleString(undefined, {minimumFractionDigits:2, maximumFractionDigits:2})}` : '&#36;--';
        
        const rsiEl = document.getElementById('ese-rsi'), rsiBox = document.getElementById('ese-box-rsi');
        rsiEl.innerText = m.wRsi.toFixed(1); rsiEl.className = `ese-box-val ${m.wRsi <= 35 ? 'text-green' : m.wRsi >= 75 ? 'text-red' : ''}`; rsiBox.className = `ese-box ${m.wRsi <= 35 ? 'border-green' : m.wRsi >= 75 ? 'border-red' : ''}`;
        
        const foreEl = document.getElementById('ese-forecast'), foreBox = document.getElementById('ese-box-forecast');
        foreEl.innerText = (m.forecast >= 0 ? '+' : '') + m.forecast.toFixed(1) + '%'; foreEl.className = `ese-box-val ${m.forecast >= 5 ? 'text-green' : m.forecast <= -5 ? 'text-red' : ''}`; foreBox.className = `ese-box ${m.forecast >= 5 ? 'border-green' : m.forecast <= -5 ? 'border-red' : ''}`;
        
        document.getElementById('ese-multiplier').innerText = multi.toFixed(2) + 'x'; document.getElementById('ese-phase').className = `ese-box-val ${m.phase === 'Expansion' ? 'text-green' : m.phase === 'Contraction' ? 'text-red' : ''}`; document.getElementById('ese-phase').innerText = m.phase;
        
        // Populate Data List
        document.getElementById('ese-picycle').innerText = piText; document.getElementById('ese-picycle').className = piClass;
        document.getElementById('ese-liquidity').innerText = liqState; document.getElementById('ese-liquidity').className = liqClass;
        document.getElementById('ese-cross').className = (m.cross === 'Golden Cross' ? 'text-green' : m.cross === 'Death Cross' ? 'text-red' : ''); document.getElementById('ese-cross').innerText = m.cross;
        document.getElementById('ese-div').className = (m.div === 'Bullish' ? 'text-green' : m.div === 'Bearish' ? 'text-red' : ''); document.getElementById('ese-div').innerText = m.div;
        document.getElementById('ese-sentiment').innerText = `${m.fngVal} (${m.fngText})`; document.getElementById('ese-sentiment').className = (m.fngVal <= 25 ? 'text-green' : m.fngVal >= 75 ? 'text-red' : '');
        document.getElementById('ese-ethbtc').innerText = m.ethbtc ? m.ethbtc.toFixed(5) : '--'; document.getElementById('ese-tvl').innerText = (m.tvl >= 0 ? '+' : '') + m.tvl.toFixed(1) + '%'; document.getElementById('ese-tvl').className = (m.tvl >= 0 ? 'text-green' : 'text-red');
        document.getElementById('ese-funding').innerText = m.funding.toFixed(4) + '%'; document.getElementById('ese-gas').innerText = gasText; document.getElementById('ese-gas').className = gasClass; document.getElementById('ese-impact').innerText = impactText; document.getElementById('ese-impact').className = impactClass;
        
        const act = document.getElementById('ese-action'); 
        act.innerText = (m.wRsi <= 35 || multi >= 1.2) ? 'Buy Trigger Active (Accumulate)' : (m.wRsi >= 75 || multi <= 0.8) ? 'Sell Trigger Active (Scale Out)' : 'Neutral State (Patience)'; 
        act.className = (m.wRsi <= 35 || multi >= 1.2) ? 'ese-footer text-green' : (m.wRsi >= 75 || multi <= 0.8) ? 'ese-footer text-red' : 'ese-footer';
    }
    
    document.getElementById('ese-noise-toggle').addEventListener('change', (e) => document.getElementById('ese-price-display').classList.toggle('ese-blur', e.target.checked));
    executeSynthesis(); setInterval(executeSynthesis, 900000);
})();
</script>

Post a Comment

0 Comments

Notice:
Comments are moderated and may not appear immediately. Please keep your comments respectful, and relevant to the post. Spam will not be tolerated. My site. My rules.

Post a Comment (0)