money/README.md

293 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# ETH↔USDT Swap Advisor — README
> Demone giornaliero che **prevede il cambio ETH/USDT** e ti **dice quando swappare**. Non esegue ordini: **notifica su Matrix** e lascia **lultima parola a un essere umano**.
---
## Cosa fa
1. **Scarica** gli ultimi *kline* da Binance per il pair ETH/USDT (fino a ~300 giorni).
2. **Costruisce un dataset** di log-return e feature derivate.
3. **Addestra** una RNN **LSTM (64 unità)** con:
* perdita **Huber** (robusta agli outlier),
* **gradient clipping**,
* **early stopping** (sulla media delle loss: si ferma quando scende sotto una frazione della loss iniziale o al max di epoche),
* split **train/validation**.
4. **Predice** la **variazione relativa di domani** (Δ%).
5. **Interroga THORNode** per stimare **fee/quote** di uno swap di riferimento.
6. **Decide** tra: `HOLD`, `SWAP_AB` (ETH→USDT), `SWAP_BA` (USDT→ETH) **solo se** il vantaggio atteso supera fee + margine di sicurezza.
7. **Non esegue** lo swap: **stampa istruzioni** e **invia una notifica Matrix** (se configurata).
8. **Mantiene stato locale** per evitare decisioni duplicate ravvicinate.
---
## Modello / Pipeline ML
* **RNN:** LSTM a **64 unità** su finestre temporali (sequenze) dei log-return.
* **Target:** variazione percentuale del prezzo *close* del giorno successivo.
* **Feature principali:** log-return, medie mobili/volatilità (rolling), normalizzazione.
* **Loss:** **Huber**; **optimizer** Adam; **gradient clipping** per stabilità.
* **Early stopping:** si arresta quando `avgLoss ≤ firstLoss × EARLY_STOP_PCT` (o raggiunte `MAX_EPOCHS`).
* **Validazione:** MAE su hold-out set per monitoraggio overfitting.
* **Persistenza:** salvataggio modello e scaler su disco.
---
## Logica decisionale (semplificata)
1. **Predizione** `pred_rel_move` (es. +0.8%).
2. **Quote THORNode****fee_totale** (bp o valore assoluto) per importi di riferimento.
3. **Edge atteso** = `|pred_rel_move| fee_totale MARGINE_SICUREZZA`.
4. Se `edge ≥ 0`:
* se `pred_rel_move > 0`**`SWAP_BA`** *(USDT→ETH)*;
* se `pred_rel_move < 0`**`SWAP_AB`** *(ETH→USDT)*;
* applica **isteresi** per evitare flip-flop.
5. Altrimenti **`HOLD`**.
**Esempio messaggi:**
* `decision: dir=HOLD pred=+0.36% fee=0.48% edge=-0.12%`
* `decision: dir=SWAP_AB (ETH→USDT) pred=-1.25% fee=0.40% edge=+0.85%`
* `decision: dir=SWAP_BA (USDT→ETH) pred=+0.90% fee=0.35% edge=+0.55%`
---
## Perché Matrix
Il demone **non esegue ordini**: invia **notifiche su Matrix** con la decisione, i numeri (predizione, fee, edge) e le **istruzioni manuali** per lo swap. In questo modo:
* cè **supervisione umana**,
* si evitano ordini indesiderati,
* si mantiene un audit trail nel canale Matrix.
**Formato notifica (esempio):**
```
[ETH/USDT] 2025-09-28
Decisione: SWAP_AB (ETH→USDT)
Pred: -1.25% | Fee stimata: 0.40% | Edge: +0.85%
Quote THORNode (ref): 5.00 ETH → 8,750.00 USDT
Istruzioni: eseguire swap su THORChain con slip <= 1%, poi aggiornare balance.json
```
---
## Installazione
### Requisiti
* Go ≥ 1.21 (build nativa) **oppure** Docker/Podman (consigliato).
* Nessuna API key per le *public klines* Binance.
* Connettività a un endpoint **THORNode**.
### Esecuzione via Docker
```bash
# .env con le variabili (vedi sotto)
docker build -t eth-usdt-swapd .
docker run --rm -d \
--name eth-usdt-swapd \
--env-file .env \
-v $(pwd)/data:/app/data \
-v $(pwd)/state:/app/state \
-v $(pwd)/models:/app/models \
eth-usdt-swapd
```
---
## Variabili dambiente
> Tutte opzionali salvo dove indicato.
### Generali
* `PAIR`
Pair Binance. Default: `ETHUSDT`.
* `INTERVAL`
Intervallo kline Binance (es. `1d`, `4h`). Default: `1d`.
* `LOOKBACK_DAYS`
Giorni di storico da scaricare (max ~300 consigliati). Default: `300`.
* `DATA_DIR`
Cartella per CSV/dataset. Default: `data/`.
* `MODELS_DIR`
Cartella per modello/scaler. Default: `models/`.
* `STATE_DIR`
Cartella stato locale. Default: `state/`.
### Scheduler / Run
* `RUN_AT_START`
Se `true`, esegue subito un ciclo allavvio oltre alla schedule. Default: `true`.
* `RUN_HOUR`
Ora locale (023) per il giro giornaliero. Default: `24`.
* `TZ`
Timezone (es. `Europe/Berlin`). Default: quello del sistema/container.
### THORNode / Fee
* `THORNODE_URL` **(richiesto)**
Endpoint THORNode per quote (es. `https://thornode.ninerealms.com`).
* `REF_FROM`
**Importo di riferimento in asset A (ETH)** per stimare fee. Default: `5.0`. Serve per avere la quotazione dello swap da THORNet.
* `REF_TO`
**Importo di riferimento in asset B (USDT)** per stima inversa. Default: `10000`.
* `MAX_SLIP_BPS`
Slippage massimo accettabile in basis points. Default: `100` (1.00%).
* `FEE_BUFFER_BPS`
Cuscinetto extra per fee impreviste (bp). Default: `5` (0.05%).
### Decisione / Risk
* `MIN_EDGE_BPS`
Margine minimo (bp) oltre la fee per procedere. Default: `10` (0.10%).
* `HYSTERESIS_BPS`
Isteresi per non invertire decisioni troppo spesso. Default: `5` (0.05%).
* `COOLDOWN_HOURS`
Ore minime tra due swap nella stessa direzione. Default: `24`.
### ML / Training
* `SEQ_LEN`
Lunghezza sequenza LSTM. Default: `60`.
* `LSTM_UNITS`
Unità LSTM. Default: `64`.
* `MAX_EPOCHS`
Epoche massime. Default: `100`.
* `EARLY_STOP_PCT`
Soglia early stopping vs loss iniziale (es. `0.50` = 50%). Default: `0.50`.
*(Imposta a `0.01` per uno **stop all1%** della firstLoss, come variante.)*
* `BATCH_SIZE`
Dimensione batch. Default: `64`.
* `LEARNING_RATE`
Learning rate Adam. Default: `0.001`.
* `VAL_SPLIT`
Frazione validation. Default: `0.2`.
### Matrix (notifiche)
* `MATRIX_ENABLED`
Abilita notifiche (`true`/`false`). Default: `false`.
* `MATRIX_HOMESERVER`
URL homeserver Matrix (es. `https://matrix-client.matrix.org`).
* `MATRIX_USER`
Username/login Matrix.
* `MATRIX_PASS`
Password Matrix.
* `MATRIX_ROOM`
Room ID o alias (es. `!abcd:server` o `#canale:server`).
### Verbosità / Debug
* `LOG_LEVEL`
`DEBUG` | `INFO` | `WARN` | `ERROR`. Default: `INFO`.
* `LOG_JSON`
Log in JSON (`true`/`false`). Default: `false`.
---
## 🗂️ Struttura file/cartelle
```
data/
ethusdt_1d.csv # klines storiche aggiornate
models/
lstm.bin # pesi modello
scaler.json # normalizzatore feature
state/
balance.json # stato per anti-duplicazione
last_decision.json # ultima decisione e timestamp
```
---
## Flusso operativo
1. **Fetch dati** Binance → aggiorna `data/*.csv`.
2. **Build dataset** → feature + scaler.
3. **Train/validate** LSTM con early stopping.
4. **Predict** Δ% domani.
5. **Quote THORNode** (fee/slip) su importi di riferimento.
6. **Decisione** (`HOLD` / `SWAP_AB` / `SWAP_BA`).
7. **Output**:
* log strutturati,
* messaggio console con **istruzioni manuali**,
* **notifica Matrix** (se abilitata).
8. **Persistenza stato** per coerenza tra run.
---
## Esempi di output console
```
2025/09/28 07:00:05 fetch binance ok: 300d ETHUSDT 1d
2025/09/28 07:00:12 train: epoch=43 avgLoss=0.0062 firstLoss=0.1128 valMAE=0.0189 (early-stop)
2025/09/28 07:00:13 thornode quote ok: from=5.000 ETH → to=8,742.10 USDT fee=0.38%
2025/09/28 07:00:13 decision: dir=SWAP_AB (ETH→USDT) pred=-1.25% fee=0.38% edge=+0.87%
2025/09/28 07:00:13 instructions: eseguire swap ETH→USDT su THORChain, slip<=1.0%, size≈ref
```
## Esempi di output su matrix
HOLD
```
consiglio: azione=HOLD expectedBps=18.602 feeBps=26.000 netBps=-7.398 confOK=true motivo=Previsione rialzista ma non abbastanza sopra fee+margine o confidenza bassa
Suggerimento: nessuna azione (HOLD). Motivo=Previsione rialzista ma non abbastanza sopra fee+margine o confidenza bassa
Suggerimento valido sino a: 2025-09-28 12:58:03 CEST
La quotazione dei costi è valida sino a 2025-09-28 12:58:03 CEST (≈ 14m 59s restanti). Non fare lo swap dopo questa data.
```
SWAP
```
consiglio: azione=ETH -> USDT expectedBps=-63.477 feeBps=8.000 netBps=45.477 confOK=true motivo=Previsione ribassista per asset from, confidenza valida, guadagno oltre fee+margine
ISTRUZIONI MANUALI: esegui swap ETH.ETH->ETH.USDT amount=0.10000000; procedi solo se feeTotali<=53.477 bps (stima THOR=8.000 bps) e costo<=~0.00053477 ETH.ETH | motivo=Previsione ribassista per asset from, confidenza valida, guadagno oltre fee+margine
Suggerimento valido sino a: 2025-09-28 12:58:03 CEST
La quotazione dei costi è valida sino a 2025-09-28 12:58:03 CEST (≈ 14m 59s restanti). Dopo questa data, verifica i costi di swap
```
---
## Troubleshooting
* **Niente decisione / sempre HOLD**
Aumenta `LOOKBACK_DAYS`, riduci `MIN_EDGE_BPS`, verifica `THORNODE_URL`.
* **Flip-flop frequenti**
Alza `HYSTERESIS_BPS` e/o `COOLDOWN_HOURS`.
* **Training lento**
Riduci `MAX_EPOCHS` o aumenta `EARLY_STOP_PCT` (es. 0.5→0.6).
* **Notifiche Matrix assenti**
Verifica `MATRIX_ENABLED=true`, credenziali e `MATRIX_ROOM`.
---
## Avvertenze
* È **strumento informativo**, non consulenza finanziaria.
* Mantiene **supervisione umana**: **non** firma né invia transazioni.
* Usa **importi di riferimento** per stimare fee; in produzione adeguare dimensioni e limiti di slippage.
---
## 📄 Licenza
VEDI file LICENSE (o specificare).
---
## ✅ Checklist rapida
* [ ] Imposta `THORNODE_URL`.
* [ ] Valuta `EARLY_STOP_PCT` (0.50 default, **0.01** per stop *molto* stretto).
* [ ] Configura Matrix (`MATRIX_ENABLED=true` + credenziali).
* [ ] Monta `data/`, `models/`, `state/`.
* [ ] Avvia container e verifica i log.