Passa ai Correlation Baskets su eToro e rimuove i motori precedenti (4.0.0)
Perché: l'utente ha chiesto un bot che operi cinque basket di coppie forex correlate su eToro, autonomo, con ledger, feed gratuiti e apprendimento costruito da zero, e ha deciso di eliminare tutto ciò che restava delle gestioni precedenti (Binance, cTrader/proba, ricerca con SQLite, GBDT, RL, TA-Lib) e di non avere approvazioni manuali sui singoli ordini. Cosa cambia: - nuovo Core dei basket (cross sintetici, decisore, cost gate, sizing, esecutore leg-risk, backtest con PSR/DSR/PBO, livelli 0-3 di apprendimento), adattatore eToro Public API, motore autonomo con equity stop, kill-switch, riconciliazione, ledger append-only, calendario e notizie con sentiment; - modalità Paper / Demo / Live (Live con flag e frase CONFERMO LIVE); - interfaccia rifatta: barra in alto con tre schede, dashboard con i soli numeri principali, fuso orario selezionabile, test di rendering in PNG; - corretto il parser dei costi eToro (campo "value"): markup e overnight non venivano letti; - strumento di ricerca ridotto a ticks / baskets / falsify con due scenari di costo; risultati in results/ e reports/: nessuna configurazione è profittevole al netto dei costi (docs/STRATEGY.md lo dice con i numeri); - documentazione completa (STRATEGY, ML_AND_LEARNING, RUNBOOK, GLOSSARY, KNOWN_ISSUES, ADR-0004, ADR-0005) e catena di rilascio aggiornata. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+33
-206
@@ -1,225 +1,52 @@
|
||||
{
|
||||
"_comment": "Encelado — arbitraggio statistico su coppie cointegrate, Binance Futures USDⓈ-M. Il bot non prende posizione sulla direzione del mercato: è long una gamba e short l'altra nel rapporto che il test di cointegrazione produce, e scommette solo sul fatto che la distanza fra le due si richiuda.",
|
||||
"_commento": "Configurazione di Encelado — Correlation Baskets su eToro (CFD forex). Le chiavi con il prefisso _ sono documentazione e vengono ignorate. I parametri della strategia (basket, preset, soglie, rischio) stanno in strategy.json accanto a questo file. Le chiavi API non stanno qui: si inseriscono dalla finestra e vivono cifrate in %LOCALAPPDATA%\\Encelado\\etoro.dat, oppure nelle variabili d'ambiente ETORO_API_KEY e ETORO_USER_KEY.",
|
||||
|
||||
"_misura": "IMPORTANTE — che cosa dice il backtest, e perché dryRun parte ATTIVO. Misurato su 6,6 anni di barre da un minuto (2020-2026) di ETHUSDT, BTCUSDT, SOLUSDT e AVAXUSDT, ripiegate su 5m, 15m, 30m, 1h e 4h, con commissione taker 4 bps più 1 bp di slippage per lato. Il risultato: su 5m nessuna combinazione di soglie supera nemmeno i filtri di taratura; su 15m e 1h la ricerca a griglia trova combinazioni che rendono in taratura e in verifica, ma NESSUNA delle prime dieci resta positiva sulla terza fetta, quella che non entra mai nella scelta. Con i valori qui sotto, sulle quattro coppie misurabili, la conferma dà tre risultati negativi e uno positivo del +0,40% su una sola operazione. La ragione di fondo è che il test di cointegrazione passa solo l'8-13% del tempo, quindi in sei anni una coppia produce qualche decina di operazioni: troppo poche per distinguere un margine reale da una serie fortunata. Questi valori sono i meglio supportati fra quelli provati, non una strategia dimostrata: per questo la configurazione di fabbrica punta alla TESTNET, dove gli ordini partono davvero ma i soldi sono finti. Lo strumento è in tools/Encelado.Backtest: 'backtest basket --data <cartella>' rifà la scelta da capo sui tuoi dati.",
|
||||
|
||||
"binance": {
|
||||
"_testnet": "true = testnet (denaro finto, stesse API). Metterlo a false opera con denaro reale. Le chiavi dei due ambienti sono diverse e vengono salvate separatamente.",
|
||||
"testnet": true,
|
||||
|
||||
"_leverage": "Leva applicata a ogni simbolo all'avvio. La guida indica 2x-3x: un libro delta-neutral si liquida comunque se una sola gamba fa un salto isolato abbastanza grande. Alzarla non aumenta il margine della strategia, moltiplica soltanto guadagno e perdita.",
|
||||
"leverage": 2,
|
||||
|
||||
"_marginType": "CROSSED mette le due gambe nello stesso pool di margine, così si compensano invece di avere ciascuna il proprio prezzo di liquidazione.",
|
||||
"marginType": "CROSSED",
|
||||
|
||||
"recvWindowMs": 5000,
|
||||
"requestsPerMinute": 1200,
|
||||
"httpTimeoutSeconds": 10,
|
||||
"maxRetries": 3
|
||||
"etoro": {
|
||||
"_note": "eToro Public API. environment = demo oppure real: chiavi e rotte sono diverse, e l'ambiente attivo è sempre visibile nella finestra.",
|
||||
"environment": "demo",
|
||||
"baseUrl": "https://public-api.etoro.com",
|
||||
"requestTimeoutSeconds": 20,
|
||||
"_fillTimeoutSeconds": "Quanto attendere l'esito di un ordine (eToro lo lavora in modo asincrono) prima di trattarlo come non confermato e riconciliare. È anche il timeout della seconda gamba (leg-risk).",
|
||||
"fillTimeoutSeconds": 5
|
||||
},
|
||||
|
||||
"engine": {
|
||||
"_timeFrame": "15m. La guida indica 5m o 15m; il backtest ha bocciato 5m senza appello — nessuna combinazione di soglie supera nemmeno i filtri di taratura, perché a cinque minuti la commissione vale circa una deviazione standard dello spread. A 15m il numero di operazioni è almeno misurabile. A 1h e 4h le operazioni scendono a poche decine in sei anni: troppo poche per dire alcunché. '1m' è rifiutato dal validatore.",
|
||||
"timeFrame": "15m",
|
||||
|
||||
"_warmupBars": "Barre storiche scaricate all'avvio per riempire la finestra dello z-score prima della prima decisione. Deve coprire zWindow.",
|
||||
"warmupBars": 1500,
|
||||
|
||||
"_calibrationBars": "Su quante barre gira la regressione di cointegrazione che produce beta e p-value. 500 è il valore della guida ed è anche il migliore misurato: a 1000 lo stesso paniere peggiora nettamente su tutte e tre le fette. Questa finestra è indipendente da zWindow, che è molto più lunga: la prima stabilisce il rapporto di copertura, la seconda dice quanto è insolito lo scostamento di adesso.",
|
||||
"calibrationBars": 500,
|
||||
|
||||
"_recalibrateHours": "Ogni quanto l'intero paniere viene rifittato e ritestato. La guida dice 24 ore; provate anche una settimana, senza differenze sostanziali.",
|
||||
"recalibrateHours": 24,
|
||||
|
||||
"_entryOrderType": "'limit' invia un limite marcabile, prezzato oltre il touch di limitOffsetBps: si comporta come un ordine a mercato ma non può eseguire a un prezzo assurdo. 'market' attraversa e basta.",
|
||||
"entryOrderType": "limit",
|
||||
"limitOffsetBps": 2,
|
||||
|
||||
"_postOnly": "Solo maker (GTX). Fa risparmiare la commissione ma un ordine che non esegue lascia una gamba scoperta, che costa molto di più. Lasciare false se non hai misurato il tuo tasso di riempimento.",
|
||||
"postOnlyEntries": false,
|
||||
|
||||
"_dryRun": "Calcola e registra tutto, non invia nessun ordine. Spento di fabbrica: in testnet i soldi sono finti e la prova più vicina alla produzione è quella con gli ordini veri sul conto di prova — eseguiti, rifiutati, parzialmente riempiti, con le stesse regole di lotto e di margine. Accendilo per osservare una configurazione nuova senza toccare nemmeno il conto di prova. Sul conto reale resta comunque la conferma esplicita all'avvio.",
|
||||
"dryRun": false,
|
||||
|
||||
"_reconcile": "Ogni quanto il bot ricontrolla conto, posizioni e ordini contro Binance. È anche quando recupera le barre che lo stream non ha consegnato e chiude le coppie rimaste con una gamba sola.",
|
||||
"reconcileSeconds": 20,
|
||||
"run": {
|
||||
"_executionMode": "Paper = simulatore locale sopra le quotazioni reali (nessun ordine sul conto). Demo = conto demo di eToro: ordini veri, denaro virtuale, il bot apre e chiude da solo. Live = conto reale: richiede allowLive = true e la frase CONFERMO LIVE a ogni avvio. Nessuna modalità chiede l'approvazione dei singoli ordini (decisione D-20).",
|
||||
"executionMode": "Demo",
|
||||
"allowLive": false,
|
||||
"_pollSeconds": "Secondi fra due letture delle quotazioni (una richiesta per tutti gli strumenti). 3 s = 20 richieste al minuto su una quota di 120: resta spazio per candele e costi.",
|
||||
"pollSeconds": 3,
|
||||
"_statusSeconds": "Ogni quanti secondi il bot scrive una riga di stato nel log (e sulla console in headless).",
|
||||
"statusSeconds": 60,
|
||||
|
||||
"_explain": "Ogni quanto il bot rilegge cosa farebbe adesso e lo scrive nel log, se è cambiato. È la riga che distingue un bot che aspetta da uno bloccato.",
|
||||
"explainSeconds": 5,
|
||||
|
||||
"_maxQuoteAge": "Rifiuta un ingresso se il book di una gamba è più vecchio di così. 0 disattiva il controllo.",
|
||||
"maxQuoteAgeSeconds": 15,
|
||||
|
||||
"_closeOnShutdown": "true = fermare il bot chiude i basket aperti a mercato. false = restano sul conto con gli stop nativi sul server, senza nessuno che applichi il take-profit o lo stop di basket finché il bot non riparte.",
|
||||
"closeOnShutdown": false,
|
||||
"logEveryBar": true
|
||||
"strategyFile": "strategy.json",
|
||||
"_cartelle": "Relative alla cartella di questo file: data (mercato, calendario, notizie, ledger, modelli), knowledge (calibrazione, proposte, registri), reports.",
|
||||
"dataDirectory": "data",
|
||||
"knowledgeDirectory": "knowledge",
|
||||
"reportsDirectory": "reports",
|
||||
"_paper": "Solo per executionMode = Paper: saldo iniziale del simulatore e slippage per gamba oltre lo spread reale del momento.",
|
||||
"paperStartingBalance": 10000,
|
||||
"paperSlippagePips": 0.3
|
||||
},
|
||||
|
||||
"risk": {
|
||||
"_stake": "Frazione dell'equity impegnata come MARGINE su una coppia. Con leva 2 il controvalore effettivamente al lavoro è il doppio, diviso fra le due gambe secondo β. Con 4 coppie al 15% il margine totale impegnato arriva al 60% dell'equity.",
|
||||
"stakePct": 0.15,
|
||||
"stakeAmount": 0,
|
||||
|
||||
"_funding": "Una coppia delta-neutral incassa il funding su una gamba e lo paga sull'altra. Quando il netto è a favore la posizione rende per il solo fatto di esistere. 0.12 è il centro dell'intervallo 10-15% indicato dalla guida. 0 disattiva.",
|
||||
"fundingTiltPct": 0.12,
|
||||
"fundingTiltThreshold": 0.0001,
|
||||
|
||||
"_exposure": "Controvalore lordo totale come multiplo dell'equity. Con leva 2 e 4 coppie al 15% si arriva a 1.2×: 2.0 lascia margine senza permettere il raddoppio.",
|
||||
"maxGrossExposurePct": 2.0,
|
||||
"maxOpenPairs": 4,
|
||||
|
||||
"_frequency": "0 = nessun limite. Sono reti contro un difetto, non contro la strategia: un ciclo che riapre la stessa coppia cento volte costa cento volte le commissioni.",
|
||||
"maxTradesPerDay": 40,
|
||||
"maxTradesPerPairPerDay": 8,
|
||||
"minSecondsBetweenEntries": 60,
|
||||
|
||||
"_dailyLoss": "Kill switch giornaliero, non disattivabile. Su futures con leva è l'ultima fermata prima di una liquidazione.",
|
||||
"maxDailyLossPct": 0.06,
|
||||
"maxDailyProfitPct": 0,
|
||||
|
||||
"_spread": "Il book più largo che una gamba può mostrare ed essere comunque entrata. Conta molto più che su un modello direzionale: un giro completo attraversa lo spread QUATTRO volte, quindi un book da 10 bps costa 40 bps contro un rientro che spesso vale meno.",
|
||||
"maxRelativeSpread": 0.0006,
|
||||
|
||||
"_notional": "Controvalore minimo e massimo per gamba, in USDT. Binance ha anche i suoi minimi per simbolo, più stringenti su BTCUSDT.",
|
||||
"minOrderNotional": 25,
|
||||
"maxOrderNotional": 0,
|
||||
|
||||
"_margin": "Rapporto massimo fra margine di mantenimento ed equity oltre il quale non si aprono nuove coppie.",
|
||||
"maxMarginRatio": 0.5,
|
||||
|
||||
"_hedge": "β fuori da [1/5, 5] viene rifiutato: non è una copertura, è una scommessa sulla seconda gamba travestita da copertura.",
|
||||
"maxHedgeRatio": 5.0
|
||||
"ui": {
|
||||
"_timeZone": "Fuso orario con cui la finestra mostra gli orari. 'computer' = quello di Windows; 'UTC'; oppure un id di Windows (es. 'W. Europe Standard Time') o IANA (es. 'Europe/Rome'). Il file di log porta l'offset, il ledger è in UTC: cambiare questo valore non tocca nessun file.",
|
||||
"timeZone": "computer"
|
||||
},
|
||||
|
||||
"logging": {
|
||||
"_level": "trace | debug | info | warn | error | none. Ogni rifiuto che ferma un ordine viene scritto a 'info' o sopra, quindi 'debug' serve per il flusso dati, non per capire perché il bot non ha operato.",
|
||||
"_level": "trace, debug, info, warn, error, none. 'info' basta: ogni rifiuto che impedisce un ordine viene scritto a questo livello o sopra, con il basket e il motivo esatto.",
|
||||
"level": "info",
|
||||
|
||||
"_directory": "Dove salvare tutti gli output. Relativa alla cartella della configurazione (Documenti\\Encelado), oppure un percorso assoluto. Si cambia anche da Impostazioni.",
|
||||
"directory": "logs",
|
||||
|
||||
"console": false,
|
||||
"_directory": "Cartella dei log, relativa a questo file se non è assoluta.",
|
||||
"directory": "logs",
|
||||
"file": "encelado.log",
|
||||
"_rotazione": "Superata maxFileSizeMb il file viene ruotato (encelado.1.log, encelado.2.log…) e ne restano maxFiles.",
|
||||
"maxFileSizeMb": 32,
|
||||
"maxFiles": 10,
|
||||
|
||||
"_analysis": "Tutte le tabelle usano il separatore ; e hanno una colonna motivazione che spiega in italiano il perché della riga. decisions.csv ha una riga per ogni barra valutata con spread, z-score e calibrazione; executions.csv una riga per ogni segnale arrivato agli ordini, con il verdetto del risk engine; trades.csv una riga per ogni evento d'ordine. decisions ed executions si uniscono su decisionId.",
|
||||
"tradeJournal": "trades.csv",
|
||||
"decisionLog": "decisions.csv",
|
||||
"executionLog": "executions.csv",
|
||||
|
||||
"logMarketData": false,
|
||||
"_righe": "statusLines = righe della striscia di attività nella dashboard; bufferedLines = righe tenute in memoria dalla pagina Log (il file su disco resta completo).",
|
||||
"statusLines": 200,
|
||||
"bufferedLines": 5000
|
||||
},
|
||||
|
||||
"storage": {
|
||||
"_note": "Il database locale (SQLite): barre canoniche, dataset, modelli, validazioni, journal e drift. Vuoto = %ProgramData%\\Encelado\\encelado.db, una cartella di sistema separata sia da Documenti (dove sta la configurazione) sia dai dati utente (dove stanno le chiavi).",
|
||||
"enabled": true,
|
||||
"databasePath": ""
|
||||
},
|
||||
|
||||
"ml": {
|
||||
"_note": "Il meta-modello (meta-labeling): un classificatore addestrato sugli esiti dei segnali passati che dice se un ingresso proposto dalla regola statistica ha probabilità di ripagare i costi. Non propone mai operazioni: può solo rifiutarne una o ridurne la size. Si addestra con lo strumento tools/Encelado.Backtest (comandi dataset, train) e vive nel database locale come 'campione' della coppia; senza campione queste voci non fanno nulla.",
|
||||
"enabled": true,
|
||||
"_minProbability": "Sotto questa probabilità predetta l'ingresso viene rifiutato. 0.55 significa: opero solo quando il modello vede un vantaggio, anche piccolo, rispetto a lanciare una moneta.",
|
||||
"minProbability": 0.55,
|
||||
"_sizeByProbability": "Con true la size è proporzionale alla convinzione del modello (2·Φ(z)−1, López de Prado), fra minSizeFraction e 1; con false è tutto o niente.",
|
||||
"sizeByProbability": true,
|
||||
"minSizeFraction": 0.25,
|
||||
"_drift": "Ogni driftCheckBars segnali valutati le feature live vengono confrontate con quelle di addestramento (PSI e Kolmogorov-Smirnov). Una feature con PSI ≥ driftPsiAlert è 'in deriva'; con driftAlertsToSuspend feature in deriva il modello viene sospeso fino alla ricalibrazione successiva e il bot torna alla sola regola statistica. 0 = mai sospendere, solo registrare.",
|
||||
"driftCheckBars": 50,
|
||||
"driftPsiAlert": 0.25,
|
||||
"driftAlertsToSuspend": 3
|
||||
},
|
||||
|
||||
"_pairs": "Il paniere della guida. Ogni coppia si legge come ln(A) − β·ln(B): A è la gamba su cui si misura lo spread, B quella di copertura. Il test di cointegrazione decide da solo, a ogni ricalibrazione, se una coppia è operabile: quelle che non passano restano in elenco e non vengono aperte. Sui dati disponibili passano il test solo l'8-17% del tempo, quindi il bot resta fermo a lungo — è il comportamento previsto.",
|
||||
|
||||
"_parametri": "I valori qui sotto vengono dalla ricerca a griglia (tools/Encelado.Backtest, comando 'basket'), non dalla guida. Le differenze rispetto alla guida sono tre e sono tutte misurate: zWindow 1500 invece di 100, entryZ 2.5 invece di 2.0, stopZ 6.0 invece di 3.5. La prima è la più importante: con una finestra vicina all'emivita del rientro (30-40 barre) la media mobile insegue lo scostamento e lo assorbe, e il margine sparisce prima ancora delle commissioni.",
|
||||
|
||||
"pairs": [
|
||||
{
|
||||
"_note": "Benchmark. È l'unica coppia del paniere risultata positiva sull'intero periodo, ma con sole 35-50 operazioni in 6,6 anni: troppe poche perché il risultato significhi qualcosa.",
|
||||
"symbolA": "ETHUSDT",
|
||||
"symbolB": "BTCUSDT",
|
||||
"enabled": true,
|
||||
"parameters": {
|
||||
"_zWindow": "Finestra mobile su cui si normalizza lo spread. 1500 barre da 15 minuti sono circa 15 giorni. Deve essere molte volte l'emivita del rientro (qui 30-40 barre), altrimenti la media insegue lo scostamento e lo cancella.",
|
||||
"zWindow": 1500,
|
||||
|
||||
"_entryZ": "Quante deviazioni standard di scostamento servono per aprire. 2.5-3.0 ha battuto costantemente 2.0.",
|
||||
"entryZ": 2.5,
|
||||
|
||||
"_exitZ": "Sotto questo valore lo spread è rientrato: si chiude in guadagno.",
|
||||
"exitZ": 0.5,
|
||||
|
||||
"_stopZ": "Stop statistico: non è uno stop di prezzo, è l'affermazione che la relazione ha smesso di valere. 6.0 ha battuto 3.5 e 4.0 — uno stop stretto su uno spread che rientra lentamente realizza perdite che sarebbero rientrate.",
|
||||
"stopZ": 6.0,
|
||||
|
||||
"_maxPValue": "Soglia di cointegrazione. È il filtro che tiene in piedi tutto: senza, ogni combinazione provata passa da leggermente positiva a −73%/−87%.",
|
||||
"maxPValue": 0.05,
|
||||
|
||||
"_halfLife": "Emivita del rientro, in barre. Sotto il minimo lo spread rientra troppo in fretta per ripagare le commissioni; sopra il massimo il capitale resta impegnato più a lungo di quanto duri la relazione.",
|
||||
"minHalfLife": 3,
|
||||
"maxHalfLife": 200,
|
||||
|
||||
"_maxBarsInTrade": "Stop temporale in barre. 0 disattiva: nei test non ha migliorato nulla, ma è la rete contro il caso peggiore — uno spread che si ferma a metà strada e ci resta per giorni.",
|
||||
"maxBarsInTrade": 0,
|
||||
|
||||
"requireCointegration": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"_note": "Layer-1. Verificata sul backtest: negativa sull'intero periodo con questi parametri.",
|
||||
"symbolA": "SOLUSDT",
|
||||
"symbolB": "AVAXUSDT",
|
||||
"enabled": true,
|
||||
"parameters": {
|
||||
"zWindow": 1500,
|
||||
"entryZ": 2.5,
|
||||
"exitZ": 0.5,
|
||||
"stopZ": 6.0,
|
||||
"maxPValue": 0.05,
|
||||
"minHalfLife": 3,
|
||||
"maxHalfLife": 200,
|
||||
"maxBarsInTrade": 0,
|
||||
"requireCointegration": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"_note": "Layer-2 su Ethereum. NON verificata: non avevo dati storici di OP e ARB. È la coppia con le premesse migliori — stesso ecosistema, stessa età, stessi flussi — ma finché non la misuri resta un'ipotesi.",
|
||||
"symbolA": "OPUSDT",
|
||||
"symbolB": "ARBUSDT",
|
||||
"enabled": true,
|
||||
"parameters": {
|
||||
"zWindow": 1500,
|
||||
"entryZ": 2.5,
|
||||
"exitZ": 0.5,
|
||||
"stopZ": 6.0,
|
||||
"maxPValue": 0.05,
|
||||
"minHalfLife": 3,
|
||||
"maxHalfLife": 200,
|
||||
"maxBarsInTrade": 0,
|
||||
"requireCointegration": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"_note": "DeFi blue-chip. NON verificata: non avevo dati storici di LINK e UNI.",
|
||||
"symbolA": "LINKUSDT",
|
||||
"symbolB": "UNIUSDT",
|
||||
"enabled": true,
|
||||
"parameters": {
|
||||
"zWindow": 1500,
|
||||
"entryZ": 2.5,
|
||||
"exitZ": 0.5,
|
||||
"stopZ": 6.0,
|
||||
"maxPValue": 0.05,
|
||||
"minHalfLife": 3,
|
||||
"maxHalfLife": 200,
|
||||
"maxBarsInTrade": 0,
|
||||
"requireCointegration": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"_comment": "Encelado — strategia Correlation Baskets su eToro. Cinque basket di due coppie forex correlate: si entra quando il cross sintetico diverge (z-score), si esce quando converge o al take-profit di basket in pip; lo stop di basket è obbligatorio. Ogni chiave con '_' davanti è documentazione.",
|
||||
|
||||
"_preset": "Conservative | Moderate | Aggressive. Fissa zIn, riskPerBasketPct, maxBaskets, tpPips, maxAdds, zStop; si cambia a caldo dalla finestra senza toccare i basket aperti. Le chiavi omonime qui sotto, se presenti, sovrascrivono il preset.",
|
||||
"preset": "Moderate",
|
||||
|
||||
"_signalMode": "ZScoreSynthetic (default, |z| >= zIn sul cross sintetico) oppure PipDivergence (fedele all'interfaccia Titany: divergenza in pip dall'ancora, dIn).",
|
||||
"signalMode": "ZScoreSynthetic",
|
||||
"_exitMode": "First = la prima fra TP in pip e rientro dello z; FixedPips = solo TP in pip lordi; ZReturn = solo |z| <= zOut.",
|
||||
"exitMode": "First",
|
||||
"_averagingMode": "Off | AddOnce | Grid. Off in live; AddOnce in paper. Moltiplicatore di lotto sempre 1,0 (niente martingala).",
|
||||
"averagingMode": "Off",
|
||||
"tpMode": "Pips",
|
||||
"_sameCrossPolicy": "I basket 4 e 5 sono entrambi EURCAD: Exclusive = uno solo aperto per volta; Half = entrambi a metà size.",
|
||||
"sameCrossPolicy": "Exclusive",
|
||||
"preferDirectCross": false,
|
||||
|
||||
"_indicatori": "Correlazione di Pearson rolling dei rendimenti M15 su window (ρ_W) e windowShort (ρ_20); z-score del cross sintetico su window; half-life OLS ricalcolata ogni halfLifeRecalcHours.",
|
||||
"window": 100,
|
||||
"windowShort": 20,
|
||||
"rhoMin": 0.60,
|
||||
"rhoShortMin": 0.40,
|
||||
"halfLifeMinBars": 4,
|
||||
"halfLifeMaxBars": 96,
|
||||
"halfLifeRecalcHours": 4,
|
||||
"atrPeriod": 14,
|
||||
"ewmaSpan": 100,
|
||||
"trendPeriod": 14,
|
||||
|
||||
"zOut": 0.25,
|
||||
"dIn": 15,
|
||||
"anchorBars": 32,
|
||||
"gridStepZ": 0.75,
|
||||
"lotMultiplier": 1.0,
|
||||
|
||||
"_uscite": "Stop di basket: |z| >= zStop, oppure perdita netta >= maxLossPerBasketPct dell'equity, oppure |ρ_20| < rhoBreak per rhoBreakBars barre, oppure maxHoldingBars barre (96 = 24 h).",
|
||||
"maxLossPerBasketPct": 1.5,
|
||||
"rhoBreak": 0.20,
|
||||
"rhoBreakBars": 8,
|
||||
"maxHoldingBars": 96,
|
||||
"tpAtrMultiple": 1.0,
|
||||
|
||||
"_costGate": "Costo = spread_A + spread_B (in pip-equivalenti di A) + markup e commissioni dell'API + overnight stimato per maxHoldingBars. Entrata solo se TP >= costMultiple × costo e ogni spread <= spreadMedianMultiple × la sua mediana delle ultime 24 h; spread oltre spreadAnomalyMultiple × mediana = chiusura forzata.",
|
||||
"costMultiple": 3,
|
||||
"spreadMedianMultiple": 2,
|
||||
"spreadAnomalyMultiple": 3,
|
||||
"slippagePipsPerLeg": 0.3,
|
||||
"overnightPipsPerDay": 0.3,
|
||||
|
||||
"_calendario": "Nessuna entrata nei blackoutBeforeMin minuti prima e blackoutAfterMin dopo un evento ad alto impatto sulle valute del basket; niente entrate dal venerdì fridayCutoffUtcHour UTC alla riapertura né nei primi openDelayMinutes dopo l'apertura settimanale; sessions = fasce orarie UTC ammesse (vuoto = sempre).",
|
||||
"blackoutBeforeMin": 45,
|
||||
"blackoutAfterMin": 30,
|
||||
"fridayCutoffUtcHour": 20,
|
||||
"openDelayMinutes": 30,
|
||||
"sessions": [],
|
||||
|
||||
"_sizing": "Lotto B = lotto A × (ATR_A × pipValue_A) / (ATR_B × pipValue_B); lotto A tale che la perdita allo stop valga riskPerBasketPct dell'equity; leva effettiva <= maxEffectiveLeverage sul nozionale complessivo; orderLeverage è la leva dichiarata a eToro per ogni gamba (1, 2, 5, 10, 20, 30).",
|
||||
"maxEffectiveLeverage": 10,
|
||||
"orderLeverage": 10,
|
||||
"_volScale": "zIn effettivo = zIn × clamp(σ_prevista / σ_media_30g, volScaleMin, volScaleMax).",
|
||||
"volScaleMin": 0.8,
|
||||
"volScaleMax": 1.5,
|
||||
"volAverageDays": 30,
|
||||
"mlMinProbability": 0.55,
|
||||
|
||||
"_sicurezza": "equityStopPct: perdita dal picco di equity oltre la quale il bot chiude tutto e si blocca (reset manuale con motivazione). dailyLossPct: perdita giornaliera oltre la quale niente nuove entrate fino al giorno dopo.",
|
||||
"equityStopPct": 9,
|
||||
"dailyLossPct": 3,
|
||||
"legTimeoutSec": 5,
|
||||
"clockSkewMaxSeconds": 5,
|
||||
|
||||
"_baskets": "I cinque basket della specifica. Il cross sintetico e il verso delle gambe sono derivati dai codici delle valute, non configurati.",
|
||||
"baskets": [
|
||||
{ "a": "EURUSD", "b": "USDCHF", "enabled": true, "note": "cross sintetico EURCHF" },
|
||||
{ "a": "AUDUSD", "b": "USDCAD", "enabled": true, "note": "cross sintetico AUDCAD" },
|
||||
{ "a": "NZDUSD", "b": "EURNZD", "enabled": true, "note": "cross sintetico EURUSD: replica EURUSD pagando due spread" },
|
||||
{ "a": "USDCAD", "b": "EURUSD", "enabled": true, "note": "cross sintetico EURCAD (stessa esposizione del basket 5)" },
|
||||
{ "a": "EURAUD", "b": "AUDCAD", "enabled": true, "note": "cross sintetico EURCAD (stessa esposizione del basket 4)" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user