money/README.md

15 KiB
Raw Permalink Blame History

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 THORNodefee_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 > 0SWAP_BA (USDT→ETH);
    • se pred_rel_move < 0SWAP_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

# .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

  • È uno strumento informativo, non una consulenza finanziaria. Dovrebbe prenderci spesso, ma non ve lo giuro.
  • Mantiene supervisione umana: non firma né invia transazioni. Lo swap lo fate voi.
  • Usa importi di riferimento per stimare fee; in produzione adeguare dimensioni e limiti di slippage.

📄 Licenza

VEDI file LICENSE.


Checklist rapida per l'installazione

  • 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.

FAQ

  • Perche' e' tutto in italiano?
  • Italy First! Make Italy Great Again!
  • Perche' l'indirizzo di USDT sembra hardcoded? Io ho il mio!
  • No, non hai il tuo. USDT non e' una moneta, bensi' un contratto (o "token") basato su Ethereum. Il suo ID e' costante e pubblico. Non hai "il tuo". Tu al limite hai un indirizzo ETH, su cui hai messo il token, che e' di fatto un contratto.
  • Perche' usi il cambio USDT vs ETH per giocare?
  • Perche' una RNN LSTM ha bisogno di un buon rapporto tra segnale e rumore. Due crypto indipendenti hanno molto piu' rumore che segnale. Se non capisci questa risposta, non farti la domanda. E non usare questo software.
  • Ma USDT e' una stablecoin sul dollaro. Perche' mai non usare il cambio in dollari, allora, e usare ETH -> USD invece di ETH -> USDT ?
  • Perche il costo dello swap e' minore, e ogni volta che swappate in moneta corrente spesso ci pagate anche le tasse, mentre tra ETH e il suo contratto in USDT il fee e' minimo.
  • Ma THORnet e' legale? Non e' una darknet?
  • No, quella e' Tor. Thornet e' uno scambiatore, legittimo, che costa poco perche' non fa KYC. Insomma, non vi chiede anche le analisi del sangue per lavorare con voi. E comunque lo usiamo solo per avere delle quotazioni e poi, manualmente, per fare lo swap, se lo usate.
  • Ma a me il dio THOR non piace. Posso usare un altro scambiatore?
  • Ovvio. Il messaggio che ti arriva su Matrix specifica anche quant'e' il fee massimo che devi accettare per guadagnarci.
  • Perche' Matrix?
  • Perche' tu ricevi il messaggio, magari anche la notifica sul tuo cellulare, e poi decidi TU cosa fare.
  • Ma io non ci capisco niente. Lasciare a me la decisione e' assurdo. Perche' non fa tutto da solo?
  • Perche' se facesse tutto da solo, i tuoi soldi sarebbero esposti a qualsiasi idiozia, AKA "black swan" , per fare un'esempio, del Washington Bozo Circus, o di Donald Stable Genius Trump, o di Elon Mezzasega Musk. Invece, un filtro umano potrebbe filtrare queste cose, e rimandare gli swap a dopo.
  • Ma io non so come fare lo swap tra USDT e ETH.
  • Forse non dovresti usare questo software, allora. E nemmeno toccare una Crypto. E anche darsi fuoco di fronte al Duomo di Milano non e' un'ipotesi da scartare del tutto.
  • Ma io non so usare Matrix e non so come creare una room.
  • Il Duomo. Il Duomo e' tuo amico.E sbrigati, perche' la proliferazione di auto elettriche potrebbe rendere difficile trovare la benzina.
  • Hai usato la IA per scrivere il codice?
  • Solo i commenti, sul codice, per risparmiare tempo. Per scrivere la RNN invece no, perche' e' troppo complicato per un Languade Model, ed e' codice che se lo sbagli fa casini inenarrabili. In generale, una IA e' un programmatore analfabeta estremamente Junior. Non gli fai scrivere una RNN LSTM: per quella, bisogna averla capita.
  • Perche' hai scritto TU la RNN? Non potevi usare delle librerie?
  • Ho cercato librerie gia' fatte, e onestamente, siccome una RNN e' solo un gangbang di tensori (come tutte le reti neurali) ho trovato che sarebbe stato piu' veloce usando le librerie gonum, che sui tensori sono molto ottimizzate.
  • Perche' non hai usato ChatGPT per fare le previsioni?
  • Riguardo alla cosa del Duomo, dicevo, ti consiglio di comprare la Benzina a 95 ottani. Il Kerosene funziona, ma uccide troppo in fretta.
  • No, sul serio, cos'hanno queste RNN di speciale?
  • Percepiscono il tempo di una serie di valori. E sono usatissime per questo. Io le ho conosciute nel mondo automotive, nella parte di big data, perche' le marche di auto raccolgono i diagnostici inviati dall'auto, e li usano per failure prediction. E anche Airbus e Boeing (per quel che vale Boeing) le usano per fare fault prediction. Sono capaci di prevedere outlier noti, cioe' prevedere le probabilita' di guasto, cioe' un evento. Mi sembravano adatte a prevedere l'andamento di un titolo.
  • Ma sono solo 64 neuroni.
  • Il doppio di quelli di un broker di cripto, in media. Per il loro standard, questa RNN e' un genio. In confronto ad un verme della sabbia, e' un pochino ritardata. Lo so.
  • No, sul serio, solo 64 neuroni?
  • Il segnale che cerchiamo non e' complicatissimo. Usando piu' neuroni non cambierebbe nulla, ma avresti delle "allucinazioni".
  • Io sono un broker di Cryptocoin, e adesso vengo a prenderti coi miei amici, perche' mi hai offeso.
  • Se sei un broker di criptocoin, hai gia' inculato tutti i soldi ai tuoi amici. Non hai amici, cocco. Dicevamo, il Duomo. Benzina e Duomo. Darsi fuoco. Ricordi?
  • Si, ma alla fine, funziona o non funziona?
  • Risposta corretta: Mediamente, ha buone probabilita' di funzionare. Ma qualche volta sbagliera'. Ho cercato di ridurre al minimo le possibilita' che sbagli. E' sensibile ai black swan anche se ho cercato di mitigarne gli impatti in fase di addestramento. Diciamo che se lo usate per un annetto di fila, dovreste guadagnare piu' di un titolo di stato.
  • Come reagisce ai trend secolari?
  • Li impara. Ma tieni conto che una delle due crypto e' una stablecoin che orbita attorno al valore di 1$, quindi dovrebbero esserci trend secolari nell'andamento di ETH. Non credo sia cosi' verosimile.
  • E' migliore o peggiore di una strategia Parrondo-Like?
  • Parrondo ha il vantaggio di poter fornire un arbitraggio anche se entrambi i due giochi sono perdenti, ma a parte piccole fluttuazioni , USDT e' costante. Non la userei per uno scalping giornaliero con USDT. Non succede praticamente mai che entrambi i giochi siano perdenti. E' vero che ho usato un gioco di Parrondo come benchmark per fare un confronto,e forse ci sono log sparsi , anche nel repo.