Add indicators fetcher, rich dashboard renderer, and remove trade executor/status

This commit is contained in:
DiTus
2026-07-29 09:11:13 +02:00
parent 2a8ee9c8c5
commit 63bab43557
7 changed files with 1166 additions and 187 deletions

239
WIKI/indicators.md Normal file
View File

@ -0,0 +1,239 @@
# 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__`):
```python
self.renderer = DashboardRenderer(table_visibility={
"market": True,
"strategies": False,
"indicators": True,
})
```
### Runtime Toggling
Toggle the Indicators table at runtime:
```python
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`.
```json
"wti_brent_ratio": {
"display_name": "WTI/BRENT",
"type": "ratio",
"numerator": "xyz:CL",
"denominator": "xyz:BRENTOIL",
"changes": ["1h", "1d"],
"show_deviation": true
}
```
- **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
### `price` — Single Price
```json
"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`.
```json
"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`.
```json
"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
```json
"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
```json
"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.
```json
"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:
```python
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
## 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:
```json
"my_new_indicator": {
"display_name": "My Indicator",
"type": "price",
"coin": "BTC",
"changes": ["1h", "1d"],
"show_deviation": true
}
```
2. 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.