Files
hyper/WIKI/indicators.md
DiTus f6d95de49f Add GOLD/SILVER ratio indicator to dashboard
Add gold_silver_ratio indicator (xyz:GOLD / xyz:SILVER) with fallback
reference of 61.59, mirroring the existing WTI/BRENT ratio setup.
Also register xyz:GOLD and xyz:SILVER in WATCHED_COINS and data_fetcher
defaults so the candle data is fetched for the new indicator.
2026-07-29 17:02:15 +02:00

7.9 KiB

Indicators Guide

This guide explains how to configure and use the Indicators table on the live terminal dashboard.

Overview

The Indicators table displays computed financial indicators (e.g., WTI/BRENT ratio, live prices, moving averages, RSI) with their current value, 1-hour and 1-day percentage changes, and deviation from a long-term average.

The system is config-driven — new indicators are added by editing _data/indicators.json. No code changes are required for standard indicator types.

Dashboard Table

The Indicators table is displayed below the Market table in the dashboard. It shows:

Column Description
# Indicator number
Indicator Display name from config
Value Current indicator value
1h Change Percentage change over the last 1 hour
1D Change Percentage change over the last 1 day
Deviation Deviation from the long-term average

Changes are color-coded: green for positive, red for negative, yellow for neutral.

Configuration

Default Visibility

The Indicators table is enabled by default. The visibility is set in main_app.py (MainApp.__init__):

self.renderer = DashboardRenderer(table_visibility={
    "market": True,
    "strategies": False,
    "indicators": True,
})

Runtime Toggling

Toggle the Indicators table at runtime:

app.toggle_table("indicators")              # flip on/off
app.toggle_table("indicators", enabled=True)  # explicitly enable
app.toggle_table("indicators", enabled=False) # explicitly disable

Indicator Types

The following indicator types are supported in _data/indicators.json:

ratio — A/B Ratio

Computes numerator / denominator.

"wti_brent_ratio": {
    "display_name": "WTI/BRENT",
    "type": "ratio",
    "numerator": "xyz:CL",
    "denominator": "xyz:BRENTOIL",
    "changes": ["1h", "1d"],
    "show_deviation": true,
    "min_data_points": 100,
    "fallback_reference": 0.96065
}
  • Value: live(numerator) / live(denominator) from latest 1m candle closes
  • 1h Change: compares to ratio from 1h candle close prices
  • 1D Change: compares to ratio from 1d candle close prices
  • Deviation: (current - long_avg) / long_avg * 100, where long_avg is the mean of daily ratios over all available history. If fewer than min_data_points (default 100) daily data points exist and fallback_reference is set, the fallback value is used instead.
"gold_silver_ratio": {
    "display_name": "GOLD/SILVER",
    "type": "ratio",
    "numerator": "xyz:GOLD",
    "denominator": "xyz:SILVER",
    "changes": ["1h", "1d"],
    "show_deviation": true,
    "min_data_points": 100,
    "fallback_reference": 61.59
}

price — Single Price

"wti_price": {
    "display_name": "WTI",
    "type": "price",
    "coin": "xyz:CL",
    "changes": ["1h", "1d"],
    "show_deviation": true
}
  • Value: latest close price from {coin}_1m table
  • 1h/1D Change: compares to close from 1h/1d candle tables
  • Deviation: (current - long_avg) / long_avg * 100, where long_avg is the mean of daily closes

spread — Price Difference

Computes numerator - denominator.

"wti_brent_spread": {
    "display_name": "WTI-BRENT Spread",
    "type": "spread",
    "numerator": "xyz:CL",
    "denominator": "xyz:BRENTOIL",
    "changes": ["1h", "1d"],
    "show_deviation": true
}

diff_pct — Percentage Difference

Computes (numerator - denominator) / denominator * 100.

"wti_brent_diff": {
    "display_name": "WTI-BRENT Diff%",
    "type": "diff_pct",
    "numerator": "xyz:CL",
    "denominator": "xyz:BRENTOIL",
    "changes": ["1h", "1d"],
    "show_deviation": true
}

