# CNB Exchange Rates Tento projekt je určen pro stahování a správu kurzů cizích měn vůči české koruně (CZK) z webu České národní banky (ČNB). Data jsou ukládána do interní SQLite databáze a lze je vyhledávat podle data a kódu měny. ## Funkce - **Stahování dat**: - Roční data pro celý rok. - Měsíční data pro konkrétní měnu a časové období. - Denní data pro konkrétní datum. - **Interní databáze**: Všechna stažená data jsou ukládána do SQLite databáze pro rychlé vyhledávání. - **Vyhledávání kurzů**: Lze vyhledat kurz pro zadané datum a měnu. Pokud kurz pro dané datum neexistuje, program aplikuje pravidla pro víkendy a státní svátky. - **Správa státních svátků**: Program obsahuje seznam státních svátků v ČR a umí je rozpoznat. - **Kontrola data a času**: Program kontroluje, zda jsou požadovaná data již k dispozici. Pro dnešní datum před 14:30 a pro budoucí data vrací chybu. - **Automatické stahování**: Lze aktivovat automatické stahování denních dat pro dnešní datum po 14:30. - **Kontrola konzistence ročních dat**: Při startu programu automaticky kontroluje, zda roční data pro aktuální rok obsahují záznamy za poslední 3 pracovní dny. Pokud ne, data jsou automaticky aktualizována. - **Automatické stahování ročních dat**: Pokud jsou požadována data pro rok, který v databázi není, program automaticky stáhne roční data pro daný rok, aktualizuje databázi a teprve poté vrátí výsledek. - **Generování reportů**: Lze vygenerovat report kurzů pro zadaný rok, měsíc nebo časové období včetně dopočítaných kurzů pro dny, kdy ve vstupních datech neexistovali. - **Správné dopočítání kurzů**: Program správně aplikuje pravidla ČNB pro dopočítání kurzů pro víkendy a svátky jak při vyhledávání (`--get-rate`), tak při generování reportů. - **Výpočet Jednotného kurzu**: Lze vypočítat 'Jednotný kurz' pro daňové účely podle metodiky ČNB jako aritmetický průměr kurzů k posledním dnům každého měsíce v roce. - **Validace dat**: Program umí validovat data pro konzistenci, detekovat změny kurzů přesahující prahové hodnoty, kontrolovat počet obchodních dnů a analyzovat časové mezery v datech. - **Analýza počtu záznamů**: Lze zobrazit počty záznamů podle různých časových období (týden, měsíc, čtvrtletí, pololetí, rok). - **Adaptivní prahy**: Systém se učí z historických dat a automaticky upravuje prahy pro detekci anomálií. - **JSON výstup**: Všechny příkazy podporují JSON formát pro programové zpracování pomocí přepínače `--json`. ## Požadavky - Python 3.6 nebo vyšší - Knihovny: `requests` ## Instalace 1. Naklonujte repozitář: ```bash git clone cd cnb_exchange_rates ``` 2. Nainstalujte požadované knihovny: ```bash pip install requests ``` ## Použití ### Spuštění CLI Všechny operace se provádějí pomocí skriptu `src/cli.py`. ```bash python src/cli.py [argumenty] ``` Při každém spuštění programu: 1. Automaticky inicializuje databázi. 2. Zkontroluje konzistenci ročních dat pro aktuální rok. Pokud data neobsahují záznamy za poslední 3 pracovní dny, jsou automaticky aktualizována. ### Argumenty - `--year ROK`: Stáhne roční data pro zadaný rok. - `-c`, `--currency MENA`: Kód měny (např. USD) pro měsíční stahování, vyhledání kurzu nebo generování reportu. - `--start-date ZACATEK`: Počáteční datum pro měsíční stahování nebo generování reportu. Formát: `DD.MM.YYYY`. - `--end-date KONEC`: Koncové datum pro měsíční stahování nebo generování reportu. Formát: `DD.MM.YYYY`. - `--date DATUM`: Stáhne denní data pro zadané datum. Formát: `DD.MM.YYYY`. - `--get-rate DATUM`: Vyhledá kurz pro zadané datum. Formát: `DD.MM.YYYY`. Vyžaduje `-c` nebo `--currency`. - `--auto-download`: Povolí automatické stahování denních dat pro dnešní datum, pokud je po 14:30 a kurz není k dispozici. - `--report-year ROK [--report-month MESIC]`: Vygeneruje report kurzů pro zadaný rok (a případně měsíc). Vyžaduje `-c` nebo `--currency`. - `--report-period ZACATEK KONEC`: Vygeneruje report kurzů pro zadané časové období. Vyžaduje `-c` nebo `--currency`. - `--stats [ROK]`: Vypočítá 'Jednotný kurz' pro daňové účely podle metodiky ČNB. Pokud je zadán rok, vytvoří kurz pro konkrétní rok. Pokud není rok zadán, vytvoří kurzy pro všechny roky s dostupnými daty. Vyžaduje `-c` nebo `--currency`. - `--validate`: Validuje data pro měnu nebo všechny měny. Zkontroluje konzistenci kurzů, počet obchodních dnů a detekuje možné chyby. - `--record-counts`: Zobrazí počet záznamů podle časových období (týden, měsíc, čtvrtletí, pololetí, rok). Vyžaduje `-c` nebo `--currency`. - `--change-threshold PRAH`: Práh pro detekci změn kurzů v procentech (výchozí: 1.0). - `--no-adaptive`: Vypne adaptivní učení prahů na základě historických dat. - `--gap-threshold DNY`: Maximální přijatelná mezera v pracovních dnech (výchozí: 3). - `--json`: Výstup ve formátu JSON místo prostého textu pro programové zpracování. ### Příklady 1. **Stažení ročních dat pro rok 2020**: ```bash python src/cli.py --year 2020 ``` 2. **Stažení měsíčních dat pro měnu USD v lednu 2025**: ```bash python src/cli.py -c USD --start-date 01.01.2025 --end-date 31.01.2025 ``` 3. **Stažení denních dat pro datum 08.08.2025**: ```bash python src/cli.py --date 08.08.2025 ``` 4. **Vyhledání kurzu USD pro datum 08.08.2025**: ```bash python src/cli.py --get-rate 08.08.2025 -c USD ``` 5. **Vyhledání kurzu USD pro víkendové datum 10.08.2025 (použije kurz z předchozího pracovního dne)**: ```bash python src/cli.py --get-rate 10.08.2025 -c USD ``` 6. **Vyhledání kurzu USD pro dnešní datum po 14:30 s automatickým stažením dat (pokud nejsou k dispozici)**: ```bash python src/cli.py --get-rate DD.MM.YYYY -c USD --auto-download ``` *(Nahraďte `DD.MM.YYYY` aktuálním datem)* 7. **Vygenerování ročního reportu kurzů pro USD za rok 2020**: ```bash python src/cli.py --report-year 2020 -c USD ``` 8. **Vygenerování měsíčního reportu kurzů pro USD za červenec 2020**: ```bash python src/cli.py --report-year 2020 --report-month 7 -c USD ``` 9. **Vygenerování reportu kurzů pro USD za období 01.07.2020 - 31.07.2020**: ```bash python src/cli.py --report-period 01.07.2020 31.07.2020 -c USD ``` 10. **Výpočet Jednotného kurzu pro daňové účely pro USD za rok 2025**: ```bash python src/cli.py --stats 2025 -c USD ``` 11. **Výpočet Jednotného kurzu pro daňové účely pro všechny roky s daty**: ```bash python src/cli.py --stats -c USD ``` 12. **Validace dat pro měnu USD za rok 2025**: ```bash python src/cli.py --validate --currency USD --year 2025 ``` 13. **Validace všech měn s vlastními prahy**: ```bash python src/cli.py --validate --change-threshold 0.5 --gap-threshold 2 ``` 14. **Zobrazení počtu záznamů podle časových období pro USD**: ```bash python src/cli.py --record-counts --currency USD --year 2025 ``` 15. **Získání posledního dostupného kurzu USD**: ```bash python src/cli.py -c USD ``` 16. **JSON výstup pro vyhledání kurzu**: ```bash python src/cli.py --get-rate 01.01.2025 -c USD --json ``` 17. **JSON výstup pro validaci dat**: ```bash python src/cli.py --validate --currency USD --year 2025 --json ``` ## JSON formát Při použití přepínače `--json` program vrací strukturovaná data ve formátu JSON: ### Jednotlivý kurz ```json { "currency": "USD", "rate": 24.214, "date": "01.01.2025", "timestamp": "2025-01-12T10:30:00Z" } ``` ### Jednotný kurz pro jeden rok ```json { "currency": "USD", "year": 2025, "unified_rate": 21.84, "calculation_date": "2025-01-12T10:30:00Z" } ``` ### Jednotný kurz pro více let ```json { "currency": "USD", "results": [ {"year": 2023, "unified_rate": 23.45}, {"year": 2024, "unified_rate": 23.28}, {"year": 2025, "unified_rate": 21.84} ], "calculation_date": "2025-01-12T10:30:00Z" } ``` ### Poslední dostupný kurz ```json { "currency": "USD", "rate": 20.632, "date": "31.12.2025", "timestamp": "2025-01-12T10:30:00Z" } ``` ### Chyba ```json { "error": "Kurz nebyl nalezen", "code": "RATE_NOT_FOUND", "timestamp": "2025-01-12T10:30:00Z" } ``` ### Validace dat ```json { "currency": "USD", "validation_year": 2025, "adaptive_analysis": { "adaptive_threshold": 1.5, "base_threshold": 1.0, "volatility_percent": 0.24, "data_points": 62 }, "price_change_violations": [ { "date": "06.01.2025", "change_percent": 1.19, "severity": "minor" } ], "temporal_gaps": [], "trading_days_validation": { "expected_trading_days": 251, "actual_data_points": 251, "discrepancy_days": 0, "data_completeness_percent": 100.0 }, "record_counts_by_period": { "2025": { "year": 251, "half_year": {"H1": 124, "H2": 127}, "quarter": {"Q1": 63, "Q2": 61, "Q3": 66, "Q4": 61}, "month": {"01": 22, "02": 20, "03": 21}, "week": {"W01": 5, "W02": 5} } }, "data_quality_score": 95 } ``` ### Počty záznamů podle období ```json { "currency": "USD", "record_counts": { "2025": { "year": 251, "half_year": {"H1": 124, "H2": 127}, "quarter": {"Q1": 63, "Q2": 61, "Q3": 66, "Q4": 61}, "month": {"01": 22, "02": 20, "03": 21, "04": 20}, "week": {"W01": 5, "W02": 5, "W03": 5} } } } ``` ## Chování při různých časech a datumech - **Budoucí datum**: Program vrátí chybu, protože kurzy pro budoucí data ještě nebyly vydány. - **Dnešní datum před 14:30**: Program vrátí chybu, protože kurzy jsou vyhlašovány po 14:30. - **Dnešní datum po 14:30**: Program vyhledá kurz. Pokud není k dispozici a je aktivní `--auto-download`, automaticky stáhne denní data. - **Minulé datum**: Program vyhledá kurz. Pokud není k dispozici, aplikuje pravidla pro víkendy a státní svátky. ## Automatická kontrola konzistence ročních dat Při každém spuštění programu: 1. Zkontroluje, zda roční data pro aktuální rok obsahují záznamy za poslední 3 pracovní dny. 2. Pokud záznamy chybí, automaticky stáhne aktualizovaná roční data. 3. Tímto způsobem je zajištěna konzistence dat pro aktuální rok, protože každý den přibývají nové záznamy. ## Automatické stahování ročních dat při vyhledávání Pokud při vyhledávání kurzu zjistí program, že databáze neobsahuje data pro požadovaný rok: 1. Automaticky stáhne roční data pro daný rok. 2. Aktualizuje databázi. 3. Teprve poté vyhledá a vrátí kurz. ## Generování reportů o kurzech Program umí vygenerovat reporty kurzů pro zadaný rok, měsíc nebo časové období. Reporty obsahují: - Kurzy pro všechny dny v zadaném období. - Dopočítané kurzy pro dny, kdy ve vstupních datech neexistovali (např. víkendy, svátky). - Poznámky o tom, zda byl kurz nalezen v databázi nebo dopočítán. Výstupní soubory jsou ve formátu CSV a jsou uloženy v adresáři `data/`. ## Správné dopočítání kurzů pro víkendy a svátky Program správně aplikuje pravidla ČNB pro dopočítání kurzů: - **Pro víkendy a svátky**: Použije se kurz z posledního dne před nimi, který měl kurz vyhlášený pro tento víkend/svátek. - **Pro běžné dny bez kurzu**: Použije se kurz z posledního pracovního dne před ním. Příklad: - 1.1.2021 (pátek) - svátek, kurz 21.387 - 2.1.2021 (sobota) - víkend, žádný kurz → použije se kurz 21.387 z 1.1.2021 - 3.1.2021 (neděle) - víkend, žádný kurz → použije se kurz 21.387 z 1.1.2021 Tato logika je aplikována jak při vyhledávání kurzu pomocí `--get-rate`, tak při generování reportů. ## Struktura projektu - `src/`: Zdrojové kódy. - `cli.py`: Hlavní skript s CLI rozhraním. - `data_fetcher.py`: Funkce pro stahování dat z ČNB. - `database.py`: Funkce pro práci s SQLite databází. - `holidays.py`: Funkce pro práci se státními svátky. - `rate_finder.py`: Funkce pro vyhledávání kurzů. - `rate_reporter.py`: Funkce pro generování reportů o kurzech. - `data/`: Adresář pro ukládání stažených dat a databáze. - `exchange_rates.db`: SQLite databáze s kurzy. - `holidays.json`: Seznam státních svátků v ČR. - `*.csv`: Stažená data a reporty v CSV formátu. - `tests/`: Testy jednotlivých modulů. ## Testování Pro spuštění testů přejděte do adresáře projektu a spusťte: ```bash python tests/test_holidays.py python tests/test_data_fetcher.py python tests/test_rate_finder.py python tests/test_data_consistency.py python tests/test_auto_yearly_download.py python tests/test_rate_reporter.py python tests/test_rate_calculation.py ``` ## Licence Tento projekt je licencován pod MIT licencí.