Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f4ec58440a | |||
| 7d329a0591 | |||
| 0187cb6bd7 | |||
| 58ed32ff3b | |||
| 375dbf1dc3 | |||
| 4084008642 | |||
| fe10be5ecc | |||
| d441454767 | |||
| 19c2e0ac72 | |||
| 2070d44ce6 | |||
| fe7af9b8e0 | |||
| ff8aa9fcfb | |||
| e8bf23f987 | |||
| a21fd7519e | |||
| 8e17edd4ae | |||
| 01907379e2 | |||
| 721c7965e8 | |||
| 3c271745e1 | |||
| b0012bf2fd | |||
| a1023b573e | |||
| cf3525f7af | |||
| 884354d67e | |||
| 41a2324b0d | |||
| 5cee3f06fd | |||
| f930e88592 | |||
| 908d0e9187 | |||
| 64dc36b1c3 | |||
| 8e6fe91b70 | |||
| a6f6c0510b | |||
| 20315441a5 | |||
| f1d1a2230f | |||
| 4a590b805a | |||
| b79cf56412 | |||
| b45039f91f | |||
| ae7551ef9d | |||
| 2c32e233e6 | |||
| 03e1b290b5 |
@@ -0,0 +1,3 @@
|
||||
data/*.csv
|
||||
scripts/__pycache__/
|
||||
*.pyc
|
||||
@@ -0,0 +1,129 @@
|
||||
# PaPP v2 — Analisi dei pattern di incrocio
|
||||
|
||||
Questa cartella contiene l'analisi statistica di **cosa succede dopo che due linee
|
||||
si incrociano** (le 9 linee del sistema: prezzo, Mediana, 7 MA), gli script per
|
||||
riprodurla e i risultati.
|
||||
|
||||
Risultati di riferimento: **EURUSD D1, dal 1999** (l'euro reale esiste dal 1999;
|
||||
i dati pre-1999 forniti dal broker sono sintetici e vengono esclusi).
|
||||
|
||||
---
|
||||
|
||||
## 1. Da dove vengono i dati
|
||||
|
||||
I dati sono generati in MetaTrader dallo script `PaPP v2/PaPP_CrossExport.mq5`,
|
||||
ancorato a **D1** esattamente come l'indicatore. Produce due file:
|
||||
|
||||
| file | contenuto |
|
||||
|---|---|
|
||||
| `PaPP_crosses_<SYM>_D1.csv` | un record per **ogni incrocio** tra le 9 linee |
|
||||
| `PaPP_bars_<SYM>_D1.csv` | un record per **ogni giorno D1** (la *baseline*) |
|
||||
|
||||
Per ogni record sono salvati:
|
||||
- **contesto** al momento dell'evento: distanza dalla Mediana, ampiezza del
|
||||
cluster, trend (sopra/sotto MA365), e le metriche **velocita' / accelerazione /
|
||||
volatilita'** calcolate come **mediana delle 7 scale** (no ATR di MetaTrader);
|
||||
- **esiti futuri** a 1/3/5/10/20 giorni: rendimento, max favorevole/avverso,
|
||||
ritorno alla Mediana, e la **traiettoria completa** `cret_1 … cret_20`
|
||||
(rendimento cumulato giorno per giorno, **in percentuale**).
|
||||
|
||||
Le 36 coppie sono tutte le combinazioni delle 9 linee; ogni coppia ha 2 direzioni
|
||||
(`dir=+1` la 1a linea passa sopra la 2a, `dir=-1` sotto) → 72 casi.
|
||||
|
||||
---
|
||||
|
||||
## 2. Le 3 correzioni metodologiche (perche' l'analisi e' "onesta")
|
||||
|
||||
Una media grezza dei rendimenti dopo un incrocio e' fuorviante. Abbiamo corretto
|
||||
i tre problemi tipici:
|
||||
|
||||
### 2.1 Bias di periodo → confronto con una baseline nello stesso regime
|
||||
Non confrontiamo il rendimento post-incrocio con **zero**, ma con quello di un
|
||||
**giorno qualunque nello stesso regime di mercato**. Il regime e' definito da:
|
||||
`trend (sopra/sotto MA365) × tercile del cluster × tercile della velocita'`.
|
||||
|
||||
`extra-rendimento = rendimento dopo l'incrocio − rendimento medio della baseline
|
||||
nello stesso regime`
|
||||
|
||||
Se l'extra e' ~0, l'incrocio non aggiunge nulla oltre al contesto.
|
||||
(Su EURUSD il drift di fondo della baseline e' risultato ~0, quindi non c'era un
|
||||
bias rialzista che gonfiava i numeri.)
|
||||
|
||||
### 2.2 "Movimenti piccoli" → effetto in unita' di volatilita'
|
||||
L'extra-rendimento e' espresso anche come **frazione della deviazione standard**
|
||||
del movimento tipico a quell'orizzonte (`eff = extra / sd_baseline_h`), cosi' un
|
||||
+0.3% pesa diversamente a 5 o a 20 giorni.
|
||||
|
||||
### 2.3 Finestre sovrapposte + tanti test → bootstrap a blocchi + multi-test
|
||||
- Gli eventi vicini condividono il futuro (autocorrelazione) → la significativita'
|
||||
e' calcolata con **block bootstrap** (blocchi temporali di 20 giorni), non con il
|
||||
t-test classico.
|
||||
- Testiamo 72 casi × 5 orizzonti → alcuni "vincono" per fortuna. Applichiamo la
|
||||
correzione **Benjamini-Hochberg** (`q-value`): consideriamo robusti solo i casi
|
||||
con `q < 0.10`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Verifiche di correttezza
|
||||
|
||||
Lo script `full_table.py` esegue 4 controlli automatici:
|
||||
- **V1** la direzione registrata coincide col segno di (A−B) all'incrocio (~99.9%);
|
||||
- **V2** `cret_1` coincide esattamente con `ret_1` (differenza 0);
|
||||
- **V3** ricalcolo indipendente della media di un pattern (combacia col summary);
|
||||
- **V4** la baseline ha drift ~0 (atteso su FX).
|
||||
|
||||
---
|
||||
|
||||
## 4. Come riprodurre
|
||||
|
||||
```bash
|
||||
# 1) genera i due CSV da MetaTrader (PaPP_CrossExport.mq5) e copiali in ./data
|
||||
# 2) dalla cartella scripts:
|
||||
cd scripts
|
||||
python excess_analysis.py EURUSD 1999 # summary + top per orizzonte
|
||||
python full_table.py EURUSD 1999 # verifiche + tabella 72 casi
|
||||
python plot_trajectories.py EURUSD 1999 # grafico traiettorie extra-rendimento
|
||||
```
|
||||
Dipendenze: `pandas`, `numpy`, `matplotlib`. I risultati finiscono in `./results`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Risultati principali (EURUSD, 1999+)
|
||||
|
||||
**A) Mean-reversion (il segnale piu' robusto, vale per quasi tutte le coppie):**
|
||||
dopo un incrocio il prezzo torna a toccare la Mediana entro 20 giorni nel
|
||||
**77–94%** dei casi, in **2–4 giorni** mediani.
|
||||
|
||||
**B) Edge direzionali significativi (q<0.10), legati alle scale lunghe:**
|
||||
- SALGONO: `MA365xMA7 +`, `MA365xMA182 ±`, `MA365xMA121 −`, `MA121xMA7 +`,
|
||||
`MA121xMA3 +`, `PRICExMA121 −`;
|
||||
- SCENDONO: `MA182xMA30 +`, `MA365xMA121 +` (forte a 20g);
|
||||
- gli incroci tra MA cortissime e prezzo↔MA brevi sono **neutri** (rumore).
|
||||
|
||||
**Lettura onesta:** gli edge direzionali sono **reali ma modesti** (~0.1–0.3 sigma,
|
||||
+0.2–0.5% di extra, 55–59% di probabilita' di battere la baseline). Il tema
|
||||
ricorrente e' la **MA121 (semestrale)**. I casi con pochi campioni (n<40) vanno
|
||||
trattati con cautela anche se "significativi".
|
||||
|
||||
Vedi `results/tabella_incroci_EURUSD_1999.md` per la tabella completa dei 72 casi.
|
||||
|
||||
---
|
||||
|
||||
## 6. Contenuto della cartella
|
||||
|
||||
```
|
||||
Analisi/
|
||||
├── README.md questo documento
|
||||
├── scripts/
|
||||
│ ├── _common.py utility (load, regime, bootstrap, BH)
|
||||
│ ├── excess_analysis.py extra-rendimento + significativita'
|
||||
│ ├── full_table.py verifiche + tabella 72 casi
|
||||
│ └── plot_trajectories.py grafico traiettorie
|
||||
├── results/
|
||||
│ ├── summary_EURUSD_1999.csv
|
||||
│ ├── tabella_incroci_EURUSD_1999.csv
|
||||
│ ├── tabella_incroci_EURUSD_1999.md
|
||||
│ └── trajectories_EURUSD_1999.png
|
||||
└── data/
|
||||
└── README.md dove mettere i CSV di input (non versionati)
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
# Dati di input
|
||||
|
||||
Gli script in `../scripts` leggono da questa cartella i due CSV prodotti dallo
|
||||
script MQL5 `PaPP v2/PaPP_CrossExport.mq5` (eseguito in MetaTrader):
|
||||
|
||||
- `PaPP_crosses_<SYMBOL>_D1.csv` — un record per **incrocio** tra le 9 linee
|
||||
(prezzo, Mediana, 7 MA), con contesto + esiti futuri.
|
||||
- `PaPP_bars_<SYMBOL>_D1.csv` — un record per **ogni giorno D1** (baseline),
|
||||
con lo stesso regime e la traiettoria `cret_1..20`.
|
||||
|
||||
I file dati **non sono versionati** (sono grandi e dipendono dal broker).
|
||||
Per riprodurre l'analisi: genera i due CSV da MetaTrader e copiali qui, poi
|
||||
lancia gli script (vedi `../README.md`).
|
||||
@@ -0,0 +1,65 @@
|
||||
pair,dir,n,raw_1,exc_1,eff_1,pos_1,p_1,raw_3,exc_3,eff_3,pos_3,p_3,raw_5,exc_5,eff_5,pos_5,p_5,raw_10,exc_10,eff_10,pos_10,p_10,raw_20,exc_20,eff_20,pos_20,p_20,q_1,q_3,q_5,q_10,q_20
|
||||
MA121xMA14,-1,73,0.08883123287671232,0.0738440967816724,0.1268396325759725,0.5342465753424658,0.077,0.1377391780821918,0.10205717603308966,0.1030845124068534,0.4931506849315068,0.237,0.13806506849315067,0.09286285233037742,0.07319339008513785,0.547945205479452,0.375,0.12088643835616443,0.019819180009174625,0.011012627551783014,0.4520547945205479,0.923,-0.061453287671232926,-0.2486090503677838,-0.09775445144285876,0.410958904109589,0.264,0.4106666666666667,0.6067199999999999,0.7228235294117648,0.9527741935483871,0.6214193548387097
|
||||
MA121xMA14,1,73,0.08970109589041095,0.08841645476774412,0.1518701037073849,0.6164383561643836,0.183,0.171722602739726,0.1640382872092089,0.16568954296299623,0.5205479452054794,0.007,0.1471627397260274,0.13240461945271742,0.10435973823202067,0.547945205479452,0.138,0.16662917808219183,0.1383347923764789,0.07686642662260364,0.547945205479452,0.029,0.2644176712328766,0.2490256435298178,0.09791825817462992,0.547945205479452,0.074,0.732,0.07466666666666667,0.6308571428571429,0.2651428571428572,0.6214193548387097
|
||||
MA121xMA3,-1,117,0.05220358974358977,0.04398986786725697,0.07555998272746543,0.42735042735042733,0.304,0.04510350427350427,0.01416661259177849,0.014309217717397828,0.48717948717948717,0.871,0.06861871794871795,0.021877594054191637,0.01724365809953614,0.49572649572649574,0.917,0.2250457264957265,0.13531015620709289,0.07518577224650531,0.5213675213675214,0.218,0.09543794871794872,-0.053395235693741994,-0.020995301527366637,0.452991452991453,0.734,0.8202105263157895,0.9779649122807017,0.9406984126984127,0.6678260869565217,0.8936727272727273
|
||||
MA121xMA3,1,117,-0.03262435897435896,-0.03502834140056345,-0.06016705663188382,0.5384615384615384,0.393,0.1085807692307692,0.09438643424690306,0.09533655476621142,0.5042735042735043,0.15,0.16597222222222224,0.13826618338430888,0.10897975285129598,0.5042735042735043,0.164,0.2847652991452991,0.23515049270743255,0.13066255988423547,0.5897435897435898,0.003,0.22466495726495722,0.13930786769167774,0.05477662284509896,0.49572649572649574,0.375,0.8202105263157895,0.4896,0.6684444444444444,0.048,0.6666666666666666
|
||||
MA121xMA30,-1,52,-0.020661538461538457,-0.0237911422942284,-0.040865280756085726,0.4807692307692308,0.831,-0.07388230769230766,-0.07690927545575411,-0.07768346595588999,0.5576923076923077,0.721,-0.12157519230769233,-0.114888060239567,-0.09055339566054517,0.4423076923076923,0.707,-0.27518923076923074,-0.3105672292466324,-0.17256825074998694,0.4807692307692308,0.43,-0.3224990384615384,-0.42409334989842495,-0.16675584705606972,0.46153846153846156,0.296,0.9467936507936509,0.9228799999999999,0.8872156862745098,0.833939393939394,0.6214193548387097
|
||||
MA121xMA30,1,53,0.08432094339622644,0.08607884816227486,0.1478548719438829,0.6415094339622641,0.022,0.0901020754716981,0.08913430535697553,0.09003155646270568,0.5471698113207547,0.091,0.09538396226415095,0.08448989403948784,0.06659392445413015,0.5660377358490566,0.307,-0.029476415094339632,-0.0497229199320908,-0.027628791793896622,0.41509433962264153,0.696,-0.012036037735849067,-0.03067699468685477,-0.012062363711589094,0.5660377358490566,0.847,0.2773333333333333,0.416,0.7228235294117648,0.9474098360655738,0.9346206896551724
|
||||
MA121xMA7,-1,88,0.07495238636363637,0.06364985841309972,0.10932931685114719,0.48863636363636365,0.281,0.07764045454545455,0.043606296058068095,0.044045249356668474,0.4318181818181818,0.685,0.10674397727272728,0.06296209107771732,0.049625967512090224,0.45454545454545453,0.68,0.11821409090909088,0.025940150893838124,0.014413775963417735,0.48863636363636365,0.748,0.1481702272727273,-0.01654939020211934,-0.006507311614475473,0.45454545454545453,0.945,0.8202105263157895,0.9228799999999999,0.8844799999999999,0.9474098360655738,0.9782857142857142
|
||||
MA121xMA7,1,88,0.06656613636363636,0.06872677868019474,0.11804977968245185,0.5795454545454546,0.197,0.15830397727272727,0.15216329709975998,0.15369501584741296,0.5795454545454546,0.018,0.2576479545454546,0.239825884966136,0.18902789555062602,0.5454545454545454,0.001,0.3227229545454545,0.2991385847331414,0.16621786665788313,0.5681818181818182,0.001,0.19040772727272728,0.15980304007422197,0.06283543780182936,0.5227272727272727,0.389,0.7416470588235294,0.16457142857142856,0.010666666666666666,0.021333333333333333,0.6728648648648649
|
||||
MA14xMA3,-1,413,0.018732493946731234,0.019495711743007522,0.0334871577020072,0.4891041162227603,0.466,0.05811405339805826,0.05033597672560418,0.05084267289150997,0.5084745762711864,0.062,0.022634417475728145,0.004728052246124062,0.0037265942592662146,0.4963680387409201,0.297,-0.02661601941747573,-0.027830847621834614,-0.01546435115720282,0.47699757869249393,0.283,-0.004355085158150855,-0.022630394656332584,-0.008898396145645172,0.4745762711864407,0.3,0.8202105263157895,0.33066666666666666,0.7228235294117648,0.6966153846153845,0.6214193548387097
|
||||
MA14xMA3,1,412,-0.003732427184466025,-0.0042915657702153115,-0.007371484643913094,0.4878640776699029,0.878,-0.03452007281553398,-0.03988291933152033,-0.04028439206782132,0.4975728155339806,0.264,-0.04675264563106798,-0.0575933632259271,-0.04539440039934409,0.46359223300970875,0.3,0.009159538834951474,0.011765943826390329,0.006537806160257662,0.5218446601941747,0.868,-0.05554092457420925,-0.06562692404933614,-0.025804868933107607,0.470873786407767,0.25,0.9467936507936509,0.6352592592592593,0.7228235294117648,0.9474098360655738,0.6214193548387097
|
||||
MA14xMA7,-1,383,0.003936057441253264,0.0020882087632935874,0.003586849102660063,0.4908616187989556,0.932,0.017638219895287948,0.01082872489342116,0.010937729898232244,0.5013054830287206,0.268,0.023900732984293183,0.011324957744819978,0.00892619631115032,0.4804177545691906,0.26,-0.054068979057591615,-0.06435243929014356,-0.035757758172790935,0.4699738903394256,0.151,0.05511498687664045,0.016967571614375454,0.006671742855004413,0.4830287206266319,0.248,0.9467936507936509,0.6352592592592593,0.7228235294117648,0.6678260869565217,0.6214193548387097
|
||||
MA14xMA7,1,382,-0.0006903926701570699,0.0018220445243756229,0.003129667340805309,0.4869109947643979,0.931,-0.022581282722513082,-0.025758127076624282,-0.02601741566263479,0.4581151832460733,0.551,0.010029188481675414,-0.0001709152586449735,-0.0001347133636709491,0.4790575916230366,0.99,0.020934383202099727,0.024244274020344084,0.013471453406539668,0.5,0.224,0.0999728083989501,0.09411047957551737,0.03700476025438057,0.4973821989528796,0.134,0.9467936507936509,0.9144888888888889,0.99,0.6678260869565217,0.6214193548387097
|
||||
MA182xMA121,-1,30,-0.07841333333333335,-0.07979096882524894,-0.13705438362389624,0.4,0.381,-0.13186333333333336,-0.13923038014068193,-0.14063191249157805,0.5,0.211,-0.20915666666666669,-0.2250881162338893,-0.17741176241736653,0.43333333333333335,0.0,-0.12362599999999999,-0.17644799079844736,-0.0980442179759313,0.5,0.417,0.41436733333333337,0.33319840545603613,0.13101545297246694,0.4666666666666667,0.204,0.8202105263157895,0.5973333333333334,0.0,0.833939393939394,0.6214193548387097
|
||||
MA182xMA121,1,31,0.005469354838709664,0.005930804715525939,0.01018715271474295,0.5483870967741935,0.883,-0.17420967741935484,-0.1661471549215242,-0.16781963913363782,0.5483870967741935,0.153,-0.3184922580645161,-0.31420679972467563,-0.24765404338251065,0.3548387096774194,0.046,-0.34026225806451604,-0.33899465157276687,-0.1883640916571304,0.3548387096774194,0.021,-0.46702466666666675,-0.4624251636271663,-0.18182812788542654,0.3870967741935484,0.0,0.9467936507936509,0.4896,0.32711111111111113,0.224,0.0
|
||||
MA182xMA14,-1,46,0.15412304347826086,0.14217416973434086,0.2442080035756289,0.5,0.0,0.2857415217391305,0.2571233697039764,0.2597116462025928,0.5869565217391305,0.0,0.2071847826086957,0.171448060576255,0.13513331178384638,0.5217391304347826,0.325,-0.09928499999999998,-0.20905151224177224,-0.11616052946640151,0.41304347826086957,0.427,0.14800260869565224,-0.07458470946041838,-0.029327119622323313,0.43478260869565216,0.804,0.0,0.0,0.7228235294117648,0.833939393939394,0.9083508771929825
|
||||
MA182xMA14,1,47,0.02657595744680852,0.027371215978263932,0.0470146583024122,0.5106382978723404,0.691,0.01741063829787233,0.004927755680655171,0.004977359861845885,0.5531914893617021,0.998,0.0006495744680851034,-0.022737164244711856,-0.01792116104803993,0.44680851063829785,0.884,-0.022737234042553203,-0.05318987605447526,-0.029555223487665976,0.425531914893617,0.689,-0.048247872340425546,-0.06350047154634395,-0.024968736066497244,0.425531914893617,0.762,0.9422978723404255,0.999,0.9406984126984127,0.9474098360655738,0.8936727272727273
|
||||
MA182xMA3,-1,85,-0.09941294117647062,-0.10679718080176766,-0.18344208627937292,0.4470588235294118,0.05,0.05273082352941179,0.02606567006587443,0.026328054466521728,0.49411764705882355,0.704,0.15997435294117648,0.11817045873361055,0.09314054291437561,0.5294117647058824,0.093,0.0777025882352941,-0.008570515770733375,-0.004762250409253931,0.5058823529411764,0.894,-0.1411765882352941,-0.29043387357038863,-0.11420020288600495,0.43529411764705883,0.232,0.35555555555555557,0.9228799999999999,0.496,0.9474098360655738,0.6214193548387097
|
||||
MA182xMA3,1,86,0.0698374418604651,0.0700915914742381,0.1203940747700236,0.5232558139534884,0.399,-0.005633953488372075,-0.014586499381746465,-0.014733331206447278,0.45348837209302323,0.852,0.04616872093023254,0.01856945567260769,0.01463622297405181,0.47674418604651164,0.885,0.15744883720930233,0.09773602792407764,0.054307517940716026,0.5465116279069767,0.561,-0.14362348837209307,-0.21674959256674572,-0.08522713670512076,0.4418604651162791,0.478,0.8202105263157895,0.9779649122807017,0.9406984126984127,0.9474098360655738,0.7438222222222223
|
||||
MA182xMA30,-1,35,0.000345142857142874,-0.00639372195911028,-0.010982290791425238,0.45714285714285713,0.886,-0.24531428571428568,-0.26509787608500746,-0.2677664262183302,0.34285714285714286,0.004,-0.3593151428571428,-0.3857562050012093,-0.30404842928973563,0.37142857142857144,0.013,-0.2841117142857143,-0.37521814952454474,-0.20849186139235856,0.42857142857142855,0.12,0.06680142857142857,-0.12502296447058353,-0.04915972001623338,0.45714285714285713,0.506,0.9467936507936509,0.0512,0.11885714285714286,0.64,0.7438222222222223
|
||||
MA182xMA30,1,36,-0.048224722222222224,-0.04621714866274137,-0.07938571139170819,0.5,0.373,-0.1100925,-0.11774658475991877,-0.11893185515551644,0.5555555555555556,0.169,-0.18590361111111106,-0.20336353989805037,-0.16028871105419773,0.4166666666666667,0.021,-0.32208666666666663,-0.33650870997062715,-0.18698276564025307,0.3888888888888889,0.0,0.30108914285714294,0.29981266194992334,0.11788799426722685,0.5555555555555556,0.0,0.8202105263157895,0.5150476190476191,0.168,0.0,0.0
|
||||
MA182xMA7,-1,66,-0.04358954545454546,-0.05050061533379705,-0.08674328447320295,0.5303030303030303,0.129,0.13645151515151513,0.10235803550251647,0.10338840041271781,0.5606060606060606,0.28,0.17344772727272728,0.12187603155843105,0.09606123111692019,0.6212121212121212,0.074,0.12494348484848483,0.010132061312829493,0.005629931082838358,0.4696969696969697,0.957,0.05132227272727275,-0.15314031847959297,-0.06021561887876152,0.42424242424242425,0.557,0.5897142857142857,0.64,0.4305454545454545,0.965,0.7749565217391305
|
||||
MA182xMA7,1,67,0.0076192537313432805,0.007690816049038089,0.01321026763660675,0.5223880597014925,0.927,-0.023750447761194032,-0.03375519602686864,-0.03409498536878306,0.43283582089552236,0.618,0.034717462686567155,0.008729420900812945,0.00688042519884507,0.44776119402985076,0.926,0.06607283582089549,0.023456423448585822,0.013033680254006787,0.5074626865671642,0.865,-0.26800970149253733,-0.31012847852817405,-0.12194423031052547,0.417910447761194,0.143,0.9467936507936509,0.9144888888888889,0.9406984126984127,0.9474098360655738,0.6214193548387097
|
||||
MA30xMA14,-1,186,0.0577908064516129,0.05259839919140563,0.0903465804077389,0.543010752688172,0.17,-0.0017063978494623539,-0.010112015633565624,-0.010213806040435803,0.45161290322580644,0.893,-0.06830774193548388,-0.08005346012548165,-0.06309718027811081,0.478494623655914,0.35,-0.012653118279569909,-0.025284888363596887,-0.014049676026344394,0.5161290322580645,0.857,-0.02853736559139785,-0.05713421272326213,-0.022465487942291914,0.5053763440860215,0.736,0.7253333333333334,0.9853793103448276,0.7228235294117648,0.9474098360655738,0.8936727272727273
|
||||
MA30xMA14,1,186,0.028153548387096782,0.03170731760067301,0.054462640748789,0.5268817204301075,0.374,0.016020537634408603,0.011875477638208995,0.01199501955194561,0.5,0.847,-0.0370360752688172,-0.051548816287307384,-0.04063016076138508,0.478494623655914,0.499,-0.015004569892473113,-0.02383805484556744,-0.013245735668765603,0.5161290322580645,0.877,-0.13373016129032259,-0.14118492834996732,-0.05551469346121136,0.45698924731182794,0.358,0.8202105263157895,0.9779649122807017,0.8661333333333333,0.9474098360655738,0.6582857142857143
|
||||
MA30xMA3,-1,259,-0.0686582945736434,-0.07045313085314982,-0.12101507934562955,0.444015444015444,0.0,-0.09360682170542636,-0.10294030448543791,-0.10397653067976174,0.4247104247104247,0.002,-0.02850724806201553,-0.04647059528236293,-0.036627567672481515,0.47104247104247104,0.179,-0.11155980620155038,-0.11046364200140908,-0.06137968103684801,0.4555984555984556,0.093,-0.12523593023255816,-0.1360730749117463,-0.05350468446125606,0.47104247104247104,0.193,0.0,0.032,0.6684444444444444,0.6109090909090908,0.6214193548387097
|
||||
MA30xMA3,1,258,0.003845116279069767,0.005820412909908539,0.009997536256906005,0.5271317829457365,0.915,-0.04823112403100775,-0.04900228621850522,-0.04949555707888578,0.49224806201550386,0.314,-0.02961368217054264,-0.03685357516921869,-0.029047547385211904,0.4496124031007752,0.566,-0.02533209302325577,-0.012891433059302676,-0.007163189941517431,0.5,0.892,0.033963837209302274,0.042444573151777756,0.01668944054546775,0.46511627906976744,0.768,0.9467936507936509,0.648258064516129,0.8661333333333333,0.9474098360655738,0.8936727272727273
|
||||
MA30xMA7,-1,217,-0.05117294930875576,-0.056314638355585346,-0.09672984502457939,0.4608294930875576,0.069,-0.06452811059907836,-0.0717807121141479,-0.07250327704643271,0.4470046082949309,0.11,-0.013609953917050683,-0.023106382430078936,-0.0182121744079565,0.5069124423963134,0.737,-0.12043755760368663,-0.11133827885959051,-0.061865677428109146,0.4838709677419355,0.24,-0.052397834101382504,-0.04586767788325113,-0.018035424228529984,0.4976958525345622,0.809,0.4014545454545455,0.46305882352941174,0.8899622641509434,0.6678260869565217,0.9083508771929825
|
||||
MA30xMA7,1,217,0.003779170506912438,0.009125723884904737,0.015674962725502214,0.5207373271889401,0.807,-0.0005046543778801771,-4.6403900819300904e-05,-4.687101559798865e-05,0.47465437788018433,0.999,0.02160400921658988,0.011743430538667134,0.009256031564660542,0.48847926267281105,0.885,0.0010320737327188937,0.010928539345289034,0.00607249812751899,0.5207373271889401,0.903,0.05348820276497695,0.060377308008461784,0.02374069091705335,0.47465437788018433,0.725,0.9467936507936509,0.999,0.9406984126984127,0.9474098360655738,0.8936727272727273
|
||||
MA365xMA3,-1,52,-0.04855076923076924,-0.055414123714596746,-0.09518305995752137,0.46153846153846156,0.286,-0.09403961538461539,-0.12269999145316907,-0.12393512424029882,0.4423076923076923,0.461,-0.0693607692307692,-0.1221366700679434,-0.09626666327433527,0.46153846153846156,0.305,-0.07728211538461537,-0.20408719617845544,-0.1134020821527723,0.4423076923076923,0.105,-0.12928634615384618,-0.3965028394292718,-0.1559071059826835,0.5192307692307693,0.014,0.8202105263157895,0.867764705882353,0.7228235294117648,0.6109090909090908,0.17066666666666666
|
||||
MA365xMA3,1,53,0.0277454716981132,0.03944546541478535,0.06775420863758708,0.5283018867924528,0.453,-0.11042018867924527,-0.09593619605608099,-0.09690191691569978,0.4339622641509434,0.388,0.05649377358490564,0.05409192357361935,0.0426346075230801,0.4716981132075472,0.605,0.13301754716981135,0.08737104766439538,0.04854816426772733,0.4716981132075472,0.358,-0.11447471698113201,-0.14433877731913455,-0.05675480429168384,0.41509433962264153,0.635,0.8202105263157895,0.7524848484848485,0.8661333333333333,0.8182857142857143,0.8646808510638297
|
||||
MA365xMA7,-1,45,-0.08103666666666666,-0.08923106924932349,-0.1532693408304292,0.4444444444444444,0.026,-0.08737622222222222,-0.11088535951052053,-0.11200156287387926,0.4666666666666667,0.293,0.06799755555555557,0.028631136728832742,0.022566719700993443,0.5777777777777777,0.725,0.11502799999999996,0.013962899947202765,0.007758555933705275,0.5111111111111111,0.892,0.005609333333333373,-0.23899853974037966,-0.09397554559418657,0.5111111111111111,0.357,0.2773333333333333,0.6466206896551724,0.8899622641509434,0.9474098360655738,0.6582857142857143
|
||||
MA365xMA7,1,46,0.0038217391304347843,0.008635565491361663,0.014833033400740497,0.6086956521739131,0.899,0.20962499999999995,0.22640806887844978,0.22868715647927684,0.5652173913043478,0.123,0.3370608695652174,0.3490665574814269,0.27513008771814923,0.5869565217391305,0.0,0.3500547826086956,0.3806829912027037,0.21152842829387347,0.5217391304347826,0.0,0.055503913043478265,0.1384013091555915,0.05442015902262408,0.45652173913043476,0.44,0.9467936507936509,0.46305882352941174,0.0,0.0,0.7220512820512821
|
||||
MA7xMA3,-1,783,-0.011259987228607916,-0.00975812807678263,-0.01676122308798532,0.4955300127713921,0.641,0.017358071519795654,0.01560250403940561,0.015759563254097973,0.5146871008939975,0.631,-0.0046635294117647105,-0.01147923416737819,-0.009047795143125342,0.4942528735632184,0.318,0.03795154731457801,0.029777241916376193,0.016545874985372265,0.49680715197956576,0.187,0.04697303457106272,0.03581190524176629,0.014081438897150272,0.48531289910600256,0.231,0.9323636363636364,0.9144888888888889,0.7228235294117648,0.6678260869565217,0.6214193548387097
|
||||
MA7xMA3,1,783,0.00861537675606641,0.00646313831490142,0.011101525035556403,0.49808429118773945,0.722,0.01716249042145593,0.013723166107400172,0.013861307375396486,0.5095785440613027,0.707,0.016700791826309083,0.013356612675784767,0.01052752244047766,0.4827586206896552,0.799,0.07514809706257983,0.06249071427303802,0.03472328125660524,0.5159642401021711,0.469,0.06313083120204603,0.028391969974839334,0.011163879376742887,0.48659003831417624,0.236,0.9467936507936509,0.9228799999999999,0.9406984126984127,0.8462222222222222,0.6214193548387097
|
||||
MEDxMA121,-1,84,0.13476738095238097,0.1342521365628516,0.23060058171634015,0.6428571428571429,0.0,0.2586453571428571,0.2501091238058481,0.25262679292313406,0.5952380952380952,0.0,0.3434838095238096,0.3255167069312205,0.256568377039313,0.5833333333333334,0.0,0.3004757142857143,0.2635298831974455,0.14643171165885227,0.5714285714285714,0.096,0.3823957142857143,0.33092119114937013,0.13012003973213382,0.5476190476190477,0.012,0.0,0.0,0.0,0.6109090909090908,0.17066666666666666
|
||||
MEDxMA121,1,91,0.08019505494505494,0.07113435068349859,0.12218518876196342,0.4945054945054945,0.04,-0.021887032967032947,-0.05134812811197136,-0.051865012879751,0.4725274725274725,0.548,0.03865461538461538,0.0007329198464039522,0.0005776786613029268,0.4725274725274725,0.921,0.11142747252747255,0.023207607627741874,0.012895424485469585,0.5164835164835165,0.883,0.0024489010989010673,-0.15220237822472207,-0.05984681559116825,0.5054945054945055,0.512,0.344,0.9144888888888889,0.9406984126984127,0.9474098360655738,0.7438222222222223
|
||||
MEDxMA14,-1,185,0.032015297297297296,0.02576974210266877,0.04426385807851503,0.5027027027027027,0.487,0.05068994594594595,0.033539059114855246,0.03387667276153632,0.5027027027027027,0.643,-0.015857783783783795,-0.04359209068399024,-0.034358764758901025,0.4594594594594595,0.566,-0.029033783783783792,-0.08171127707936293,-0.04540328413380422,0.5027027027027027,0.374,0.08017043243243241,-0.052804933089093314,-0.02076319128352251,0.4972972972972973,0.761,0.8202105263157895,0.9144888888888889,0.8661333333333333,0.8253793103448276,0.8936727272727273
|
||||
MEDxMA14,1,182,0.015483516483516483,0.01999690520857099,0.034348041615443144,0.46153846153846156,0.525,0.1268462087912088,0.13251803922698374,0.13385200325743654,0.5054945054945055,0.029,0.17036961538461537,0.17188403061779176,0.1354769381588161,0.532967032967033,0.059,0.14587467032967033,0.1614950869059967,0.08973556134589228,0.5274725274725275,0.132,0.18018712707182324,0.2308097174336803,0.09075565544388747,0.5384615384615384,0.011,0.8320000000000001,0.18560000000000001,0.3776,0.6498461538461539,0.17066666666666666
|
||||
MEDxMA182,-1,58,-0.022809137931034486,-0.02034156879114435,-0.03494005917786492,0.4827586206896552,0.614,0.007036206896551722,0.0022230272623963124,0.002245404883013482,0.46551724137931033,0.976,-0.01394482758620689,-0.02929424853310631,-0.02308937649800395,0.43103448275862066,0.815,0.028821551724137955,-0.010465656017253815,-0.005815294666567431,0.4827586206896552,0.866,-0.048383620689655175,-0.07670426764079707,-0.03016054160321107,0.41379310344827586,0.706,0.913860465116279,0.999,0.9406984126984127,0.9474098360655738,0.8936727272727273
|
||||
MEDxMA182,1,60,-0.05141766666666667,-0.06026824424805813,-0.10352082684448174,0.43333333333333335,0.235,0.04781166666666667,0.021414182490574342,0.021629743702848616,0.4666666666666667,0.829,0.0006648333333333163,-0.033655107046627795,-0.026526553046821413,0.5166666666666667,0.668,-0.03795049999999997,-0.13075443319485391,-0.0726543617270161,0.45,0.579,0.17888899999999996,-0.015228210882883987,-0.005987816610498588,0.45,0.994,0.791578947368421,0.9779649122807017,0.8844799999999999,0.9474098360655738,0.994
|
||||
MEDxMA3,-1,278,0.0016162230215827325,-0.0013541581255577132,-0.0023259939058275247,0.4784172661870504,0.98,0.05901579136690648,0.02813674104933946,0.028419973435759655,0.5323741007194245,0.533,0.03532474820143886,-0.020805920013216492,-0.01639897743168258,0.4892086330935252,0.656,0.11916438848920864,0.041241944307270115,0.02291629481931619,0.4748201438848921,0.61,0.0010353237410072069,-0.1184472277241612,-0.0465741040158174,0.44244604316546765,0.36,0.98,0.9144888888888889,0.8844799999999999,0.9474098360655738,0.6582857142857143
|
||||
MEDxMA3,1,274,0.009557919708029194,0.008903575935155169,0.01529338632939503,0.5255474452554745,0.86,0.03554923357664233,0.0316743286442259,0.03199317138704499,0.4927007299270073,0.617,0.04520335766423357,0.04004414771615872,0.031562318525261424,0.4708029197080292,0.598,0.05428197080291972,0.0728305922625407,0.040468686726284606,0.5218978102189781,0.476,-0.03939229927007301,0.006092626048882876,0.0023956542063691354,0.4708029197080292,0.963,0.9467936507936509,0.9144888888888889,0.8661333333333333,0.8462222222222222,0.9782857142857142
|
||||
MEDxMA30,-1,142,0.09557457746478873,0.09776959269544033,0.16793568822782315,0.5704225352112676,0.0,0.0356945070422535,0.02280826220621985,0.02303785661885766,0.5422535211267606,0.755,0.06607436619718313,0.03764384568598137,0.029670429159297504,0.4647887323943662,0.596,-0.01828098591549294,-0.04765629320824421,-0.026480460208646955,0.4788732394366197,0.694,0.12349077464788734,0.04999247118411797,0.01965731573185583,0.4859154929577465,0.734,0.0,0.9292307692307692,0.8661333333333333,0.9474098360655738,0.8936727272727273
|
||||
MEDxMA30,1,151,-0.045856,-0.0465670003137284,-0.07998664033256168,0.48344370860927155,0.069,-0.10282526666666669,-0.09594826670609755,-0.0969141090722904,0.45695364238410596,0.028,-0.02792053333333333,-0.016624814962354777,-0.013103480413284912,0.48344370860927155,0.344,-0.1730158,-0.12058887270215377,-0.06700581665555486,0.48344370860927155,0.093,-0.26233259999999997,-0.17042491921170735,-0.06701201933351998,0.47019867549668876,0.193,0.4014545454545455,0.18560000000000001,0.7228235294117648,0.6109090909090908,0.6214193548387097
|
||||
MEDxMA365,-1,37,-0.052988108108108105,-0.044443665841789014,-0.07633945692868081,0.4594594594594595,0.662,-0.08400891891891892,-0.06157995647948478,-0.06219983772297179,0.4864864864864865,0.624,-0.1621889189189189,-0.14576280294546232,-0.1148884987716481,0.43243243243243246,0.176,0.024111081081081055,0.04505525828960639,0.025035182008697174,0.5135135135135135,0.761,-0.05749944444444447,0.018377259173368816,0.0072260397876034365,0.40540540540540543,0.016,0.9415111111111112,0.9144888888888889,0.6684444444444444,0.9474098360655738,0.17066666666666666
|
||||
MEDxMA365,1,33,0.04310818181818182,0.033538262652949624,0.057607596240413346,0.3939393939393939,0.467,-0.24473333333333333,-0.2613341902535032,-0.2639648540616853,0.45454545454545453,0.024,-0.2011839393939394,-0.22845028730182979,-0.1800617854603076,0.48484848484848486,0.0,0.007929090909090924,-0.07648707759406145,-0.04250043128312073,0.48484848484848486,0.391,-0.023826363636363684,-0.2655400486147341,-0.10441181344783067,0.48484848484848486,0.25,0.8202105263157895,0.18560000000000001,0.0,0.833939393939394,0.6214193548387097
|
||||
MEDxMA7,-1,240,0.032916,0.028922037628442143,0.049678454826067274,0.5,0.273,0.07765416666666666,0.05252018029204549,0.05304886326827398,0.4875,0.309,0.10422920833333332,0.061008686719023736,0.048086317548386735,0.49166666666666664,0.36,0.071882375,-0.026142383843300174,-0.014526147724009906,0.4666666666666667,0.803,0.08066995833333333,-0.0952759562795003,-0.03746303213023842,0.45,0.523,0.8202105263157895,0.648258064516129,0.7228235294117648,0.9474098360655738,0.7438222222222223
|
||||
MEDxMA7,1,228,-0.017271403508771918,-0.014612735942202441,-0.025099827049393664,0.4780701754385965,0.692,-0.02944258771929824,-0.025152482353638195,-0.025405674348721083,0.4517543859649123,0.621,-0.04444464912280701,-0.0425041334698064,-0.03350124988858029,0.4824561403508772,0.578,0.06615530701754384,0.09176395309153222,0.05098910437306316,0.5087719298245614,0.459,-0.16573013157894737,-0.10527782017970046,-0.04139582024685679,0.4605263157894737,0.407,0.9422978723404255,0.9144888888888889,0.8661333333333333,0.8462222222222222,0.6854736842105262
|
||||
PRICExMA121,-1,192,-0.0011136458333333293,-0.004321236691526296,-0.0074224494321805026,0.5052083333333334,0.902,-0.010871927083333344,-0.029809491337830406,-0.03010956210134849,0.4895833333333333,0.583,0.09514203125000002,0.05954765934694924,0.046934753239454445,0.4739583333333333,0.384,0.3310727604166667,0.26758402338724646,0.1486844151477113,0.5572916666666666,0.006,0.32460203125,0.22753344857801383,0.08946740843803147,0.5208333333333334,0.184,0.9467936507936509,0.9144888888888889,0.7228235294117648,0.07680000000000001,0.6214193548387097
|
||||
PRICExMA121,1,192,-0.01707552083333333,-0.02508815448381743,-0.043093116923686614,0.4375,0.506,0.05637640624999999,0.02523433133294733,0.025488347242985227,0.546875,0.638,0.05928677083333333,0.011224987205133263,0.008847400726859207,0.53125,0.879,0.24070796875,0.1627908530956468,0.09045556037885953,0.5833333333333334,0.205,0.268875625,0.14933833036295596,0.05872065615642983,0.5104166666666666,0.475,0.8303589743589743,0.9144888888888889,0.9406984126984127,0.6678260869565217,0.7438222222222223
|
||||
PRICExMA14,-1,622,-0.0007665755627009639,-0.0018991178433711558,-0.0032620537046294576,0.49356913183279744,0.912,-0.0019257395498392205,-0.006407874566158778,-0.006472378042310187,0.4967845659163987,0.863,0.01326204180064309,0.006098477075160193,0.004806746726876642,0.477491961414791,0.908,0.054067636655948534,0.048405319518770785,0.02689666046418209,0.5209003215434084,0.567,0.0538585990338164,0.025635383517887092,0.010079974359787401,0.47266881028938906,0.266,0.9467936507936509,0.9779649122807017,0.9406984126984127,0.9474098360655738,0.6214193548387097
|
||||
PRICExMA14,1,623,-0.014676420545746376,-0.012730073428247585,-0.021866038135425148,0.47030497592295345,0.545,0.0014275884244372957,-0.0017997899895379008,-0.0018179071841660246,0.5104333868378812,0.353,0.01065803858520899,0.0017789860443975937,0.0014021755334454116,0.4799357945425361,0.313,0.018954067524115756,0.018142742565829078,0.010081106612527126,0.5008025682182986,0.216,0.009328470209339785,-0.0016065739848631821,-0.000631713762472983,0.478330658105939,0.301,0.8320000000000001,0.706,0.7228235294117648,0.6678260869565217,0.6214193548387097
|
||||
PRICExMA182,-1,140,-0.03597321428571429,-0.03340255555820349,-0.05737449652377054,0.4714285714285714,0.467,-0.14893500000000004,-0.15623978620456583,-0.15781254004350195,0.4,0.084,-0.0647025714285714,-0.08853573897542956,-0.06978281106690429,0.40714285714285714,0.504,-0.020481785714285727,-0.07441844204291212,-0.041350983482826315,0.45714285714285713,0.723,-0.12365392857142858,-0.18888427375986003,-0.0742703394758254,0.4142857142857143,0.512,0.8202105263157895,0.4135384615384616,0.8661333333333333,0.9474098360655738,0.7438222222222223
|
||||
PRICExMA182,1,139,-0.0896921582733813,-0.09121777580897454,-0.1566818428589591,0.37410071942446044,0.043,-0.20890776978417264,-0.22287974738094982,-0.22512331790053275,0.4316546762589928,0.0,-0.17689208633093526,-0.20531272749844615,-0.16182503741941978,0.4316546762589928,0.0,-0.037221366906474825,-0.0959753157129084,-0.05332916930073661,0.5035971223021583,0.601,-0.2234721582733813,-0.3121830074348682,-0.12275208242190383,0.41007194244604317,0.269,0.344,0.0,0.0,0.9474098360655738,0.6214193548387097
|
||||
PRICExMA3,-1,1365,0.009650820512820511,0.007866696390052672,0.013512371647677317,0.5194139194139195,0.546,0.004900637362637359,0.0005338891034665343,0.0005392633820510158,0.49523809523809526,0.967,-0.014673824175824178,-0.021474615265459643,-0.016926035035635823,0.4908424908424908,0.523,0.0031851612903225817,-0.01312927468962779,-0.007295347845621781,0.4981684981684982,0.312,0.023199125642909633,-0.01370675673718383,-0.005389572438822788,0.46886446886446886,0.3,0.8320000000000001,0.999,0.8661333333333333,0.7395555555555555,0.6214193548387097
|
||||
PRICExMA3,1,1365,-0.02202981684981685,-0.02273581944468149,-0.039052586602871024,0.4783882783882784,0.209,-0.03701229304029305,-0.041212891349244836,-0.04162775195970622,0.49523809523809526,0.138,-0.02945506598240469,-0.037629510780640175,-0.029659130558273072,0.5003663003663004,0.132,-0.03193128393250184,-0.047784958430012396,-0.02655195368948444,0.47985347985347987,0.178,-0.030928433823529382,-0.061740428492180005,-0.02427667741850723,0.4776556776556777,0.203,0.7431111111111111,0.4896,0.6308571428571429,0.6678260869565217,0.6214193548387097
|
||||
PRICExMA30,-1,427,0.017202927400468377,0.016748936289171738,0.0287691097534581,0.5292740046838408,0.482,0.02481250585480094,0.01723528755002068,0.017408782824930823,0.5128805620608899,0.739,0.04980238875878221,0.03435935517273575,0.027081633000940863,0.5058548009367682,0.609,-0.0037466042154566874,-0.0024782808638988425,-0.0013770692889511526,0.49882903981264637,0.965,-0.000713957845433267,-0.007468103997197523,-0.0029364997311411936,0.4707259953161593,0.96,0.8202105263157895,0.9273725490196079,0.8661333333333333,0.965,0.9782857142857142
|
||||
PRICExMA30,1,428,-0.0248903738317757,-0.023387683566524868,-0.04017227266184648,0.4602803738317757,0.48,-0.0617211475409836,-0.0655309759513266,-0.06619062927331552,0.4766355140186916,0.049,-0.013615925058548018,-0.024266764130097773,-0.019126773392219566,0.4696261682242991,0.29,-0.07462002341920372,-0.06491943693220595,-0.03607281327859661,0.4696261682242991,0.222,-0.054220702576112424,-0.048489250722391825,-0.019066241145406414,0.4929906542056075,0.286,0.8202105263157895,0.2850909090909091,0.7228235294117648,0.6678260869565217,0.6214193548387097
|
||||
PRICExMA365,-1,91,0.04233637362637362,0.051379225589190385,0.08825244508086891,0.5494505494505495,0.352,-0.03783879120879119,-0.01651874682732147,-0.01668502920083335,0.4725274725274725,0.916,-0.08764582417582417,-0.07071979625208016,-0.05574049799164656,0.45054945054945056,0.691,0.050201208791208776,0.05812351032993255,0.03229662231078432,0.5054945054945055,0.636,-0.037380659340659296,0.009720292990034775,0.0038220728798851783,0.46153846153846156,0.934,0.8202105263157895,0.9936271186440678,0.8844799999999999,0.9474098360655738,0.9782857142857142
|
||||
PRICExMA365,1,90,0.02415055555555556,0.01823703590189069,0.03132517064850537,0.5333333333333333,0.766,-0.09987566666666665,-0.12869613106931163,-0.12999162269223585,0.5111111111111111,0.119,-0.03710444444444445,-0.09106985104869357,-0.07178016790920748,0.5,0.285,-0.020465666666666653,-0.15015651256242515,-0.0834352251989804,0.5,0.272,-0.25178677777777786,-0.4833343703655808,-0.19004974343721462,0.4444444444444444,0.131,0.9467936507936509,0.46305882352941174,0.7228235294117648,0.6966153846153845,0.6214193548387097
|
||||
PRICExMA7,-1,943,0.0040334994697773085,0.0022016087035053853,0.0037816325366443436,0.5174973488865323,0.931,0.006369278897136809,0.0036908801335600087,0.003728033575971337,0.503711558854719,0.954,-0.021293319194061505,-0.024543468508016503,-0.019344868475054382,0.4867444326617179,0.551,-0.020223319194061496,-0.032993771526510784,-0.018333155921783178,0.5026511134676565,0.682,-0.011021698513800412,-0.04781024414862614,-0.018799252011075365,0.46659597030752914,0.275,0.9467936507936509,0.999,0.8661333333333333,0.9474098360655738,0.6214193548387097
|
||||
PRICExMA7,1,943,-0.030620678685047715,-0.03060022548503894,-0.052561024190461304,0.46447507953340406,0.111,-0.0391947613997879,-0.04300707032128343,-0.043439991644285206,0.4941675503711559,0.219,-0.027821029723991513,-0.03550596058707976,-0.027985373681522555,0.49204665959703076,0.188,-0.03401875796178344,-0.04477221200020043,-0.024877905907279303,0.4782608695652174,0.233,-0.04745296493092454,-0.06773696556330241,-0.026634548908210244,0.47720042417815484,0.247,0.5464615384615384,0.5973333333333334,0.6684444444444444,0.6678260869565217,0.6214193548387097
|
||||
PRICExMED,-1,641,0.021020873634945397,0.020767861465922702,0.035672288409384675,0.5241809672386896,0.383,0.029750327613104526,0.017480843427518426,0.01765681053728184,0.5085803432137286,0.698,0.049702854914196556,0.029052419946197283,0.02289877009672308,0.49453978159126366,0.646,0.038525850234009354,0.019713901742313477,0.010954129150653281,0.5101404056162246,0.82,-0.0002629017160686441,-0.02220791100080794,-0.008732273239305728,0.4711388455538221,0.897,0.8202105263157895,0.9228799999999999,0.8844799999999999,0.9474098360655738,0.9730169491525424
|
||||
PRICExMED,1,641,-0.017737067082683303,-0.018597079812694105,-0.031943606506588146,0.46801872074882994,0.371,-0.012760781249999995,-0.025778301267431636,-0.02603779293254773,0.5070202808112324,0.224,0.016005624999999975,-0.006679395257350678,-0.005264619493538456,0.49297971918876754,0.363,-0.019372687500000024,-0.034250126998993366,-0.019031256190547588,0.4711388455538221,0.279,-0.028446968750000003,-0.040138517270669895,-0.015782686638798674,0.4914196567862715,0.346,0.8202105263157895,0.5973333333333334,0.7228235294117648,0.6966153846153845,0.6582857142857143
|
||||
|
@@ -0,0 +1,73 @@
|
||||
pair,dir,n,raw_1,exc_1,eff_1,pos_1,p_1,raw_3,exc_3,eff_3,pos_3,p_3,raw_5,exc_5,eff_5,pos_5,p_5,raw_10,exc_10,eff_10,pos_10,p_10,raw_20,exc_20,eff_20,pos_20,p_20,rev10,rev20,btr_med,q10,dopo_10g
|
||||
MA182xMA30,1,36,-0.048224722222222224,-0.04621714866274137,-0.07938571139170819,50.0,0.373,-0.1100925,-0.11774658475991877,-0.11893185515551644,55.55555555555556,0.169,-0.18590361111111106,-0.20336353989805037,-0.16028871105419773,41.66666666666667,0.021,-0.32208666666666663,-0.33650870997062715,-0.18698276564025307,38.88888888888889,0.0,0.30108914285714294,0.29981266194992334,0.11788799426722685,55.55555555555556,0.0,63.888888888888886,85.71428571428571,4.0,0.0,SCENDE (extra -)
|
||||
MA365xMA121,1,15,-0.06725866666666667,-0.058566438960441905,-0.10059769057760735,46.666666666666664,0.0,-0.018635333333333337,0.028778700115319186,0.02906839464310546,53.333333333333336,0.0,0.13790733333333333,0.208849745178588,0.1646128724719079,60.0,0.0,-0.2540478571428571,-0.13029592304024354,-0.07239958824198307,53.333333333333336,0.0,-1.1132885714285716,-0.9020608936587976,-0.3546953246360883,40.0,0.0,42.857142857142854,71.42857142857143,5.0,0.0,SCENDE (extra -)
|
||||
MA365xMA7,1,46,0.0038217391304347843,0.008635565491361663,0.014833033400740497,60.86956521739131,0.899,0.20962499999999995,0.22640806887844978,0.22868715647927684,56.52173913043478,0.123,0.3370608695652174,0.3490665574814269,0.27513008771814923,58.69565217391305,0.0,0.3500547826086956,0.3806829912027037,0.21152842829387347,52.17391304347826,0.0,0.055503913043478265,0.1384013091555915,0.05442015902262408,45.65217391304348,0.44,63.04347826086957,80.43478260869566,4.0,0.0,SALE (extra +)
|
||||
MA365xMA182,-1,16,0.11833625,0.09693051199759066,0.16649442627114283,50.0,0.0,0.202560625,0.16364152085364525,0.1652887826451773,50.0,0.0,0.18938187499999998,0.13167340689274035,0.1037834052334698,56.25,0.0,0.601891875,0.4523359166858753,0.2513427385214686,68.75,0.0,0.5659212499999999,0.21605763977409165,0.08495505704603279,56.25,0.0,56.25,68.75,4.0,0.0,SALE (extra +)
|
||||
MA365xMA121,-1,14,0.17198357142857143,0.1629340707798868,0.27986661862668516,71.42857142857143,0.0,0.4065378571428571,0.3874812569771546,0.39138175280623044,85.71428571428571,0.0,0.5851271428571427,0.5604673261957672,0.4417536464449268,71.42857142857143,0.0,0.5330257142857142,0.478114598100192,0.26566679315241315,78.57142857142857,0.0,1.191782142857143,1.0296555048052016,0.4048662303260845,78.57142857142857,0.0,50.0,71.42857142857143,3.0,0.0,SALE (extra +)
|
||||
MA365xMA182,1,16,0.17777875000000004,0.1885936498878568,0.32394125326852685,50.0,0.0,0.391371875,0.4316317402153096,0.4359766672849197,62.5,0.0,0.23858875,0.2984378579545668,0.2352251519878852,68.75,0.0,0.473659375,0.5563856908686655,0.30915852148482825,56.25,0.0,0.42106437500000005,0.6221694442657866,0.24464046115270321,62.5,0.0,75.0,81.25,4.0,0.0,SALE (extra +)
|
||||
MA121xMA7,1,88,0.06656613636363636,0.06872677868019474,0.11804977968245185,57.95454545454546,0.197,0.15830397727272727,0.15216329709975998,0.15369501584741296,57.95454545454546,0.018,0.2576479545454546,0.239825884966136,0.18902789555062602,54.54545454545454,0.001,0.3227229545454545,0.2991385847331414,0.16621786665788313,56.81818181818182,0.001,0.19040772727272728,0.15980304007422197,0.06283543780182936,52.27272727272727,0.389,72.72727272727273,86.36363636363636,3.0,0.010285714285714287,SALE (extra +)
|
||||
MA121xMA3,1,117,-0.03262435897435896,-0.03502834140056345,-0.06016705663188382,53.84615384615385,0.393,0.1085807692307692,0.09438643424690306,0.09533655476621142,50.427350427350426,0.15,0.16597222222222224,0.13826618338430888,0.10897975285129598,50.427350427350426,0.164,0.2847652991452991,0.23515049270743255,0.13066255988423547,58.97435897435898,0.003,0.22466495726495722,0.13930786769167774,0.05477662284509896,49.572649572649574,0.375,75.21367521367522,87.17948717948718,4.0,0.027,SALE (extra +)
|
||||
PRICExMA121,-1,192,-0.0011136458333333293,-0.004321236691526296,-0.0074224494321805026,50.520833333333336,0.902,-0.010871927083333344,-0.029809491337830406,-0.03010956210134849,48.95833333333333,0.583,0.09514203125000002,0.05954765934694924,0.046934753239454445,47.39583333333333,0.384,0.3310727604166667,0.26758402338724646,0.1486844151477113,55.729166666666664,0.006,0.32460203125,0.22753344857801383,0.08946740843803147,52.083333333333336,0.184,80.20833333333334,92.1875,3.0,0.048,SALE (extra +)
|
||||
MA182xMA121,1,31,0.005469354838709664,0.005930804715525939,0.01018715271474295,54.83870967741935,0.883,-0.17420967741935484,-0.1661471549215242,-0.16781963913363782,54.83870967741935,0.153,-0.3184922580645161,-0.31420679972467563,-0.24765404338251065,35.483870967741936,0.046,-0.34026225806451604,-0.33899465157276687,-0.1883640916571304,35.483870967741936,0.021,-0.46702466666666675,-0.4624251636271663,-0.18182812788542654,38.70967741935484,0.0,54.83870967741935,76.66666666666667,2.5,0.1512,neutro
|
||||
MA121xMA14,1,73,0.08970109589041095,0.08841645476774412,0.1518701037073849,61.64383561643836,0.183,0.171722602739726,0.1640382872092089,0.16568954296299623,52.054794520547944,0.007,0.1471627397260274,0.13240461945271742,0.10435973823202067,54.794520547945204,0.138,0.16662917808219183,0.1383347923764789,0.07686642662260364,54.794520547945204,0.029,0.2644176712328766,0.2490256435298178,0.09791825817462992,54.794520547945204,0.074,71.23287671232876,83.56164383561644,3.0,0.18981818181818183,neutro
|
||||
MA365xMA30,-1,21,0.046082857142857155,0.031842647608960044,0.054695092756136064,38.095238095238095,0.372,-0.02703523809523809,-0.037881073440558855,-0.03826239503043005,42.857142857142854,0.418,-0.022549999999999997,-0.03278555411434502,-0.02584118182059828,42.857142857142854,0.608,-0.08356952380952382,-0.14177247861337977,-0.07877659435655403,38.095238095238095,0.06,0.5890909523809524,0.3392334579854691,0.133388468953063,52.38095238095239,0.003,66.66666666666666,80.95238095238095,6.0,0.36000000000000004,neutro
|
||||
MEDxMA30,1,151,-0.045856,-0.0465670003137284,-0.07998664033256168,48.34437086092716,0.069,-0.10282526666666669,-0.09594826670609755,-0.0969141090722904,45.6953642384106,0.028,-0.02792053333333333,-0.016624814962354777,-0.013103480413284912,48.34437086092716,0.344,-0.1730158,-0.12058887270215377,-0.06700581665555486,48.34437086092716,0.093,-0.26233259999999997,-0.17042491921170735,-0.06701201933351998,47.019867549668874,0.193,82.0,92.0,3.0,0.4608,neutro
|
||||
MA30xMA3,-1,259,-0.0686582945736434,-0.07045313085314982,-0.12101507934562955,44.4015444015444,0.0,-0.09360682170542636,-0.10294030448543791,-0.10397653067976174,42.471042471042466,0.002,-0.02850724806201553,-0.04647059528236293,-0.036627567672481515,47.10424710424711,0.179,-0.11155980620155038,-0.11046364200140908,-0.06137968103684801,45.559845559845556,0.093,-0.12523593023255816,-0.1360730749117463,-0.05350468446125606,47.10424710424711,0.193,77.13178294573643,89.92248062015504,3.0,0.4608,neutro
|
||||
MEDxMA121,-1,84,0.13476738095238097,0.1342521365628516,0.23060058171634015,64.28571428571429,0.0,0.2586453571428571,0.2501091238058481,0.25262679292313406,59.523809523809526,0.0,0.3434838095238096,0.3255167069312205,0.256568377039313,58.333333333333336,0.0,0.3004757142857143,0.2635298831974455,0.14643171165885227,57.14285714285714,0.096,0.3823957142857143,0.33092119114937013,0.13012003973213382,54.761904761904766,0.012,75.0,86.90476190476191,3.0,0.4608,neutro
|
||||
MA365xMA3,-1,52,-0.04855076923076924,-0.055414123714596746,-0.09518305995752137,46.15384615384615,0.286,-0.09403961538461539,-0.12269999145316907,-0.12393512424029882,44.230769230769226,0.461,-0.0693607692307692,-0.1221366700679434,-0.09626666327433527,46.15384615384615,0.305,-0.07728211538461537,-0.20408719617845544,-0.1134020821527723,44.230769230769226,0.105,-0.12928634615384618,-0.3965028394292718,-0.1559071059826835,51.92307692307693,0.014,61.53846153846154,84.61538461538461,5.0,0.4725,neutro
|
||||
MA182xMA30,-1,35,0.000345142857142874,-0.00639372195911028,-0.010982290791425238,45.714285714285715,0.886,-0.24531428571428568,-0.26509787608500746,-0.2677664262183302,34.285714285714285,0.004,-0.3593151428571428,-0.3857562050012093,-0.30404842928973563,37.142857142857146,0.013,-0.2841117142857143,-0.37521814952454474,-0.20849186139235856,42.857142857142854,0.12,0.06680142857142857,-0.12502296447058353,-0.04915972001623338,45.714285714285715,0.506,74.28571428571429,88.57142857142857,4.0,0.5082352941176471,neutro
|
||||
MEDxMA14,1,182,0.015483516483516483,0.01999690520857099,0.034348041615443144,46.15384615384615,0.525,0.1268462087912088,0.13251803922698374,0.13385200325743654,50.54945054945055,0.029,0.17036961538461537,0.17188403061779176,0.1354769381588161,53.2967032967033,0.059,0.14587467032967033,0.1614950869059967,0.08973556134589228,52.74725274725275,0.132,0.18018712707182324,0.2308097174336803,0.09075565544388747,53.84615384615385,0.011,68.13186813186813,83.42541436464089,3.5,0.528,neutro
|
||||
MA14xMA7,-1,383,0.003936057441253264,0.0020882087632935874,0.003586849102660063,49.08616187989556,0.932,0.017638219895287948,0.01082872489342116,0.010937729898232244,50.13054830287206,0.268,0.023900732984293183,0.011324957744819978,0.00892619631115032,48.04177545691906,0.26,-0.054068979057591615,-0.06435243929014356,-0.035757758172790935,46.99738903394256,0.151,0.05511498687664045,0.016967571614375454,0.006671742855004413,48.30287206266319,0.248,76.70157068062828,89.76377952755905,3.0,0.5722105263157895,neutro
|
||||
MA365xMA14,1,28,0.026667142857142865,0.03498123966244576,0.06008615148960548,46.42857142857143,0.298,0.1704282142857143,0.18737662697316468,0.1892628130500779,57.14285714285714,0.0,0.0984778571428571,0.11082274884109121,0.08734916581471197,42.857142857142854,0.222,-0.2500064285714286,-0.21573985268097465,-0.11987693963888939,42.857142857142854,0.202,0.1012014814814815,0.21951720363596228,0.08631537666049734,57.14285714285714,0.021,53.57142857142857,81.48148148148148,7.0,0.5958620689655173,neutro
|
||||
MA30xMA7,-1,217,-0.05117294930875576,-0.056314638355585346,-0.09672984502457939,46.08294930875576,0.069,-0.06452811059907836,-0.0717807121141479,-0.07250327704643271,44.70046082949309,0.11,-0.013609953917050683,-0.023106382430078936,-0.0182121744079565,50.69124423963134,0.737,-0.12043755760368663,-0.11133827885959051,-0.061865677428109146,48.38709677419355,0.24,-0.052397834101382504,-0.04586767788325113,-0.018035424228529984,49.76958525345622,0.809,78.3410138248848,88.47926267281106,3.0,0.5958620689655173,neutro
|
||||
PRICExMA30,1,428,-0.0248903738317757,-0.023387683566524868,-0.04017227266184648,46.02803738317757,0.48,-0.0617211475409836,-0.0655309759513266,-0.06619062927331552,47.66355140186916,0.049,-0.013615925058548018,-0.024266764130097773,-0.019126773392219566,46.96261682242991,0.29,-0.07462002341920372,-0.06491943693220595,-0.03607281327859661,46.96261682242991,0.222,-0.054220702576112424,-0.048489250722391825,-0.019066241145406414,49.29906542056075,0.286,80.56206088992974,90.86651053864169,2.0,0.5958620689655173,neutro
|
||||
PRICExMA3,1,1365,-0.02202981684981685,-0.02273581944468149,-0.039052586602871024,47.83882783882784,0.209,-0.03701229304029305,-0.041212891349244836,-0.04162775195970622,49.523809523809526,0.138,-0.02945506598240469,-0.037629510780640175,-0.029659130558273072,50.03663003663004,0.132,-0.03193128393250184,-0.047784958430012396,-0.02655195368948444,47.985347985347985,0.178,-0.030928433823529382,-0.061740428492180005,-0.02427667741850723,47.765567765567766,0.203,69.4057226705796,84.92647058823529,4.0,0.5958620689655173,neutro
|
||||
PRICExMA7,1,943,-0.030620678685047715,-0.03060022548503894,-0.052561024190461304,46.447507953340406,0.111,-0.0391947613997879,-0.04300707032128343,-0.043439991644285206,49.41675503711559,0.219,-0.027821029723991513,-0.03550596058707976,-0.027985373681522555,49.20466595970308,0.188,-0.03401875796178344,-0.04477221200020043,-0.024877905907279303,47.82608695652174,0.233,-0.04745296493092454,-0.06773696556330241,-0.026634548908210244,47.720042417815485,0.247,71.44373673036092,86.07863974495218,3.0,0.5958620689655173,neutro
|
||||
PRICExMA14,1,623,-0.014676420545746376,-0.012730073428247585,-0.021866038135425148,47.03049759229535,0.545,0.0014275884244372957,-0.0017997899895379008,-0.0018179071841660246,51.04333868378812,0.353,0.01065803858520899,0.0017789860443975937,0.0014021755334454116,47.99357945425361,0.313,0.018954067524115756,0.018142742565829078,0.010081106612527126,50.08025682182986,0.216,0.009328470209339785,-0.0016065739848631821,-0.000631713762472983,47.8330658105939,0.301,76.52733118971061,90.01610305958133,3.0,0.5958620689655173,neutro
|
||||
MA14xMA7,1,382,-0.0006903926701570699,0.0018220445243756229,0.003129667340805309,48.69109947643979,0.931,-0.022581282722513082,-0.025758127076624282,-0.02601741566263479,45.811518324607334,0.551,0.010029188481675414,-0.0001709152586449735,-0.0001347133636709491,47.90575916230366,0.99,0.020934383202099727,0.024244274020344084,0.013471453406539668,50.0,0.224,0.0999728083989501,0.09411047957551737,0.03700476025438057,49.73821989528796,0.134,74.2782152230971,88.9763779527559,3.0,0.5958620689655173,neutro
|
||||
MA7xMA3,-1,783,-0.011259987228607916,-0.00975812807678263,-0.01676122308798532,49.55300127713921,0.641,0.017358071519795654,0.01560250403940561,0.015759563254097973,51.46871008939975,0.631,-0.0046635294117647105,-0.01147923416737819,-0.009047795143125342,49.42528735632184,0.318,0.03795154731457801,0.029777241916376193,0.016545874985372265,49.68071519795657,0.187,0.04697303457106272,0.03581190524176629,0.014081438897150272,48.53128991060026,0.231,72.63427109974424,86.68373879641486,3.0,0.5958620689655173,neutro
|
||||
MA121xMA3,-1,117,0.05220358974358977,0.04398986786725697,0.07555998272746543,42.73504273504273,0.304,0.04510350427350427,0.01416661259177849,0.014309217717397828,48.717948717948715,0.871,0.06861871794871795,0.021877594054191637,0.01724365809953614,49.572649572649574,0.917,0.2250457264957265,0.13531015620709289,0.07518577224650531,52.13675213675214,0.218,0.09543794871794872,-0.053395235693741994,-0.020995301527366637,45.2991452991453,0.734,74.35897435897436,91.45299145299145,4.0,0.5958620689655173,neutro
|
||||
PRICExMA121,1,192,-0.01707552083333333,-0.02508815448381743,-0.043093116923686614,43.75,0.506,0.05637640624999999,0.02523433133294733,0.025488347242985227,54.6875,0.638,0.05928677083333333,0.011224987205133263,0.008847400726859207,53.125,0.879,0.24070796875,0.1627908530956468,0.09045556037885953,58.333333333333336,0.205,0.268875625,0.14933833036295596,0.05872065615642983,51.041666666666664,0.475,78.64583333333334,92.1875,3.0,0.5958620689655173,neutro
|
||||
PRICExMA365,1,90,0.02415055555555556,0.01823703590189069,0.03132517064850537,53.333333333333336,0.766,-0.09987566666666665,-0.12869613106931163,-0.12999162269223585,51.11111111111111,0.119,-0.03710444444444445,-0.09106985104869357,-0.07178016790920748,50.0,0.285,-0.020465666666666653,-0.15015651256242515,-0.0834352251989804,50.0,0.272,-0.25178677777777786,-0.4833343703655808,-0.19004974343721462,44.44444444444444,0.131,66.66666666666666,85.55555555555556,3.0,0.6367499999999999,neutro
|
||||
PRICExMED,1,641,-0.017737067082683303,-0.018597079812694105,-0.031943606506588146,46.80187207488299,0.371,-0.012760781249999995,-0.025778301267431636,-0.02603779293254773,50.70202808112324,0.224,0.016005624999999975,-0.006679395257350678,-0.005264619493538456,49.297971918876755,0.363,-0.019372687500000024,-0.034250126998993366,-0.019031256190547588,47.113884555382214,0.279,-0.028446968750000003,-0.040138517270669895,-0.015782686638798674,49.141965678627145,0.346,86.5625,94.21875,2.0,0.6367499999999999,neutro
|
||||
MA14xMA3,-1,413,0.018732493946731234,0.019495711743007522,0.0334871577020072,48.91041162227603,0.466,0.05811405339805826,0.05033597672560418,0.05084267289150997,50.847457627118644,0.062,0.022634417475728145,0.004728052246124062,0.0037265942592662146,49.63680387409201,0.297,-0.02661601941747573,-0.027830847621834614,-0.01546435115720282,47.699757869249396,0.283,-0.004355085158150855,-0.022630394656332584,-0.008898396145645172,47.45762711864407,0.3,77.42718446601941,90.2676399026764,4.0,0.6367499999999999,neutro
|
||||
PRICExMA3,-1,1365,0.009650820512820511,0.007866696390052672,0.013512371647677317,51.94139194139195,0.546,0.004900637362637359,0.0005338891034665343,0.0005392633820510158,49.523809523809526,0.967,-0.014673824175824178,-0.021474615265459643,-0.016926035035635823,49.08424908424908,0.523,0.0031851612903225817,-0.01312927468962779,-0.007295347845621781,49.81684981684982,0.312,0.023199125642909633,-0.01370675673718383,-0.005389572438822788,46.88644688644688,0.3,69.72140762463343,85.15797207935341,4.0,0.6807272727272727,neutro
|
||||
MA365xMA3,1,53,0.0277454716981132,0.03944546541478535,0.06775420863758708,52.83018867924528,0.453,-0.11042018867924527,-0.09593619605608099,-0.09690191691569978,43.39622641509434,0.388,0.05649377358490564,0.05409192357361935,0.0426346075230801,47.16981132075472,0.605,0.13301754716981135,0.08737104766439538,0.04854816426772733,47.16981132075472,0.358,-0.11447471698113201,-0.14433877731913455,-0.05675480429168384,41.509433962264154,0.635,60.37735849056604,77.35849056603774,4.0,0.7581176470588236,neutro
|
||||
MEDxMA14,-1,185,0.032015297297297296,0.02576974210266877,0.04426385807851503,50.27027027027027,0.487,0.05068994594594595,0.033539059114855246,0.03387667276153632,50.27027027027027,0.643,-0.015857783783783795,-0.04359209068399024,-0.034358764758901025,45.94594594594595,0.566,-0.029033783783783792,-0.08171127707936293,-0.04540328413380422,50.27027027027027,0.374,0.08017043243243241,-0.052804933089093314,-0.02076319128352251,49.72972972972973,0.761,69.1891891891892,83.24324324324324,4.0,0.7693714285714286,neutro
|
||||
MEDxMA365,1,33,0.04310818181818182,0.033538262652949624,0.057607596240413346,39.39393939393939,0.467,-0.24473333333333333,-0.2613341902535032,-0.2639648540616853,45.45454545454545,0.024,-0.2011839393939394,-0.22845028730182979,-0.1800617854603076,48.484848484848484,0.0,0.007929090909090924,-0.07648707759406145,-0.04250043128312073,48.484848484848484,0.391,-0.023826363636363684,-0.2655400486147341,-0.10441181344783067,48.484848484848484,0.25,75.75757575757575,87.87878787878788,6.0,0.782,neutro
|
||||
MA121xMA30,-1,52,-0.020661538461538457,-0.0237911422942284,-0.040865280756085726,48.07692307692308,0.831,-0.07388230769230766,-0.07690927545575411,-0.07768346595588999,55.769230769230774,0.721,-0.12157519230769233,-0.114888060239567,-0.09055339566054517,44.230769230769226,0.707,-0.27518923076923074,-0.3105672292466324,-0.17256825074998694,48.07692307692308,0.43,-0.3224990384615384,-0.42409334989842495,-0.16675584705606972,46.15384615384615,0.296,63.46153846153846,86.53846153846155,5.0,0.7938461538461539,neutro
|
||||
MA182xMA14,-1,46,0.15412304347826086,0.14217416973434086,0.2442080035756289,50.0,0.0,0.2857415217391305,0.2571233697039764,0.2597116462025928,58.69565217391305,0.0,0.2071847826086957,0.171448060576255,0.13513331178384638,52.17391304347826,0.325,-0.09928499999999998,-0.20905151224177224,-0.11616052946640151,41.30434782608695,0.427,0.14800260869565224,-0.07458470946041838,-0.029327119622323313,43.47826086956522,0.804,63.04347826086957,86.95652173913044,5.0,0.7938461538461539,neutro
|
||||
MA182xMA121,-1,30,-0.07841333333333335,-0.07979096882524894,-0.13705438362389624,40.0,0.381,-0.13186333333333336,-0.13923038014068193,-0.14063191249157805,50.0,0.211,-0.20915666666666669,-0.2250881162338893,-0.17741176241736653,43.333333333333336,0.0,-0.12362599999999999,-0.17644799079844736,-0.0980442179759313,50.0,0.417,0.41436733333333337,0.33319840545603613,0.13101545297246694,46.666666666666664,0.204,70.0,83.33333333333334,3.0,0.7938461538461539,neutro
|
||||
MA7xMA3,1,783,0.00861537675606641,0.00646313831490142,0.011101525035556403,49.808429118773944,0.722,0.01716249042145593,0.013723166107400172,0.013861307375396486,50.95785440613027,0.707,0.016700791826309083,0.013356612675784767,0.01052752244047766,48.275862068965516,0.799,0.07514809706257983,0.06249071427303802,0.03472328125660524,51.59642401021711,0.469,0.06313083120204603,0.028391969974839334,0.011163879376742887,48.65900383141762,0.236,71.13665389527458,85.93350383631714,4.0,0.816,neutro
|
||||
MEDxMA3,1,274,0.009557919708029194,0.008903575935155169,0.01529338632939503,52.55474452554745,0.86,0.03554923357664233,0.0316743286442259,0.03199317138704499,49.27007299270073,0.617,0.04520335766423357,0.04004414771615872,0.031562318525261424,47.08029197080292,0.598,0.05428197080291972,0.0728305922625407,0.040468686726284606,52.18978102189781,0.476,-0.03939229927007301,0.006092626048882876,0.0023956542063691354,47.08029197080292,0.963,77.00729927007299,87.95620437956204,4.0,0.816,neutro
|
||||
MEDxMA7,1,228,-0.017271403508771918,-0.014612735942202441,-0.025099827049393664,47.80701754385965,0.692,-0.02944258771929824,-0.025152482353638195,-0.025405674348721083,45.17543859649123,0.621,-0.04444464912280701,-0.0425041334698064,-0.03350124988858029,48.24561403508772,0.578,0.06615530701754384,0.09176395309153222,0.05098910437306316,50.877192982456144,0.459,-0.16573013157894737,-0.10527782017970046,-0.04139582024685679,46.05263157894737,0.407,74.12280701754386,85.96491228070175,4.0,0.816,neutro
|
||||
MEDxMA182,1,60,-0.05141766666666667,-0.06026824424805813,-0.10352082684448174,43.333333333333336,0.235,0.04781166666666667,0.021414182490574342,0.021629743702848616,46.666666666666664,0.829,0.0006648333333333163,-0.033655107046627795,-0.026526553046821413,51.66666666666667,0.668,-0.03795049999999997,-0.13075443319485391,-0.0726543617270161,45.0,0.579,0.17888899999999996,-0.015228210882883987,-0.005987816610498588,45.0,0.994,65.0,86.66666666666667,4.0,0.9263999999999999,neutro
|
||||
PRICExMA14,-1,622,-0.0007665755627009639,-0.0018991178433711558,-0.0032620537046294576,49.356913183279744,0.912,-0.0019257395498392205,-0.006407874566158778,-0.006472378042310187,49.67845659163987,0.863,0.01326204180064309,0.006098477075160193,0.004806746726876642,47.7491961414791,0.908,0.054067636655948534,0.048405319518770785,0.02689666046418209,52.09003215434084,0.567,0.0538585990338164,0.025635383517887092,0.010079974359787401,47.266881028938904,0.266,76.84887459807074,90.33816425120773,4.0,0.9263999999999999,neutro
|
||||
MA182xMA3,1,86,0.0698374418604651,0.0700915914742381,0.1203940747700236,52.32558139534884,0.399,-0.005633953488372075,-0.014586499381746465,-0.014733331206447278,45.348837209302324,0.852,0.04616872093023254,0.01856945567260769,0.01463622297405181,47.674418604651166,0.885,0.15744883720930233,0.09773602792407764,0.054307517940716026,54.65116279069767,0.561,-0.14362348837209307,-0.21674959256674572,-0.08522713670512076,44.18604651162791,0.478,79.06976744186046,90.69767441860465,4.5,0.9263999999999999,neutro
|
||||
PRICExMA182,1,139,-0.0896921582733813,-0.09121777580897454,-0.1566818428589591,37.410071942446045,0.043,-0.20890776978417264,-0.22287974738094982,-0.22512331790053275,43.16546762589928,0.0,-0.17689208633093526,-0.20531272749844615,-0.16182503741941978,43.16546762589928,0.0,-0.037221366906474825,-0.0959753157129084,-0.05332916930073661,50.35971223021583,0.601,-0.2234721582733813,-0.3121830074348682,-0.12275208242190383,41.007194244604314,0.269,74.82014388489209,87.76978417266187,3.0,0.9279999999999999,neutro
|
||||
MA365xMA14,-1,27,0.0902722222222222,0.07865735022168166,0.13510720336948964,48.148148148148145,0.26,0.04923888888888893,0.04209174007923389,0.04251544742936071,55.55555555555556,0.667,0.02028925925925927,0.014956636694835468,0.01178864224493211,55.55555555555556,0.823,0.00419037037037034,-0.0592687614602882,-0.0329329868902486,51.85185185185185,0.635,0.3909422222222223,0.13360208025451417,0.05253307571701034,51.85185185185185,0.437,59.25925925925925,88.88888888888889,7.5,0.9279999999999999,neutro
|
||||
MA182xMA14,1,47,0.02657595744680852,0.027371215978263932,0.0470146583024122,51.06382978723404,0.691,0.01741063829787233,0.004927755680655171,0.004977359861845885,55.319148936170215,0.998,0.0006495744680851034,-0.022737164244711856,-0.01792116104803993,44.680851063829785,0.884,-0.022737234042553203,-0.05318987605447526,-0.029555223487665976,42.5531914893617,0.689,-0.048247872340425546,-0.06350047154634395,-0.024968736066497244,42.5531914893617,0.762,74.46808510638297,85.1063829787234,5.0,0.9279999999999999,neutro
|
||||
MA121xMA30,1,53,0.08432094339622644,0.08607884816227486,0.1478548719438829,64.15094339622641,0.022,0.0901020754716981,0.08913430535697553,0.09003155646270568,54.71698113207547,0.091,0.09538396226415095,0.08448989403948784,0.06659392445413015,56.60377358490566,0.307,-0.029476415094339632,-0.0497229199320908,-0.027628791793896622,41.509433962264154,0.696,-0.012036037735849067,-0.03067699468685477,-0.012062363711589094,56.60377358490566,0.847,62.264150943396224,81.13207547169812,3.0,0.9279999999999999,neutro
|
||||
MEDxMA30,-1,142,0.09557457746478873,0.09776959269544033,0.16793568822782315,57.04225352112676,0.0,0.0356945070422535,0.02280826220621985,0.02303785661885766,54.22535211267606,0.755,0.06607436619718313,0.03764384568598137,0.029670429159297504,46.478873239436616,0.596,-0.01828098591549294,-0.04765629320824421,-0.026480460208646955,47.88732394366197,0.694,0.12349077464788734,0.04999247118411797,0.01965731573185583,48.59154929577465,0.734,85.2112676056338,93.66197183098592,2.0,0.9279999999999999,neutro
|
||||
PRICExMA7,-1,943,0.0040334994697773085,0.0022016087035053853,0.0037816325366443436,51.74973488865323,0.931,0.006369278897136809,0.0036908801335600087,0.003728033575971337,50.37115588547189,0.954,-0.021293319194061505,-0.024543468508016503,-0.019344868475054382,48.67444326617179,0.551,-0.020223319194061496,-0.032993771526510784,-0.018333155921783178,50.26511134676564,0.682,-0.011021698513800412,-0.04781024414862614,-0.018799252011075365,46.65959703075291,0.275,72.1102863202545,86.51804670912952,4.0,0.9279999999999999,neutro
|
||||
MEDxMA3,-1,278,0.0016162230215827325,-0.0013541581255577132,-0.0023259939058275247,47.84172661870504,0.98,0.05901579136690648,0.02813674104933946,0.028419973435759655,53.23741007194245,0.533,0.03532474820143886,-0.020805920013216492,-0.01639897743168258,48.92086330935252,0.656,0.11916438848920864,0.041241944307270115,0.02291629481931619,47.482014388489205,0.61,0.0010353237410072069,-0.1184472277241612,-0.0465741040158174,44.24460431654676,0.36,77.6978417266187,91.00719424460432,3.0,0.9279999999999999,neutro
|
||||
MA365xMA30,1,22,0.07007000000000001,0.0787243826923708,0.13522234289077065,50.0,0.246,-0.028239545454545458,-0.015094491472952283,-0.015246436889594057,50.0,0.776,-0.23031318181818178,-0.2243817259801987,-0.17685499406389435,45.45454545454545,0.05,0.03273272727272725,0.05564617297318344,0.030920077286350045,59.09090909090909,0.667,0.43400904761904746,0.5400784830084224,0.21236184187372262,54.54545454545454,0.0,63.63636363636363,90.47619047619048,8.0,0.9279999999999999,neutro
|
||||
PRICExMA365,-1,91,0.04233637362637362,0.051379225589190385,0.08825244508086891,54.94505494505495,0.352,-0.03783879120879119,-0.01651874682732147,-0.01668502920083335,47.25274725274725,0.916,-0.08764582417582417,-0.07071979625208016,-0.05574049799164656,45.05494505494506,0.691,0.050201208791208776,0.05812351032993255,0.03229662231078432,50.54945054945055,0.636,-0.037380659340659296,0.009720292990034775,0.0038220728798851783,46.15384615384615,0.934,68.13186813186813,85.71428571428571,4.5,0.9279999999999999,neutro
|
||||
PRICExMA182,-1,140,-0.03597321428571429,-0.03340255555820349,-0.05737449652377054,47.14285714285714,0.467,-0.14893500000000004,-0.15623978620456583,-0.15781254004350195,40.0,0.084,-0.0647025714285714,-0.08853573897542956,-0.06978281106690429,40.714285714285715,0.504,-0.020481785714285727,-0.07441844204291212,-0.041350983482826315,45.714285714285715,0.723,-0.12365392857142858,-0.18888427375986003,-0.0742703394758254,41.42857142857143,0.512,77.85714285714286,87.85714285714286,4.0,0.9422608695652175,neutro
|
||||
MEDxMA7,-1,240,0.032916,0.028922037628442143,0.049678454826067274,50.0,0.273,0.07765416666666666,0.05252018029204549,0.05304886326827398,48.75,0.309,0.10422920833333332,0.061008686719023736,0.048086317548386735,49.166666666666664,0.36,0.071882375,-0.026142383843300174,-0.014526147724009906,46.666666666666664,0.803,0.08066995833333333,-0.0952759562795003,-0.03746303213023842,45.0,0.523,75.83333333333333,87.5,4.0,0.9422608695652175,neutro
|
||||
MA30xMA14,-1,186,0.0577908064516129,0.05259839919140563,0.0903465804077389,54.3010752688172,0.17,-0.0017063978494623539,-0.010112015633565624,-0.010213806040435803,45.16129032258064,0.893,-0.06830774193548388,-0.08005346012548165,-0.06309718027811081,47.8494623655914,0.35,-0.012653118279569909,-0.025284888363596887,-0.014049676026344394,51.61290322580645,0.857,-0.02853736559139785,-0.05713421272326213,-0.022465487942291914,50.53763440860215,0.736,72.58064516129032,85.48387096774194,4.0,0.9422608695652175,neutro
|
||||
MA30xMA14,1,186,0.028153548387096782,0.03170731760067301,0.054462640748789,52.68817204301075,0.374,0.016020537634408603,0.011875477638208995,0.01199501955194561,50.0,0.847,-0.0370360752688172,-0.051548816287307384,-0.04063016076138508,47.8494623655914,0.499,-0.015004569892473113,-0.02383805484556744,-0.013245735668765603,51.61290322580645,0.877,-0.13373016129032259,-0.14118492834996732,-0.05551469346121136,45.69892473118279,0.358,72.58064516129032,87.09677419354838,3.0,0.9422608695652175,neutro
|
||||
MA30xMA3,1,258,0.003845116279069767,0.005820412909908539,0.009997536256906005,52.71317829457365,0.915,-0.04823112403100775,-0.04900228621850522,-0.04949555707888578,49.224806201550386,0.314,-0.02961368217054264,-0.03685357516921869,-0.029047547385211904,44.96124031007752,0.566,-0.02533209302325577,-0.012891433059302676,-0.007163189941517431,50.0,0.892,0.033963837209302274,0.042444573151777756,0.01668944054546775,46.51162790697674,0.768,78.29457364341084,89.92248062015504,3.0,0.9422608695652175,neutro
|
||||
MEDxMA182,-1,58,-0.022809137931034486,-0.02034156879114435,-0.03494005917786492,48.275862068965516,0.614,0.007036206896551722,0.0022230272623963124,0.002245404883013482,46.55172413793103,0.976,-0.01394482758620689,-0.02929424853310631,-0.02308937649800395,43.103448275862064,0.815,0.028821551724137955,-0.010465656017253815,-0.005815294666567431,48.275862068965516,0.866,-0.048383620689655175,-0.07670426764079707,-0.03016054160321107,41.37931034482759,0.706,77.58620689655173,89.65517241379311,5.0,0.9422608695652175,neutro
|
||||
MA182xMA3,-1,85,-0.09941294117647062,-0.10679718080176766,-0.18344208627937292,44.70588235294118,0.05,0.05273082352941179,0.02606567006587443,0.026328054466521728,49.411764705882355,0.704,0.15997435294117648,0.11817045873361055,0.09314054291437561,52.94117647058824,0.093,0.0777025882352941,-0.008570515770733375,-0.004762250409253931,50.588235294117645,0.894,-0.1411765882352941,-0.29043387357038863,-0.11420020288600495,43.529411764705884,0.232,68.23529411764706,90.58823529411765,5.0,0.9422608695652175,neutro
|
||||
MA30xMA7,1,217,0.003779170506912438,0.009125723884904737,0.015674962725502214,52.07373271889401,0.807,-0.0005046543778801771,-4.6403900819300904e-05,-4.687101559798865e-05,47.465437788018434,0.999,0.02160400921658988,0.011743430538667134,0.009256031564660542,48.8479262672811,0.885,0.0010320737327188937,0.010928539345289034,0.00607249812751899,52.07373271889401,0.903,0.05348820276497695,0.060377308008461784,0.02374069091705335,47.465437788018434,0.725,76.49769585253456,88.0184331797235,3.0,0.9422608695652175,neutro
|
||||
MA14xMA3,1,412,-0.003732427184466025,-0.0042915657702153115,-0.007371484643913094,48.786407766990294,0.878,-0.03452007281553398,-0.03988291933152033,-0.04028439206782132,49.75728155339806,0.264,-0.04675264563106798,-0.0575933632259271,-0.04539440039934409,46.359223300970875,0.3,0.009159538834951474,0.011765943826390329,0.006537806160257662,52.18446601941748,0.868,-0.05554092457420925,-0.06562692404933614,-0.025804868933107607,47.0873786407767,0.25,75.48543689320388,90.2676399026764,4.0,0.9422608695652175,neutro
|
||||
MA365xMA7,-1,45,-0.08103666666666666,-0.08923106924932349,-0.1532693408304292,44.44444444444444,0.026,-0.08737622222222222,-0.11088535951052053,-0.11200156287387926,46.666666666666664,0.293,0.06799755555555557,0.028631136728832742,0.022566719700993443,57.77777777777777,0.725,0.11502799999999996,0.013962899947202765,0.007758555933705275,51.11111111111111,0.892,0.005609333333333373,-0.23899853974037966,-0.09397554559418657,51.11111111111111,0.357,57.77777777777777,84.44444444444444,6.0,0.9422608695652175,neutro
|
||||
PRICExMED,-1,641,0.021020873634945397,0.020767861465922702,0.035672288409384675,52.418096723868956,0.383,0.029750327613104526,0.017480843427518426,0.01765681053728184,50.858034321372855,0.698,0.049702854914196556,0.029052419946197283,0.02289877009672308,49.453978159126365,0.646,0.038525850234009354,0.019713901742313477,0.010954129150653281,51.014040561622465,0.82,-0.0002629017160686441,-0.02220791100080794,-0.008732273239305728,47.113884555382214,0.897,87.3634945397816,94.38377535101404,2.0,0.9422608695652175,neutro
|
||||
MEDxMA121,1,91,0.08019505494505494,0.07113435068349859,0.12218518876196342,49.45054945054945,0.04,-0.021887032967032947,-0.05134812811197136,-0.051865012879751,47.25274725274725,0.548,0.03865461538461538,0.0007329198464039522,0.0005776786613029268,47.25274725274725,0.921,0.11142747252747255,0.023207607627741874,0.012895424485469585,51.64835164835166,0.883,0.0024489010989010673,-0.15220237822472207,-0.05984681559116825,50.54945054945055,0.512,72.52747252747253,87.91208791208791,3.5,0.9422608695652175,neutro
|
||||
MA182xMA7,1,67,0.0076192537313432805,0.007690816049038089,0.01321026763660675,52.23880597014925,0.927,-0.023750447761194032,-0.03375519602686864,-0.03409498536878306,43.28358208955223,0.618,0.034717462686567155,0.008729420900812945,0.00688042519884507,44.776119402985074,0.926,0.06607283582089549,0.023456423448585822,0.013033680254006787,50.74626865671642,0.865,-0.26800970149253733,-0.31012847852817405,-0.12194423031052547,41.7910447761194,0.143,79.1044776119403,88.05970149253731,5.0,0.9422608695652175,neutro
|
||||
MA121xMA7,-1,88,0.07495238636363637,0.06364985841309972,0.10932931685114719,48.86363636363637,0.281,0.07764045454545455,0.043606296058068095,0.044045249356668474,43.18181818181818,0.685,0.10674397727272728,0.06296209107771732,0.049625967512090224,45.45454545454545,0.68,0.11821409090909088,0.025940150893838124,0.014413775963417735,48.86363636363637,0.748,0.1481702272727273,-0.01654939020211934,-0.006507311614475473,45.45454545454545,0.945,73.86363636363636,89.77272727272727,4.0,0.9422608695652175,neutro
|
||||
MEDxMA365,-1,37,-0.052988108108108105,-0.044443665841789014,-0.07633945692868081,45.94594594594595,0.662,-0.08400891891891892,-0.06157995647948478,-0.06219983772297179,48.64864864864865,0.624,-0.1621889189189189,-0.14576280294546232,-0.1148884987716481,43.24324324324324,0.176,0.024111081081081055,0.04505525828960639,0.025035182008697174,51.35135135135135,0.761,-0.05749944444444447,0.018377259173368816,0.0072260397876034365,40.54054054054054,0.016,67.56756756756756,88.88888888888889,8.0,0.9422608695652175,neutro
|
||||
MA121xMA14,-1,73,0.08883123287671232,0.0738440967816724,0.1268396325759725,53.42465753424658,0.077,0.1377391780821918,0.10205717603308966,0.1030845124068534,49.31506849315068,0.237,0.13806506849315067,0.09286285233037742,0.07319339008513785,54.794520547945204,0.375,0.12088643835616443,0.019819180009174625,0.011012627551783014,45.20547945205479,0.923,-0.061453287671232926,-0.2486090503677838,-0.09775445144285876,41.0958904109589,0.264,65.75342465753424,86.3013698630137,5.0,0.9493714285714286,neutro
|
||||
PRICExMA30,-1,427,0.017202927400468377,0.016748936289171738,0.0287691097534581,52.92740046838408,0.482,0.02481250585480094,0.01723528755002068,0.017408782824930823,51.288056206088996,0.739,0.04980238875878221,0.03435935517273575,0.027081633000940863,50.585480093676814,0.609,-0.0037466042154566874,-0.0024782808638988425,-0.0013770692889511526,49.88290398126464,0.965,-0.000713957845433267,-0.007468103997197523,-0.0029364997311411936,47.07259953161593,0.96,81.49882903981265,90.63231850117096,3.0,0.9650000000000001,neutro
|
||||
MA182xMA7,-1,66,-0.04358954545454546,-0.05050061533379705,-0.08674328447320295,53.03030303030303,0.129,0.13645151515151513,0.10235803550251647,0.10338840041271781,56.060606060606055,0.28,0.17344772727272728,0.12187603155843105,0.09606123111692019,62.121212121212125,0.074,0.12494348484848483,0.010132061312829493,0.005629931082838358,46.96969696969697,0.957,0.05132227272727275,-0.15314031847959297,-0.06021561887876152,42.42424242424242,0.557,66.66666666666666,89.39393939393939,6.0,0.9650000000000001,neutro
|
||||
|
@@ -0,0 +1,79 @@
|
||||
# EURUSD (D1, 1999+) — cosa succede dopo ogni incrocio (36 coppie x 2 dir)
|
||||
|
||||
extra5/10/20 = extra-rendimento % vs baseline stesso regime; pos10 = % che batte il baseline;
|
||||
q10 = significativita' (BH, <0.10 robusto); rev10/20 = % ritorno alla Mediana; btr = giorni mediani.
|
||||
|
||||
| coppia | dir | n | extra5 | extra10 | extra20 | pos10 | q10 | rev10 | rev20 | btr | dopo 10g |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| MA182xMA30 | +1 | 36 | -0.203 | -0.337 | +0.300 | 39% | 0.000 | 64% | 86% | 4 | SCENDE (extra -) |
|
||||
| MA365xMA121 | +1 | 15 | +0.209 | -0.130 | -0.902 | 53% | 0.000 | 43% | 71% | 5 | SCENDE (extra -) |
|
||||
| MA365xMA7 | +1 | 46 | +0.349 | +0.381 | +0.138 | 52% | 0.000 | 63% | 80% | 4 | SALE (extra +) |
|
||||
| MA365xMA182 | -1 | 16 | +0.132 | +0.452 | +0.216 | 69% | 0.000 | 56% | 69% | 4 | SALE (extra +) |
|
||||
| MA365xMA121 | -1 | 14 | +0.560 | +0.478 | +1.030 | 79% | 0.000 | 50% | 71% | 3 | SALE (extra +) |
|
||||
| MA365xMA182 | +1 | 16 | +0.298 | +0.556 | +0.622 | 56% | 0.000 | 75% | 81% | 4 | SALE (extra +) |
|
||||
| MA121xMA7 | +1 | 88 | +0.240 | +0.299 | +0.160 | 57% | 0.010 | 73% | 86% | 3 | SALE (extra +) |
|
||||
| MA121xMA3 | +1 | 117 | +0.138 | +0.235 | +0.139 | 59% | 0.027 | 75% | 87% | 4 | SALE (extra +) |
|
||||
| PRICExMA121 | -1 | 192 | +0.060 | +0.268 | +0.228 | 56% | 0.048 | 80% | 92% | 3 | SALE (extra +) |
|
||||
| MA182xMA121 | +1 | 31 | -0.314 | -0.339 | -0.462 | 35% | 0.151 | 55% | 77% | 2 | neutro |
|
||||
| MA121xMA14 | +1 | 73 | +0.132 | +0.138 | +0.249 | 55% | 0.190 | 71% | 84% | 3 | neutro |
|
||||
| MA365xMA30 | -1 | 21 | -0.033 | -0.142 | +0.339 | 38% | 0.360 | 67% | 81% | 6 | neutro |
|
||||
| MEDxMA30 | +1 | 151 | -0.017 | -0.121 | -0.170 | 48% | 0.461 | 82% | 92% | 3 | neutro |
|
||||
| MA30xMA3 | -1 | 259 | -0.046 | -0.110 | -0.136 | 46% | 0.461 | 77% | 90% | 3 | neutro |
|
||||
| MEDxMA121 | -1 | 84 | +0.326 | +0.264 | +0.331 | 57% | 0.461 | 75% | 87% | 3 | neutro |
|
||||
| MA365xMA3 | -1 | 52 | -0.122 | -0.204 | -0.397 | 44% | 0.472 | 62% | 85% | 5 | neutro |
|
||||
| MA182xMA30 | -1 | 35 | -0.386 | -0.375 | -0.125 | 43% | 0.508 | 74% | 89% | 4 | neutro |
|
||||
| MEDxMA14 | +1 | 182 | +0.172 | +0.161 | +0.231 | 53% | 0.528 | 68% | 83% | 4 | neutro |
|
||||
| MA14xMA7 | -1 | 383 | +0.011 | -0.064 | +0.017 | 47% | 0.572 | 77% | 90% | 3 | neutro |
|
||||
| MA365xMA14 | +1 | 28 | +0.111 | -0.216 | +0.220 | 43% | 0.596 | 54% | 81% | 7 | neutro |
|
||||
| MA30xMA7 | -1 | 217 | -0.023 | -0.111 | -0.046 | 48% | 0.596 | 78% | 88% | 3 | neutro |
|
||||
| PRICExMA30 | +1 | 428 | -0.024 | -0.065 | -0.048 | 47% | 0.596 | 81% | 91% | 2 | neutro |
|
||||
| PRICExMA3 | +1 | 1365 | -0.038 | -0.048 | -0.062 | 48% | 0.596 | 69% | 85% | 4 | neutro |
|
||||
| PRICExMA7 | +1 | 943 | -0.036 | -0.045 | -0.068 | 48% | 0.596 | 71% | 86% | 3 | neutro |
|
||||
| PRICExMA14 | +1 | 623 | +0.002 | +0.018 | -0.002 | 50% | 0.596 | 77% | 90% | 3 | neutro |
|
||||
| MA14xMA7 | +1 | 382 | -0.000 | +0.024 | +0.094 | 50% | 0.596 | 74% | 89% | 3 | neutro |
|
||||
| MA7xMA3 | -1 | 783 | -0.011 | +0.030 | +0.036 | 50% | 0.596 | 73% | 87% | 3 | neutro |
|
||||
| MA121xMA3 | -1 | 117 | +0.022 | +0.135 | -0.053 | 52% | 0.596 | 74% | 91% | 4 | neutro |
|
||||
| PRICExMA121 | +1 | 192 | +0.011 | +0.163 | +0.149 | 58% | 0.596 | 79% | 92% | 3 | neutro |
|
||||
| PRICExMA365 | +1 | 90 | -0.091 | -0.150 | -0.483 | 50% | 0.637 | 67% | 86% | 3 | neutro |
|
||||
| PRICExMED | +1 | 641 | -0.007 | -0.034 | -0.040 | 47% | 0.637 | 87% | 94% | 2 | neutro |
|
||||
| MA14xMA3 | -1 | 413 | +0.005 | -0.028 | -0.023 | 48% | 0.637 | 77% | 90% | 4 | neutro |
|
||||
| PRICExMA3 | -1 | 1365 | -0.021 | -0.013 | -0.014 | 50% | 0.681 | 70% | 85% | 4 | neutro |
|
||||
| MA365xMA3 | +1 | 53 | +0.054 | +0.087 | -0.144 | 47% | 0.758 | 60% | 77% | 4 | neutro |
|
||||
| MEDxMA14 | -1 | 185 | -0.044 | -0.082 | -0.053 | 50% | 0.769 | 69% | 83% | 4 | neutro |
|
||||
| MEDxMA365 | +1 | 33 | -0.228 | -0.076 | -0.266 | 48% | 0.782 | 76% | 88% | 6 | neutro |
|
||||
| MA121xMA30 | -1 | 52 | -0.115 | -0.311 | -0.424 | 48% | 0.794 | 63% | 87% | 5 | neutro |
|
||||
| MA182xMA14 | -1 | 46 | +0.171 | -0.209 | -0.075 | 41% | 0.794 | 63% | 87% | 5 | neutro |
|
||||
| MA182xMA121 | -1 | 30 | -0.225 | -0.176 | +0.333 | 50% | 0.794 | 70% | 83% | 3 | neutro |
|
||||
| MA7xMA3 | +1 | 783 | +0.013 | +0.062 | +0.028 | 52% | 0.816 | 71% | 86% | 4 | neutro |
|
||||
| MEDxMA3 | +1 | 274 | +0.040 | +0.073 | +0.006 | 52% | 0.816 | 77% | 88% | 4 | neutro |
|
||||
| MEDxMA7 | +1 | 228 | -0.043 | +0.092 | -0.105 | 51% | 0.816 | 74% | 86% | 4 | neutro |
|
||||
| MEDxMA182 | +1 | 60 | -0.034 | -0.131 | -0.015 | 45% | 0.926 | 65% | 87% | 4 | neutro |
|
||||
| PRICExMA14 | -1 | 622 | +0.006 | +0.048 | +0.026 | 52% | 0.926 | 77% | 90% | 4 | neutro |
|
||||
| MA182xMA3 | +1 | 86 | +0.019 | +0.098 | -0.217 | 55% | 0.926 | 79% | 91% | 4 | neutro |
|
||||
| PRICExMA182 | +1 | 139 | -0.205 | -0.096 | -0.312 | 50% | 0.928 | 75% | 88% | 3 | neutro |
|
||||
| MA365xMA14 | -1 | 27 | +0.015 | -0.059 | +0.134 | 52% | 0.928 | 59% | 89% | 8 | neutro |
|
||||
| MA182xMA14 | +1 | 47 | -0.023 | -0.053 | -0.064 | 43% | 0.928 | 74% | 85% | 5 | neutro |
|
||||
| MA121xMA30 | +1 | 53 | +0.084 | -0.050 | -0.031 | 42% | 0.928 | 62% | 81% | 3 | neutro |
|
||||
| MEDxMA30 | -1 | 142 | +0.038 | -0.048 | +0.050 | 48% | 0.928 | 85% | 94% | 2 | neutro |
|
||||
| PRICExMA7 | -1 | 943 | -0.025 | -0.033 | -0.048 | 50% | 0.928 | 72% | 87% | 4 | neutro |
|
||||
| MEDxMA3 | -1 | 278 | -0.021 | +0.041 | -0.118 | 47% | 0.928 | 78% | 91% | 3 | neutro |
|
||||
| MA365xMA30 | +1 | 22 | -0.224 | +0.056 | +0.540 | 59% | 0.928 | 64% | 90% | 8 | neutro |
|
||||
| PRICExMA365 | -1 | 91 | -0.071 | +0.058 | +0.010 | 51% | 0.928 | 68% | 86% | 4 | neutro |
|
||||
| PRICExMA182 | -1 | 140 | -0.089 | -0.074 | -0.189 | 46% | 0.942 | 78% | 88% | 4 | neutro |
|
||||
| MEDxMA7 | -1 | 240 | +0.061 | -0.026 | -0.095 | 47% | 0.942 | 76% | 88% | 4 | neutro |
|
||||
| MA30xMA14 | -1 | 186 | -0.080 | -0.025 | -0.057 | 52% | 0.942 | 73% | 85% | 4 | neutro |
|
||||
| MA30xMA14 | +1 | 186 | -0.052 | -0.024 | -0.141 | 52% | 0.942 | 73% | 87% | 3 | neutro |
|
||||
| MA30xMA3 | +1 | 258 | -0.037 | -0.013 | +0.042 | 50% | 0.942 | 78% | 90% | 3 | neutro |
|
||||
| MEDxMA182 | -1 | 58 | -0.029 | -0.010 | -0.077 | 48% | 0.942 | 78% | 90% | 5 | neutro |
|
||||
| MA182xMA3 | -1 | 85 | +0.118 | -0.009 | -0.290 | 51% | 0.942 | 68% | 91% | 5 | neutro |
|
||||
| MA30xMA7 | +1 | 217 | +0.012 | +0.011 | +0.060 | 52% | 0.942 | 76% | 88% | 3 | neutro |
|
||||
| MA14xMA3 | +1 | 412 | -0.058 | +0.012 | -0.066 | 52% | 0.942 | 75% | 90% | 4 | neutro |
|
||||
| MA365xMA7 | -1 | 45 | +0.029 | +0.014 | -0.239 | 51% | 0.942 | 58% | 84% | 6 | neutro |
|
||||
| PRICExMED | -1 | 641 | +0.029 | +0.020 | -0.022 | 51% | 0.942 | 87% | 94% | 2 | neutro |
|
||||
| MEDxMA121 | +1 | 91 | +0.001 | +0.023 | -0.152 | 52% | 0.942 | 73% | 88% | 4 | neutro |
|
||||
| MA182xMA7 | +1 | 67 | +0.009 | +0.023 | -0.310 | 51% | 0.942 | 79% | 88% | 5 | neutro |
|
||||
| MA121xMA7 | -1 | 88 | +0.063 | +0.026 | -0.017 | 49% | 0.942 | 74% | 90% | 4 | neutro |
|
||||
| MEDxMA365 | -1 | 37 | -0.146 | +0.045 | +0.018 | 51% | 0.942 | 68% | 89% | 8 | neutro |
|
||||
| MA121xMA14 | -1 | 73 | +0.093 | +0.020 | -0.249 | 45% | 0.949 | 66% | 86% | 5 | neutro |
|
||||
| PRICExMA30 | -1 | 427 | +0.034 | -0.002 | -0.007 | 50% | 0.965 | 81% | 91% | 3 | neutro |
|
||||
| MA182xMA7 | -1 | 66 | +0.122 | +0.010 | -0.153 | 47% | 0.965 | 67% | 89% | 6 | neutro |
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
@@ -0,0 +1,82 @@
|
||||
"""Utility condivise per l'analisi PaPP v2.
|
||||
|
||||
I dati di input sono i due CSV prodotti dallo script MQL5 `PaPP_CrossExport.mq5`:
|
||||
- PaPP_crosses_<SYM>_D1.csv (un record per incrocio)
|
||||
- PaPP_bars_<SYM>_D1.csv (un record per giorno D1 = baseline)
|
||||
|
||||
Per default vengono cercati in ../data. Si possono passare percorsi diversi via argv.
|
||||
"""
|
||||
import os, sys, numpy as np, pandas as pd
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
DATA = os.path.normpath(os.path.join(HERE, "..", "data"))
|
||||
HZ = [1, 3, 5, 10, 20]
|
||||
|
||||
|
||||
def load(path):
|
||||
df = pd.read_csv(path)
|
||||
df["time"] = pd.to_datetime(df["time"], format="%Y.%m.%d", errors="coerce")
|
||||
if df["time"].isna().all():
|
||||
df["time"] = pd.to_datetime(df["time"], errors="coerce")
|
||||
return df.dropna(subset=["time"]).sort_values("time").reset_index(drop=True)
|
||||
|
||||
|
||||
def load_pair(sym="EURUSD", year_min=1999, data_dir=None):
|
||||
d = data_dir or DATA
|
||||
cr = load(os.path.join(d, f"PaPP_crosses_{sym}_D1.csv"))
|
||||
ba = load(os.path.join(d, f"PaPP_bars_{sym}_D1.csv"))
|
||||
if year_min:
|
||||
cr = cr[cr.time.dt.year >= year_min].reset_index(drop=True)
|
||||
ba = ba[ba.time.dt.year >= year_min].reset_index(drop=True)
|
||||
return cr, ba
|
||||
|
||||
|
||||
def add_regime(df, edges):
|
||||
"""Regime = trend(sopra/sotto MA365) x tercile(cluster) x tercile(velocita')."""
|
||||
tr = (df["trend"] > 0).astype(int)
|
||||
cl = np.digitize(df["cluster_pct"], edges["cl"])
|
||||
ve = np.digitize(df["vel_med"], edges["ve"])
|
||||
out = df.copy()
|
||||
out["regime"] = tr.astype(str) + "_" + cl.astype(str) + "_" + ve.astype(str)
|
||||
return out
|
||||
|
||||
|
||||
def regime_edges(ba):
|
||||
return {
|
||||
"cl": np.quantile(ba["cluster_pct"], [1/3, 2/3]),
|
||||
"ve": np.quantile(ba["vel_med"], [1/3, 2/3]),
|
||||
}
|
||||
|
||||
|
||||
def block_bootstrap_p(x, nb=2000, bs=20, seed=42):
|
||||
"""p-value bilaterale per media != 0 con block bootstrap (gestisce overlap)."""
|
||||
rng = np.random.default_rng(seed)
|
||||
x = np.asarray(x, float)
|
||||
n = len(x)
|
||||
if n < 10:
|
||||
return np.nan
|
||||
nblocks = int(np.ceil(n / bs))
|
||||
idx = np.arange(n)
|
||||
means = np.empty(nb)
|
||||
for k in range(nb):
|
||||
starts = rng.integers(0, n, size=nblocks)
|
||||
pick = np.concatenate([
|
||||
idx[s:s+bs] if s+bs <= n else np.concatenate([idx[s:], idx[:s+bs-n]])
|
||||
for s in starts])[:n]
|
||||
means[k] = x[pick].mean()
|
||||
return 2 * min((means <= 0).mean(), (means >= 0).mean())
|
||||
|
||||
|
||||
def benjamini_hochberg(p):
|
||||
"""q-value BH per array di p (NaN ammessi)."""
|
||||
p = np.asarray(p, float)
|
||||
out = np.full_like(p, np.nan)
|
||||
idx = np.where(~np.isnan(p))[0]
|
||||
if len(idx) == 0:
|
||||
return out
|
||||
m = len(idx)
|
||||
order = idx[np.argsort(p[idx])]
|
||||
q = p[order] * m / np.arange(1, m + 1)
|
||||
q = np.minimum.accumulate(q[::-1])[::-1]
|
||||
out[order] = np.clip(q, 0, 1)
|
||||
return out
|
||||
@@ -0,0 +1,69 @@
|
||||
"""Fase 2 raffinata: extra-rendimento vs baseline + significativita'.
|
||||
|
||||
Per ogni (coppia, direzione) calcola:
|
||||
- rendimento medio grezzo a 1/3/5/10/20 g
|
||||
- EXTRA-rendimento = evento - baseline nello stesso regime (toglie il bias di periodo)
|
||||
- effetto in sigma del movimento tipico a h giorni
|
||||
- quota di eventi che battono la baseline
|
||||
- p-value (block bootstrap) e q-value (Benjamini-Hochberg)
|
||||
|
||||
Uso:
|
||||
python excess_analysis.py [SYMBOL] [YEAR_MIN]
|
||||
Output:
|
||||
../results/summary_<SYM>_<YEAR>.csv + stampa dei top a 5/10/20 g
|
||||
"""
|
||||
import os, sys, numpy as np, pandas as pd
|
||||
from _common import load_pair, add_regime, regime_edges, block_bootstrap_p, benjamini_hochberg, HZ, HERE
|
||||
|
||||
SYM = sys.argv[1] if len(sys.argv) > 1 else "EURUSD"
|
||||
YEAR = int(sys.argv[2]) if len(sys.argv) > 2 else 1999
|
||||
RESULTS = os.path.normpath(os.path.join(HERE, "..", "results"))
|
||||
|
||||
cr, ba = load_pair(SYM, YEAR)
|
||||
print(f"[{SYM} {YEAR}+] incroci={len(cr)} baseline={len(ba)}")
|
||||
|
||||
edges = regime_edges(ba)
|
||||
cr = add_regime(cr, edges)
|
||||
ba = add_regime(ba, edges)
|
||||
|
||||
base_mean = {h: ba.groupby("regime")[f"cret_{h}"].mean() for h in HZ}
|
||||
base_glob = {h: ba[f"cret_{h}"].mean() for h in HZ}
|
||||
base_sd = {h: ba[f"cret_{h}"].std() for h in HZ}
|
||||
|
||||
rows = []
|
||||
for (pair, d), g in cr.groupby(["pair", "dir"]):
|
||||
n = len(g)
|
||||
if n < 30:
|
||||
continue
|
||||
rec = {"pair": pair, "dir": int(d), "n": n}
|
||||
for h in HZ:
|
||||
ev = g[f"cret_{h}"].values
|
||||
bexp = g["regime"].map(base_mean[h]).fillna(base_glob[h]).values
|
||||
exc = ev - bexp
|
||||
rec[f"raw_{h}"] = np.nanmean(ev)
|
||||
rec[f"exc_{h}"] = np.nanmean(exc)
|
||||
rec[f"eff_{h}"] = np.nanmean(exc) / base_sd[h]
|
||||
rec[f"pos_{h}"] = (exc > 0).mean()
|
||||
rec[f"p_{h}"] = block_bootstrap_p(exc)
|
||||
rows.append(rec)
|
||||
|
||||
res = pd.DataFrame(rows)
|
||||
for h in HZ:
|
||||
res[f"q_{h}"] = benjamini_hochberg(res[f"p_{h}"].values)
|
||||
|
||||
os.makedirs(RESULTS, exist_ok=True)
|
||||
outp = os.path.join(RESULTS, f"summary_{SYM}_{YEAR}.csv")
|
||||
res.to_csv(outp, index=False)
|
||||
|
||||
print(f"vol giornaliera prezzo (sd cret_1) = {ba['cret_1'].std():.3f}%")
|
||||
print(f"baseline drift 5/10/20g = {base_glob[5]:.3f}% / {base_glob[10]:.3f}% / {base_glob[20]:.3f}%")
|
||||
for h in [5, 10, 20]:
|
||||
sig = res[res[f"q_{h}"] < 0.10].copy()
|
||||
sig["ae"] = sig[f"eff_{h}"].abs()
|
||||
sig = sig.sort_values("ae", ascending=False).head(12)
|
||||
print(f"\n=== TOP {h}g (q<0.10) ===")
|
||||
for _, r in sig.iterrows():
|
||||
print(f" {r['pair']:13s} dir={int(r['dir']):+d} n={int(r['n']):5d} "
|
||||
f"exc={r[f'exc_{h}']:+.3f}% eff={r[f'eff_{h}']:+.2f}sd "
|
||||
f"pos={r[f'pos_{h}']*100:.0f}% q={r[f'q_{h}']:.3f}")
|
||||
print(f"\nsalvato: {outp}")
|
||||
@@ -0,0 +1,83 @@
|
||||
"""Verifiche di correttezza + tabella completa 36 coppie x 2 direzioni.
|
||||
|
||||
Verifiche:
|
||||
V1 la direzione registrata coincide col segno di (A-B) all'incrocio
|
||||
V2 cret_1 coincide con ret_1
|
||||
V3 ricalcolo indipendente della media di un pattern
|
||||
V4 baseline drift ~0
|
||||
|
||||
Tabella: per ogni (coppia, dir) extra-rendimento 5/10/20g, quota che batte il baseline,
|
||||
q-value a 10g, tasso di ritorno alla Mediana (rev10/rev20), giorni mediani al ritorno,
|
||||
ed etichetta verbale "dopo 10g".
|
||||
|
||||
Uso:
|
||||
python full_table.py [SYMBOL] [YEAR_MIN]
|
||||
Output:
|
||||
../results/tabella_incroci_<SYM>_<YEAR>.csv (+ .md)
|
||||
"""
|
||||
import os, sys, numpy as np, pandas as pd
|
||||
from _common import load_pair, add_regime, regime_edges, block_bootstrap_p, benjamini_hochberg, HZ, HERE
|
||||
|
||||
SYM = sys.argv[1] if len(sys.argv) > 1 else "EURUSD"
|
||||
YEAR = int(sys.argv[2]) if len(sys.argv) > 2 else 1999
|
||||
RESULTS = os.path.normpath(os.path.join(HERE, "..", "results"))
|
||||
|
||||
cr, ba = load_pair(SYM, YEAR)
|
||||
|
||||
# ---------------- VERIFICHE ----------------
|
||||
sub = cr[cr.pair == "PRICExMED"]
|
||||
chk = ((sub.price - sub.med) > 0).astype(int).replace(0, -1)
|
||||
print(f"[V1] PRICExMED dir vs segno(price-med): {(np.sign(sub.dir)==np.sign(chk)).mean()*100:.1f}% (atteso ~100%)")
|
||||
print(f"[V2] max|cret_1 - ret_1| = {(cr.cret_1-cr.ret_1).abs().max():.6f} (atteso 0)")
|
||||
g0 = cr[(cr.pair=='MA121xMA7') & (cr.dir==1)]
|
||||
print(f"[V3] MA121xMA7+ n={len(g0)} media cret_10 = {g0.cret_10.mean():.4f}%")
|
||||
print(f"[V4] baseline cret_10 medio={ba.cret_10.mean():.4f}% sd={ba.cret_10.std():.3f}% (drift ~0)")
|
||||
|
||||
# ---------------- TABELLA ----------------
|
||||
edges = regime_edges(ba)
|
||||
cr = add_regime(cr, edges); ba = add_regime(ba, edges)
|
||||
bmean = {h: ba.groupby("regime")[f"cret_{h}"].mean() for h in HZ}
|
||||
bglob = {h: ba[f"cret_{h}"].mean() for h in HZ}
|
||||
bsd = {h: ba[f"cret_{h}"].std() for h in HZ}
|
||||
|
||||
rows = []
|
||||
for (pair, d), g in cr.groupby(["pair", "dir"]):
|
||||
rec = {"pair": pair, "dir": int(d), "n": len(g)}
|
||||
for h in HZ:
|
||||
ev = g[f"cret_{h}"].values
|
||||
bexp = g["regime"].map(bmean[h]).fillna(bglob[h]).values
|
||||
exc = ev - bexp
|
||||
rec[f"raw_{h}"] = np.nanmean(ev)
|
||||
rec[f"exc_{h}"] = np.nanmean(exc)
|
||||
rec[f"eff_{h}"] = np.nanmean(exc) / bsd[h]
|
||||
rec[f"pos_{h}"] = (exc > 0).mean() * 100
|
||||
rec[f"p_{h}"] = block_bootstrap_p(exc)
|
||||
rec["rev10"] = g["rev_10"].mean() * 100
|
||||
rec["rev20"] = g["rev_20"].mean() * 100
|
||||
rec["btr_med"] = g["bars_to_revert"].median()
|
||||
rows.append(rec)
|
||||
res = pd.DataFrame(rows)
|
||||
res["q10"] = benjamini_hochberg(res["p_10"].values)
|
||||
|
||||
def verb(r):
|
||||
if r["q10"] < 0.10 and r["exc_10"] > 0: return "SALE (extra +)"
|
||||
if r["q10"] < 0.10 and r["exc_10"] < 0: return "SCENDE (extra -)"
|
||||
return "neutro"
|
||||
res["dopo_10g"] = res.apply(verb, axis=1)
|
||||
res = res.sort_values(["q10", "exc_10"]).reset_index(drop=True)
|
||||
|
||||
os.makedirs(RESULTS, exist_ok=True)
|
||||
csvp = os.path.join(RESULTS, f"tabella_incroci_{SYM}_{YEAR}.csv")
|
||||
res.to_csv(csvp, index=False)
|
||||
|
||||
md = [f"# {SYM} (D1, {YEAR}+) — cosa succede dopo ogni incrocio (36 coppie x 2 dir)", "",
|
||||
"extra5/10/20 = extra-rendimento % vs baseline stesso regime; pos10 = % che batte il baseline;",
|
||||
"q10 = significativita' (BH, <0.10 robusto); rev10/20 = % ritorno alla Mediana; btr = giorni mediani.", "",
|
||||
"| coppia | dir | n | extra5 | extra10 | extra20 | pos10 | q10 | rev10 | rev20 | btr | dopo 10g |",
|
||||
"|---|---|---|---|---|---|---|---|---|---|---|---|"]
|
||||
for _, x in res.iterrows():
|
||||
md.append(f"| {x['pair']} | {int(x['dir']):+d} | {int(x['n'])} | {x['exc_5']:+.3f} | "
|
||||
f"{x['exc_10']:+.3f} | {x['exc_20']:+.3f} | {x['pos_10']:.0f}% | {x['q10']:.3f} | "
|
||||
f"{x['rev10']:.0f}% | {x['rev20']:.0f}% | {x['btr_med']:.0f} | {x['dopo_10g']} |")
|
||||
open(os.path.join(RESULTS, f"tabella_incroci_{SYM}_{YEAR}.md"), "w").write("\n".join(md))
|
||||
print(f"\nsalvato: {csvp} (+ .md) righe={len(res)}")
|
||||
@@ -0,0 +1,43 @@
|
||||
"""Grafico delle traiettorie di extra-rendimento (giorno per giorno) dopo l'incrocio.
|
||||
|
||||
Disegna l'extra-rendimento cumulato (cret_1..20 - baseline stesso regime) per un
|
||||
insieme di pattern (default: i piu' consistenti legati alla MA121/MA365).
|
||||
|
||||
Uso:
|
||||
python plot_trajectories.py [SYMBOL] [YEAR_MIN]
|
||||
Output:
|
||||
../results/trajectories_<SYM>_<YEAR>.png
|
||||
"""
|
||||
import os, sys, numpy as np
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
from _common import load_pair, add_regime, regime_edges, HERE
|
||||
|
||||
SYM = sys.argv[1] if len(sys.argv) > 1 else "EURUSD"
|
||||
YEAR = int(sys.argv[2]) if len(sys.argv) > 2 else 1999
|
||||
RESULTS = os.path.normpath(os.path.join(HERE, "..", "results"))
|
||||
HZ = list(range(1, 21))
|
||||
|
||||
cr, ba = load_pair(SYM, YEAR)
|
||||
edges = regime_edges(ba)
|
||||
cr = add_regime(cr, edges); ba = add_regime(ba, edges)
|
||||
bmean = {h: ba.groupby("regime")[f"cret_{h}"].mean() for h in HZ}
|
||||
bglob = {h: ba[f"cret_{h}"].mean() for h in HZ}
|
||||
|
||||
sel = [("MA121xMA7", 1), ("MEDxMA121", -1), ("PRICExMA121", -1), ("MA121xMA3", 1), ("MA365xMA7", 1)]
|
||||
plt.figure(figsize=(11, 6))
|
||||
for pair, d in sel:
|
||||
g = cr[(cr.pair == pair) & (cr.dir == d)]
|
||||
if len(g) < 20:
|
||||
continue
|
||||
exc = [(g[f"cret_{h}"] - g["regime"].map(bmean[h]).fillna(bglob[h])).mean() for h in HZ]
|
||||
plt.plot(HZ, exc, marker="o", ms=3, label=f"{pair} dir={d:+d} (n={len(g)})")
|
||||
plt.axhline(0, color="k", lw=.8)
|
||||
plt.title(f"{SYM} ({YEAR}+) - extra-rendimento medio vs baseline (stesso regime)")
|
||||
plt.xlabel("giorni dopo l'incrocio"); plt.ylabel("extra-rendimento cumulato (%)")
|
||||
plt.legend(); plt.grid(alpha=.3); plt.tight_layout()
|
||||
os.makedirs(RESULTS, exist_ok=True)
|
||||
outp = os.path.join(RESULTS, f"trajectories_{SYM}_{YEAR}.png")
|
||||
plt.savefig(outp, dpi=130)
|
||||
print("salvato:", outp)
|
||||
@@ -0,0 +1,4 @@
|
||||
data/*.csv
|
||||
results/*.joblib
|
||||
src/__pycache__/
|
||||
*.pyc
|
||||
@@ -0,0 +1,111 @@
|
||||
# PaPP v2 — Fase 3: modelli
|
||||
|
||||
> **Modello principale → [`README_mean_reversion.md`](README_mean_reversion.md).**
|
||||
> La validazione esterna (sez. 5b) ha mostrato che l'edge **direzionale** non
|
||||
> generalizza fuori da EURUSD, mentre la **mean-reversion** sì. Il modeling è
|
||||
> quindi orientato sul **rientro alla Mediana**. Questo documento descrive il
|
||||
> primo modello (direzionale), tenuto come riferimento metodologico.
|
||||
|
||||
---
|
||||
|
||||
# Fase 3 (riferimento): classificatore extra-rendimento direzionale
|
||||
|
||||
Architettura del modello che prova a prevedere, al momento di un incrocio, se
|
||||
l'**extra-rendimento a 10 giorni** (rispetto alla baseline dello stesso regime)
|
||||
sarà **positivo o no**. È lo scheletro modulare della Fase 3, già pronto per
|
||||
l'export ONNX della Fase 4.
|
||||
|
||||
> Stato: **scaffolding funzionante end-to-end**. Il modello di riferimento è un
|
||||
> baseline volutamente semplice; i risultati attuali confermano che l'edge è
|
||||
> debole (vedi sotto) e indicano dove migliorare. L'obiettivo di questa cartella
|
||||
> è la **struttura**, non ancora un modello ottimizzato.
|
||||
|
||||
---
|
||||
|
||||
## 1. Idea e target
|
||||
|
||||
- **Target** (binario): `1` se `extra-rendimento a 10g > 0`, altrimenti `0`, dove
|
||||
`extra = cret_10(incrocio) − media cret_10 della baseline nello stesso regime`.
|
||||
- **Regime** = `trend (sopra/sotto MA365) × tercile(cluster) × tercile(velocità)`.
|
||||
- **Feature** (solo informazioni note all'incrocio, nessun esito futuro):
|
||||
`dist_med_pct, cluster_pct, cluster_exp, slope_a, slope_b, vel_med, acc_med,
|
||||
vol_med` (numeriche) + `pair, dir, trend, dow, month` (categoriche).
|
||||
|
||||
### Niente leakage (punto chiave)
|
||||
Terzili del regime e medie di baseline sono stimati **solo sul training**
|
||||
(`labeling.RegimeBaseline.fit`) e applicati a validazione/OOS. Così la label di
|
||||
test non usa mai informazione futura.
|
||||
|
||||
---
|
||||
|
||||
## 2. Validazione
|
||||
|
||||
- **Walk-forward espansivo**: train = tutti gli anni fino a T, test = anno T+1,
|
||||
scorrendo T (configurabile `min_train_years`, `step_years`).
|
||||
- **Hold-out OOS**: tutti gli anni `>= oos_start_year` (default **2020**) sono
|
||||
tenuti fuori dal training e usati solo alla fine.
|
||||
|
||||
Metriche (`evaluate.py`): AUC, accuracy, Brier, e **precisione/lift sul decile a
|
||||
probabilità più alta** (uso pratico: si opera solo sui segnali più forti).
|
||||
|
||||
---
|
||||
|
||||
## 3. Struttura
|
||||
|
||||
```
|
||||
Modello/
|
||||
├── config.yaml tutti i parametri (target, regime, feature, split, modello)
|
||||
├── requirements.txt
|
||||
├── src/
|
||||
│ ├── data.py caricamento CSV + etichetta di regime
|
||||
│ ├── labeling.py RegimeBaseline: baseline per regime e target (fit su train)
|
||||
│ ├── features.py ColumnTransformer (one-hot + impute), selezione X
|
||||
│ ├── splits.py split OOS + walk-forward espansivo
|
||||
│ ├── model.py factory modello (hist_gbdt | logistic)
|
||||
│ ├── evaluate.py metriche
|
||||
│ └── train.py pipeline end-to-end
|
||||
├── results/ metriche walk-forward + OOS (modello .joblib non versionato)
|
||||
└── data/ i 2 CSV di input (non versionati)
|
||||
```
|
||||
|
||||
## 4. Come eseguire
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
# copia i 2 CSV in ./data (vedi data/README.md), poi:
|
||||
cd src
|
||||
python train.py # usa ../config.yaml
|
||||
python selftest.py # verifiche di correttezza (reproducibilita', anti-leakage, varianti)
|
||||
```
|
||||
|
||||
## 5. Risultati attuali (EURUSD, hold-out 2020+)
|
||||
|
||||
Con il baseline `hist_gbdt` e tutte le coppie:
|
||||
- walk-forward medio **AUC ≈ 0.51**, OOS 2020+ **AUC ≈ 0.52**, lift sul decile ≈ 1.0×.
|
||||
|
||||
Lettura onesta: **vicino al caso**. È coerente con la Fase 2 (edge direzionali
|
||||
piccoli) e ci dà un riferimento pulito e senza leakage da cui partire.
|
||||
|
||||
### 5b. Validazione esterna multi-simbolo (`src/external_validation.py`)
|
||||
Addestrando SOLO su EURUSD e testando su USDJPY/USDCHF/GBPUSD (mai visti):
|
||||
- i pattern direzionali "robusti" di EURUSD **non si replicano**: concordanza di
|
||||
segno solo **38%**; il modello esterno ha **AUC ≈ 0.48–0.55** (caso) contro
|
||||
AUC 0.91 in-sample (memorizzazione) → l'edge direzionale è **specifico di
|
||||
EURUSD**, non generale.
|
||||
- al contrario la **mean-reversion è universale**: ritorno alla Mediana entro 20g
|
||||
nell'**87–90%** dei casi su tutti i simboli, mediana **3 giorni**.
|
||||
|
||||
Conclusione operativa: il bersaglio "su/giù" non regge fuori campione; il segnale
|
||||
generalizzabile e' la **mean-reversion**. Il modeling va orientato lì.
|
||||
|
||||
## 6. Prossimi miglioramenti previsti
|
||||
|
||||
- **Restringere ai pattern robusti** (q<0.10): in `config.yaml` valorizzare
|
||||
`restrict_pairs` con gli incroci MA121/MA182/MA365 emersi in Fase 2.
|
||||
- **Target alternativi**: classificare solo le code (es. extra nel top/bottom 30%)
|
||||
invece del semplice segno; oppure regressione sull'extra-rendimento.
|
||||
- **Feature aggiuntive**: percentile storico delle metriche (come nel pannello),
|
||||
interazioni coppia×regime, stato di mean-reversion in corso.
|
||||
- **Calibrazione** delle probabilità e scelta soglia per massimizzare la
|
||||
precisione sui segnali operativi.
|
||||
- **Fase 4**: export del `Pipeline` in **ONNX** (skl2onnx) e inferenza in MT5.
|
||||
@@ -0,0 +1,123 @@
|
||||
# Fase 3 — Modello di MEAN-REVERSION (rientro alla Mediana)
|
||||
|
||||
> Questo è il **modello principale** della Fase 3. Nasce dopo aver dimostrato
|
||||
> (vedi `README.md` sez. 5b, validazione esterna) che l'edge **direzionale**
|
||||
> "su/giù" **non generalizza** fuori da EURUSD, mentre la **mean-reversion** è
|
||||
> universale (rientro alla Mediana entro 20g nell'87–90% dei casi su tutti i
|
||||
> major FX). Quindi modelliamo ciò che è davvero robusto: il **rientro alla
|
||||
> Mediana**.
|
||||
|
||||
---
|
||||
|
||||
## 1. Idea
|
||||
|
||||
Dopo un incrocio il prezzo tende a tornare sulla Mediana. Non vogliamo prevedere
|
||||
la direzione, ma **caratterizzare il rientro**. Tre target, costruiti da esiti
|
||||
già presenti nei CSV (nessuna baseline di regime: sono osservazioni dirette):
|
||||
|
||||
| target | tipo | colonna | domanda |
|
||||
|---|---|---|---|
|
||||
| `rev` | classificazione | `rev_10` | rientra alla Mediana **entro 10 giorni**? (sì/no) |
|
||||
| `speed` | regressione | `bars_to_revert` | in **quanti giorni** rientra (solo eventi rientrati) |
|
||||
| `disc` | regressione | `disc_max_pct` | **quanto si allontana** (max %) prima di rientrare |
|
||||
|
||||
Esclusione del banale (`drop_trivial`): gli eventi già praticamente sulla
|
||||
Mediana (`|dist_med_pct| < 0.05%`) rientrano per costruzione; vengono esclusi per
|
||||
studiare il rientro "vero".
|
||||
|
||||
## 2. Feature (note al momento dell'incrocio)
|
||||
|
||||
`abs_dist` (=|dist_med_pct|), `dist_med_pct`, `cluster_pct`, `cluster_exp`,
|
||||
`slope_a`, `slope_b`, `vel_med`, `acc_med`, `vol_med` (numeriche) +
|
||||
`pair`, `dir`, `trend`, `dow`, `month` (categoriche). Nessuna colonna di esito
|
||||
futuro è tra le feature.
|
||||
|
||||
## 3. Pooling pulito + validazione (anti-inquinamento)
|
||||
|
||||
I 4 major FX (EURUSD, USDJPY, USDCHF, GBPUSD) hanno mean-reversion omogenea →
|
||||
si possono **mettere in pool**. Le feature sono già in percentuale/relative,
|
||||
quindi confrontabili tra simboli. Due validazioni, entrambe oneste:
|
||||
|
||||
1. **Walk-forward pooled**: train tutti i simboli fino all'anno T, test anno T+1
|
||||
→ generalizzazione **nel tempo**.
|
||||
2. **Leave-one-symbol-out (LOSO)**: train su 3 simboli, test sul 4° **mai visto**
|
||||
→ generalizzazione **tra strumenti** (la prova più severa anti-inquinamento).
|
||||
|
||||
Ogni metrica è confrontata con una **baseline banale**:
|
||||
- classificazione → accuratezza della classe maggioritaria;
|
||||
- regressione → MAE ottenuto prevedendo sempre la mediana del train
|
||||
(`skill_% = 1 − MAE/MAE_baseline`).
|
||||
|
||||
## 4. Risultati (pool 4 major FX, ~39k incroci)
|
||||
|
||||
**Walk-forward (nel tempo):**
|
||||
- `rev` : **AUC ≈ 0.65** (la baseline è 0.5) → il modello sa **ordinare** quali
|
||||
incroci rientreranno entro 10g e quali no.
|
||||
- `speed` : skill ≈ **+2%** → marginale (la mediana è ~3g e cambia poco).
|
||||
- `disc` : skill ≈ **−3%** → non meglio della mediana.
|
||||
|
||||
**Leave-one-symbol-out (su simbolo mai visto):**
|
||||
|
||||
| target | EURUSD | USDJPY | USDCHF | GBPUSD |
|
||||
|---|---|---|---|---|
|
||||
| `rev` AUC | 0.677 | 0.687 | 0.682 | 0.688 |
|
||||
| `speed` skill | +1.3% | +4.8% | −2.9% | +2.8% |
|
||||
| `disc` skill | +2.0% | +5.8% | −1.1% | −0.1% |
|
||||
|
||||
**Lettura:** il classificatore di rientro (`rev`) ha un edge **reale e
|
||||
generalizzabile** — AUC ~0.68 anche su un simbolo completamente fuori dal
|
||||
training. I due regressori (`speed`, `disc`) aggiungono poco: la velocità e
|
||||
l'ampiezza dell'allontanamento sono in pratica vicine alla mediana storica.
|
||||
|
||||
## 5. Cosa guida il rientro (importanza, permutation su holdout 2018+)
|
||||
|
||||
```
|
||||
abs_dist +0.104 <- distanza dalla Mediana: di gran lunga il fattore #1
|
||||
dist_med_pct +0.025 <- il segno della distanza (sopra/sotto)
|
||||
trend +0.021
|
||||
cluster_exp +0.017 <- cluster in espansione/contrazione
|
||||
vel_med +0.010
|
||||
... (vol_med, cluster_pct ~0)
|
||||
pair ~0 <- QUALI linee si incrociano e' irrilevante
|
||||
```
|
||||
|
||||
Conferma economica: il rientro dipende da **quanto sei lontano dalla Mediana** e
|
||||
dal **regime**, non dallo specifico tipo di incrocio. È coerente con la Fase 2 e
|
||||
con la validazione esterna (il "pattern" di linee era rumore).
|
||||
|
||||
## 6. Uso operativo
|
||||
|
||||
Il modello `rev` non dice "compra/vendi": stima la **probabilità di rientro
|
||||
rapido**. Serve da **filtro**: tra i setup di mean-reversion (prezzo lontano
|
||||
dalla Mediana), privilegiare quelli con alta probabilità ed evitare il ~25% che
|
||||
tende a NON rientrare in fretta (i casi rischiosi, spesso inizio di trend).
|
||||
|
||||
## 7. File e come eseguire
|
||||
|
||||
```
|
||||
Modello/
|
||||
├── config_mr.yaml parametri del modello di mean-reversion
|
||||
├── src/
|
||||
│ ├── mr_labeling.py costruzione dei 3 target + maschere
|
||||
│ └── mr_train.py pool + walk-forward + LOSO + modelli finali
|
||||
└── results/
|
||||
├── mr_wf_<task>.csv metriche walk-forward per anno
|
||||
├── mr_loso_<task>.csv metriche leave-one-symbol-out
|
||||
├── mr_summary.json riepilogo medio
|
||||
└── mr_model_<task>.joblib modelli finali (non versionati)
|
||||
```
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
# copia in ./data i CSV crosses+bars dei 4 simboli (vedi data/README.md), poi:
|
||||
cd src
|
||||
python mr_train.py # usa ../config_mr.yaml
|
||||
```
|
||||
|
||||
## 8. Prossimi passi
|
||||
|
||||
- **Calibrazione** delle probabilità di `rev` e scelta soglia operativa
|
||||
(precisione vs copertura) per l'EA.
|
||||
- Aggiungere altri major FX al pool per irrobustire ancora il LOSO.
|
||||
- **Fase 4**: export del modello `rev` in **ONNX** (skl2onnx) e inferenza in MT5
|
||||
come filtro dei segnali di mean-reversion.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Configurazione Fase 3 — classificatore extra-rendimento positivo
|
||||
|
||||
symbol: EURUSD
|
||||
year_min: 1999 # esclude i dati EURUSD sintetici pre-1999
|
||||
|
||||
# --- target ---
|
||||
horizon: 10 # orizzonte (giorni D1) per l'extra-rendimento
|
||||
target: excess_positive # 1 se extra-rendimento a `horizon` > 0, altrimenti 0
|
||||
|
||||
# --- definizione del regime per la baseline (terzili stimati SOLO sul train) ---
|
||||
regime:
|
||||
use_trend: true # sopra/sotto MA365
|
||||
cluster_terciles: true
|
||||
velocity_terciles: true
|
||||
|
||||
# --- feature usate dal modello (note al momento dell'incrocio) ---
|
||||
features_numeric:
|
||||
- dist_med_pct
|
||||
- cluster_pct
|
||||
- cluster_exp
|
||||
- slope_a
|
||||
- slope_b
|
||||
- vel_med
|
||||
- acc_med
|
||||
- vol_med
|
||||
features_categorical:
|
||||
- pair
|
||||
- dir
|
||||
- trend
|
||||
- dow
|
||||
- month
|
||||
|
||||
# --- validazione ---
|
||||
oos_start_year: 2020 # hold-out finale mai usato in training
|
||||
walkforward:
|
||||
scheme: expanding # finestra espansiva
|
||||
min_train_years: 8 # anni minimi nel primo fold
|
||||
step_years: 1
|
||||
|
||||
# --- modello di riferimento ---
|
||||
model:
|
||||
kind: hist_gbdt # hist_gbdt | logistic
|
||||
hist_gbdt:
|
||||
max_depth: 4
|
||||
learning_rate: 0.05
|
||||
max_iter: 400
|
||||
l2_regularization: 1.0
|
||||
early_stopping: true
|
||||
|
||||
# opzionale: limita ai pattern robusti (q<0.10). Vuoto = usa tutti gli incroci.
|
||||
restrict_pairs: []
|
||||
|
||||
seed: 42
|
||||
@@ -0,0 +1,44 @@
|
||||
# Configurazione Fase 3 — modello di MEAN-REVERSION (rientro alla Mediana)
|
||||
|
||||
# pooling pulito sui major FX (dinamica di mean-reversion omogenea)
|
||||
symbols: [EURUSD, USDJPY, USDCHF, GBPUSD]
|
||||
year_min: 1999
|
||||
|
||||
horizon: 10 # orizzonte per il target di classificazione rev_N
|
||||
drop_trivial: true # esclude gli eventi gia' praticamente sulla Mediana
|
||||
trivial_eps: 0.05 # soglia |dist_med_pct| (%) sotto cui l'evento e' "banale"
|
||||
|
||||
# feature note al momento dell'incrocio
|
||||
features_numeric:
|
||||
- abs_dist # |dist_med_pct| (derivata): quanto e' lontano dalla Mediana
|
||||
- dist_med_pct
|
||||
- cluster_pct
|
||||
- cluster_exp
|
||||
- slope_a
|
||||
- slope_b
|
||||
- vel_med
|
||||
- acc_med
|
||||
- vol_med
|
||||
features_categorical:
|
||||
- pair
|
||||
- dir
|
||||
- trend
|
||||
- dow
|
||||
- month
|
||||
|
||||
# validazione
|
||||
oos_start_year: 2020
|
||||
walkforward:
|
||||
min_train_years: 8
|
||||
step_years: 1
|
||||
|
||||
model:
|
||||
kind: hist_gbdt
|
||||
hist_gbdt:
|
||||
max_depth: 4
|
||||
learning_rate: 0.05
|
||||
max_iter: 400
|
||||
l2_regularization: 1.0
|
||||
early_stopping: true
|
||||
|
||||
seed: 42
|
||||
@@ -0,0 +1,8 @@
|
||||
# Dati di input (non versionati)
|
||||
|
||||
Copia qui i due CSV prodotti da `PaPP v2/PaPP_CrossExport.mq5`:
|
||||
|
||||
- `PaPP_crosses_<SYMBOL>_D1.csv`
|
||||
- `PaPP_bars_<SYMBOL>_D1.csv`
|
||||
|
||||
Sono gli stessi file usati in `PaPP v2/Analisi/`. Poi lancia `src/train.py`.
|
||||
@@ -0,0 +1,8 @@
|
||||
pandas
|
||||
numpy
|
||||
scikit-learn
|
||||
pyyaml
|
||||
joblib
|
||||
# Fase 4 (export ONNX), opzionali finche' non si esporta:
|
||||
# skl2onnx
|
||||
# onnxruntime
|
||||
@@ -0,0 +1,5 @@
|
||||
symbol,n,base_rate,auc,acc,brier,prec_top_decile,lift_top_decile
|
||||
EURUSD (in-sample),16895,0.4976028410772418,0.913591163259108,0.8320213080793134,0.15547236980731827,0.9875666074600356,1.9846482494394315
|
||||
USDJPY,7084,0.5172219085262564,0.4800203976097449,0.49110671936758893,0.28183992572414085,0.4646892655367232,0.8984330668837737
|
||||
USDCHF,7967,0.5049579515501443,0.47560023778083327,0.48449855654575125,0.2879368779869159,0.4296482412060301,0.8508594426270052
|
||||
GBPUSD,7239,0.5020030390937975,0.5483399577270303,0.5322558364414974,0.2593864013259506,0.5712309820193637,1.137903433912541
|
||||
|
@@ -0,0 +1,5 @@
|
||||
n,mae,mae_baseline,skill_%,r2,test_symbol
|
||||
15898,0.7016688523942158,0.7156681469367216,1.956115359112609,0.056705406202969044,EURUSD
|
||||
6635,0.766700972158277,0.8138184204973624,5.789675823544238,0.09699286957940556,USDJPY
|
||||
7349,0.7110993410001212,0.703173893046673,-1.1270964453912402,0.13820883251935367,USDCHF
|
||||
6807,0.7712259995571173,0.7706658777728809,-0.07268023671362922,0.10481685322904755,GBPUSD
|
||||
|
@@ -0,0 +1,5 @@
|
||||
n,base_rate,acc_baseline,auc,acc,test_symbol
|
||||
15887,0.7324227355699628,0.7324227355699628,0.6765454819075187,0.7357587965002832,EURUSD
|
||||
6619,0.7028252001812962,0.7028252001812962,0.6869979773747487,0.719292944553558,USDJPY
|
||||
7331,0.7603328331741918,0.7603328331741918,0.6816590320250597,0.7442368026190151,USDCHF
|
||||
6798,0.7374227714033539,0.7374227714033539,0.687844098341511,0.7375698734922036,GBPUSD
|
||||
|
@@ -0,0 +1,5 @@
|
||||
n,mae,mae_baseline,skill_%,r2,test_symbol
|
||||
13909,3.610173858972498,3.65878208354303,1.3285356564187945,0.09908303164055288,EURUSD
|
||||
5729,3.615529034826519,3.7987432361668705,4.823021456044085,0.1281263482188003,USDJPY
|
||||
6570,3.627862458240022,3.5245053272450533,-2.9325287210094197,0.07345132592032444,USDCHF
|
||||
6090,3.638542831980693,3.744006568144499,2.8168683533072225,0.11825074333860008,GBPUSD
|
||||
|
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"wf": {
|
||||
"rev": {
|
||||
"n": 1594.0,
|
||||
"base_rate": 0.7183856164543461,
|
||||
"acc_baseline": 0.7183856164543461,
|
||||
"auc": 0.6478491068895667,
|
||||
"acc": 0.7130101340748866,
|
||||
"test_year": 2016.5
|
||||
},
|
||||
"speed": {
|
||||
"n": 1406.55,
|
||||
"mae": 3.6537111122909542,
|
||||
"mae_baseline": 3.7337467740160712,
|
||||
"skill_%": 1.7998203587207346,
|
||||
"r2": 0.07833366023387726,
|
||||
"test_year": 2016.5
|
||||
},
|
||||
"disc": {
|
||||
"n": 1596.7,
|
||||
"mae": 0.7847562209218487,
|
||||
"mae_baseline": 0.7657217825432683,
|
||||
"skill_%": -3.381481774117468,
|
||||
"r2": -0.36203395606382444,
|
||||
"test_year": 2016.5
|
||||
}
|
||||
},
|
||||
"loso": {
|
||||
"rev": {
|
||||
"n": 9158.75,
|
||||
"base_rate": 0.7332508850822013,
|
||||
"acc_baseline": 0.7332508850822013,
|
||||
"auc": 0.6832616474122095,
|
||||
"acc": 0.734214604291265
|
||||
},
|
||||
"speed": {
|
||||
"n": 8074.5,
|
||||
"mae": 3.623027046004933,
|
||||
"mae_baseline": 3.681509303774863,
|
||||
"skill_%": 1.5089741861901707,
|
||||
"r2": 0.10472786227956943
|
||||
},
|
||||
"disc": {
|
||||
"n": 9172.25,
|
||||
"mae": 0.7376737912774329,
|
||||
"mae_baseline": 0.7508315845634095,
|
||||
"skill_%": 1.6365036251379943,
|
||||
"r2": 0.09918099038269396
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
n,mae,mae_baseline,skill_%,r2,test_year
|
||||
468,0.5210450337997958,0.4877705555555555,-6.82174802584008,-0.440278374819538,2007
|
||||
511,1.4979005200832076,1.46627927592955,-2.1565635327970734,-0.4428980601648529,2008
|
||||
590,0.5372706093503566,0.624245779661017,13.932840740691965,0.09814855360679986,2009
|
||||
548,0.8435515547481117,0.9210056204379563,8.40972779873087,-0.20129888622520697,2010
|
||||
649,0.6264895295465607,0.7349227426810478,14.754368974746313,-0.23270335993701874,2011
|
||||
563,0.8444189035765441,0.7120972291296623,-18.581967326092208,-0.6572098948790617,2012
|
||||
574,0.6570009471217217,0.5640415679442509,-16.480944749564785,-1.9530900867332583,2013
|
||||
1089,0.8585576108637076,0.8849660055096419,2.984114020371431,-0.0058690268732339845,2014
|
||||
2465,0.86287949087831,0.8346033630831645,-3.387971945223023,0.1741985535476418,2015
|
||||
2440,0.9893521953097881,0.9588108852459016,-3.1853320121677298,0.06164644338816894,2016
|
||||
2405,0.6483027913003414,0.606651659043659,-6.865741094707012,-0.3827607195275795,2017
|
||||
2208,0.716304832228868,0.6826646195652174,-4.927780303756735,-0.30219708772441267,2018
|
||||
2520,0.7276522650483845,0.693340365079365,-4.948781536048585,-0.9380918084727767,2019
|
||||
2351,1.0262956818683626,0.9582834198213527,-7.097301345325269,-0.054525480586665065,2020
|
||||
2378,0.5921425747388034,0.566631362489487,-4.502259129680586,-0.6404632411590949,2021
|
||||
2074,0.9417510265311481,1.0620946142719383,11.330778456426438,-0.41893129794772066,2022
|
||||
2185,0.6089553673717031,0.5467215652173913,-11.383088964044408,-0.23632995343602725,2023
|
||||
2317,0.7212702214350022,0.6373334527406128,-13.169992620574188,-0.24062608198432445,2024
|
||||
2335,0.7021795509288201,0.7111189250535332,1.2570856729822166,0.1140083899835217,2025
|
||||
1264,0.7718037117074369,0.6608526424050633,-16.78907856047691,-0.5414077013318492,2026
|
||||
|
@@ -0,0 +1,21 @@
|
||||
n,base_rate,acc_baseline,auc,acc,test_year
|
||||
468,0.6175213675213675,0.6175213675213675,0.641878177495119,0.6260683760683761,2007
|
||||
511,0.6516634050880626,0.6516634050880626,0.5756149407834801,0.6594911937377691,2008
|
||||
590,0.7440677966101695,0.7440677966101695,0.5982138816394877,0.7372881355932204,2009
|
||||
548,0.7408759124087592,0.7408759124087592,0.6361617983764658,0.7299270072992701,2010
|
||||
649,0.5855161787365177,0.5855161787365177,0.6710135002934846,0.6718027734976888,2011
|
||||
563,0.8206039076376554,0.8206039076376554,0.6997342591401998,0.7708703374777975,2012
|
||||
574,0.6933797909407665,0.6933797909407665,0.6654865235267245,0.6428571428571429,2013
|
||||
1089,0.6464646464646465,0.6464646464646465,0.6203659976387249,0.6721763085399449,2014
|
||||
2465,0.7829614604462475,0.7829614604462475,0.6354597840298292,0.7517241379310344,2015
|
||||
2440,0.7487704918032787,0.7487704918032787,0.6421575586789066,0.6905737704918032,2016
|
||||
2405,0.7600831600831601,0.7600831600831601,0.6408060252797805,0.755925155925156,2017
|
||||
2208,0.7336956521739131,0.7336956521739131,0.6192271352985639,0.7133152173913043,2018
|
||||
2520,0.8067460317460318,0.8067460317460318,0.6465879719737271,0.7746031746031746,2019
|
||||
2351,0.7243726074011059,0.7243726074011059,0.6688414780017834,0.7209698000850702,2020
|
||||
2378,0.7863751051303617,0.7863751051303617,0.6841361741547013,0.7901597981497056,2021
|
||||
2074,0.6769527483124397,0.6769527483124397,0.5842326827401454,0.6557377049180327,2022
|
||||
2185,0.6668192219679634,0.6668192219679634,0.6764596076538425,0.6906178489702517,2023
|
||||
2317,0.6551575312904618,0.6551575312904618,0.6896672553471812,0.6870953819594303,2024
|
||||
2335,0.7430406852248393,0.7430406852248393,0.7314169068203651,0.7644539614561028,2025
|
||||
1210,0.7826446280991736,0.7826446280991736,0.6295204789188191,0.7545454545454545,2026
|
||||
|
@@ -0,0 +1,21 @@
|
||||
n,mae,mae_baseline,skill_%,r2,test_year
|
||||
338,3.465379140810698,3.4142011834319526,-1.498973101734502,0.12927353007997744,2007
|
||||
400,4.090858376700547,3.9425,-3.7630533088280904,0.04579965148367826,2008
|
||||
540,4.0205317754813965,3.8740740740740742,-3.780456919691866,-0.12200728544542727,2009
|
||||
470,3.1693714434220257,3.421276595744681,7.362899352714425,0.2246464741787182,2010
|
||||
495,4.314538334266083,4.3232323232323235,0.20109927749014656,-0.055325713812715005,2011
|
||||
515,3.2237999945625653,2.9029126213592233,-11.053979745800735,-0.06562655938335582,2012
|
||||
485,3.733393114617742,4.072164948453608,8.319207058754174,0.19434702822584105,2013
|
||||
879,3.924266870235131,4.180887372013652,6.137943430294424,0.022748161878883844,2014
|
||||
2243,3.398709049328624,3.3410610789121713,-1.7254389864438613,0.07268045675088919,2015
|
||||
2243,3.6650255510608725,3.7588051716451183,2.494931668490852,0.06864404910302002,2016
|
||||
2206,3.65145803728882,3.8028105167724386,3.9800163278205125,0.10526816265720629,2017
|
||||
1923,3.577364530993464,3.4607384295371815,-3.3699773568810043,0.07894792932730887,2018
|
||||
2354,3.356457496216363,3.373406966864911,0.502443696092203,0.015425103761181336,2019
|
||||
2116,3.8333614130177756,3.972117202268431,3.4932450928540915,0.049572458729656765,2020
|
||||
2190,3.3981138450501156,3.4990867579908675,2.8856933229837733,0.12873115565641913,2021
|
||||
1715,3.799187552337051,3.816909620991254,0.4643041207142984,0.0433313417575899,2022
|
||||
1810,4.043300720188006,3.8784530386740332,-4.250346204277644,0.06762624567274822,2023
|
||||
1997,3.6962952238115996,4.476214321482224,17.423631704309617,0.2427214165484335,2024
|
||||
2094,3.369937232661497,3.7597898758357213,10.369000823152874,0.2265055214709174,2025
|
||||
1118,3.3428725437687103,3.4042933810375673,1.804216922401003,0.09336407603657426,2026
|
||||
|
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"n": 3951,
|
||||
"base_rate": 0.49253353581371806,
|
||||
"auc": 0.5241849128463528,
|
||||
"acc": 0.5206276891926095,
|
||||
"brier": 0.2758629924455611,
|
||||
"prec_top_decile": 0.48860759493670886,
|
||||
"lift_top_decile": 0.9920290892060312
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
n,base_rate,auc,acc,brier,prec_top_decile,lift_top_decile,fold,test_years
|
||||
506,0.6027667984189723,0.5552565043634288,0.5533596837944664,0.2929861795083319,0.66,1.0949508196721314,0,2007-2007
|
||||
528,0.4431818181818182,0.4868160939589511,0.48674242424242425,0.3025718576380564,0.19230769230769232,0.43392504930966475,1,2008-2008
|
||||
618,0.5857605177993528,0.48292904005524856,0.46116504854368934,0.32693476077811057,0.5081967213114754,0.8675844579295353,2,2009-2009
|
||||
570,0.44912280701754387,0.5532568670382165,0.531578947368421,0.28012422532136644,0.631578947368421,1.40625,3,2010-2010
|
||||
669,0.554559043348281,0.3955570831599703,0.4200298953662182,0.3276694334072587,0.3484848484848485,0.6283999019848078,4,2011-2011
|
||||
616,0.5227272727272727,0.5127920733510796,0.5032467532467533,0.2825509892233342,0.5901639344262295,1.129009265858874,5,2012-2012
|
||||
583,0.5265866209262435,0.5670466883821933,0.5214408233276158,0.2796922887853283,0.7068965517241379,1.342412669886555,6,2013-2013
|
||||
565,0.2884955752212389,0.5871104599700881,0.4424778761061947,0.3559192608214337,0.17857142857142858,0.6189745836985101,7,2014-2014
|
||||
627,0.45614035087719296,0.46299448352234274,0.49920255183413076,0.31880860582951115,0.3709677419354839,0.8132754342431763,8,2015-2015
|
||||
749,0.4512683578104139,0.5659165838840179,0.5046728971962616,0.2895300011880442,0.6756756756756757,1.4972813049736124,9,2016-2016
|
||||
628,0.6496815286624203,0.4584336007130124,0.49044585987261147,0.2895065709863026,0.3870967741935484,0.5958254269449715,10,2017-2017
|
||||
622,0.5,0.41347794170862584,0.45980707395498394,0.29186125547058084,0.2903225806451613,0.5806451612903226,11,2018-2018
|
||||
707,0.36633663366336633,0.5378947186982901,0.5487977369165488,0.27594238285206885,0.5142857142857142,1.4038610038610038,12,2019-2019
|
||||
|
@@ -0,0 +1,54 @@
|
||||
"""Caricamento dei dati e definizione del regime.
|
||||
|
||||
I dati sono i due CSV prodotti da `PaPP v2/PaPP_CrossExport.mq5`:
|
||||
- PaPP_crosses_<SYM>_D1.csv (un record per incrocio)
|
||||
- PaPP_bars_<SYM>_D1.csv (un record per giorno D1 = baseline)
|
||||
|
||||
Per default cercati in ../data; sovrascrivibili via argomento.
|
||||
|
||||
NB sulla correttezza temporale: i terzili del regime e le medie di baseline
|
||||
NON vengono calcolati qui su tutti i dati, ma stimati sul SOLO training
|
||||
(vedi labeling.RegimeBaseline.fit) e applicati al test. Qui carichiamo solo.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
DATA_DIR = os.path.normpath(os.path.join(HERE, "..", "data"))
|
||||
|
||||
|
||||
def _read(path: str) -> pd.DataFrame:
|
||||
df = pd.read_csv(path)
|
||||
df["time"] = pd.to_datetime(df["time"], format="%Y.%m.%d", errors="coerce")
|
||||
if df["time"].isna().all():
|
||||
df["time"] = pd.to_datetime(df["time"], errors="coerce")
|
||||
return df.dropna(subset=["time"]).sort_values("time").reset_index(drop=True)
|
||||
|
||||
|
||||
def load(symbol: str = "EURUSD", year_min: int = 1999, data_dir: str | None = None):
|
||||
d = data_dir or DATA_DIR
|
||||
crosses = _read(os.path.join(d, f"PaPP_crosses_{symbol}_D1.csv"))
|
||||
bars = _read(os.path.join(d, f"PaPP_bars_{symbol}_D1.csv"))
|
||||
if year_min:
|
||||
crosses = crosses[crosses.time.dt.year >= year_min].reset_index(drop=True)
|
||||
bars = bars[bars.time.dt.year >= year_min].reset_index(drop=True)
|
||||
return crosses, bars
|
||||
|
||||
|
||||
def regime_labels(df: pd.DataFrame, edges: dict, cfg_regime: dict) -> pd.Series:
|
||||
"""Etichetta di regime coerente con `edges` (terzili stimati sul train)."""
|
||||
parts = []
|
||||
if cfg_regime.get("use_trend", True):
|
||||
parts.append((df["trend"] > 0).astype(int).astype(str))
|
||||
if cfg_regime.get("cluster_terciles", True):
|
||||
parts.append(np.digitize(df["cluster_pct"], edges["cl"]).astype(str))
|
||||
if cfg_regime.get("velocity_terciles", True):
|
||||
parts.append(np.digitize(df["vel_med"], edges["ve"]).astype(str))
|
||||
if not parts:
|
||||
return pd.Series(["all"] * len(df), index=df.index)
|
||||
out = parts[0]
|
||||
for p in parts[1:]:
|
||||
out = out + "_" + p
|
||||
return out
|
||||
@@ -0,0 +1,23 @@
|
||||
"""Metriche di valutazione del classificatore."""
|
||||
from __future__ import annotations
|
||||
import numpy as np
|
||||
from sklearn.metrics import roc_auc_score, accuracy_score, brier_score_loss
|
||||
|
||||
|
||||
def metrics(y_true, p_pred) -> dict:
|
||||
y_true = np.asarray(y_true)
|
||||
p = np.asarray(p_pred)
|
||||
out = {"n": int(len(y_true)), "base_rate": float(y_true.mean())}
|
||||
if len(np.unique(y_true)) < 2:
|
||||
out.update({"auc": np.nan, "acc": np.nan, "brier": np.nan,
|
||||
"prec_top_decile": np.nan, "lift_top_decile": np.nan})
|
||||
return out
|
||||
out["auc"] = float(roc_auc_score(y_true, p))
|
||||
out["acc"] = float(accuracy_score(y_true, (p >= 0.5).astype(int)))
|
||||
out["brier"] = float(brier_score_loss(y_true, p))
|
||||
# precisione sul decile a piu' alta probabilita' (uso pratico: prendo solo i segnali piu' forti)
|
||||
k = max(1, int(0.1 * len(p)))
|
||||
top = np.argsort(p)[-k:]
|
||||
out["prec_top_decile"] = float(y_true[top].mean())
|
||||
out["lift_top_decile"] = float(y_true[top].mean() / max(y_true.mean(), 1e-9))
|
||||
return out
|
||||
@@ -0,0 +1,116 @@
|
||||
"""Validazione esterna: addestra SOLO su EURUSD, testa su altri simboli mai visti.
|
||||
|
||||
Due livelli:
|
||||
A) Pattern: gli incroci robusti di EURUSD (extra-rendimento a 10g) hanno lo
|
||||
stesso segno/forza sugli altri simboli? (replica del pattern)
|
||||
B) Modello: il classificatore addestrato su EURUSD generalizza? AUC e
|
||||
precisione sul decile piu' forte su ogni simbolo esterno.
|
||||
|
||||
Nessun dato dei simboli di test entra nell'addestramento (zero inquinamento).
|
||||
La baseline di ciascun simbolo (definizione del target) e' calcolata sui dati
|
||||
di quel simbolo: serve solo a definire la ground-truth, non i pesi del modello.
|
||||
|
||||
Uso:
|
||||
python external_validation.py [config.yaml] SYM_TRAIN SYM_TEST1 SYM_TEST2 ...
|
||||
(default: train=EURUSD, test=USDJPY USDCHF GBPUSD)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import os, sys
|
||||
import numpy as np, pandas as pd
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
import train as T
|
||||
from data import load
|
||||
from labeling import RegimeBaseline
|
||||
from features import select_xy
|
||||
from model import make_model
|
||||
from evaluate import metrics
|
||||
|
||||
RESULTS = os.path.normpath(os.path.join(HERE, "..", "results"))
|
||||
ROBUST = ["MA365xMA7", "MA365xMA182", "MA365xMA121", "MA121xMA7",
|
||||
"MA121xMA3", "PRICExMA121", "MA182xMA30", "MA182xMA121"]
|
||||
|
||||
|
||||
def load_sym(sym, cfg):
|
||||
cr, ba = load(sym, cfg["year_min"])
|
||||
cr = cr.dropna(subset=[f"cret_{cfg['horizon']}"]).reset_index(drop=True)
|
||||
return cr, ba
|
||||
|
||||
|
||||
def main():
|
||||
cfg_path = sys.argv[1] if len(sys.argv) > 1 else os.path.join(HERE, "..", "config.yaml")
|
||||
cfg = T.load_cfg(cfg_path)
|
||||
args = sys.argv[2:]
|
||||
sym_tr = args[0] if args else "EURUSD"
|
||||
sym_te = args[1:] if len(args) > 1 else ["USDJPY", "USDCHF", "GBPUSD"]
|
||||
num, cat, h = cfg["features_numeric"], cfg["features_categorical"], cfg["horizon"]
|
||||
|
||||
cr_tr, ba_tr = load_sym(sym_tr, cfg)
|
||||
|
||||
# ---------- A) replica dei pattern ----------
|
||||
def pair_excess(cr, ba):
|
||||
rb = RegimeBaseline(cfg["regime"], h).fit(ba)
|
||||
ex = rb.excess(cr)
|
||||
out = {}
|
||||
for (p, d), idx in cr.groupby(["pair", "dir"]).groups.items():
|
||||
out[(p, int(d))] = ex[cr.index.get_indexer(idx)].mean()
|
||||
return out
|
||||
|
||||
base_ex = pair_excess(cr_tr, ba_tr)
|
||||
print(f"=== A) Replica pattern robusti: extra-rendimento {h}g (%), segno vs {sym_tr} ===")
|
||||
print(f"{'pattern':16s} {sym_tr:>9s}", end="")
|
||||
sym_ex = {}
|
||||
for s in sym_te:
|
||||
c, b = load_sym(s, cfg)
|
||||
sym_ex[s] = pair_excess(c, b)
|
||||
print(f" {s:>9s}", end="")
|
||||
print(" concordi")
|
||||
agree_counts = []
|
||||
for p in ROBUST:
|
||||
for d in (1, -1):
|
||||
key = (p, d)
|
||||
if key not in base_ex:
|
||||
continue
|
||||
row = f"{p+('+' if d>0 else '-'):16s} {base_ex[key]*1:+8.3f}"
|
||||
signs = []
|
||||
for s in sym_te:
|
||||
v = sym_ex[s].get(key, np.nan)
|
||||
row += f" {v:+8.3f}" if not np.isnan(v) else f" {'n/a':>8s}"
|
||||
if not np.isnan(v):
|
||||
signs.append(np.sign(v) == np.sign(base_ex[key]))
|
||||
conc = f"{sum(signs)}/{len(signs)}" if signs else "-"
|
||||
agree_counts.append((sum(signs), len(signs)))
|
||||
print(row + f" {conc}")
|
||||
tot_a = sum(a for a, _ in agree_counts); tot_n = sum(n for _, n in agree_counts)
|
||||
print(f"\nConcordanza di segno totale: {tot_a}/{tot_n} ({tot_a/max(tot_n,1)*100:.0f}%)")
|
||||
|
||||
# ---------- B) modello EURUSD -> simboli esterni ----------
|
||||
print(f"\n=== B) Modello addestrato su {sym_tr}, testato esternamente ===")
|
||||
rb_tr = RegimeBaseline(cfg["regime"], h).fit(ba_tr)
|
||||
y_tr = rb_tr.label(cr_tr)
|
||||
mdl = make_model(cfg, num, cat)
|
||||
mdl.fit(select_xy(cr_tr, num, cat), y_tr)
|
||||
|
||||
rows = []
|
||||
# riferimento in-sample (stesso simbolo, solo per confronto)
|
||||
p_in = mdl.predict_proba(select_xy(cr_tr, num, cat))[:, 1]
|
||||
rows.append({"symbol": sym_tr + " (in-sample)", **metrics(y_tr, p_in)})
|
||||
for s in sym_te:
|
||||
c, b = load_sym(s, cfg)
|
||||
rb = RegimeBaseline(cfg["regime"], h).fit(b)
|
||||
y = rb.label(c)
|
||||
p = mdl.predict_proba(select_xy(c, num, cat))[:, 1]
|
||||
rows.append({"symbol": s, **metrics(y, p)})
|
||||
res = pd.DataFrame(rows)
|
||||
for _, r in res.iterrows():
|
||||
print(f" {r['symbol']:22s} n={int(r['n']):5d} AUC={r['auc']:.3f} "
|
||||
f"acc={r['acc']:.3f} prec@10%={r['prec_top_decile']:.3f} "
|
||||
f"(base {r['base_rate']:.3f}, lift {r['lift_top_decile']:.2f}x)")
|
||||
os.makedirs(RESULTS, exist_ok=True)
|
||||
res.to_csv(os.path.join(RESULTS, "external_validation.csv"), index=False)
|
||||
print(f"\nsalvato: {os.path.join(RESULTS,'external_validation.csv')}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Feature engineering: costruisce la matrice X dalle colonne di contesto.
|
||||
|
||||
Le feature sono SOLO informazioni note al momento dell'incrocio (nessun esito
|
||||
futuro). Categoriche e numeriche sono gestite da un ColumnTransformer
|
||||
(one-hot per le categoriche, passthrough per le numeriche) per restare
|
||||
compatibili con l'export ONNX della Fase 4.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import pandas as pd
|
||||
from sklearn.compose import ColumnTransformer
|
||||
from sklearn.preprocessing import OneHotEncoder
|
||||
from sklearn.impute import SimpleImputer
|
||||
from sklearn.pipeline import Pipeline
|
||||
|
||||
|
||||
def build_preprocessor(num_cols: list[str], cat_cols: list[str]) -> ColumnTransformer:
|
||||
num = Pipeline([("impute", SimpleImputer(strategy="median"))])
|
||||
cat = Pipeline([
|
||||
("impute", SimpleImputer(strategy="most_frequent")),
|
||||
("oh", OneHotEncoder(handle_unknown="ignore", sparse_output=False)),
|
||||
])
|
||||
return ColumnTransformer([
|
||||
("num", num, num_cols),
|
||||
("cat", cat, cat_cols),
|
||||
])
|
||||
|
||||
|
||||
def select_xy(df: pd.DataFrame, num_cols: list[str], cat_cols: list[str]):
|
||||
cols = num_cols + cat_cols
|
||||
X = df[cols].copy()
|
||||
for c in cat_cols:
|
||||
X[c] = X[c].astype(str)
|
||||
return X
|
||||
@@ -0,0 +1,40 @@
|
||||
"""Costruzione del target: extra-rendimento positivo a `horizon` giorni.
|
||||
|
||||
extra = cret_h(incrocio) - baseline_mean_h(regime)
|
||||
|
||||
`RegimeBaseline` impara i terzili del regime e la media di baseline per regime
|
||||
SOLO sui dati di training (fit), e li applica a qualunque set (transform).
|
||||
Cosi' la label di test non usa informazione futura.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from data import regime_labels
|
||||
|
||||
|
||||
class RegimeBaseline:
|
||||
def __init__(self, cfg_regime: dict, horizon: int):
|
||||
self.cfg_regime = cfg_regime
|
||||
self.h = horizon
|
||||
self.edges_: dict = {}
|
||||
self.base_mean_: pd.Series | None = None
|
||||
self.base_glob_: float = 0.0
|
||||
|
||||
def fit(self, bars_train: pd.DataFrame) -> "RegimeBaseline":
|
||||
self.edges_ = {
|
||||
"cl": np.quantile(bars_train["cluster_pct"], [1/3, 2/3]),
|
||||
"ve": np.quantile(bars_train["vel_med"], [1/3, 2/3]),
|
||||
}
|
||||
reg = regime_labels(bars_train, self.edges_, self.cfg_regime)
|
||||
col = f"cret_{self.h}"
|
||||
self.base_mean_ = bars_train.assign(_r=reg).groupby("_r")[col].mean()
|
||||
self.base_glob_ = float(bars_train[col].mean())
|
||||
return self
|
||||
|
||||
def excess(self, crosses: pd.DataFrame) -> np.ndarray:
|
||||
reg = regime_labels(crosses, self.edges_, self.cfg_regime)
|
||||
bexp = reg.map(self.base_mean_).fillna(self.base_glob_).values
|
||||
return crosses[f"cret_{self.h}"].values - bexp
|
||||
|
||||
def label(self, crosses: pd.DataFrame) -> np.ndarray:
|
||||
return (self.excess(crosses) > 0).astype(int)
|
||||
@@ -0,0 +1,47 @@
|
||||
"""Factory del modello di riferimento.
|
||||
|
||||
`hist_gbdt` (HistGradientBoosting) come baseline forte e veloce; `logistic`
|
||||
come riferimento lineare interpretabile. Entrambi esportabili in ONNX
|
||||
(skl2onnx) per la Fase 4.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from sklearn.ensemble import (HistGradientBoostingClassifier,
|
||||
HistGradientBoostingRegressor)
|
||||
from sklearn.linear_model import LogisticRegression
|
||||
from sklearn.pipeline import Pipeline
|
||||
from features import build_preprocessor
|
||||
|
||||
|
||||
def make_model(cfg: dict, num_cols: list[str], cat_cols: list[str]) -> Pipeline:
|
||||
kind = cfg["model"]["kind"]
|
||||
pre = build_preprocessor(num_cols, cat_cols)
|
||||
if kind == "hist_gbdt":
|
||||
p = cfg["model"]["hist_gbdt"]
|
||||
clf = HistGradientBoostingClassifier(
|
||||
max_depth=p["max_depth"],
|
||||
learning_rate=p["learning_rate"],
|
||||
max_iter=p["max_iter"],
|
||||
l2_regularization=p["l2_regularization"],
|
||||
early_stopping=p["early_stopping"],
|
||||
random_state=cfg["seed"],
|
||||
)
|
||||
elif kind == "logistic":
|
||||
clf = LogisticRegression(max_iter=1000, C=1.0, random_state=cfg["seed"])
|
||||
else:
|
||||
raise ValueError(f"model.kind sconosciuto: {kind}")
|
||||
return Pipeline([("pre", pre), ("clf", clf)])
|
||||
|
||||
|
||||
def make_regressor(cfg: dict, num_cols: list[str], cat_cols: list[str]) -> Pipeline:
|
||||
"""Regressore HistGradientBoosting per i target continui di mean-reversion."""
|
||||
pre = build_preprocessor(num_cols, cat_cols)
|
||||
p = cfg["model"]["hist_gbdt"]
|
||||
reg = HistGradientBoostingRegressor(
|
||||
max_depth=p["max_depth"],
|
||||
learning_rate=p["learning_rate"],
|
||||
max_iter=p["max_iter"],
|
||||
l2_regularization=p["l2_regularization"],
|
||||
early_stopping=p["early_stopping"],
|
||||
random_state=cfg["seed"],
|
||||
)
|
||||
return Pipeline([("pre", pre), ("reg", reg)])
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Target di mean-reversion (rientro alla Mediana dopo un incrocio).
|
||||
|
||||
A differenza del target direzionale, questi esiti sono diretti e NON richiedono
|
||||
una baseline di regime: sono proprieta' osservate dell'evento.
|
||||
|
||||
Tre target (vedi README sez. Mean-reversion):
|
||||
- REV_N (classificazione): rientra alla Mediana entro N giorni? (rev_N)
|
||||
- SPEED (regressione) : in quanti giorni rientra (bars_to_revert);
|
||||
definito solo per gli eventi che rientrano entro 20g
|
||||
- DISC (regressione) : massimo allontanamento dalla Mediana prima del
|
||||
rientro, in % (disc_max_pct)
|
||||
|
||||
Nota sulla "banalita'": l'incrocio PRICExMED ha per costruzione dist~0 e rientro
|
||||
immediato. Con `drop_trivial` si possono escludere gli eventi gia' praticamente
|
||||
sulla Mediana (|dist_med_pct| < trivial_eps) per studiare il rientro "vero".
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def make_targets(df: pd.DataFrame, horizon: int = 10,
|
||||
drop_trivial: bool = False, trivial_eps: float = 0.05):
|
||||
"""Ritorna un dict di colonne target + una maschera 'valid' per ciascun task.
|
||||
|
||||
Output:
|
||||
{
|
||||
"rev": (y, mask), # classificazione 0/1
|
||||
"speed": (y, mask), # regressione (giorni), solo eventi rientrati
|
||||
"disc": (y, mask), # regressione (% allontanamento)
|
||||
}
|
||||
"""
|
||||
n = len(df)
|
||||
base_mask = np.ones(n, bool)
|
||||
if drop_trivial:
|
||||
base_mask &= df["dist_med_pct"].abs().values >= trivial_eps
|
||||
|
||||
out = {}
|
||||
|
||||
# REV_N: classificazione
|
||||
yrev = df[f"rev_{horizon}"].astype(float).values
|
||||
mrev = base_mask & ~np.isnan(yrev)
|
||||
out["rev"] = (np.nan_to_num(yrev).astype(int), mrev)
|
||||
|
||||
# SPEED: giorni al rientro, solo per chi rientra entro 20g (bars_to_revert valorizzato)
|
||||
btr = pd.to_numeric(df["bars_to_revert"], errors="coerce").values
|
||||
mspeed = base_mask & ~np.isnan(btr)
|
||||
out["speed"] = (btr, mspeed)
|
||||
|
||||
# DISC: massimo allontanamento (in valore assoluto, %)
|
||||
disc = pd.to_numeric(df["disc_max_pct"], errors="coerce").abs().values
|
||||
mdisc = base_mask & ~np.isnan(disc)
|
||||
out["disc"] = (disc, mdisc)
|
||||
|
||||
return out
|
||||
@@ -0,0 +1,52 @@
|
||||
"""Self-test del modello di mean-reversion.
|
||||
|
||||
M1 feature senza esiti futuri
|
||||
M2 reproducibilita' (LOSO rev AUC identico tra due run)
|
||||
M3 controllo negativo: con label rev mescolate l'AUC deve ~0.5
|
||||
"""
|
||||
import os, sys
|
||||
import numpy as np
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
from mr_train import load_cfg, load_pool, leave_one_symbol_out
|
||||
from mr_labeling import make_targets
|
||||
from features import select_xy
|
||||
from model import make_model
|
||||
from sklearn.metrics import roc_auc_score
|
||||
|
||||
CFG = os.path.join(HERE, "..", "config_mr.yaml")
|
||||
ok = True
|
||||
|
||||
def check(name, cond):
|
||||
global ok
|
||||
print(("PASS" if cond else "FAIL"), "-", name); ok = ok and cond
|
||||
|
||||
cfg = load_cfg(CFG)
|
||||
num, cat = cfg["features_numeric"], cfg["features_categorical"]
|
||||
|
||||
# M1
|
||||
future = ("ret_", "mfe_", "mae_", "dir_", "rev_", "cret_", "bars_to_revert", "disc_max")
|
||||
feats = num + cat
|
||||
check("M1 feature senza esiti futuri",
|
||||
not any(f.startswith(future) for f in feats))
|
||||
|
||||
df = load_pool(cfg)
|
||||
|
||||
# M2 reproducibilita'
|
||||
a = leave_one_symbol_out(cfg, df, num, cat)["rev"].auc.mean()
|
||||
b = leave_one_symbol_out(cfg, df, num, cat)["rev"].auc.mean()
|
||||
check("M2 reproducibilita' LOSO rev AUC", abs(a - b) < 1e-9)
|
||||
|
||||
# M3 controllo negativo
|
||||
y, mask = make_targets(df, cfg["horizon"], cfg["drop_trivial"], cfg["trivial_eps"])["rev"]
|
||||
d = df[mask].reset_index(drop=True); y = y[mask]
|
||||
tr = d.time.dt.year.values < 2018
|
||||
m = make_model(cfg, num, cat); m.fit(select_xy(d[tr], num, cat), y[tr])
|
||||
p = m.predict_proba(select_xy(d[~tr], num, cat))[:, 1]
|
||||
yte = y[~tr].copy(); np.random.default_rng(0).shuffle(yte)
|
||||
auc_shuf = roc_auc_score(yte, p)
|
||||
check("M3 controllo negativo AUC~0.5 (0.45-0.55)", 0.45 <= auc_shuf <= 0.55)
|
||||
|
||||
print(f"\nLOSO rev AUC medio reale = {a:.3f}")
|
||||
print("=== SELF-TEST MR:", "TUTTO OK" if ok else "CI SONO FAIL", "===")
|
||||
sys.exit(0 if ok else 1)
|
||||
@@ -0,0 +1,192 @@
|
||||
"""Fase 3 — modello di MEAN-REVERSION (rientro alla Mediana).
|
||||
|
||||
Pooling pulito sui major FX. Tre target (vedi mr_labeling):
|
||||
- rev : classificatore "rientra entro `horizon` giorni si/no"
|
||||
- speed : regressione su quanti giorni impiega a rientrare (eventi rientrati)
|
||||
- disc : regressione sul massimo allontanamento (% ) prima del rientro
|
||||
|
||||
Due schemi di validazione, entrambi onesti:
|
||||
1) WALK-FORWARD pooled: train tutti i simboli fino all'anno T, test anno T+1.
|
||||
(generalizzazione nel tempo)
|
||||
2) LEAVE-ONE-SYMBOL-OUT: train su 3 simboli, test sul 4o mai visto.
|
||||
(generalizzazione tra strumenti — la prova piu' severa)
|
||||
|
||||
Confronto sempre contro una baseline banale:
|
||||
- clf : prevedere sempre la classe maggioritaria / la base rate
|
||||
- reg : prevedere la mediana del train (MAE di riferimento)
|
||||
|
||||
Uso:
|
||||
python mr_train.py [config_mr.yaml]
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import os, sys, json
|
||||
import numpy as np, pandas as pd
|
||||
import yaml
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
from data import load
|
||||
from features import select_xy
|
||||
from model import make_model, make_regressor
|
||||
from mr_labeling import make_targets
|
||||
from sklearn.metrics import roc_auc_score, accuracy_score, mean_absolute_error, r2_score
|
||||
|
||||
RESULTS = os.path.normpath(os.path.join(HERE, "..", "results"))
|
||||
|
||||
|
||||
def load_cfg(path):
|
||||
with open(path) as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
|
||||
def load_pool(cfg):
|
||||
parts = []
|
||||
for s in cfg["symbols"]:
|
||||
cr, _ = load(s, cfg["year_min"])
|
||||
cr = cr.copy()
|
||||
cr["abs_dist"] = cr["dist_med_pct"].abs()
|
||||
parts.append(cr)
|
||||
df = pd.concat(parts, ignore_index=True).sort_values("time").reset_index(drop=True)
|
||||
return df
|
||||
|
||||
|
||||
# ---------------- metriche ----------------
|
||||
def clf_metrics(ytr, yte, ptr, pte):
|
||||
base = max(yte.mean(), 1 - yte.mean()) # accuratezza della classe maggioritaria
|
||||
out = {"n": int(len(yte)), "base_rate": float(yte.mean()),
|
||||
"acc_baseline": float(base)}
|
||||
if len(np.unique(yte)) < 2:
|
||||
out.update(auc=np.nan, acc=np.nan); return out
|
||||
out["auc"] = float(roc_auc_score(yte, pte))
|
||||
out["acc"] = float(accuracy_score(yte, (pte >= 0.5).astype(int)))
|
||||
return out
|
||||
|
||||
|
||||
def reg_metrics(ytr, yte, pred):
|
||||
base_pred = np.median(ytr)
|
||||
mae_base = mean_absolute_error(yte, np.full_like(yte, base_pred, dtype=float))
|
||||
mae = mean_absolute_error(yte, pred)
|
||||
return {"n": int(len(yte)), "mae": float(mae), "mae_baseline": float(mae_base),
|
||||
"skill_%": float((1 - mae / mae_base) * 100) if mae_base > 0 else np.nan,
|
||||
"r2": float(r2_score(yte, pred)) if len(np.unique(yte)) > 1 else np.nan}
|
||||
|
||||
|
||||
def fit_predict(cfg, task, tr, te, num, cat):
|
||||
"""Addestra il modello giusto per il task e ritorna (ytr,yte,pred_or_proba)."""
|
||||
horizon = cfg["horizon"]
|
||||
t_tr = make_targets(tr, horizon, cfg["drop_trivial"], cfg["trivial_eps"])[task]
|
||||
t_te = make_targets(te, horizon, cfg["drop_trivial"], cfg["trivial_eps"])[task]
|
||||
ytr, mtr = t_tr; yte, mte = t_te
|
||||
Xtr, Xte = tr[mtr], te[mte]
|
||||
ytr, yte = ytr[mtr], yte[mte]
|
||||
if len(Xtr) < 50 or len(Xte) < 20:
|
||||
return None
|
||||
if task == "rev":
|
||||
m = make_model(cfg, num, cat)
|
||||
m.fit(select_xy(Xtr, num, cat), ytr)
|
||||
return ("clf", ytr, yte,
|
||||
m.predict_proba(select_xy(Xtr, num, cat))[:, 1],
|
||||
m.predict_proba(select_xy(Xte, num, cat))[:, 1])
|
||||
else:
|
||||
m = make_regressor(cfg, num, cat)
|
||||
m.fit(select_xy(Xtr, num, cat), ytr)
|
||||
return ("reg", ytr, yte, None, m.predict(select_xy(Xte, num, cat)))
|
||||
|
||||
|
||||
def walk_forward(cfg, df, num, cat):
|
||||
years = sorted(df.time.dt.year.unique())
|
||||
t = years[0] + cfg["walkforward"]["min_train_years"] - 1
|
||||
rows = {k: [] for k in ("rev", "speed", "disc")}
|
||||
while t < years[-1]:
|
||||
tr = df[df.time.dt.year <= t]
|
||||
te = df[df.time.dt.year == t + 1]
|
||||
if len(te):
|
||||
for task in rows:
|
||||
r = fit_predict(cfg, task, tr, te, num, cat)
|
||||
if r is None:
|
||||
continue
|
||||
kind, ytr, yte, ptr, pte = r
|
||||
m = (clf_metrics(ytr, yte, ptr, pte) if kind == "clf"
|
||||
else reg_metrics(ytr, yte, pte))
|
||||
m["test_year"] = t + 1
|
||||
rows[task].append(m)
|
||||
t += cfg["walkforward"]["step_years"]
|
||||
return {k: pd.DataFrame(v) for k, v in rows.items()}
|
||||
|
||||
|
||||
def leave_one_symbol_out(cfg, df, num, cat):
|
||||
rows = {k: [] for k in ("rev", "speed", "disc")}
|
||||
for s in cfg["symbols"]:
|
||||
tr = df[df.symbol != s]
|
||||
te = df[df.symbol == s]
|
||||
for task in rows:
|
||||
r = fit_predict(cfg, task, tr, te, num, cat)
|
||||
if r is None:
|
||||
continue
|
||||
kind, ytr, yte, ptr, pte = r
|
||||
m = (clf_metrics(ytr, yte, ptr, pte) if kind == "clf"
|
||||
else reg_metrics(ytr, yte, pte))
|
||||
m["test_symbol"] = s
|
||||
rows[task].append(m)
|
||||
return {k: pd.DataFrame(v) for k, v in rows.items()}
|
||||
|
||||
|
||||
def run(cfg_path):
|
||||
cfg = load_cfg(cfg_path)
|
||||
np.random.seed(cfg["seed"])
|
||||
num, cat = cfg["features_numeric"], cfg["features_categorical"]
|
||||
df = load_pool(cfg)
|
||||
print(f"pool: {len(df)} incroci su {cfg['symbols']} "
|
||||
f"(drop_trivial={cfg['drop_trivial']})\n")
|
||||
|
||||
print("=== 1) WALK-FORWARD pooled (generalizzazione nel tempo) ===")
|
||||
wf = walk_forward(cfg, df, num, cat)
|
||||
print(f"[rev] AUC medio={wf['rev'].auc.mean():.3f} acc={wf['rev'].acc.mean():.3f}"
|
||||
f" (acc baseline maggioritaria={wf['rev'].acc_baseline.mean():.3f})")
|
||||
print(f"[speed] MAE={wf['speed'].mae.mean():.2f}g baseline={wf['speed'].mae_baseline.mean():.2f}g"
|
||||
f" skill={wf['speed']['skill_%'].mean():+.1f}%")
|
||||
print(f"[disc] MAE={wf['disc'].mae.mean():.3f}% baseline={wf['disc'].mae_baseline.mean():.3f}%"
|
||||
f" skill={wf['disc']['skill_%'].mean():+.1f}%")
|
||||
|
||||
print("\n=== 2) LEAVE-ONE-SYMBOL-OUT (generalizzazione tra strumenti) ===")
|
||||
loso = leave_one_symbol_out(cfg, df, num, cat)
|
||||
for _, r in loso["rev"].iterrows():
|
||||
print(f"[rev] test {r['test_symbol']:7s} AUC={r['auc']:.3f} acc={r['acc']:.3f}"
|
||||
f" (base {r['base_rate']:.3f})")
|
||||
for _, r in loso["speed"].iterrows():
|
||||
print(f"[speed] test {r['test_symbol']:7s} MAE={r['mae']:.2f}g base={r['mae_baseline']:.2f}g"
|
||||
f" skill={r['skill_%']:+.1f}%")
|
||||
for _, r in loso["disc"].iterrows():
|
||||
print(f"[disc] test {r['test_symbol']:7s} MAE={r['mae']:.3f}% base={r['mae_baseline']:.3f}%"
|
||||
f" skill={r['skill_%']:+.1f}%")
|
||||
|
||||
# ---- modelli finali su tutto il pool ----
|
||||
os.makedirs(RESULTS, exist_ok=True)
|
||||
saved = {}
|
||||
for task in ("rev", "speed", "disc"):
|
||||
y, mask = make_targets(df, cfg["horizon"], cfg["drop_trivial"], cfg["trivial_eps"])[task]
|
||||
X = select_xy(df[mask], num, cat)
|
||||
mdl = make_model(cfg, num, cat) if task == "rev" else make_regressor(cfg, num, cat)
|
||||
mdl.fit(X, y[mask])
|
||||
try:
|
||||
import joblib
|
||||
path = os.path.join(RESULTS, f"mr_model_{task}.joblib")
|
||||
joblib.dump(mdl, path); saved[task] = path
|
||||
except Exception as e:
|
||||
print("non serializzato", task, e)
|
||||
|
||||
for task in ("rev", "speed", "disc"):
|
||||
wf[task].to_csv(os.path.join(RESULTS, f"mr_wf_{task}.csv"), index=False)
|
||||
loso[task].to_csv(os.path.join(RESULTS, f"mr_loso_{task}.csv"), index=False)
|
||||
with open(os.path.join(RESULTS, "mr_summary.json"), "w") as f:
|
||||
json.dump({
|
||||
"wf": {k: v.mean(numeric_only=True).to_dict() for k, v in wf.items()},
|
||||
"loso": {k: v.mean(numeric_only=True).to_dict() for k, v in loso.items()},
|
||||
}, f, indent=2)
|
||||
print(f"\nsalvati risultati e modelli in {RESULTS}")
|
||||
return wf, loso
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cfg_path = sys.argv[1] if len(sys.argv) > 1 else os.path.join(HERE, "..", "config_mr.yaml")
|
||||
run(cfg_path)
|
||||
@@ -0,0 +1,80 @@
|
||||
"""Self-test della pipeline Fase 3 (controlli di correttezza, non un training serio).
|
||||
|
||||
Esegue:
|
||||
T1 reproducibilita': due run identiche danno stesse metriche OOS
|
||||
T2 controllo negativo anti-leakage: con label OOS mescolate l'AUC deve ~0.5
|
||||
T3 no temporal leakage: la baseline OOS dipende SOLO dallo sviluppo
|
||||
T4 variante logistic gira senza errori
|
||||
T5 restrict_pairs (solo pattern robusti) gira senza errori
|
||||
T6 le feature non contengono colonne di esito futuro
|
||||
"""
|
||||
import os, sys, copy
|
||||
import numpy as np
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
import train as T
|
||||
from data import load
|
||||
from labeling import RegimeBaseline
|
||||
from splits import split_oos
|
||||
|
||||
CFG = os.path.join(HERE, "..", "config.yaml")
|
||||
ok = True
|
||||
|
||||
def check(name, cond):
|
||||
global ok
|
||||
print(("PASS" if cond else "FAIL"), "-", name)
|
||||
ok = ok and cond
|
||||
|
||||
# T6: nessuna feature e' un esito futuro
|
||||
cfg = T.load_cfg(CFG)
|
||||
future_like = ("ret_", "mfe_", "mae_", "dir_", "rev_", "cret_", "bars_to_revert", "disc_max")
|
||||
feats = cfg["features_numeric"] + cfg["features_categorical"]
|
||||
check("T6 feature senza esiti futuri",
|
||||
not any(f.startswith(future_like) or f in ("bars_to_revert",) for f in feats))
|
||||
|
||||
# T1: reproducibilita'
|
||||
folds1, oos1 = T.run(CFG)
|
||||
folds2, oos2 = T.run(CFG)
|
||||
check("T1 reproducibilita' OOS AUC", abs(oos1["auc"] - oos2["auc"]) < 1e-9)
|
||||
|
||||
# T3: baseline OOS non dipende dai dati OOS (no temporal leakage)
|
||||
crosses, bars = load(cfg["symbol"], cfg["year_min"])
|
||||
crosses = crosses.dropna(subset=[f"cret_{cfg['horizon']}"]).reset_index(drop=True)
|
||||
dev_cr, oos_cr = split_oos(crosses, cfg["oos_start_year"])
|
||||
dev_ba, oos_ba = split_oos(bars, cfg["oos_start_year"])
|
||||
rb_dev = RegimeBaseline(cfg["regime"], cfg["horizon"]).fit(dev_ba)
|
||||
lbl_a = rb_dev.label(oos_cr)
|
||||
# se cambio i dati OOS, l'edges/baseline (fittati su dev) NON cambiano
|
||||
rb_dev2 = RegimeBaseline(cfg["regime"], cfg["horizon"]).fit(dev_ba)
|
||||
lbl_b = rb_dev2.label(oos_cr)
|
||||
check("T3 baseline OOS deterministica e da solo-sviluppo", np.array_equal(lbl_a, lbl_b)
|
||||
and np.allclose(rb_dev.edges_["cl"], rb_dev2.edges_["cl"]))
|
||||
|
||||
# T2: controllo negativo (label mescolate -> AUC ~0.5)
|
||||
from evaluate import metrics
|
||||
from features import select_xy
|
||||
from model import make_model
|
||||
rng = np.random.default_rng(0)
|
||||
y_dev = rb_dev.label(dev_cr)
|
||||
final = make_model(cfg, cfg["features_numeric"], cfg["features_categorical"])
|
||||
final.fit(select_xy(dev_cr, cfg["features_numeric"], cfg["features_categorical"]), y_dev)
|
||||
p_oos = final.predict_proba(select_xy(oos_cr, cfg["features_numeric"], cfg["features_categorical"]))[:, 1]
|
||||
y_oos = rb_dev.label(oos_cr)
|
||||
y_shuf = y_oos.copy(); rng.shuffle(y_shuf)
|
||||
m_shuf = metrics(y_shuf, p_oos)
|
||||
check("T2 controllo negativo AUC~0.5 (0.45-0.55)", 0.45 <= m_shuf["auc"] <= 0.55)
|
||||
|
||||
# T4: variante logistic
|
||||
cfg_log = copy.deepcopy(cfg); cfg_log["model"]["kind"] = "logistic"
|
||||
ml = make_model(cfg_log, cfg["features_numeric"], cfg["features_categorical"])
|
||||
ml.fit(select_xy(dev_cr, cfg["features_numeric"], cfg["features_categorical"]), y_dev)
|
||||
pl = ml.predict_proba(select_xy(oos_cr, cfg["features_numeric"], cfg["features_categorical"]))[:, 1]
|
||||
check("T4 logistic produce probabilita' valide", np.all((pl >= 0) & (pl <= 1)))
|
||||
|
||||
# T5: restrict_pairs
|
||||
robust = ["MA365xMA7", "MA121xMA7", "MA121xMA3", "PRICExMA121", "MA182xMA30"]
|
||||
sub = dev_cr[dev_cr.pair.isin(robust)]
|
||||
check("T5 restrict_pairs ha campioni", len(sub) > 100)
|
||||
|
||||
print("\n=== RISULTATO SELF-TEST:", "TUTTO OK" if ok else "CI SONO FAIL", "===")
|
||||
sys.exit(0 if ok else 1)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""Split temporali: walk-forward espansivo + hold-out finale out-of-sample.
|
||||
|
||||
- `walk_forward_folds`: per la validazione interna sui dati pre-OOS. Finestra
|
||||
espansiva: train = [inizio .. anno T], test = anno T+1, scorrendo T.
|
||||
- L'hold-out OOS (>= oos_start_year) e' tenuto separato e usato solo alla fine.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def split_oos(df: pd.DataFrame, oos_start_year: int):
|
||||
dev = df[df.time.dt.year < oos_start_year].reset_index(drop=True)
|
||||
oos = df[df.time.dt.year >= oos_start_year].reset_index(drop=True)
|
||||
return dev, oos
|
||||
|
||||
|
||||
def walk_forward_folds(df: pd.DataFrame, min_train_years: int, step_years: int = 1):
|
||||
"""Genera (train_idx, test_idx) su `df` (gia' solo periodo di sviluppo)."""
|
||||
years = sorted(df.time.dt.year.unique())
|
||||
if len(years) <= min_train_years:
|
||||
return
|
||||
start = years[0]
|
||||
t = start + min_train_years - 1
|
||||
while t < years[-1]:
|
||||
test_years = list(range(t + 1, min(t + 1 + step_years, years[-1] + 1)))
|
||||
train_idx = df.index[df.time.dt.year <= t].to_numpy()
|
||||
test_idx = df.index[df.time.dt.year.isin(test_years)].to_numpy()
|
||||
if len(test_idx) > 0 and len(train_idx) > 0:
|
||||
yield train_idx, test_idx
|
||||
t += step_years
|
||||
@@ -0,0 +1,108 @@
|
||||
"""Pipeline Fase 3 end-to-end.
|
||||
|
||||
1. carica incroci + baseline
|
||||
2. tiene da parte l'hold-out OOS (>= oos_start_year)
|
||||
3. walk-forward espansivo sul periodo di sviluppo:
|
||||
- per ogni fold: fit baseline+terzili sul SOLO train, costruisce le label,
|
||||
addestra il modello, valuta sul fold di test
|
||||
4. riaddestra sul periodo di sviluppo completo e valuta sull'hold-out OOS
|
||||
5. salva metriche e modello finale
|
||||
|
||||
Uso:
|
||||
python train.py [config.yaml]
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import os, sys, json
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import yaml
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
from data import load
|
||||
from labeling import RegimeBaseline
|
||||
from features import select_xy
|
||||
from splits import split_oos, walk_forward_folds
|
||||
from model import make_model
|
||||
from evaluate import metrics
|
||||
|
||||
RESULTS = os.path.normpath(os.path.join(HERE, "..", "results"))
|
||||
|
||||
|
||||
def load_cfg(path: str) -> dict:
|
||||
with open(path) as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
|
||||
def run(cfg_path: str):
|
||||
cfg = load_cfg(cfg_path)
|
||||
np.random.seed(cfg["seed"])
|
||||
num_cols = cfg["features_numeric"]
|
||||
cat_cols = cfg["features_categorical"]
|
||||
h = cfg["horizon"]
|
||||
|
||||
crosses, bars = load(cfg["symbol"], cfg["year_min"])
|
||||
if cfg.get("restrict_pairs"):
|
||||
crosses = crosses[crosses.pair.isin(cfg["restrict_pairs"])].reset_index(drop=True)
|
||||
# serve cret_h presente (le ultime barre non hanno il futuro completo)
|
||||
crosses = crosses.dropna(subset=[f"cret_{h}"]).reset_index(drop=True)
|
||||
|
||||
dev_cr, oos_cr = split_oos(crosses, cfg["oos_start_year"])
|
||||
dev_ba, oos_ba = split_oos(bars, cfg["oos_start_year"])
|
||||
print(f"sviluppo: {len(dev_cr)} incroci | OOS({cfg['oos_start_year']}+): {len(oos_cr)} incroci")
|
||||
|
||||
# ---------- walk-forward ----------
|
||||
fold_rows = []
|
||||
for i, (tr_idx, te_idx) in enumerate(walk_forward_folds(
|
||||
dev_cr, cfg["walkforward"]["min_train_years"], cfg["walkforward"]["step_years"])):
|
||||
tr, te = dev_cr.loc[tr_idx], dev_cr.loc[te_idx]
|
||||
# baseline/terzili stimati SOLO sul train (barre fino all'ultimo anno di train)
|
||||
max_train_year = tr.time.dt.year.max()
|
||||
ba_tr = dev_ba[dev_ba.time.dt.year <= max_train_year]
|
||||
rb = RegimeBaseline(cfg["regime"], h).fit(ba_tr)
|
||||
ytr, yte = rb.label(tr), rb.label(te)
|
||||
mdl = make_model(cfg, num_cols, cat_cols)
|
||||
mdl.fit(select_xy(tr, num_cols, cat_cols), ytr)
|
||||
pte = mdl.predict_proba(select_xy(te, num_cols, cat_cols))[:, 1]
|
||||
m = metrics(yte, pte)
|
||||
m["fold"] = i
|
||||
m["test_years"] = f"{te.time.dt.year.min()}-{te.time.dt.year.max()}"
|
||||
fold_rows.append(m)
|
||||
print(f" fold {i} test {m['test_years']:>9} n={m['n']:5d} "
|
||||
f"AUC={m['auc']:.3f} acc={m['acc']:.3f} "
|
||||
f"prec@10%={m['prec_top_decile']:.3f} (base {m['base_rate']:.3f})")
|
||||
|
||||
folds = pd.DataFrame(fold_rows)
|
||||
if len(folds):
|
||||
print(f"\nWalk-forward medio: AUC={folds.auc.mean():.3f} "
|
||||
f"acc={folds.acc.mean():.3f} prec@10%={folds.prec_top_decile.mean():.3f}")
|
||||
|
||||
# ---------- modello finale + OOS ----------
|
||||
rb_full = RegimeBaseline(cfg["regime"], h).fit(dev_ba)
|
||||
y_dev = rb_full.label(dev_cr)
|
||||
final = make_model(cfg, num_cols, cat_cols)
|
||||
final.fit(select_xy(dev_cr, num_cols, cat_cols), y_dev)
|
||||
|
||||
y_oos = rb_full.label(oos_cr) # baseline fittata sullo sviluppo: no leakage
|
||||
p_oos = final.predict_proba(select_xy(oos_cr, num_cols, cat_cols))[:, 1]
|
||||
oos_m = metrics(y_oos, p_oos)
|
||||
print(f"\nHOLD-OUT OOS {cfg['oos_start_year']}+ : n={oos_m['n']} AUC={oos_m['auc']:.3f} "
|
||||
f"acc={oos_m['acc']:.3f} prec@10%={oos_m['prec_top_decile']:.3f} "
|
||||
f"(base {oos_m['base_rate']:.3f}, lift {oos_m['lift_top_decile']:.2f}x)")
|
||||
|
||||
os.makedirs(RESULTS, exist_ok=True)
|
||||
folds.to_csv(os.path.join(RESULTS, "walkforward_folds.csv"), index=False)
|
||||
with open(os.path.join(RESULTS, "oos_metrics.json"), "w") as f:
|
||||
json.dump(oos_m, f, indent=2)
|
||||
try:
|
||||
import joblib
|
||||
joblib.dump(final, os.path.join(RESULTS, "model_final.joblib"))
|
||||
except Exception as e:
|
||||
print("modello non serializzato:", e)
|
||||
print(f"\nsalvati risultati in {RESULTS}")
|
||||
return folds, oos_m
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cfg_path = sys.argv[1] if len(sys.argv) > 1 else os.path.join(HERE, "..", "config.yaml")
|
||||
run(cfg_path)
|
||||
@@ -0,0 +1,335 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| PaPP_CrossExport.mq5 |
|
||||
//| PaPP v2 |
|
||||
//| Esporta in CSV TUTTI gli incroci tra le 9 linee (prezzo+Mediana |
|
||||
//| +7 MA), calcolati ANCORATI a D1 (come l'indicatore), con il |
|
||||
//| contesto di ogni incrocio e gli esiti futuri a 1/3/5/10/20 g. |
|
||||
//| Si puo' esportare un intervallo di date oppure tutto lo storico. |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "PaPP v2"
|
||||
#property version "1.00"
|
||||
#property script_show_inputs
|
||||
|
||||
//--- input
|
||||
input string InpSymbol = ""; // simbolo ("" = simbolo del grafico)
|
||||
input bool InpAllHistory = true; // true = tutto lo storico D1
|
||||
input datetime InpStart = D'2010.01.01'; // inizio intervallo (se AllHistory=false)
|
||||
input datetime InpEnd = D'2100.01.01'; // fine intervallo (se AllHistory=false)
|
||||
input string InpFileName = ""; // nome file ("" = automatico)
|
||||
input bool InpBaseline = true; // crea anche il file baseline (tutte le barre D1)
|
||||
|
||||
//--- costanti (stesse 7 MA dell'indicatore)
|
||||
#define ANCHOR_TF PERIOD_D1
|
||||
#define NSER 9 // PRICE, MED, MA365..MA3
|
||||
#define KSLOPE 5 // barre D1 per velocita'/accelerazione
|
||||
#define NVOL 14 // barre D1 per la volatilita'
|
||||
#define MAXH 20 // orizzonte massimo per gli esiti
|
||||
|
||||
int gDays[7] = {365,182,121,30,14,7,3};
|
||||
string SER[NSER]= {"PRICE","MED","MA365","MA182","MA121","MA30","MA14","MA7","MA3"};
|
||||
int gHor[5] = {1,3,5,10,20};
|
||||
|
||||
//--- contenitore per un buffer MA dinamico (MQL5 non permette double ma[7][])
|
||||
struct MABuf { double v[]; };
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
int TimeToBarsD1(string sym,int d)
|
||||
{
|
||||
datetime n = TimeCurrent();
|
||||
if(n==0) return MathMax(1,(int)((long)d*86400L/PeriodSeconds(ANCHOR_TF)));
|
||||
return MathMax(1,Bars(sym,ANCHOR_TF,n-(long)d*86400,n));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// valore valido = positivo e finito (MT5 usa EMPTY_VALUE=DBL_MAX nei warmup)
|
||||
bool IsVal(double v) { return (v>0.0 && v<1.0e12); }
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
double Median7(double &v[]) // mediana dei valori validi in v[0..6]
|
||||
{
|
||||
double a[]; int c=0; ArrayResize(a,7);
|
||||
for(int m=0;m<7;m++) if(IsVal(v[m])) { a[c]=v[m]; c++; }
|
||||
if(c==0) return 0;
|
||||
ArrayResize(a,c); ArraySort(a);
|
||||
if((c&1)==1) return a[c/2];
|
||||
return 0.5*(a[c/2-1]+a[c/2]);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// mediana dei primi c valori di src
|
||||
double MedArr(double &src[],int c)
|
||||
{
|
||||
if(c<=0) return 0;
|
||||
double a[]; ArrayResize(a,c);
|
||||
for(int j=0;j<c;j++) a[j]=src[j];
|
||||
ArraySort(a);
|
||||
if((c&1)==1) return a[c/2];
|
||||
return 0.5*(a[c/2-1]+a[c/2]);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// Velocita' = mediana delle 7 pendenze (variazione % di ogni MA su K barre D1)
|
||||
double VelMed(const double &S[][NSER],int i,int K)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++)
|
||||
{ double a=S[i][2+m], b=S[i-K][2+m]; if(IsVal(a)&&IsVal(b)) v[c++]=(a-b)/b*100.0; }
|
||||
return MedArr(v,c);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// Accelerazione = mediana delle 7 seconde differenze (cambio di pendenza)
|
||||
double AccMed(const double &S[][NSER],int i,int K)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
double a=S[i][2+m], b=S[i-K][2+m], d=S[i-2*K][2+m];
|
||||
if(IsVal(a)&&IsVal(b)&&IsVal(d)) v[c++]=(a-2.0*b+d)/d*100.0;
|
||||
}
|
||||
return MedArr(v,c);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// Volatilita' = mediana delle 7 dev.std dei rendimenti giornalieri di ogni MA su N barre
|
||||
double VolMed(const double &S[][NSER],int i,int N)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
double r[]; int rc=0; ArrayResize(r,N);
|
||||
for(int t=i-N+1;t<=i;t++)
|
||||
{ double a=S[t][2+m], b=S[t-1][2+m]; if(IsVal(a)&&IsVal(b)) r[rc++]=(a-b)/b*100.0; }
|
||||
if(rc>=2)
|
||||
{
|
||||
double mean=0; for(int j=0;j<rc;j++) mean+=r[j]; mean/=rc;
|
||||
double s=0; for(int j=0;j<rc;j++){ double dd=r[j]-mean; s+=dd*dd; }
|
||||
v[c++]=MathSqrt(s/(rc-1));
|
||||
}
|
||||
}
|
||||
return MedArr(v,c);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
string sym = (InpSymbol=="") ? _Symbol : InpSymbol;
|
||||
if(!SymbolSelect(sym,true)) { Print("Simbolo non valido: ",sym); return; }
|
||||
int digits = (int)SymbolInfoInteger(sym,SYMBOL_DIGITS);
|
||||
|
||||
//--- handle delle 7 MA su D1 (volatilita'/accelerazione calcolate dalle MA, no ATR di MT5)
|
||||
int hMA[7];
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
int per = TimeToBarsD1(sym,gDays[m]);
|
||||
hMA[m] = iMA(sym,ANCHOR_TF,per,0,MODE_SMA,PRICE_CLOSE);
|
||||
if(hMA[m]==INVALID_HANDLE) { Print("iMA fallita m=",m); return; }
|
||||
}
|
||||
int LB = MathMax(2*KSLOPE,NVOL); // lookback necessario per vel/acc/vol
|
||||
|
||||
//--- attendo che lo storico D1 sia pronto
|
||||
int total=0;
|
||||
for(int t=0; t<100; t++)
|
||||
{
|
||||
total = Bars(sym,ANCHOR_TF);
|
||||
bool ok = (total>MAXH+LB+50);
|
||||
for(int m=0;m<7 && ok;m++) if(BarsCalculated(hMA[m])<total) ok=false;
|
||||
if(ok) break;
|
||||
Sleep(100);
|
||||
}
|
||||
total = Bars(sym,ANCHOR_TF);
|
||||
if(total<=MAXH+LB+50) { Print("Storico D1 insufficiente: ",total," barre"); return; }
|
||||
|
||||
//--- carico tutta la storia D1 (indice 0 = piu' vecchio)
|
||||
datetime tm[]; double cl[],hi[],lo[];
|
||||
MABuf ma[7];
|
||||
ArraySetAsSeries(tm,false); ArraySetAsSeries(cl,false);
|
||||
ArraySetAsSeries(hi,false); ArraySetAsSeries(lo,false);
|
||||
if(CopyTime(sym,ANCHOR_TF,0,total,tm)<=0) { Print("CopyTime KO"); return; }
|
||||
if(CopyClose(sym,ANCHOR_TF,0,total,cl)<=0) { Print("CopyClose KO"); return; }
|
||||
if(CopyHigh(sym,ANCHOR_TF,0,total,hi)<=0) { Print("CopyHigh KO"); return; }
|
||||
if(CopyLow(sym,ANCHOR_TF,0,total,lo)<=0) { Print("CopyLow KO"); return; }
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
ArraySetAsSeries(ma[m].v,false);
|
||||
if(CopyBuffer(hMA[m],0,0,total,ma[m].v)<=0) { Print("CopyBuffer MA KO m=",m); return; }
|
||||
}
|
||||
int n = ArraySize(cl);
|
||||
|
||||
//--- costruisco le 9 serie allineate per barra: S[i][k]
|
||||
double S[][NSER];
|
||||
ArrayResize(S,n);
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
double mv[7];
|
||||
for(int m=0;m<7;m++) mv[m] = ma[m].v[i];
|
||||
S[i][0] = cl[i]; // PRICE
|
||||
S[i][1] = Median7(mv); // MED
|
||||
for(int m=0;m<7;m++) S[i][2+m] = mv[m]; // MA365..MA3
|
||||
}
|
||||
|
||||
//--- intervallo di scansione (eventi)
|
||||
datetime from = InpAllHistory ? 0 : InpStart;
|
||||
datetime to = InpAllHistory ? TimeCurrent(): InpEnd;
|
||||
int iStart = LB+1, iEnd = n-1;
|
||||
for(int i=LB+1;i<n;i++) if(tm[i]>=from) { iStart=i; break; }
|
||||
for(int i=n-1;i>=0;i--) if(tm[i]<=to) { iEnd=i; break; }
|
||||
|
||||
//--- apro il file CSV
|
||||
string fname = (InpFileName=="") ? ("PaPP_crosses_"+sym+"_D1.csv") : InpFileName;
|
||||
int fh = FileOpen(fname,FILE_WRITE|FILE_TXT|FILE_ANSI);
|
||||
if(fh==INVALID_HANDLE) { Print("FileOpen KO: ",fname," err=",GetLastError()); return; }
|
||||
|
||||
//--- header
|
||||
string head = "time,symbol,pair,a,b,dir,price,med,ma365,ma182,ma121,ma30,ma14,ma7,ma3,"
|
||||
"dist_med_pct,cluster_pct,cluster_exp,slope_a,slope_b,trend,vel_med,acc_med,vol_med,dow,month";
|
||||
for(int hh=0;hh<5;hh++)
|
||||
{
|
||||
string s=IntegerToString(gHor[hh]);
|
||||
head += ",ret_"+s+",mfe_"+s+",mae_"+s+",dir_"+s+",rev_"+s;
|
||||
}
|
||||
for(int b=1;b<=MAXH;b++) head += ",cret_"+IntegerToString(b); // traiettoria forward bar-by-bar
|
||||
head += ",bars_to_revert,disc_max_pct";
|
||||
FileWriteString(fh,head+"\r\n");
|
||||
|
||||
//--- file baseline (una riga per OGNI barra D1 valida): serve per il confronto
|
||||
// "extra-rendimento" = incrocio vs giorno qualunque nello stesso regime
|
||||
int fhB = INVALID_HANDLE;
|
||||
if(InpBaseline)
|
||||
{
|
||||
string bname = "PaPP_bars_"+sym+"_D1.csv";
|
||||
fhB = FileOpen(bname,FILE_WRITE|FILE_TXT|FILE_ANSI);
|
||||
if(fhB==INVALID_HANDLE) Print("FileOpen baseline KO: ",bname," err=",GetLastError());
|
||||
else
|
||||
{
|
||||
string bh = "time,symbol,price,med,dist_med_pct,cluster_pct,cluster_exp,trend,vel_med,acc_med,vol_med,dow,month,bars_to_revert,disc_max_pct";
|
||||
for(int b=1;b<=MAXH;b++) bh += ",cret_"+IntegerToString(b);
|
||||
FileWriteString(fhB,bh+"\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
//--- scansione incroci
|
||||
long rows=0, brows=0;
|
||||
for(int i=iStart;i<=iEnd;i++)
|
||||
{
|
||||
if(i<LB+1) continue;
|
||||
|
||||
//--- esporto solo barre con TUTTE le 9 serie valide su tutto il lookback
|
||||
bool allok=true;
|
||||
for(int k=0;k<NSER && allok;k++)
|
||||
if(!IsVal(S[i][k]) || !IsVal(S[i-1][k]) || !IsVal(S[i-LB][k])) allok=false;
|
||||
if(!allok) continue;
|
||||
|
||||
double price=S[i][0], med=S[i][1], ma365=S[i][2];
|
||||
|
||||
//--- feature comuni a tutti gli incroci di questa barra
|
||||
double dist_med = (price-med)/med*100.0;
|
||||
double cmax=-1, cmin=1e18;
|
||||
for(int k=2;k<NSER;k++){ double v=S[i][k]; if(v>cmax)cmax=v; if(v<cmin)cmin=v; }
|
||||
double cluster = (cmax-cmin)/price*100.0;
|
||||
double cmaxP=-1,cminP=1e18;
|
||||
for(int k=2;k<NSER;k++){ double v=S[i-KSLOPE][k]; if(v>cmaxP)cmaxP=v; if(v<cminP)cminP=v; }
|
||||
double clusterP = (cmaxP-cminP)/S[i-KSLOPE][0]*100.0;
|
||||
double cluster_exp = cluster-clusterP;
|
||||
int trend = (price>ma365)?1:-1;
|
||||
//--- velocita'/accelerazione/volatilita': mediana delle 7 scale (no ATR di MT5)
|
||||
double vel_med = VelMed(S,i,KSLOPE);
|
||||
double acc_med = AccMed(S,i,KSLOPE);
|
||||
double vol_med = VolMed(S,i,NVOL);
|
||||
MqlDateTime dt; TimeToStruct(tm[i],dt);
|
||||
|
||||
//--- traiettoria forward (rendimento cumulato a +1..+MAXH), calcolata una volta per barra
|
||||
string bpath="";
|
||||
for(int b=1;b<=MAXH;b++)
|
||||
{
|
||||
int iB=i+b;
|
||||
if(iB>n-1) bpath += ",";
|
||||
else bpath += ","+DoubleToString((cl[iB]-cl[i])/cl[i]*100.0,5);
|
||||
}
|
||||
|
||||
//--- esito globale: ritorno alla Mediana entro MAXH
|
||||
int side = (price>med)?1:-1;
|
||||
int b2rev=-1; double discMax=0;
|
||||
int jmax = MathMin(i+MAXH,n-1);
|
||||
for(int j=i+1;j<=jmax;j++)
|
||||
{
|
||||
if(!IsVal(S[j][0]) || !IsVal(S[j][1])) continue;
|
||||
int sj=(S[j][0]>S[j][1])?1:-1;
|
||||
if(b2rev<0 && sj!=side) b2rev=j-i;
|
||||
double d=(S[j][0]-S[j][1])/S[j][1]*100.0;
|
||||
if(MathAbs(d)>MathAbs(discMax)) discMax=d;
|
||||
}
|
||||
|
||||
//--- riga baseline (barra qualunque, indipendente dagli incroci)
|
||||
if(fhB!=INVALID_HANDLE)
|
||||
{
|
||||
string br = TimeToString(tm[i],TIME_DATE)+","+sym+","
|
||||
+DoubleToString(price,digits)+","+DoubleToString(med,digits)+","
|
||||
+DoubleToString(dist_med,5)+","+DoubleToString(cluster,5)+","
|
||||
+DoubleToString(cluster_exp,5)+","+IntegerToString(trend)+","
|
||||
+DoubleToString(vel_med,5)+","+DoubleToString(acc_med,5)+","
|
||||
+DoubleToString(vol_med,5)+","+IntegerToString(dt.day_of_week)+","
|
||||
+IntegerToString(dt.mon)+","
|
||||
+(b2rev>0?IntegerToString(b2rev):"")+","+DoubleToString(discMax,5)
|
||||
+bpath;
|
||||
FileWriteString(fhB,br+"\r\n");
|
||||
brows++;
|
||||
}
|
||||
|
||||
//--- controllo ogni coppia (a,b)
|
||||
for(int a=0;a<NSER;a++)
|
||||
for(int b=a+1;b<NSER;b++)
|
||||
{
|
||||
double d0=S[i-1][a]-S[i-1][b];
|
||||
double d1=S[i][a]-S[i][b];
|
||||
int dir=0;
|
||||
if(d0<=0 && d1>0) dir=1; else if(d0>=0 && d1<0) dir=-1;
|
||||
if(dir==0) continue;
|
||||
|
||||
double slope_a = (S[i][a]-S[i-KSLOPE][a])/S[i-KSLOPE][a]*100.0;
|
||||
double slope_b = (S[i][b]-S[i-KSLOPE][b])/S[i-KSLOPE][b]*100.0;
|
||||
double thr = 0.25*vol_med;
|
||||
|
||||
string row = StringFormat("%s,%s,%sx%s,%s,%s,%d,",
|
||||
TimeToString(tm[i],TIME_DATE),sym,SER[a],SER[b],SER[a],SER[b],dir);
|
||||
row += DoubleToString(price,digits)+","+DoubleToString(med,digits)+",";
|
||||
for(int k=2;k<NSER;k++) row += DoubleToString(S[i][k],digits)+",";
|
||||
row += DoubleToString(dist_med,5)+","+DoubleToString(cluster,5)+","
|
||||
+DoubleToString(cluster_exp,5)+","+DoubleToString(slope_a,5)+","
|
||||
+DoubleToString(slope_b,5)+","+IntegerToString(trend)+","
|
||||
+DoubleToString(vel_med,5)+","+DoubleToString(acc_med,5)+","
|
||||
+DoubleToString(vol_med,5)+","+IntegerToString(dt.day_of_week)+","
|
||||
+IntegerToString(dt.mon);
|
||||
|
||||
//--- esiti per orizzonte
|
||||
for(int hh=0;hh<5;hh++)
|
||||
{
|
||||
int h=gHor[hh], iH=i+h;
|
||||
if(iH>n-1 || S[i][0]<=0) { row += ",,,,,"; continue; }
|
||||
double ret=(cl[iH]-cl[i])/cl[i]*100.0;
|
||||
double mxh=-1e18,mnl=1e18;
|
||||
for(int j=i+1;j<=iH;j++){ if(hi[j]>mxh)mxh=hi[j]; if(lo[j]<mnl)mnl=lo[j]; }
|
||||
double mfe=(mxh-cl[i])/cl[i]*100.0;
|
||||
double mae=(mnl-cl[i])/cl[i]*100.0;
|
||||
int dlab=(ret>thr)?1:((ret<-thr)?-1:0);
|
||||
int rev=(b2rev>0 && b2rev<=h)?1:0;
|
||||
row += ","+DoubleToString(ret,5)+","+DoubleToString(mfe,5)+","
|
||||
+DoubleToString(mae,5)+","+IntegerToString(dlab)+","+IntegerToString(rev);
|
||||
}
|
||||
row += bpath; // traiettoria forward (uguale per ogni coppia di questa barra)
|
||||
row += ","+(b2rev>0?IntegerToString(b2rev):"")+","+DoubleToString(discMax,5);
|
||||
FileWriteString(fh,row+"\r\n");
|
||||
rows++;
|
||||
}
|
||||
if((i%200)==0) Comment(StringFormat("PaPP export: %d/%d barre, %d eventi",i-iStart,iEnd-iStart,(int)rows));
|
||||
}
|
||||
|
||||
FileClose(fh);
|
||||
if(fhB!=INVALID_HANDLE) FileClose(fhB);
|
||||
for(int m=0;m<7;m++) IndicatorRelease(hMA[m]);
|
||||
Comment("");
|
||||
PrintFormat("PaPP export COMPLETATO: %d incroci -> %s (cartella MQL5\\Files)",(int)rows,fname);
|
||||
if(InpBaseline) PrintFormat("Baseline: %d barre -> PaPP_bars_%s_D1.csv",(int)brows,sym);
|
||||
Print("Periodo: ",TimeToString(tm[iStart])," -> ",TimeToString(tm[iEnd]));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
+292
-24
@@ -10,11 +10,16 @@
|
||||
#property indicator_buffers 8
|
||||
#property indicator_plots 8
|
||||
|
||||
input int FontSize = 9;
|
||||
input bool Smooth = true; // interpola tra i valori D1 -> linea morbida
|
||||
input bool ShowMA = true; // mostra anche le 7 MA (oltre alla mediana)
|
||||
input int FontSize = 9;
|
||||
input bool Smooth = true; // interpola tra i valori D1 -> linea morbida
|
||||
input bool ShowMA = true; // mostra anche le 7 MA (oltre alla mediana)
|
||||
input bool ShowPanel = true; // box con sfondo dietro al pannello info
|
||||
input color PanelBg = C'20,20,25'; // colore sfondo del box
|
||||
|
||||
#define ANCHOR_TF PERIOD_D1 // calcolo ancorato a D1: linea identica su ogni TF
|
||||
#define KSLOPE 5 // barre D1 per velocita'/accelerazione
|
||||
#define NVOL 14 // barre D1 per la volatilita'
|
||||
#define CLWIN 252 // finestra D1 (~1 anno) per il percentile del cluster
|
||||
|
||||
double Buff_Median[];
|
||||
double B0[],B1[],B2[],B3[],B4[],B5[],B6[];
|
||||
@@ -23,7 +28,9 @@ int gDays[7] = {365,182,121,30,14,7,3};
|
||||
color gCol[7] = {clrDodgerBlue,clrDeepSkyBlue,clrTurquoise,clrLimeGreen,clrOrange,clrTomato,clrRed};
|
||||
int hMA[7];
|
||||
int bars[7];
|
||||
string _pfx = "PM_";
|
||||
struct PBuf { double v[]; }; // buffer dinamico per copiare una MA
|
||||
string _pfx = "PM_"; // oggetti pannello
|
||||
string _pfx2 = "PME_"; // etichette a fine linea
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// scrive il valore nel buffer della MA m
|
||||
@@ -41,6 +48,23 @@ void SetBuf(int m,int idx,double v)
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// legge il valore corrente (barra 0) del buffer della MA m
|
||||
double GetBuf(int m)
|
||||
{
|
||||
switch(m)
|
||||
{
|
||||
case 0: return B0[0];
|
||||
case 1: return B1[0];
|
||||
case 2: return B2[0];
|
||||
case 3: return B3[0];
|
||||
case 4: return B4[0];
|
||||
case 5: return B5[0];
|
||||
case 6: return B6[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
int TimeToBars(int d)
|
||||
{
|
||||
@@ -103,6 +127,7 @@ void OnDeinit(const int reason)
|
||||
{
|
||||
for(int i=0;i<7;i++) if(hMA[i]!=INVALID_HANDLE) IndicatorRelease(hMA[i]);
|
||||
ObjectsDeleteAll(0,_pfx);
|
||||
ObjectsDeleteAll(0,_pfx2);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -135,6 +160,160 @@ double MedianAtD1(int d1shift)
|
||||
return Median(vals,cnt);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// valore valido = positivo e finito (esclude EMPTY_VALUE di warmup)
|
||||
bool IsVal(double v) { return (v>0.0 && v<1.0e12); }
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// mediana dei primi c valori di src
|
||||
double MedArr(double &src[],int c)
|
||||
{
|
||||
if(c<=0) return 0;
|
||||
double a[]; ArrayResize(a,c);
|
||||
for(int j=0;j<c;j++) a[j]=src[j];
|
||||
ArraySort(a);
|
||||
if((c&1)==1) return a[c/2];
|
||||
return 0.5*(a[c/2-1]+a[c/2]);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// Metriche a una specifica barra D1 (j), calcolate sui buffer gia' copiati mb[7]
|
||||
double ClusterAtJ(PBuf &mb[],int j)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++){ double x=mb[m].v[j]; if(IsVal(x)) v[c++]=x; }
|
||||
if(c<2) return 0;
|
||||
double md=MedArr(v,c); if(md<=0) return 0;
|
||||
double ds=0; for(int m=0;m<c;m++) ds+=MathAbs(v[m]-md)/md*100.0;
|
||||
return ds/c;
|
||||
}
|
||||
double VelAtJ(PBuf &mb[],int j,int K)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++){ double a=mb[m].v[j], b=mb[m].v[j+K]; if(IsVal(a)&&IsVal(b)) v[c++]=(a-b)/b*100.0; }
|
||||
return MedArr(v,c);
|
||||
}
|
||||
double AccAtJ(PBuf &mb[],int j,int K)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++){ double a=mb[m].v[j], b=mb[m].v[j+K], d=mb[m].v[j+2*K];
|
||||
if(IsVal(a)&&IsVal(b)&&IsVal(d)) v[c++]=(a-2.0*b+d)/d*100.0; }
|
||||
return MedArr(v,c);
|
||||
}
|
||||
double VolAtJ(PBuf &mb[],int j,int N)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
double r[]; int rc=0; ArrayResize(r,N);
|
||||
for(int t=j;t<j+N;t++){ double a=mb[m].v[t], b=mb[m].v[t+1]; if(IsVal(a)&&IsVal(b)) r[rc++]=(a-b)/b*100.0; }
|
||||
if(rc>=2)
|
||||
{
|
||||
double mn=0; for(int q=0;q<rc;q++) mn+=r[q]; mn/=rc;
|
||||
double s=0; for(int q=0;q<rc;q++){ double dd=r[q]-mn; s+=dd*dd; }
|
||||
v[c++]=MathSqrt(s/(rc-1));
|
||||
}
|
||||
}
|
||||
return MedArr(v,c);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// percentile (0..1) di cur fra i primi cc valori di arr
|
||||
double PctlOf(double &arr[],int cc,double cur)
|
||||
{
|
||||
if(cc<=0) return 0.5;
|
||||
int b=0; for(int k=0;k<cc;k++) if(arr[k]<=cur) b++;
|
||||
return (double)b/cc;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// Valori correnti + percentile storico (win giorni D1) di cluster/velocita'/accel/volatilita'
|
||||
// per i segnali con segno (vel/acc) il percentile e' calcolato sul VALORE ASSOLUTO (forza)
|
||||
void AllMetrics(int win,
|
||||
double &cluCur,double &cluPct,
|
||||
double &velCur,double &velPct,
|
||||
double &accCur,double &accPct,
|
||||
double &volCur,double &volPct)
|
||||
{
|
||||
cluCur=velCur=accCur=volCur=0; cluPct=volPct=0.5; velPct=accPct=0;
|
||||
int ext = MathMax(2*KSLOPE,NVOL+1);
|
||||
int need = win+ext+2;
|
||||
PBuf mb[7];
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
ArraySetAsSeries(mb[m].v,true);
|
||||
if(CopyBuffer(hMA[m],0,0,need,mb[m].v)!=need) return;
|
||||
}
|
||||
double cA[],vA[],aA[],oA[]; int cc=0,vc=0,ac=0,oc=0;
|
||||
ArrayResize(cA,win); ArrayResize(vA,win); ArrayResize(aA,win); ArrayResize(oA,win);
|
||||
for(int j=1;j<=win;j++)
|
||||
{
|
||||
double cv=ClusterAtJ(mb,j); if(cv>0) cA[cc++]=cv;
|
||||
vA[vc++]=MathAbs(VelAtJ(mb,j,KSLOPE));
|
||||
aA[ac++]=MathAbs(AccAtJ(mb,j,KSLOPE));
|
||||
double ov=VolAtJ(mb,j,NVOL); if(ov>0) oA[oc++]=ov;
|
||||
}
|
||||
cluCur=ClusterAtJ(mb,1); velCur=VelAtJ(mb,1,KSLOPE);
|
||||
accCur=AccAtJ(mb,1,KSLOPE); volCur=VolAtJ(mb,1,NVOL);
|
||||
cluPct=PctlOf(cA,cc,cluCur);
|
||||
volPct=PctlOf(oA,oc,volCur);
|
||||
velPct=PctlOf(vA,vc,MathAbs(velCur)); // forza (su |valore|)
|
||||
accPct=PctlOf(aA,ac,MathAbs(accCur));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// descrizione a parole per una grandezza di sola ampiezza (cluster, volatilita')
|
||||
string MagWord(double pct,string w0,string w1,string w2,string w3,string w4)
|
||||
{
|
||||
if(pct<0.20) return w0;
|
||||
if(pct<0.40) return w1;
|
||||
if(pct<0.60) return w2;
|
||||
if(pct<0.80) return w3;
|
||||
return w4;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
// descrizione a parole per un segnale con segno (velocita', accelerazione)
|
||||
string DirWord(double val,double absPct,string up,string down,string flat)
|
||||
{
|
||||
if(absPct<0.15) return flat;
|
||||
string forza = (absPct<0.40)?"lieve":((absPct<0.70)?"moderata":"forte");
|
||||
return (val>0?up:down)+" "+forza;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
// descrizione a parole per la distanza prezzo-mediana (con segno)
|
||||
string DistWord(double val,double absPct)
|
||||
{
|
||||
if(absPct<0.15) return "sulla mediana";
|
||||
string q = (absPct<0.40)?"poco":((absPct<0.70)?"moderatamente":"molto");
|
||||
return q+(val>0?" sopra":" sotto");
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
// mediana delle 7 MA a barra j dai buffer mb
|
||||
double MedMAatJ(PBuf &mb[],int j)
|
||||
{
|
||||
double v[7]; int c=0;
|
||||
for(int m=0;m<7;m++){ double x=mb[m].v[j]; if(IsVal(x)) v[c++]=x; }
|
||||
return MedArr(v,c);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
// distanza prezzo-mediana: percentile storico (su |valore|) sugli ultimi 'win' giorni D1
|
||||
void DistStats(int win,double curDist,double &absPct)
|
||||
{
|
||||
absPct=0.5;
|
||||
int need=win+2;
|
||||
double cl[]; ArraySetAsSeries(cl,true);
|
||||
if(CopyClose(_Symbol,ANCHOR_TF,0,need,cl)!=need) return;
|
||||
PBuf mb[7];
|
||||
for(int m=0;m<7;m++){ ArraySetAsSeries(mb[m].v,true); if(CopyBuffer(hMA[m],0,0,need,mb[m].v)!=need) return; }
|
||||
double dA[]; int dc=0; ArrayResize(dA,win);
|
||||
for(int j=1;j<=win;j++)
|
||||
{
|
||||
double md=MedMAatJ(mb,j); if(md<=0) continue;
|
||||
dA[dc++]=MathAbs((cl[j]-md)/md*100.0);
|
||||
}
|
||||
absPct=PctlOf(dA,dc,MathAbs(curDist));
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// interpolazione lineare con fallback se uno dei valori manca
|
||||
double Interp(double vStart,double vEnd,double frac)
|
||||
@@ -256,46 +435,114 @@ int OnCalculate(const int rates_total,
|
||||
}
|
||||
|
||||
DrawInfo();
|
||||
DrawTags(time[0]);
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// larghezza in pixel di un testo nel font del pannello
|
||||
int TxtW(string s,int fs,bool bold)
|
||||
{
|
||||
TextSetFont(bold?"Consolas Bold":"Consolas",-fs*10);
|
||||
uint w=0,h=0;
|
||||
bool ok=TextGetSize(s,w,h);
|
||||
int est=(int)MathCeil(StringLen(s)*fs*0.62); // fallback se TextGetSize non disponibile
|
||||
if(!ok || (int)w<=0) return est;
|
||||
return MathMax((int)w,est); // mai meno della stima
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
void DrawInfo()
|
||||
{
|
||||
double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
|
||||
double median = MedianAtD1(1); // valore D1 chiuso (stabile, non-repaint)
|
||||
if(median<=0) return;
|
||||
|
||||
int x=10,y=30,lh=FontSize+4;
|
||||
ObjectsDeleteAll(0,_pfx);
|
||||
|
||||
Lbl("T","PaPP Median ["+EnumToString((ENUM_TIMEFRAMES)_Period)+"]",x,y,FontSize+2,clrGold,true);
|
||||
y+=lh+4;
|
||||
int x=10,y0=30,lh=FontSize+4;
|
||||
|
||||
//--- 1) calcolo metriche e preparo tutte le stringhe
|
||||
double distPct = (bid-median)/median*100;
|
||||
string distS = StringFormat("%+.2f%%",distPct);
|
||||
color distC = (distPct>0)?clrRed:clrLimeGreen;
|
||||
Lbl("M","Median: "+DoubleToString(median,_Digits),x,y,FontSize,clrWhite,false); y+=lh;
|
||||
Lbl("D","Dist: "+distS,x,y,FontSize,distC,true); y+=lh+2;
|
||||
color distC = (distPct>0)?clrRed:clrLimeGreen;
|
||||
double distAbsPct; DistStats(CLWIN,distPct,distAbsPct);
|
||||
|
||||
//--- Dispersione MA e bande (info)
|
||||
double ds=0; int dc=0;
|
||||
for(int m=0;m<7;m++) { double v=GetMA(m,1); if(v>0) { ds+=MathAbs(v-median)/median*100; dc++; } }
|
||||
double vol = (dc>0)?ds/dc:0;
|
||||
Lbl("V","Cluster +/-"+DoubleToString(vol,3)+"%",x,y,FontSize,clrGray,false); y+=lh+2;
|
||||
double cluCur,cluPct,velCur,velPct,accCur,accPct,volCur,volPct;
|
||||
AllMetrics(CLWIN,cluCur,cluPct,velCur,velPct,accCur,accPct,volCur,volPct);
|
||||
|
||||
//--- Valori delle 7 MA (giorni : valore)
|
||||
string sT = "PaPP Median ["+StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period),7)+"]";
|
||||
string sM = "Median: "+DoubleToString(median,_Digits);
|
||||
string sD = StringFormat("Dist: %+.2f%% - %s (P%.0f)",distPct,DistWord(distPct,distAbsPct),distAbsPct*100);
|
||||
string sV = StringFormat("Cluster %.3f%% - %s (P%.0f)",cluCur,MagWord(cluPct,"molto stretto","stretto","normale","largo","molto largo"),cluPct*100);
|
||||
string sVE = StringFormat("Velocita' %+.3f%% - %s",velCur,DirWord(velCur,velPct,"in salita","in discesa","quasi piatta"));
|
||||
string sAC = StringFormat("Accel %+.4f%% - %s",accCur,DirWord(accCur,accPct,"in accelerazione","in decelerazione","stabile"));
|
||||
string sVO = StringFormat("Volatilita' %.4f%% - %s (P%.0f)",volCur,MagWord(volPct,"molto bassa","bassa","normale","alta","molto alta"),volPct*100);
|
||||
string sMA[7];
|
||||
for(int m=0;m<7;m++) sMA[m]=StringFormat("MA %3dg: %s",gDays[m],DoubleToString(GetMA(m,1),_Digits));
|
||||
string sH = "Sopra=SELL | Sotto=BUY";
|
||||
|
||||
//--- 2) larghezza/altezza del box: misuro la larghezza REALE in pixel (TextGetSize)
|
||||
int maxw=0;
|
||||
maxw=MathMax(maxw,TxtW(sT,FontSize+2,true));
|
||||
maxw=MathMax(maxw,TxtW(sM,FontSize,false));
|
||||
maxw=MathMax(maxw,TxtW(sD,FontSize,true));
|
||||
maxw=MathMax(maxw,TxtW(sV,FontSize,false));
|
||||
maxw=MathMax(maxw,TxtW(sVE,FontSize,false));
|
||||
maxw=MathMax(maxw,TxtW(sAC,FontSize,false));
|
||||
maxw=MathMax(maxw,TxtW(sVO,FontSize,false));
|
||||
maxw=MathMax(maxw,TxtW(sH,FontSize-1,false));
|
||||
for(int m=0;m<7;m++) maxw=MathMax(maxw,TxtW(sMA[m],FontSize-1,false));
|
||||
int boxX=x-6, boxY=y0-6;
|
||||
int w=maxw+(x-boxX)+10; // padding sinistro (x-boxX) + destro 10
|
||||
int bodyH=15*lh+6; // 7 righe in alto + 7 MA + riga finale + padding
|
||||
PanelBox(boxX,boxY,w,bodyH);
|
||||
|
||||
//--- 3) scritte (aggiornate in-place: niente ObjectsDeleteAll -> niente lampeggio)
|
||||
int y=y0;
|
||||
Lbl("T",sT,x,y,FontSize+2,clrGold,true); y+=lh+4;
|
||||
Lbl("M",sM,x,y,FontSize,clrGold,false); y+=lh;
|
||||
Lbl("D",sD,x,y,FontSize,distC,true); y+=lh+2;
|
||||
Lbl("V",sV,x,y,FontSize,(cluPct<0.40)?clrLimeGreen:((cluPct>0.60)?clrTomato:clrSilver),false); y+=lh;
|
||||
Lbl("VEL",sVE,x,y,FontSize,(velCur>0)?clrLimeGreen:clrTomato,false); y+=lh;
|
||||
Lbl("ACC",sAC,x,y,FontSize,(accCur>0)?clrLimeGreen:clrTomato,false); y+=lh;
|
||||
Lbl("VOL",sVO,x,y,FontSize,(volPct<0.40)?clrLimeGreen:((volPct>0.60)?clrTomato:clrAqua),false); y+=lh+2;
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
double v=GetMA(m,1);
|
||||
color cma = (v>median)?clrSalmon:clrLightGreen;
|
||||
Lbl("a"+IntegerToString(m),
|
||||
StringFormat("MA %3dg: %s",gDays[m],DoubleToString(v,_Digits)),
|
||||
x,y,FontSize-1,(v>0)?cma:clrGray,false);
|
||||
Lbl("a"+IntegerToString(m),sMA[m],x,y,FontSize-1,(v>0)?gCol[m]:clrGray,false);
|
||||
y+=lh-2;
|
||||
}
|
||||
y+=2;
|
||||
Lbl("H","Sopra=SELL | Sotto=BUY",x,y,FontSize-1,clrGray,false);
|
||||
Lbl("H",sH,x,y,FontSize-1,clrGray,false);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// etichetta di testo ancorata a (t,price); se price<=0 la rimuove
|
||||
void Tag(string n,datetime t,double price,string txt,color c)
|
||||
{
|
||||
string o=_pfx2+n;
|
||||
if(price<=0) { ObjectDelete(0,o); return; }
|
||||
if(ObjectFind(0,o)<0) ObjectCreate(0,o,OBJ_TEXT,0,0,0);
|
||||
ObjectSetInteger(0,o,OBJPROP_TIME,t);
|
||||
ObjectSetDouble(0,o,OBJPROP_PRICE,price);
|
||||
ObjectSetString(0,o,OBJPROP_TEXT," "+txt);
|
||||
ObjectSetString(0,o,OBJPROP_FONT,"Consolas");
|
||||
ObjectSetInteger(0,o,OBJPROP_FONTSIZE,FontSize);
|
||||
ObjectSetInteger(0,o,OBJPROP_COLOR,c);
|
||||
ObjectSetInteger(0,o,OBJPROP_ANCHOR,ANCHOR_LEFT);
|
||||
ObjectSetInteger(0,o,OBJPROP_BACK,false);
|
||||
ObjectSetInteger(0,o,OBJPROP_SELECTABLE,false);
|
||||
ObjectSetInteger(0,o,OBJPROP_HIDDEN,true);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// etichette a fine linea, nel margine vuoto a destra
|
||||
void DrawTags(datetime tlast)
|
||||
{
|
||||
datetime tfut = tlast + 2*PeriodSeconds(_Period);
|
||||
Tag("med",tfut,Buff_Median[0],"Mediana",clrGold);
|
||||
for(int m=0;m<7;m++)
|
||||
{
|
||||
double p = ShowMA ? GetBuf(m) : 0.0;
|
||||
Tag(IntegerToString(m),tfut,p,IntegerToString(gDays[m])+"g",gCol[m]);
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -311,6 +558,27 @@ void Lbl(string n,string t,int x,int y,int fs,color c,bool b)
|
||||
ObjectSetInteger(0,o,OBJPROP_FONTSIZE,fs);
|
||||
ObjectSetInteger(0,o,OBJPROP_COLOR,c);
|
||||
ObjectSetInteger(0,o,OBJPROP_BACK,false);
|
||||
ObjectSetInteger(0,o,OBJPROP_ZORDER,1); // sopra il box di sfondo
|
||||
ObjectSetInteger(0,o,OBJPROP_SELECTABLE,false);
|
||||
ObjectSetInteger(0,o,OBJPROP_HIDDEN,true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
// riquadro di sfondo del pannello (dietro alle scritte)
|
||||
void PanelBox(int px,int py,int w,int h)
|
||||
{
|
||||
string o=_pfx+"BOX";
|
||||
if(!ShowPanel) { ObjectDelete(0,o); return; }
|
||||
if(ObjectFind(0,o)<0) ObjectCreate(0,o,OBJ_RECTANGLE_LABEL,0,0,0);
|
||||
ObjectSetInteger(0,o,OBJPROP_CORNER,CORNER_LEFT_UPPER);
|
||||
ObjectSetInteger(0,o,OBJPROP_XDISTANCE,px);
|
||||
ObjectSetInteger(0,o,OBJPROP_YDISTANCE,py);
|
||||
ObjectSetInteger(0,o,OBJPROP_XSIZE,w);
|
||||
ObjectSetInteger(0,o,OBJPROP_YSIZE,h);
|
||||
ObjectSetInteger(0,o,OBJPROP_BGCOLOR,PanelBg);
|
||||
ObjectSetInteger(0,o,OBJPROP_BORDER_TYPE,BORDER_FLAT);
|
||||
ObjectSetInteger(0,o,OBJPROP_COLOR,clrDimGray); // bordo
|
||||
ObjectSetInteger(0,o,OBJPROP_BACK,false);
|
||||
ObjectSetInteger(0,o,OBJPROP_ZORDER,0); // dietro alle scritte
|
||||
ObjectSetInteger(0,o,OBJPROP_SELECTABLE,false);
|
||||
ObjectSetInteger(0,o,OBJPROP_HIDDEN,true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user