ma — Moving Average

"wti_ma_20": {
    "display_name": "WTI MA(20)",
    "type": "ma",
    "coin": "xyz:CL",
    "timeframe": "1h",
    "period": 20,
    "changes": ["1h", "1d"],
    "show_deviation": true
}
  • Value: latest SMA value on the specified timeframe
  • 1h Change: compares to MA value from 1h candle table
  • 1D Change: compares to MA value from 1d candle table
  • Deviation: (current_price - MA) / MA * 100 (how far the live price is from the MA)

rsi — Relative Strength Index

"wti_rsi_14": {
    "display_name": "WTI RSI(14)",
    "type": "rsi",
    "coin": "xyz:CL",
    "timeframe": "1h",
    "period": 14,
    "changes": ["1h", "1d"],
    "show_deviation": true
}
  • Value: latest RSI value (0-100) on the specified timeframe
  • 1h/1D Change: absolute change in RSI points
  • Deviation: RSI - 50 (deviation from neutral)

custom — Custom Function

Calls a user-defined Python function.

"custom_indicator": {
    "display_name": "My Custom Indicator",
    "type": "custom",
    "module": "indicators.custom_indicators",
    "function": "my_custom_calc",
    "args": {"param1": "value1"},
    "changes": ["1h", "1d"],
    "show_deviation": true
}

The custom function must accept db_path as the first argument, plus any args from the config, and return a dict:

def my_custom_calc(db_path, **kwargs):
    return {
        "value": 0.96611,
        "reference": 0.96044,
        "changes": {"1h": 0.12, "1d": -0.45},
        "deviation": 0.59
    }
}

Data Sources

All indicator calculations read from the SQLite database _data/market_data.db:

  • Live value: latest close price from {coin}_1m candle table (updated in real-time by live_candle_fetcher.py)
  • 1h change: close price from {coin}_1h candle table (second-to-last completed 1h candle)
  • 1D change: close price from {coin}_1d candle table (second-to-last completed 1d candle)
  • Reference value: mean of daily values over all available historical data. If fewer than min_data_points daily data points exist and fallback_reference is set, the fallback value is used instead.

Process Architecture

indicators_fetcher.py (subprocess, runs every 30s)
    |
    +---> indicators.py (IndicatorCalculator)
    |         |
    |         +---> _data/market_data.db (SQLite candle data)
    |         +---> _data/indicators.json (config)
    |
    +---> _logs/indicators_status.json (output)
            |
            +---> main_app.py (MainApp.read_indicators_status)
                    |
                    +---> dashboard.py (DashboardRenderer.build_indicators_table)

File Reference

File Description
_data/indicators.json Indicator definitions (config)
indicators.py IndicatorCalculator class — computation logic
indicators_fetcher.py Standalone script — runs in a loop, computes indicators, writes JSON
dashboard.py DashboardRenderer.build_indicators_table() — renders the table
main_app.py run_indicators_fetcher() — process target; MainApp.read_indicators_status() — reads JSON
_logs/indicators_status.json Output file with computed indicator values

Adding a New Indicator

  1. Edit _data/indicators.json and add a new entry:
"my_new_indicator": {
    "display_name": "My Indicator",
    "type": "price",
    "coin": "BTC",
    "changes": ["1h", "1d"],
    "show_deviation": true
}
  1. Restart the application (python main_app.py). The Indicators Fetcher will automatically pick up the new config on its next run.

No code changes are needed for standard indicator types (ratio, price, spread, diff_pct, ma, rsi). For custom calculations, use the custom type.

Optional Deviation Config Fields

The following optional fields control the deviation reference value:

Field Type Default Description
min_data_points int 100 Minimum number of historical daily data points required before using the computed mean as the reference
fallback_reference float null If set and available data points are below min_data_points, this value is used as the reference instead of the computed mean