Files
Encelado/Encelado/docs/DATA_SOURCES.md
T
Alby96andClaude Fable 5.1 13d64d1830 5.0 Fase 1: registro persistente degli ordini, stati Pending, orfane adottate e chiuse
Un ordine dall'esito ignoto non viene più abbandonato: entra in
data/state/pending_orders.json prima della chiamata HTTP, l'esito si legge per
orderId (il server non registra il referenceId degli ordini v2) e in mancanza
si ricostruisce dalla posizione comparsa sul conto. Una gamba senza esito porta
il basket in PendingA/PendingB invece di rifiutarlo; alla risoluzione parte la
gamba B, ridimensionata sulle unità eseguite, oppure la gamba A viene richiusa.
Ogni posizione del conto è classificata basket / orfana-bot / esterna: le orfane
del bot vengono adottate e chiuse, le esterne contate e mai toccate. Il picco di
equity ignora i movimenti di cassa. Bonifica da headless, orders.jsonl, contatori
in dashboard, bandit che propone e non applica. ADR-0009, test (m)-(q).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-23 10:54:50 +02:00

11 KiB
Raw Blame History

Fonti dei dati

Aggiornato: 2026-09-16. Ogni fonte è stata verificata alla data indicata; se un feed cambia o sparisce, la voce va aggiornata e la decisione annotata in docs/QUESTIONS.md.

1. Mercato

Fonte Cosa Formato Frequenza Limiti Fallback
eToro Public APIGET /api/v2/market-data/rates?instrumentIds=… bid/ask di tutti gli strumenti in una chiamata JSON {results:[{instrumentId,bid,ask,date,quoteType}]} polling ogni run.pollSeconds (3 s) quota condivisa 120/min con le altre rotte di market data; il bot ne usa ~20/min nessuno: senza quote il bot non decide
eToro Public APIGET /api/v1/market-data/instruments/{id}/history/candles/asc/FifteenMinutes/1000 ultime 1000 candele M15 (mid, senza spread) JSON all'avvio, per il riscaldamento e il delta non pagina: niente data di partenza, al massimo ~10 giorni le barre locali salvate a ogni chiusura
eToro Public APIGET /api/v2/market-data/instruments?symbols=…, POST /trading/info/{demo/}eligibility id, nome, esposizione minima, leve, limiti di stop JSON all'avvio, scritti in instruments.json 120/min e 20/min dedicate valori prudenti incorporati (esposizione minima 1000 USD, leve 1-20)
eToro Public APIPOST /trading/info/{demo/}costs markup, spread di mercato, commissione, overnight e weekend per un ordine ipotetico JSON {costs:[{costType, currency, value}]} — il campo è value (verificato il 2026-09-16: EURUSD 10 000 unità → markup 0, marketSpread 0,1 USD, overnightFee 0,91 USD/giorno) ogni 15 minuti per strumento 20/min dedicate markup 0 e overnight da strategy.json
Tick MetaTrader 5A:\Download\Trading\<SYMBOL>_<da>_<a>.csv tick bid/ask 2018-12-12 → 2026-09-15, UTC (verificato sui fine settimana: chiusura venerdì 20:53 estate / 21:57 inverno, riapertura domenica 21:05 / 22:05) tab-separato <DATE> <TIME> <BID> <ASK> <LAST> <VOLUME> <FLAGS>; flag 2 = solo bid, 4 = solo ask, 6 = entrambi una tantum, backtest ticks EURAUD copre solo parte del 2018, del 2021 e del 2026 (39 615 barre contro ~192 000 delle altre): il basket EURAUD/AUDCAD è misurabile solo su quei tratti
Barre M15 derivate — Documenti\Encelado\data\market\candles_<SYMBOL>_M15.csv OHLC bid e ask, spread medio, numero di tick, provenienza CSV ; (schema in docs/LEDGER_SCHEMA.md) scritte dallo strumento e aggiornate dal bot a ogni barra chiusa

Qualità (data/market/data_quality.csv, generato da backtest ticks, e reports/data_quality.csv dal bot): buchi > 1 h nei giorni feriali, salti > 2 % fra barre, duplicati. Una barra sospetta sospende le decisioni sul basket coinvolto per quella barra.

