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.
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, wherelong_avgis the mean of daily ratios over all available history. If fewer thanmin_data_points(default 100) daily data points exist andfallback_referenceis 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}_1mtable - 1h/1D Change: compares to close from 1h/1d candle tables
- Deviation:
(current - long_avg) / long_avg * 100, wherelong_avgis 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}_1mcandle table (updated in real-time bylive_candle_fetcher.py) - 1h change: close price from
{coin}_1hcandle table (second-to-last completed 1h candle) - 1D change: close price from
{coin}_1dcandle table (second-to-last completed 1d candle) - Reference value: mean of daily values over all available historical data. If fewer than
min_data_pointsdaily data points exist andfallback_referenceis 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
- Edit
_data/indicators.jsonand add a new entry:
"my_new_indicator": {
"display_name": "My Indicator",
"type": "price",
"coin": "BTC",
"changes": ["1h", "1d"],
"show_deviation": true
}
- 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 |