Giacenze Crypto

Configurazione JSON per le importazioni personalizzate

Questa guida spiega come creare un file JSON per importare qualunque file CSV nella raccolta dei movimenti crypto. Il JSON descrive:

Ogni proprietà ha un valore predefinito. Se non la inserisci nel JSON, viene usato il default indicato.

Struttura generale

{
"nomeExchange": "...",
"fontePrezzoPreferita": "",
"fornitore": "...",
"estrazione": "...",
"descrizione": "",
"versione": "",
"versioneMinimaApp": "",
"nomeWallet": "...",
"testing": false,
"separatore": ",",
"separatoreValoreMoneta": "",
"coppia": { ... },
"encoding": "UTF-8",
"righeIntestazione": 1,
"rigaIntestazione": 1,
"autoDetectColonne": false,
"mappaAutoDetect": { ... },
"formatoData": "yyyy-MM-dd HH:mm:ss",
"fuso": "UTC",
"consolidaRigheStessaData": false,
"tolleranzaSecondiConsolidamento": 2,
"causaliDifferite": [],
"causaliConsolidaPerGiorno": [],
"minutiScambioDifferito": 15,
"colonne": { ... },
"raggruppamentoPerCausale": { ... },
"colonneControvalore": { ... },
"mappaCausali": { ... },
"causalePerNota": [ ... ],
"causaliChiuse": [ ... ],
"causaliUscita": [ ... ],
"causaliEntrata": [ ... ],
"versoForzato": "",
"causaliScambiaGambe": [ ... ],
"gambaDoppiaConSegnoSuUscita": false,
"ricostruisciLordoSeFeeSuMonetaUscita": false,
"ricostruisciLordoSeFeeSuMonetaEntrata": false,
"rimuoviCaseSensitive": false,
"rimuoviDaNomeMoneta": [ ... ],
"rinominaMonete": { ... },
"walletPerCausale": { ... },
"walletSpecularePerCausale": { ... },
"girocontoFiat": { ... },
"causaliDerivati": { ... },
"causaliAllertaDerivati": [ ... ],
"campiExtra": { ... },
"centralizzato": false,
"separatoreCausale": ".",
"causaliUppercase": false
}