1.1 Ordini e posizioni (rotte verificate il 2026-09-23 sull'OpenAPI v1.379.0 e con chiamate reali sul conto demo)

Rotta Uso Note verificate
POST api/v2/trading/execution/{demo/}orders invio dell'ordine (action open, transaction buy/sellShort, orderType mkt, units, leverage, stopLossRate) risponde 200 con orderId; il server lavora l'ordine in modo asincrono. Non registra l'x-request-id come riferimento: la lettura per orderId di un ordine del bot mostra referenceID = 00000000-0000-0000-0000-000000000000. Quota 20/min condivisa con chiusure e cancellazioni.
GET api/v2/trading/info/{demo/}orders:lookup?orderId=<id> esito dell'ordine, con le posizioni prodotte (positionExecutions[].positionId, openingData.avgPrice, units, executionTime, fees) è la chiave usata dal bot. requestedUnits/requestedAmount possono differire dalle unità inviate: il 2026-09-16 il server ha ridotto gli ordini a 2 000 USD di margine (frozenAmount 2000, unità a sei decimali ricalcolate). Quota 60/min condivisa con close-orders/{id} e orders/{id}.
GET api/v2/trading/info/{demo/}orders:lookup?referenceId=<x-request-id> ripiego quando la risposta al POST è andata persa 404 per gli ordini v2 del bot (vedi sopra).
GET api/v1/trading/info/{demo/}orders/{orderId} ripiego per orderId con la risposta v1 (statusID, errorCode, positions[] {positionID, rate, units, occurred, isOpen}) verificato con l'ordine 381739181.
DELETE api/v2/trading/execution/{demo/}orders/{orderId} cancellazione di un ordine non ancora eseguito (kill-switch) 200 = richiesta accettata, non annullamento avvenuto: confermare con il lookup (7 o 9 = annullato, 6 = in corso). Idempotente su ordini già chiusi.
GET api/v1/trading/info/{demo/}pnl conto e posizioni in una chiamata: clientPortfolio.credit, bonusCredit, unrealizedPnL, positions[] {positionID, instrumentID, isBuy, units, openRate, openDateTime, amount (margine), leverage, unrealizedPnL.pnL, totalFees} equity = credit + bonus + Σ amount + unrealized; available = credit + bonus; usedMargin = Σ amount. Il conto demo non compare in api/v1/balances (solo i conti reali).
GET api/v1/trading/info/trade/{demo/}history?minDate=…&page=…&pageSize=200 posizioni chiuse: positionId, orderId, openRate, closeRate, openTime, closeTime, netProfit, fees, investment netProfit non include fees. Fonte del realizzato della scheda Storico e della distinzione fra chiusure e movimenti di cassa.

Stati dell'ordine (status.id / statusID): 1 Received, 2 Placed, 3 Filled, 4 Rejected, 5 PartiallyFilled, 6 PendingCancel, 7 Canceled, 8 Expired, 9 CanceledPartiallyFilled, 10 RejectedPartiallyFilled, 11 WaitingForMarket, 12 PendingTriggeredRate. Il bot tratta 3 e 5 come eseguito, 4, 7, 8, 9, 10 come rifiutato/annullato, 1, 2, 6, 11, 12 come in corso; in assenza di risposta lo stato è Unknown e l'ordine resta nel registro. Esiste anche POST api/v3/trading/execution/{demo/}orders (202, stessa semantica, settlementType obbligatorio): non usato, annotato per il futuro.

2. Calendario economico

Fonte URL Formato Aggiornamento Note
Forex Factory via FairEconomy https://nfs.faireconomy.media/ff_calendar_thisweek.json JSON [{title,country,date,impact,forecast,previous,actual}], date con offset (ora di New York) il feed cambia più volte al giorno; il bot lo rilegge ogni 10 minuti, mai più di una richiesta al minuto country è già il codice valuta (USD, EUR, GBP, JPY, AUD, NZD, CAD, CHF, CNY, All); impact ∈ {High, Medium, Low, Holiday}
variante XML https://nfs.faireconomy.media/ff_calendar_thisweek.xml <weeklyevents><event> con date MM-DD-YYYY e time 8:15am in UTC (verificato contro il JSON: "10:30pm" del 09-13 = "18:30-04:00") idem usata solo come riserva

Archivio: data/calendar/events.jsonl (append-only, una riga per evento, dedup per title+date+country; un actual che arriva dopo la pubblicazione è una riga nuova). Feature derivate per ogni valuta: minutesToNextHigh, minutesSinceLastHigh, surpriseLast = (actual forecast)/|forecast|.

Limite: il feed copre la settimana corrente. Non esiste uno storico gratuito: il backtest non applica il blackout né le feature di calendario, e lo dice (docs/STRATEGY.md).

3. Notizie (RSS)

Tutte lette con User-Agent: Encelado/4.0 (+correlation baskets; contact: operator), al massimo una richiesta al minuto per fonte, con backoff esponenziale sugli errori e rispetto di robots.txt (gruppo User-agent: *). Verifica del 2026-09-16:

Fonte URL Formato Esito
FXStreet https://www.fxstreet.com/rss/news RSS 2.0 200
ForexLive https://www.forexlive.com/feed/ RSS 2.0 200
Federal Reserve https://www.federalreserve.gov/feeds/press_all.xml RSS 2.0 200 con lo User-Agent del bot; con uno User-Agent minimale risponde con una pagina HTML "not found"
BCE https://www.ecb.europa.eu/rss/press.html RSS 2.0 200
Bank of England https://www.bankofengland.co.uk/rss/news RSS 2.0 200
RBA https://www.rba.gov.au/rss/rss-cb-media-releases.xml RSS 1.0 (RDF) 200 alla prima verifica, poi "Access Denied" (Akamai) a richieste successive: tenuta con backoff, coperta anche da Google News "Reserve Bank of Australia"
Bank of Canada https://www.bankofcanada.ca/content_type/press-releases/feed/ RSS 1.0 (RDF) 200
SNB https://www.snb.ch/en/rss/press-releases 404: omessa (D-08); coperta da Google News "Swiss National Bank"
RBNZ https://www.rbnz.govt.nz/rss/news 403 "website unavailable": omessa (D-08); coperta da Google News RBNZ
Google News https://news.google.com/rss/search?q=<query>&hl=en-US&gl=US&ceid=US:en per EURUSD, "Swiss National Bank", RBNZ, forex dollar RSS 2.0 200

Archivio: data/news/news_YYYYMM.jsonl (append-only, una riga per item, dedup per hash(link)), con published, source, title, summary, link, currencies, scores{net, hawkish, riskOff}.

Sentiment senza librerie (Encelado.Core/News/SentimentLexicon.cs, SentimentEngine.cs): lessico incorporato in tre dimensioni (tono positivo/negativo ~180 termini ciascuno, hawkish/dovish ~80, risk-on/risk-off ~50), negazione a finestra di tre parole, attribuzione alle valute per entità (Fed, Powell, FOMC → USD; ECB, Lagarde → EUR; BoJ → JPY; RBA → AUD; RBNZ → NZD; BoC → CAD; SNB → CHF; BoE → GBP), parole-paese e nomi di coppia. Per ogni valuta e finestra (1 h, 4 h, 24 h): netSentiment, hawkishScore, riskOff (globale), newsCount, con decadimento esponenziale a emivita 2 h. Le feature di un basket sono le differenze fra le sue due valute non comuni.

Copie dei feed usate dai test: tests/fixtures/ (scaricate il 2026-09-16).

4. Schema dei file in Documenti\Encelado

encelado.json, strategy.json, instruments.json
data/market/candles_<SYMBOL>_M15.csv     timeUtc;bidOpen;bidHigh;bidLow;bidClose;askOpen;askHigh;askLow;askClose;spreadMean;ticks;motivazione
data/market/data_quality.csv             simbolo;tick_letti;tick_scartati;barre;prima_barra;ultima_barra;buchi_feriali_oltre_1h;barre_spike;spread_mediano_pip;motivazione
data/calendar/events.jsonl               {title,country,date,impact,forecast,previous,actual}
data/news/news_YYYYMM.jsonl              {hash,published,source,title,summary,link,currencies[],scores{net,hawkish,riskOff}}
data/cache/<fonte>.xml|json              ultimo corpo buono di ogni feed
data/ledger/decisions.jsonl              vedi docs/LEDGER_SCHEMA.md (rotazione mensile in decisions_YYYYMM.jsonl)
data/ledger/baskets.csv                  vedi docs/LEDGER_SCHEMA.md
data/ledger/orders.jsonl                 una riga per ordine inviato e per cambio di stato (5.0)
data/state/baskets_state.json            posizioni aperte, ingressi in attesa, picco di equity al netto dei movimenti di cassa, blocchi
data/state/pending_orders.json           il registro degli ordini (5.0)
data/state/paper_state.json              il conto del simulatore (solo Paper)
data/models/*.json                       modelli (livelli 1-3) e stato del bandit
knowledge/*.csv, *.md                    calibrazione, proposte, registri, insight settimanali
reports/*.csv                            qualità dati, falsificazione, bonifica_YYYYMMDD (5.0)
logs/encelado.log                        log applicativo (;)