|
||
---|---|---|
vendor | ||
.dockerignore | ||
.gitignore | ||
Dockerfile | ||
LICENSE | ||
README.md | ||
config.go | ||
data.go | ||
dataset.go | ||
decision.go | ||
docker-compose.example | ||
go.mod | ||
go.sum | ||
helpers.go | ||
main.go | ||
matrix.go | ||
messages.go | ||
rnn.go | ||
state.go | ||
util.go |
README.md
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 l’ultima parola a un essere umano.
Cosa fa
-
Scarica gli ultimi kline da Binance per il pair ETH/USDT (fino a ~300 giorni).
-
Costruisce un dataset di log-return e feature derivate.
-
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.
-
Predice la variazione relativa di domani (Δ%).
-
Interroga THORNode per stimare fee/quote di uno swap di riferimento.
-
Decide tra:
HOLD
,SWAP_AB
(ETH→USDT),SWAP_BA
(USDT→ETH) solo se il vantaggio atteso supera fee + margine di sicurezza. -
Non esegue lo swap: stampa istruzioni e invia una notifica Matrix (se configurata).
-
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 raggiunteMAX_EPOCHS
). - Validazione: MAE su hold-out set per monitoraggio overfitting.
- Persistenza: salvataggio modello e scaler su disco.
Logica decisionale (semplificata)
-
Predizione
pred_rel_move
(es. +0.8%). -
Quote THORNode → fee_totale (bp o valore assoluto) per importi di riferimento.
-
Edge atteso =
|pred_rel_move| − fee_totale − MARGINE_SICUREZZA
. -
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.
- se
-
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 d’ambiente
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
Setrue
, esegue subito un ciclo all’avvio oltre alla schedule. Default:true
.RUN_HOUR
Ora locale (0–23) 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 a0.01
per uno stop all’1% 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
-
Fetch dati Binance → aggiorna
data/*.csv
. -
Build dataset → feature + scaler.
-
Train/validate LSTM con early stopping.
-
Predict Δ% domani.
-
Quote THORNode (fee/slip) su importi di riferimento.
-
Decisione (
HOLD
/SWAP_AB
/SWAP_BA
). -
Output:
- log strutturati,
- messaggio console con istruzioni manuali,
- notifica Matrix (se abilitata).
-
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
, riduciMIN_EDGE_BPS
, verificaTHORNODE_URL
. - Flip-flop frequenti
Alza
HYSTERESIS_BPS
e/oCOOLDOWN_HOURS
. - Training lento
Riduci
MAX_EPOCHS
o aumentaEARLY_STOP_PCT
(es. 0.5→0.6). - Notifiche Matrix assenti
Verifica
MATRIX_ENABLED=true
, credenziali eMATRIX_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.