1. Intestazione {#1-intestazione}

nomeExchange

Tipo: stringa Default: “” (stringa vuota)

Nome dell’exchange o della piattaforma sorgente. Se lasciato vuoto, il programma chiede interattivamente il nome in fase di importazione.

"nomeExchange": "Binance"

⚠️ Non cambiarlo dopo aver importato dei movimenti. Il nome finisce nel campo Exchange del movimento e il programma lo usa in due modi. Per riconoscere i duplicati quando reimporti lo stesso file, e per decidere a quale gruppo wallet appartiene il movimento nel calcolo fiscale. Se lo modifichi, i movimenti già in archivio non vengono più riconosciuti, quindi un nuovo import li duplica, e passano a un altro gruppo wallet, a meno che tu non li riunisca con un alias. nomeWallet invece non ha effetti fiscali e può essere cambiato liberamente.

fontePrezzoPreferita

Tipo: stringa Default: “” (nessuna preferenza)

Exchange da preferire, fra quelli già scaricati, quando si cerca il prezzo di un movimento importato da questa configurazione — lo stesso id usato da CCXT, minuscolo ("binance", "okx", "cryptocom", "bybit", "coinbase", "bitstamp", "kucoin"). Non limita da chi si scarica: tutti gli exchange configurati vengono comunque interrogati al momento del download dei prezzi; questo campo sceglie solo quale dei prezzi già in cache usare quando più di uno è disponibile per lo stesso movimento. Si applica solo ai movimenti che non hanno già un prezzo o un controvalore nel CSV stesso (colonne prezzo e valoreEuro entrambe assenti/vuote), e solo al momento dell’import — le rivalorizzazioni fiscali successive non lo consultano.

"fontePrezzoPreferita": "binance"

nomeWallet

Tipo: stringa Default: “Principale”

Nome del wallet di destinazione. Può essere sovrascritto causale per causale tramite walletPerCausale.

"nomeWallet": "Spot"

testing

Tipo: booleano Default: false

Se true, segnala in fase di importazione che il file di configurazione è in fase di test e l’importazione potrebbe non essere affidabile.

"testing": true

fornitore e estrazione

Tipo: stringa Default: “” (stringa vuota)

Decidono dove compare la configurazione nelle due tendine della finestra di importazione: fornitore è la voce della prima tendina (l’exchange o il servizio), estrazione quella della seconda (quale export di quel fornitore si sta caricando).

Vanno indicati solo quando non si ricavano da soli: per un exchange basta nomeExchange, e per i formati che contengono i movimenti di piattaforme diverse (CoinTracking, Tatax) basta la parola nel nome del file. Se mancano entrambi si usa il nome del file di configurazione. estrazione va scritta senza ripetere il nome del fornitore, che è già nella prima tendina.

"fornitore": "OKX",
"estrazione": "Funding"

descrizione

Tipo: stringa Default: “” (nessun suggerimento)

Testo libero che descrive la configurazione: da dove si scarica il file, cosa copre, quali sono i limiti noti. Non cambia in nessun modo l’importazione. Viene mostrato come suggerimento (tooltip) quando passi il mouse sulla voce nella finestra di importazione. Per andare a capo e limitare la larghezza conviene scriverlo in HTML, come fanno le configurazioni ufficiali.

"descrizione": "<html><div style='width:380px'>Export CSV dei movimenti di conto. Gli interessi giornalieri sono sommati in un solo movimento.</div></html>"

versione

Tipo: stringa Default: “”

Numero di revisione del file (per esempio "1.002"). Il programma non lo usa per importare: serve a chi mantiene la configurazione per capire quale revisione è installata, e conviene aumentarlo a ogni modifica se condividi il file con altri.

versioneMinimaApp

Tipo: stringa Default: “” (nessun vincolo)

Versione minima del programma che sa interpretare questa configurazione, per esempio "1.0.64.06". Va indicata quando il file usa una funzione del formato aggiunta di recente (tra queste separatoreValoreMoneta, causaliScambiaGambe, versoForzato). Un’installazione più vecchia non propone la configurazione nella finestra di importazione, invece di proporla e poi leggerla male senza accorgersene. Se il vincolo non serve, lascia il campo vuoto.

"versioneMinimaApp": "1.0.64.06"

2. Struttura fisica del CSV {#2-struttura-fisica-del-csv}

separatore

Tipo: stringa Default: “,”

Carattere che divide le colonne nel CSV.

Valore Quando usarlo
”,” Standard internazionale, default.
”;” Export da Excel con impostazioni europee.
“\t” File TSV (tab-separated).
”|” Caso raro, usato da alcuni exchange.
"separatore": ";"

encoding

Tipo: stringa Default: “UTF-8”

Usa “UTF-8” nella maggior parte dei casi. Se i caratteri speciali risultano corrotti, prova “ISO-8859-1” oppure “Windows-1252”.

righeIntestazione

Tipo: numero intero Default: 1

Quante righe iniziali del CSV vanno saltate prima dei dati. Se il CSV non ha intestazione, imposta 0.

rigaIntestazione

Tipo: numero intero Default: 1

Quale riga (indice 1-based) contiene i nomi delle colonne. Usata solo se autoDetectColonne è true.

autoDetectColonne

Tipo: booleano Default: false

Se true, legge i nomi delle colonne dalla riga di intestazione e assegna automaticamente gli indici tramite mappaAutoDetect.

mappaAutoDetect

Tipo: oggetto chiave-valore

Mappa il nome dell’intestazione CSV al nome del campo logico. Valori validi: data, causale, moneta, quantita, segno, valoreEuro, monetaFee, quantitaFee, idTransazione, idGruppo, wallet. (prezzo, monetaUscita, quantitaUscita, causale2, causale3 non sono riconosciuti dall’auto-detect: vanno indicati a mano in colonne se servono.)

"autoDetectColonne": true,
"mappaAutoDetect": {
"Timestamp": "data",
"Type": "causale",
"Asset": "moneta",
"Amount": "quantita",
"Fee Amount": "quantitaFee",
"Fee Asset": "monetaFee",
"TxID": "idTransazione"
}

formatoData

Tipo: stringa Default: “yyyy-MM-dd HH:mm:ss”

Formato della data/ora nel CSV, con i token Java di DateTimeFormatter.

Token Significato Esempio
yyyy Anno a 4 cifre 2025
yy Anno a 2 cifre 25
MM Mese a 2 cifre 06
dd Giorno a 2 cifre 17
HH Ora 0-23 18
mm Minuti 39
ss Secondi 10
"formatoData": "dd.MM.yyyy HH:mm:ss"
"formatoData": "MM/dd/yy HH:mm"

fuso

Tipo: stringa Default: “UTC”

Fuso orario delle date nel CSV. Vengono convertite nel fuso locale dell’app.

"fuso": "UTC"
"fuso": "Europe/Rome"
"fuso": "UTC+2"

3. Colonne del CSV {#3-colonne-del-csv}

Mappa i campi logici agli indici numerici delle colonne del CSV, contando da 0. Usa -1 per indicare che una colonna non è presente.

"colonne": {
"data": 0,
"causale": 1,
"moneta": 2,
"quantita": 3,
"segno": -1,
"valoreEuro": -1,
"prezzo": -1,
"monetaFee": -1,
"quantitaFee": -1,
"idTransazione": -1,
"wallet": -1,
"monetaUscita": -1,
"quantitaUscita":-1,
"note": -1,
"causale2": -1,
"causale3": -1
}

Come trovare l’indice di una colonna

Apri il CSV, guarda la riga di intestazione e conta le colonne partendo da 0.

"Timestamp","Tipo","Asset","Quantita","Valore EUR"
0 1 2 3 4

Quindi: “data”: 0, “causale”: 1, “moneta”: 2 e così via.

Campi disponibili

Campo Descrizione
data Obbligatorio - data e ora del movimento.
causale Tipo di operazione nel CSV (Deposit, Trade, Staking…).
moneta Simbolo del token (BTC, ETH…).
quantita Quantità del movimento (negativa=uscita, positiva=entrata).
segno Colonna separata che indica il segno (+ o -).
valoreEuro Controvalore in euro già calcolato nel CSV.
prezzo Prezzo unitario del token al momento dell’operazione.
monetaFee Simbolo della moneta usata per la commissione.
quantitaFee Quantità della commissione pagata.
idTransazione ID univoco per raggruppare righe correlate dello stesso trade.
wallet Nome del wallet, se variabile riga per riga.
monetaUscita Moneta in uscita (CSV con entrata e uscita sulla stessa riga).
quantitaUscita Quantita in uscita (CSV con entrata e uscita sulla stessa riga).
note Colonna di testo libero da riportare nel campo Note del movimento. Serve anche a causalePerNota (vedi sezione 4).

Importo e moneta nella stessa cella

Tipo: stringa Default: “” (importo e moneta sono due colonne distinte)

Alcuni export scrivono importo e simbolo insieme, per esempio 407.57 AME. In questo caso indica lo stesso indice di colonna sia per quantita sia per moneta (e, se serve, per quantitaUscita/monetaUscita e quantitaFee/monetaFee), e in separatoreValoreMoneta il carattere che divide i due pezzi. Quando le due colonne coincidono il programma separa il numero dal simbolo usando quel carattere.

"separatoreValoreMoneta": " ",
"colonne": { "quantita": 5, "moneta": 5, "quantitaFee": 6, "monetaFee": 6 }

Coppia di trading in una sola cella

Tipo: oggetto { colonna, separatore, base, quote } Default: assente

Alcuni export di trading non hanno colonne per le monete e riportano solo la coppia, per esempio KCS-ETH. Il blocco coppia dice dove si trova la coppia e come dividerla. Il programma aggiunge a ogni riga due colonne virtuali alle posizioni base e quote, che poi usi nelle colonne come una qualsiasi altra colonna (di solito base come moneta e quote come monetaUscita).

Campo Descrizione
colonna Indice della colonna che contiene la coppia.
separatore Carattere che divide base e quota. Default -. Non può essere vuoto.
base Indice della prima colonna virtuale. Scegli un numero oltre l’ultima colonna vera del CSV.
quote Indice della seconda colonna virtuale, stessa regola.

Una riga la cui cella non contiene il separatore viene scartata e segnalata come COPPIA NON VALIDA.

"coppia": { "colonna": 3, "separatore": "-", "base": 16, "quote": 17 },
"colonne": { "moneta": 16, "quantita": 7, "monetaUscita": 17, "quantitaUscita": 8 },
"causaliScambiaGambe": ["SELL"]

L’esempio è quello di KuCoin: la coppia sta nella colonna 3, le colonne virtuali 16 e 17 vengono dopo l’ultima colonna vera, e le vendite (SELL) hanno i ruoli di entrata e uscita invertiti rispetto agli acquisti (vedi causaliScambiaGambe).

Causale composita

Alcuni CSV distribuiscono il tipo di operazione su più colonne. Si possono combinare fino a 3 colonne in una causale composita concatenate da separatoreCausale.

Parametro Default Descrizione
causale2 (in colonne) -1 Indice della seconda colonna causale.
causale3 (in colonne) -1 Indice della terza colonna causale.
separatoreCausale ”.” Carattere di giunzione tra le parti.
causaliUppercase false Se true converte ogni parte in maiuscolo prima di concatenare.

Esempio: causale=1 (“Trade”), causale2=2 (“Buy”), separatoreCausale=”.” produce la chiave “Trade.Buy” da usare in mappaCausali.

"colonne": { "causale": 1, "causale2": 2 },
"separatoreCausale": ".",
"mappaCausali": { "Trade.Buy": "SCAMBIO CRYPTO-CRYPTO" }

Entrata e uscita sulla stessa riga

Alcuni CSV (es. Koinly, CoinTracking) riportano l’intero scambio su una sola riga. In quel caso moneta/quantita = lato entrata, monetaUscita/quantitaUscita = lato uscita.

"colonne": {
"data": 8, "causale": 0,
"moneta": 2, "quantita": 1,
"monetaUscita": 4, "quantitaUscita": 3,
"monetaFee": 6, "quantitaFee": 5
}

gambaDoppiaConSegnoSuUscita

Tipo: booleano Default: false

Per gli export (tipico Nexo) in cui ogni riga ha due colonne moneta, ma solo quando le monete sono diverse si tratta di uno scambio. Quando la moneta di uscita coincide con quella principale (interessi, versamenti, prelievi…) la riga è un movimento a gamba singola e il verso sta nel segno della colonna di uscita. Con true il programma applica questa regola, altrimenti un accredito di interessi NEXO → NEXO diventerebbe un finto scambio. Se l’importo principale è zero si usa quello della colonna di uscita.

causaliScambiaGambe

Tipo: array di causali CSV originali Default: [] (nessuna)

Per le righe che portano già entrambe le gambe, scambia il ruolo di entrata e uscita delle due colonne prima di ogni altra elaborazione. Serve quando l’export usa colonne dal ruolo fisso (per esempio “Deal amount” e “Total”) ma la direzione reale dipende dalla causale: con Buy entra “Deal amount” ed esce “Total”, con Sell accade il contrario. Elenca qui le causali per cui le colonne vanno invertite. Se moneta e quantità condividono la stessa cella (separatoreValoreMoneta) simbolo e importo si scambiano insieme.

"causaliScambiaGambe": ["Sell"]

idGruppo (nella sezione colonne)

Tipo: numero intero Default: -1 (assente)

Colonna su cui raggruppare le righe quando non coincide con quella dell’identificativo. I due ruoli sono distinti: idTransazione dice chi è la riga — finisce nel movimento ed è ciò su cui lavora il controllo dei duplicati — mentre idGruppo dice con chi sta.

Nell’export di trading di OKX, ad esempio, ogni gamba e ogni esecuzione parziale hanno un id diverso ma condividono l’Order id: usare il primo anche per raggruppare spezzerebbe ogni scambio in gambe isolate. Quando idGruppo non è indicata si raggruppa come sempre sull’identificativo, quindi le configurazioni che non la usano non cambiano comportamento.

Quando idGruppo è presente, il file viene inoltre ordinato per quel campo (e poi per idTransazione) prima dell’importazione, perché il raggruppamento lavora su righe consecutive e gli export intercalano le gambe di ordini diversi.

"colonne": { "idTransazione": 0, "idGruppo": 1 }

raggruppamentoPerCausale

Tipo: oggetto causale CSV → indice colonna Default: {} (nessun override)

Sovrascrive la colonna di raggruppamento solo per le causali elencate. Serve quando le gambe di uno stesso movimento condividono una colonna diversa da idGruppo/idTransazione e i loro timestamp non sono identici.

Caso reale (Coinbase): le due gambe di un Convert hanno la stessa identica stringa nella colonna note ("Converted 22 ALEPH to 4.68065032 ZETA") ma sull’export a volte cadono a 1-2 secondi di distanza; raggruppando sul timestamp esatto verrebbero spezzate in un deposito e un prelievo separati. Raggruppando sulla colonna note (indice 10) si ricompongono. Va abbinato a consolidaRigheStessaData

"raggruppamentoPerCausale": { "Convert": 10 },
"consolidaRigheStessaData": true,
"tolleranzaSecondiConsolidamento": 60,
"causaliDifferite": ["Convert"]

4. Mappatura delle causali {#4-mappatura-delle-causali}

mappaCausali

Tipo: oggetto chiave-valore

Traduce le causali originali del CSV nelle tipologie interne dell’applicazione. Ogni causale deve avere una voce qui, altrimenti la riga viene scartata. La ricerca è case insensitive per default.

"mappaCausali": {
"Deposit": "TRASFERIMENTO-CRYPTO",
"Withdrawal": "TRASFERIMENTO-CRYPTO",
"Trade": "SCAMBIO CRYPTO-CRYPTO",
"Staking Rewards": "STAKING REWARDS",
"Commission": "COMMISSIONI",
"earn":"EARN",
"cashback":"CASHBACK"
}

Per ignorare righe senza contarle come scarti, mappa su “IGNORA” (vale anche “NON CONSIDERARE”):

"mappaCausali": { "Internal Transfer": "IGNORA" }

Tipologie interne che puoi usare come valore:

Valore Quando usarlo
SCAMBIO CRYPTO-CRYPTO Scambio fra due monete. Anche DUST-CONVERSION per la conversione dei saldi minimi.
ACQUISTO CRYPTO / VENDITA CRYPTO Acquisto o vendita di crypto contro valuta FIAT.
DEPOSITO FIAT / PRELIEVO FIAT Versamento o prelievo di valuta FIAT.
TRASFERIMENTO-CRYPTO Deposito o prelievo di crypto. Il verso lo decide il segno della quantità, per questo non esistono tipologie separate per deposito e prelievo.
TRASFERIMENTO-CRYPTO-INTERNO Spostamento fra comparti dello stesso exchange. Non genera plusvalenze.
SCAMBIO DIFFERITO Metà di uno scambio che compare come due righe indipendenti (vedi sezione 6).
REWARD, ALTRE-REWARD, EARN, STAKING REWARDS, CASHBACK, AIRDROP Ricompense di vario tipo.
COMMISSIONI Commissione pagata come movimento a sé.
IGNORA Riga da saltare senza segnalarla come scartata.

Una causale non presente in mappaCausali (e non coperta da causalePerNota) fa scartare la riga, che compare fra i movimenti sconosciuti del resoconto con il testo CAUSALE SCONOSCIUTA. Per altri esempi apri le configurazioni ufficiali nella cartella config/import/.

causalePerNota

Tipo: array di regole { causale, notaContiene, tipo } Default: [] (nessuna regola)

Riclassifica una riga in base al testo libero della colonna note, quando la causale del CSV da sola non basta a distinguere la natura del movimento. Richiede che colonne.note sia impostata.

Ogni regola:

Campo Obbligatorio Descrizione
causale no Causale CSV che la riga deve avere. Se omessa, la regola vale per qualsiasi causale.
notaContiene sì Sottostringa cercata nella colonna note (confronto case-insensitive).
tipo sì Tipologia interna da assegnare (le stesse usabili in mappaCausali: EARN, REWARD, AIRDROP, STAKING REWARDS, COMMISSIONI, …).

Le regole si valutano in ordine: vince la prima che combacia. Se nessuna regola combacia si usa la normale mappaCausali.

Caso reale (Coinbase): i premi arrivano tutti come causale Receive e si riconoscono solo dalla nota.

"colonne": { "note": 10 },
"causalePerNota": [
  { "causale": "Receive", "notaContiene": "from Coinbase Earn",     "tipo": "EARN" },
  { "causale": "Receive", "notaContiene": "from Coinbase Referral", "tipo": "REWARD" },
  { "causale": "Receive", "notaContiene": "airdrop",                "tipo": "AIRDROP" }
]

causaliChiuse

Tipo: array di stringhe (tipologie interne)

Tipologie interne che devono essere trattate come movimenti singoli anche se condividono l’ID transazione con altre righe. Usa per staking, cashback, commissioni, depositi e prelievi. Si indica la tipologia interna (il valore di mappaCausali), non la causale del CSV. In vecchie configurazioni la chiave si chiama movimentoChiuso, che il programma accetta ancora come sinonimo.

"causaliChiuse": [
"TRASFERIMENTO-CRYPTO",
"STAKING REWARDS","CASHBACK","COMMISSIONI"
]

5. Gestione del segno {#5-gestione-del-segno}

Per default il segno viene letto dalla quantità (negativa = uscita, positiva = entrata). Se la quantità è sempre positiva e il verso si deduce dalla causale, usa causaliUscita e causaliEntrata.

causaliUscita

Tipo: array di causali CSV originali

Le righe con queste causali avranno la quantità forzata negativa.

"causaliUscita": ["Withdrawal","Trade Sell","Fee"]

causaliEntrata

Tipo: array di causali CSV originali

Le righe con queste causali avranno la quantità forzata positiva.

"causaliEntrata": ["Deposit","Trade Buy","Staking Rewards","Cashback"]

versoForzato

Tipo: stringa "ENTRATA" o "USCITA" Default: “” (nessuna forzatura)

Forza il verso di ogni riga del file, qualunque sia la causale. Serve per gli export divisi per direzione, come i file dei soli depositi o dei soli prelievi di Gate.io, in cui non c’è nessuna colonna causale affidabile da cui dedurre il verso. A differenza di causaliUscita/causaliEntrata non dipende dal testo della causale. Qualunque altro valore viene ignorato.

"versoForzato": "ENTRATA"

Esempio pratico

"Data","Tipo","Moneta","Quantita"
"2025-01-15","Deposito","BTC","0.5"
"2025-01-16","Prelievo","ETH","1.2"
"causaliUscita": ["Prelievo"],
"causaliEntrata": ["Deposito","Staking","Cashback"]

6. Consolidamento righe correlate {#6-consolidamento-righe-correlate}

Alcuni exchange suddividono una singola operazione in più righe CSV (es. riga per moneta venduta + riga per moneta acquistata). Le opzioni seguenti permettono di raggrupparle.

consolidaRigheStessaData

Tipo: booleano Default: false
"consolidaRigheStessaData": true

tolleranzaSecondiConsolidamento

Tipo: numero intero Default: 2

Usato solo se consolidaRigheStessaData è true. Quanti secondi di differenza sono tollerati tra due righe perché vengano considerate parte della stessa operazione.

"tolleranzaSecondiConsolidamento": 5

causaliDifferite

Tipo: array di causali CSV originali

Se specificato, la tolleranza temporale viene applicata solo ai gruppi che contengono almeno una riga con queste causali; per le altre viene richiesto timestamp identico.

"causaliDifferite": ["Trade","Swap"]

causaliConsolidaPerGiorno

Tipo: array di causali CSV originali Default: [] (nessuna)

Somma le righe con queste causali in un solo movimento per giorno, moneta e causale. È pensato per gli export che accreditano micro-interessi molte volte al giorno (un export Bitget ne conteneva 28.000): senza la somma l’archivio si riempie di decine di migliaia di movimenti minuscoli. Il movimento risultante prende la data del primo accredito del giorno e le altre colonne dalla prima riga, con la sola quantità sostituita dalla somma. La commissione della prima riga viene azzerata, perché non va attribuita all’intero giorno. Il giorno è quello del fuso del tuo sistema. La somma avviene prima del raggruppamento delle righe.

"causaliConsolidaPerGiorno": ["Interest"]

La causale SCAMBIO DIFFERITO e minutiScambioDifferito

Alcune operazioni (l’Auto-Invest di Binance, un recupero fondi, una redistribuzione di token) mostrano nel CSV due righe indipendenti — un prelievo e un deposito, spesso di monete diverse — che in realtà sono le due metà dello stesso scambio, avvenuto “dietro le quinte” dell’exchange. Mappando la causale su SCAMBIO DIFFERITO (invece che su TRASFERIMENTO-CRYPTO) quella riga entra anche nella ricerca automatica di abbinamento a fine import: se, fra tutte le righe SCAMBIO DIFFERITO di questa importazione, un prelievo trova un deposito entro minutiScambioDifferito minuti e con un controvalore che non si scosta di oltre il 10%, i due movimenti vengono trasformati in un vero scambio (trasferimento verso una piattaforma fittizia, scambio, trasferimento di ritorno) invece di restare due movimenti scollegati.

SCAMBIO DIFFERITO va sempre aggiunta anche a causaliChiuse (è un movimento a gamba singola, come TRASFERIMENTO-CRYPTO).

Tipo: numero intero (minuti) Default: 15
"minutiScambioDifferito": 15

Il valore di default (15 minuti) è quello storicamente usato per Binance; un altro exchange, con tempi di regolamento diversi, può richiederne uno diverso.

idTransazione (nella sezione colonne)

Se il CSV ha una colonna con un ID univoco per transazione, indicarla consente di raggruppare righe anche se i timestamp differiscono oltre la tolleranza.

"colonne": { "idTransazione": 5 }

7. Gestione commissioni {#7-gestione-commissioni}

ricostruisciLordoSeFeeSuMonetaUscita

Tipo: booleano Default: false

Controlla se, quando la commissione è nella stessa moneta dell’uscita, il sistema deve ricostruire il lordo del movimento principale.

Esempio: uscita -500 USDC e fee 1 USDC. Con true: movimento principale -499 USDC + movimento commissione -1 USDC. Usalo quando la quantità nel CSV è già comprensiva della fee (riga unica).

"ricostruisciLordoSeFeeSuMonetaUscita": true

ricostruisciLordoSeFeeSuMonetaEntrata

Tipo: booleano Default: false

Controlla se, quando la commissione è nella stessa moneta dell’entrata, il sistema deve ricostruire il lordo del movimento principale.

Esempio: entrata 500 USDC e fee 1 USDC. Con true: movimento principale 501 USDC + movimento commissione -1 USDC. Usalo quando la quantità nel CSV è al netto della fee (riga unica).

"ricostruisciLordoSeFeeSuMonetaEntrata": true

colonneControvalore

Tipo: oggetto Default: assente

Per gli export in cui la colonna del totale comprende sia la commissione sia lo spread (tipico di Coinbase retail: Total (inclusive of fees and/or spread)). Per le cripto-attività la commissione non è deducibile dal costo di carico (art. 68 c. 9-bis TUIR), ma lo spread sì — non è una commissione. Con questo blocco, per le sole causali indicate, il controvalore usato come costo di carico diventa totale − commissione (lo spread resta dentro), invece della colonna valoreEuro.

Campo Descrizione
totale Indice colonna del totale comprensivo di commissione e spread.
commissione Indice colonna della commissione. Conta solo se è un importo positivo (alcune righe dust contengono un rapporto di spread con segno: viene ignorato).
valuta Indice colonna con la valuta di totale/commissione (es. la colonna “Price Currency” = EUR). Usata per la gamba FIAT sintetica e per il movimento commissione.
causali Causali CSV per cui applicare il ricalcolo totale − commissione.
causaliConMovimentoCommissione Sottoinsieme di causali: righe che portano la sola gamba crypto in entrata. Per queste viene sintetizzata la gamba FIAT in uscita di importo totale − commissione (l’operazione diventa un vero acquisto FIAT→crypto invece di un semplice deposito) e la commissione esce come movimento COMMISSIONI a sé nella valuta indicata.
noteAcquistoDaSaldo Elenco di testi (confronto senza distinzione fra maiuscole e minuscole) che, nella colonna note, indicano un acquisto pagato dal saldo dell’exchange (per Coinbase "EUR Wallet"). Vale solo per le causali di causaliConMovimentoCommissione. Se la nota non è vuota e non contiene nessuno di questi testi, l’acquisto è stato pagato con uno strumento esterno al saldo (carta, Apple Pay, Google Pay, bonifico diretto): in quel caso non si sintetizzano né la gamba FIAT né il movimento commissione, e resta il solo deposito crypto, caricato a costo pieno (totale − commissione) senza muovere euro. Nota vuota oppure elenco vuoto: comportamento normale.

Per le causali in causali ma non in causaliConMovimentoCommissione (es. gli scambi crypto/crypto, dove le monete sono già nette e la commissione è espressa solo in euro) viene corretto solo il controvalore, senza movimento commissione aggiuntivo.

"colonne": { "valoreEuro": 7 },
"colonneControvalore": {
  "totale": 8,
  "commissione": 9,
  "valuta": 5,
  "causali": ["Buy", "Convert"],
  "causaliConMovimentoCommissione": ["Buy"],
  "noteAcquistoDaSaldo": ["EUR Wallet"]
}

8. Pulizia e normalizzazione nomi moneta {#8-pulizia-e-normalizzazione-nomi-moneta}

rimuoviDaNomeMoneta

Tipo: array di stringhe

Rimuove testi indesiderati dal nome del token. Supporta la sintassi ? per troncare tutto ciò che viene dopo o prima.

Sintassi Effetto su BTC.STAKING@CRYPTO.COM Risultato
.STAKING? Rimuove .STAKING e tutto quello che segue BTC
?.STAKING Rimuove .STAKING e tutto quello che precede @CRYPTO.COM
.STAKING Rimuove solo la parola esatta BTC@CRYPTO.COM

Le regole vengono applicate in sequenza. Prima quelle più ampie (con ?).

"rimuoviDaNomeMoneta": [".STAKING?",".EARN?",".LOCKED?","@CRYPTO.COM"]

rimuoviCaseSensitive

Tipo: booleano Default: false

rinominaMonete

Tipo: oggetto chiave-valore

Rinomina un simbolo moneta. La rinomina avviene dopo la pulizia con rimuoviDaNomeMoneta.

"rinominaMonete": { "IOTA": "MIOTA", "LUNA2": "LUNA", "WBTC": "BTC" }

9. Wallet per causale e giroconti fra wallet {#9-wallet-per-causale}

walletPerCausale

Tipo: oggetto chiave-valore

Permette di assegnare un wallet diverso da nomeWallet per specifiche causali. La chiave è la causale originale del CSV.

"walletPerCausale": {
"Staking Rewards": "Staking", "Earn": "Earn", "Lockup": "Locked"
}

walletSpecularePerCausale

Tipo: oggetto chiave-valore

Per le causali indicate viene creato, oltre al movimento normale, un secondo movimento uguale e contrario sul wallet indicato: se la riga porta 100 USDT in uscita dal wallet principale, ne viene generata l’entrata di 100 USDT sul wallet della gamba speculare. La chiave è la causale originale del CSV.

Serve per le operazioni che spostano una moneta in un comparto dell’exchange e la restituiscono più tardi, con un rendimento e a volte in un’altra moneta: sono due righe del CSV distanti settimane, che l’importazione non può accoppiare da sola. Le due gambe tengono il saldo esatto su entrambi i lati, e la differenza fra quanto è uscito e quanto è rientrato resta come giacenza negativa sul comparto, segnalata fra gli errori e da sistemare a mano registrando la reward corrispondente.

"walletSpecularePerCausale": {
"Dual Savings Purchase": "Investimenti", "Dual Savings Settlement": "Investimenti"
}

Tre cose da sapere:

girocontoFiat

Tipo: oggetto Default: assente

Per gli euro (o un’altra valuta FIAT) spostati fra due wallet tuoi, per esempio da Coinbase ad Coinbase Pro. Nei CSV sono un prelievo FIAT su un wallet e un deposito FIAT sull’altro, indistinguibili da un bonifico dalla banca: chi conta i depositi FIAT per sapere quanto ha versato conta due volte gli stessi soldi, e il quadro RW li legge come apporto e prelievo. Con questo blocco, alla fine di ogni importazione, il programma cerca nell’intero archivio le coppie e le trasforma in un normale trasferimento fra wallet. La categoria resta deposito/prelievo FIAT, così il saldo si sposta davvero da un wallet all’altro.

Campo Descrizione
controparte nomeExchange dell’altro wallet del giroconto.
causali Causali CSV dei giroconti su questo wallet.
causaliControparte Causali CSV dei giroconti sul wallet controparte.
secondiTolleranza Scarto massimo in secondi fra le due gambe. Default 60.
"girocontoFiat": {
  "controparte": "Coinbase",
  "causali": ["deposit", "withdrawal"],
  "causaliControparte": ["Exchange Deposit", "Exchange Withdrawal", "Pro Deposit", "Pro Withdrawal"],
  "secondiTolleranza": 60
}

Tre cose da sapere:

10. Derivati {#10-derivati}

Il programma non calcola i redditi da derivati (futures, perpetui, opzioni, Dual Investment, art. 67 c-quater TUIR): li tratta come cripto-attività, e questo non è corretto sul piano fiscale. Le due chiavi seguenti servono a farli riconoscere e ad avvisare l’utente.

causaliDerivati

Tipo: oggetto causale CSV → tipo Default: {}

Per ogni causale elencata, i movimenti che nascono da quella riga ricevono nel campo Derivato un tipo che li identifica. Il tipo non cambia il calcolo, serve solo a riconoscerli e filtrarli. Una causale presente qui fa comparire anche l’avviso di fine importazione e l’avvertenza nelle stampe dei quadri W/RW e T/RT.

I tipi usati dalle configurazioni ufficiali sono PNL (risultato realizzato), FUNDING, BONUS, RIMBORSO_COMMISSIONI, CONSEGNA, DUAL e COMMISSIONE.

"causaliDerivati": {
"funding": "FUNDING", "trade": "PNL", "feeRefund": "RIMBORSO_COMMISSIONI"
}

causaliAllertaDerivati

Tipo: array di causali CSV originali Default: []

Fa comparire l’avviso sui derivati a fine importazione per le causali elencate, senza marcare i movimenti. Le causali di causaliDerivati entrano automaticamente anche qui. Le configurazioni ufficiali ripetono le stesse causali in entrambe le chiavi, perché le versioni del programma più vecchie ignorano causaliDerivati e leggono solo questa. Se scrivi una configurazione solo per la tua installazione basta causaliDerivati.

"causaliAllertaDerivati": ["Dual Savings Purchase"]

11. Campi extra {#11-campi-extra}

campiExtra

Tipo: oggetto indiceMovimento -> indiceColonnaCSV

Copia il contenuto di una colonna CSV in un campo specifico del movimento. Funzione avanzata e raramente necessaria.

"campiExtra": { "7": 9 }

12. Centralizzato {#12-centralizzato}

centralizzato

Tipo: booleano Default: false

Indica che questo file è gestito centralmente dal repository ufficiale. All’avvio del programma, quando vengono controllati i file di configurazione da GitHub, se un file locale ha centralizzato: true e non e più presente nel repository, viene automaticamente eliminato.

I file creati localmente dall’utente non devono avere centralizzato: true, altrimenti potrebbero essere cancellati involontariamente.

"centralizzato": true

Esempi completi

Esempio 1: Binance Spot - righe separate per ogni lato dello scambio CSV “Date(UTC)”,”OrderNo”,”Pair”,”Type”,”Filled”,”Total”,”Fee”,”Fee Coin”

"2025-03-10 14:22:01","123456","BTCUSDT","BUY","0.01 BTC","620.50 USDT","0.00001","BTC"
"2025-03-10 14:22:01","123456","BTCUSDT","SELL","620.50 USDT","","0.62","USDT"

JSON:

{
"nomeExchange": "Binance", "nomeWallet": "Principale",
"separatore": ",", "formatoData": "yyyy-MM-dd HH:mm:ss", "fuso": "UTC",
"consolidaRigheStessaData": true, "tolleranzaSecondiConsolidamento": 2,
"colonne": {
"data": 0, "idTransazione": 1, "causale": 3,
"moneta": 2, "quantita": 4, "quantitaFee": 6, "monetaFee": 7
},
"mappaCausali": { "BUY": "SCAMBIO CRYPTO-CRYPTO", "SELL": "SCAMBIO CRYPTO-CRYPTO" }
}

Esempio 2: Riga singola per movimento - es. Tatax

CSV:

"Data","Tipo","Asset","Quantita"
"2025-09-15 10:00:00","Deposito","BTC","0.5"
"2025-09-16 11:30:00","Staking","BTC.STAKING@CRYPTO.COM","0.0001"
"2025-09-17 09:00:00","Prelievo","ETH","0.1"

JSON:

{
"nomeExchange": "Crypto.com", "nomeWallet": "Principale",
"separatore": ",", "formatoData": "yyyy-MM-dd HH:mm:ss", "fuso": "UTC",
"consolidaRigheStessaData": false,
"colonne": { "data": 0, "causale": 1, "moneta": 2, "quantita": 3 },
"mappaCausali": {
"Deposito": "TRASFERIMENTO-CRYPTO", "Prelievo": "TRASFERIMENTO-CRYPTO",
"Staking": "STAKING REWARDS"
},
"causaliChiuse": ["TRASFERIMENTO-CRYPTO","STAKING REWARDS"],
"causaliEntrata": ["Deposito","Staking"],
"causaliUscita": ["Prelievo"],
"rimuoviDaNomeMoneta": [".STAKING?",".EARN?","@CRYPTO.COM"],
"rimuoviCaseSensitive": false
}

Esempio 3: Scambio su riga singola - es. CoinTracking

CSV:

"Tipo","Acquisto","Cur.","Vendita","Cur.","Fee","Cur.Fee","Exchange","Data"
"Operazione","2132","CRO","487.04","USDC","1.18","USDC","Crypto.com","17.09.2025 18:39:10"
"Deposito","89.4","CRO","","","","","Crypto.com","28.08.2025 07:38:42"
"Prelievo","","","24.32","USDC","","","Crypto.com","03.09.2025 18:11:09"

JSON:

{
"nomeExchange": "Crypto.com Exchange", "nomeWallet": "Principale",
"separatore": ",", "formatoData": "dd.MM.yyyy HH:mm:ss", "fuso": "UTC",
"colonne": {
"data": 8, "causale": 0, "moneta": 2, "quantita": 1,
"monetaUscita": 4, "quantitaUscita": 3, "quantitaFee": 5, "monetaFee": 6
},
"mappaCausali": {
"Deposito": "TRASFERIMENTO-CRYPTO", "Prelievo": "TRASFERIMENTO-CRYPTO",
"Operazione": "SCAMBIO CRYPTO-CRYPTO"
},
"ricostruisciLordoSeFeeSuMonetaUscita": false,
"ricostruisciLordoSeFeeSuMonetaEntrata": true
}

Esempio 4: Causale composita su più colonne

CSV:

"Date","Category","SubType","Amount","Currency"
"2025-01-10","Trade","Buy","0.005","BTC"
"2025-01-10","Trade","Sell","200","USDT"
"2025-01-11","Earn","Staking","0.0001","ETH"

JSON:

{
"nomeExchange": "Exchange XYZ", "separatore": ",",
"formatoData": "yyyy-MM-dd", "fuso": "UTC",
"consolidaRigheStessaData": true,
"colonne": { "data": 0, "moneta": 4, "quantita": 3, "causale": 1, "causale2": 2 },
"separatoreCausale": ".", "causaliUppercase": false,
"mappaCausali": {
"Trade.Buy": "SCAMBIO CRYPTO-CRYPTO",
"Trade.Sell": "SCAMBIO CRYPTO-CRYPTO",
"Earn.Staking": "STAKING REWARDS"
},
"causaliChiuse": ["STAKING REWARDS"],
"causaliEntrata": [], "causaliUscita": []
}

Checklist rapida

Dove mettere il file

Nella cartella di lavoro del programma si trovano due cartelle di configurazione:

Un file JSON messo in una di queste due cartelle compare nella finestra di importazione insieme agli import nativi, ordinato per fornitore ed estrazione (il vecchio prefisso [JSON] non c’è più: la distinzione è nei campi, non nell’etichetta).

I file creati personalmente vanno lasciati senza centralizzato (o con "centralizzato": false): non verranno mai eliminati automaticamente dall’aggiornamento dal repository remoto.

Torna all’indice della documentazione