Live Institutional Bias Demo

This demo uses the PineTS library to load the market data and calculate the indicators, and QFChart library for visualizing the results.


Loading Data ...

About EMA Crossover with Background Color Zones

What This Indicator Does

This indicator implements a classic dual EMA crossover system with visual background color zones to make trend identification effortless. It uses a 9-period EMA (fast) and an 18-period EMA (slow) plotted directly on the price chart. When the fast EMA crosses above the slow EMA, a blue background zone appears, signaling bullish momentum. When the fast EMA crosses below the slow EMA, an orange background zone appears, signaling bearish momentum.

How It Works

The indicator consists of three simple components:

Trading the EMA Crossover

Common trading strategies using this indicator:

Why EMAs Work

Exponential Moving Averages give more weight to recent prices compared to Simple Moving Averages, making them more responsive to price changes. The 9/18 EMA combination provides a good balance between responsiveness and noise filtering:

Background Color Visualization

The background colors are the key innovation in this implementation. Instead of manually watching for crossovers, the colored zones make the current trend instantly visible at a glance. This is especially useful when monitoring multiple charts or making quick trading decisions.

EMA Crossover with QFChart & PineTS

This live demo showcases QFChart's background rendering capability combined with PineTS's real-time indicator calculations. The EMAs are continuously recalculated using PineTS's optimized incremental state management, while QFChart renders the lines and background colors as overlay plots on the main chart. The chart updates every 3 seconds with live market data from Binance, showing trend changes as they happen.

Technical Implementation

This demo demonstrates several advanced QFChart features:

Indicator Code

Here's the actual implementation:

const institBiasIndicator = (context) => {
    const ema9 = ta.ema(close, 9);
    const ema18 = ta.ema(close, 18);

    const bull_bias = ema9 > ema18;
    const bear_bias = ema9 < ema18;

    plot(ema9, 'EMA 9', { title: 'EMA 9', color: '#2962FF', style: 'line' });
    plot(ema18, 'EMA 18', { title: 'EMA 18', color: '#FF6D00', style: 'line' });
    plot(bull_bias, 'Bull Bias', {
        title: 'Bull Bias',
        color: '#2962FF',
        style: 'background',
    });
    bgcolor(bear_bias ? '#FF6D00' : na, { title: 'Bear Bias' });
};

Use Cases

Customization Ideas

You can easily modify this indicator:

Getting Started

To use this indicator in your own application:

// Define the indicator
const emaIndicator = (context) => {
    const ema9 = ta.ema(close, 9);
    const ema18 = ta.ema(close, 18);
    const bull_bias = ema9 > ema18;
    const bear_bias = ema9 < ema18;
    
    plot(ema9, 'EMA 9', { color: '#2962FF', style: 'line' });
    plot(ema18, 'EMA 18', { color: '#FF6D00', style: 'line' });
    plot(bull_bias, 'Bull Bias', { color: '#2962FF', style: 'background' });
    bgcolor(bear_bias ? '#FF6D00' : na, { title: 'Bear Bias' });
};

// Create PineTS instance and stream data
const pineTS = new PineTS(PineTS.Provider.Binance, 'BTCUSDC', '1h', 500);
const stream = pineTS.stream(emaIndicator, {
    pageSize: 100,
    live: true,
    interval: 3000
});

// Initialize QFChart
const chart = new QFChart.QFChart(container, {
    title: 'BTC/USDT',
    lastPriceLine: { visible: true, showCountdown: true },
    interval: 60 * 60 * 1000
});

// Handle data updates
stream.on('data', (ctx) => {
    if (!chart.initialized) {
        chart.setMarketData(ctx.marketData);
        indicator = chart.addIndicator('EMA Crossover', ctx.plots, {
            isOverlay: true
        });
    } else {
        indicator.updateData(ctx.plots);
        chart.updateData([latestBar]);
    }
});

Learn More