======================================================================================== 🚀 EXPORTAÇÃO COMPLETA (SEM BACKUPS/icon.png) 📅 2026-06-21 08:50:14 | 📠/var/www/html 📊 Total ficheiros: 280 ======================================================================================== 📋 FICHEIROS ENCONTRADOS: ---------------------------------------------------------------------------------------- ✅ ai.php 9544 bytes ✅ alfa/api/bootstrap/bootstrap.php 1205 bytes ✅ alfa/api/bootstrap/logger.php 841 bytes ✅ alfa/api/bootstrap/simbolos.php 13793 bytes ✅ alfa/api/bootstrap/simplecache.php 963 bytes ✅ alfa/api/bootstrap/utilizador.php 1147 bytes ✅ alfa/api/bootstrap/validacao.php 1044 bytes ✅ alfa/api/calculos.php 122942 bytes ✅ alfa/api/calculos.php.bak.20260615 115450 bytes ✅ alfa/api/calculos.php.bak.pre-yahoo 115450 bytes ✅ alfa/api/calculos.php.bak.pre-yahoo-20260616 115450 bytes ✅ alfa/api/calculos.php.bak.pre-yahoo2 115450 bytes ✅ alfa/api/calculos.php.bak.stable 115450 bytes ✅ alfa/api/calculos.php.bak.stable-permissions 116004 bytes ✅ alfa/api/converter.php 10959 bytes ✅ alfa/api/downloadacoes.php 560 bytes ✅ alfa/api/downloadcaixa.php 429 bytes ✅ alfa/api/downloadhistoricoativos.php 704 bytes ✅ alfa/api/gerar_de_extrato.php 10025 bytes ✅ alfa/api/listar_ficheiros.php 1310 bytes ✅ alfa/api/obterprecosatuais.php 1245 bytes ✅ alfa/api/obtervariacaodia.php 1173 bytes ✅ alfa/api/simbolos.php 13712 bytes ✅ alfa/api/transacoesvistos.php 4202 bytes ✅ alfa/api/upload-dadosacoes.php 3263 bytes ✅ alfa/api/uploadacoes.php 1600 bytes ✅ alfa/api/uploadcaixa.php 2578 bytes ✅ alfa/api/uploadextratorevolut.php 1143 bytes ✅ alfa/api/uploadhistoricoativos.php 1289 bytes ✅ alfa/api/utilizador.php 1042 bytes ✅ alfa/aprovacao.json 23736 bytes ✅ alfa/base-dados-dinheiro.html 16609 bytes ✅ alfa/caixa.html 29056 bytes ✅ alfa/converter.php 71 bytes ✅ alfa/dados_csv/agostinha/lucro-mensal.json 8128 bytes ✅ alfa/dados_csv/agostinha/movimentos-caixa.csv 231 bytes ✅ alfa/dados_csv/agostinha/transacoes-acoes.csv 338 bytes ✅ alfa/dados_csv/dadosacoes.csv 20530 bytes ✅ alfa/dados_csv/filipe/extrato-revolut.csv 17561 bytes ✅ alfa/dados_csv/filipe/lucro-mensal.json 43267 bytes ✅ alfa/dados_csv/filipe/movimentos-caixa.csv 8762 bytes ✅ alfa/dados_csv/filipe/transacoes-acoes.csv 7267 bytes ✅ alfa/dados_csv/historico-cambio-date.txt 10 bytes ✅ alfa/dados_csv/historico-cambio.json 44556 bytes ✅ alfa/dados_csv/historico-precos-mensal.json 96868 bytes ✅ alfa/dados_csv/maria/extrato-revolut.csv 1636 bytes ✅ alfa/dados_csv/maria/lucro-mensal.json 38309 bytes ✅ alfa/dados_csv/maria/movimentos-caixa.csv 91 bytes ✅ alfa/dados_csv/maria/transacoes-acoes.csv 182 bytes ✅ alfa/dados_csv/precos-atuais.json 2159 bytes ✅ alfa/dados_csv/prevclose-cache.json 4748 bytes ✅ alfa/dados_csv/tiago/extrato-revolut.csv 59378 bytes ✅ alfa/dados_csv/tiago/historico-ativos.csv 3416 bytes ✅ alfa/dados_csv/tiago/historico-cambio-date.txt 19 bytes ✅ alfa/dados_csv/tiago/historico-cambio.json 8403 bytes ✅ alfa/dados_csv/tiago/lucro-mensal.json 46810 bytes ✅ alfa/dados_csv/tiago/movimentos-caixa.csv 16668 bytes ✅ alfa/dados_csv/tiago/precos-atuais.json 831 bytes ✅ alfa/dados_csv/tiago/transacoes-acoes.csv 29472 bytes ✅ alfa/dados_csv/tiago/transacoes-vistos.json 66 bytes ✅ alfa/dados_csv/variacao-dia.json 2328 bytes ✅ alfa/estilos-backend.css 6586 bytes ✅ alfa/exportar_projeto.php 2764 bytes ✅ alfa/ferramentas.html 3626 bytes ✅ alfa/gerar_movimentos_caixa.php 4083 bytes ✅ alfa/gravar_historico_mensal.php 4452 bytes ✅ alfa/historico-carteira.json 2 bytes ✅ alfa/importar-revolut.js 4576 bytes ✅ alfa/importar_revolut.php 3998 bytes ✅ alfa/index.html 12619 bytes ✅ alfa/irs.html 25346 bytes ✅ alfa/lucro-mensal-grafico.html 34273 bytes ✅ alfa/manifest.webmanifest 565 bytes ✅ alfa/pwa-register.js 306 bytes ✅ alfa/resumo.html 64152 bytes ✅ alfa/sw.js 1320 bytes ✅ alfa/transacoes.html 25559 bytes ✅ alfa/upload-dadosacoes.html 10525 bytes ✅ alfa/verificar-revolut.html 28043 bytes ✅ alfa/verificar-revolut.html.bak 28043 bytes ✅ alfa/verificar_diferencas_revolut.php 23201 bytes ✅ alfa/verificar_diferencas_revolut.php.bak 23201 bytes ✅ api/bootstrap/bootstrap.php 443 bytes ✅ api/bootstrap/logger.php 841 bytes ✅ api/bootstrap/simbolos.php 13712 bytes ✅ api/bootstrap/simplecache.php 963 bytes ✅ api/bootstrap/utilizador.php 1147 bytes ✅ api/bootstrap/validacao.php 1044 bytes ✅ api/calculos-atualizar.log 15056 bytes ✅ api/calculos.php 111631 bytes ✅ api/downloadacoes.php 560 bytes ✅ api/downloadcaixa.php 429 bytes ✅ api/downloadhistoricoativos.php 704 bytes ✅ api/gerar_de_extrato.php 10025 bytes ✅ api/listar_ficheiros.php 1310 bytes ✅ api/obterprecosatuais.php 2674 bytes ✅ api/obtervariacaodia.php 11452 bytes ✅ api/perplexity.php 7835 bytes ✅ api/simbolos.php 13712 bytes ✅ api/transacoesvistos.php 4202 bytes ✅ api/uploadacoes.php 1600 bytes ✅ api/uploadcaixa.php 2578 bytes ✅ api/uploadextratorevolut.php 1143 bytes ✅ api/uploadhistoricoativos.php 1289 bytes ✅ api/utilizador.php 1042 bytes ✅ api_atualizar.php 8599 bytes ✅ atualizar.html 18589 bytes ✅ backup_20260611_153533/ai.php 9544 bytes ✅ backup_20260611_153533/api/bootstrap/bootstrap.php 443 bytes ✅ backup_20260611_153533/api/bootstrap/logger.php 841 bytes ✅ backup_20260611_153533/api/bootstrap/simbolos.php 13712 bytes ✅ backup_20260611_153533/api/bootstrap/simplecache.php 963 bytes ✅ backup_20260611_153533/api/bootstrap/utilizador.php 1147 bytes ✅ backup_20260611_153533/api/bootstrap/validacao.php 1044 bytes ✅ backup_20260611_153533/api/calculos-atualizar.log 15056 bytes ✅ backup_20260611_153533/api/calculos.php 111631 bytes ✅ backup_20260611_153533/api/downloadacoes.php 560 bytes ✅ backup_20260611_153533/api/downloadcaixa.php 429 bytes ✅ backup_20260611_153533/api/downloadhistoricoativos.php 704 bytes ✅ backup_20260611_153533/api/gerar_de_extrato.php 10025 bytes ✅ backup_20260611_153533/api/listar_ficheiros.php 1310 bytes ✅ backup_20260611_153533/api/obterprecosatuais.php 2674 bytes ✅ backup_20260611_153533/api/obtervariacaodia.php 11452 bytes ✅ backup_20260611_153533/api/perplexity.php 7835 bytes ✅ backup_20260611_153533/api/simbolos.php 13712 bytes ✅ backup_20260611_153533/api/transacoesvistos.php 4202 bytes ✅ backup_20260611_153533/api/uploadacoes.php 1600 bytes ✅ backup_20260611_153533/api/uploadcaixa.php 2578 bytes ✅ backup_20260611_153533/api/uploadextratorevolut.php 1143 bytes ✅ backup_20260611_153533/api/uploadhistoricoativos.php 1289 bytes ✅ backup_20260611_153533/api/utilizador.php 1042 bytes ✅ backup_20260611_153533/api_atualizar.php 8597 bytes ✅ backup_20260611_153533/auth.php 162 bytes ✅ backup_20260611_153533/converter.php 1791 bytes ✅ backup_20260611_153533/dados_csv/agostinha/lucro-mensal.json 8128 bytes ✅ backup_20260611_153533/dados_csv/agostinha/movimentos-caixa.csv 231 bytes ✅ backup_20260611_153533/dados_csv/agostinha/transacoes-acoes.csv 338 bytes ✅ backup_20260611_153533/dados_csv/converter.php 10888 bytes ✅ backup_20260611_153533/dados_csv/dadosacoes.csv 20258 bytes ✅ backup_20260611_153533/dados_csv/extrato-revolut.csv 59378 bytes ✅ backup_20260611_153533/dados_csv/filipe/extrato-revolut.csv 17561 bytes ✅ backup_20260611_153533/dados_csv/filipe/lucro-mensal.json 43267 bytes ✅ backup_20260611_153533/dados_csv/filipe/movimentos-caixa.csv 8615 bytes ✅ backup_20260611_153533/dados_csv/filipe/transacoes-acoes.csv 7194 bytes ✅ backup_20260611_153533/dados_csv/historico-ativos.csv 3416 bytes ✅ backup_20260611_153533/dados_csv/historico-cambio-date.txt 10 bytes ✅ backup_20260611_153533/dados_csv/historico-cambio.json 44374 bytes ✅ backup_20260611_153533/dados_csv/historico-precos-mensal.json 99027 bytes ✅ backup_20260611_153533/dados_csv/maria/extrato-revolut.csv 1636 bytes ✅ backup_20260611_153533/dados_csv/maria/lucro-mensal.json 38309 bytes ✅ backup_20260611_153533/dados_csv/maria/movimentos-caixa.csv 612 bytes ✅ backup_20260611_153533/dados_csv/maria/transacoes-acoes.csv 589 bytes ✅ backup_20260611_153533/dados_csv/movimentos-caixa.csv 17894 bytes ✅ backup_20260611_153533/dados_csv/precos-atuais.json 2088 bytes ✅ backup_20260611_153533/dados_csv/prevclose-cache.json 3242 bytes ✅ backup_20260611_153533/dados_csv/tiago/extrato-revolut.csv 59378 bytes ✅ backup_20260611_153533/dados_csv/tiago/historico-ativos.csv 3416 bytes ✅ backup_20260611_153533/dados_csv/tiago/historico-cambio-date.txt 19 bytes ✅ backup_20260611_153533/dados_csv/tiago/historico-cambio.json 8403 bytes ✅ backup_20260611_153533/dados_csv/tiago/lucro-mensal.json 46810 bytes ✅ backup_20260611_153533/dados_csv/tiago/movimentos-caixa.csv 16619 bytes ✅ backup_20260611_153533/dados_csv/tiago/precos-atuais.json 831 bytes ✅ backup_20260611_153533/dados_csv/tiago/transacoes-acoes.csv 29395 bytes ✅ backup_20260611_153533/dados_csv/tiago/transacoes-vistos.json 66 bytes ✅ backup_20260611_153533/dados_csv/transacoes-acoes.csv 29114 bytes ✅ backup_20260611_153533/dados_csv/transacoes-vistos.json 66 bytes ✅ backup_20260611_153533/dados_csv/variacao-dia.json 2328 bytes ✅ backup_20260611_153533/exportar_projeto.php 2764 bytes ✅ backup_20260611_153533/gerar_movimentos_caixa.php 4083 bytes ✅ backup_20260611_153533/gravar_historico_mensal.php 4452 bytes ✅ backup_20260611_153533/importar_revolut.php 3998 bytes ✅ backup_20260611_153533/info.php 81 bytes ✅ backup_20260611_153533/login.php 1995 bytes ✅ backup_20260611_153533/logout.php 99 bytes ✅ backup_20260611_153533/users.json 139 bytes ✅ backup_20260611_153533/verificar_diferencas_revolut.php 23201 bytes ✅ base-dados-dinheiro.html 16609 bytes ✅ caixa.html 29056 bytes ✅ converter.php 1791 bytes ✅ dados_csv/agostinha/lucro-mensal.json 8128 bytes ✅ dados_csv/agostinha/movimentos-caixa.csv 231 bytes ✅ dados_csv/agostinha/transacoes-acoes.csv 338 bytes ✅ dados_csv/cache-hpm/hpm_aapl.us_m.json 14133 bytes ✅ dados_csv/cache-hpm/hpm_eunl.de_m.json 4385 bytes ✅ dados_csv/cache-hpm/hpm_exxt.de_m.json 5255 bytes ✅ dados_csv/cache-hpm/hpm_googl.us_m.json 7203 bytes ✅ dados_csv/cache-hpm/hpm_nvda.us_m.json 9299 bytes ✅ dados_csv/cache-hpm/hpm_vusa.de_m.json 2742 bytes ✅ dados_csv/cache-hpm/hpm_xaueur_m.json 17938 bytes ✅ dados_csv/cache/atualizar_hpm_perplexity.php 12870 bytes ✅ dados_csv/cache/csv/aapl_us_m.csv 28451 bytes ✅ dados_csv/cache/debug_pplx.php 1516 bytes ✅ dados_csv/cache/hpm_aapl.us_m.json 14133 bytes ✅ dados_csv/cache/hpm_eunl.de_m.json 4385 bytes ✅ dados_csv/cache/hpm_exxt.de_m.json 5257 bytes ✅ dados_csv/cache/hpm_nvda.us_m.json 9299 bytes ✅ dados_csv/cache/stooq-monthclose-06c3aa3b46204b8a839cad65fd4aacae2c09a5d8.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-1fa134046098bf2bad8b14b3b8a3fb863879f1fe.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-1fef489aa8a128b144b1a811322576d3ce0bf95e.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-2afd55491aeacfdfebc48d1b11cb7487e916340f.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-2b5f7fb577a745a3b957342c4065f6615753e1ba.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-2d294b32d9ff1c6a95cd057d25656040d673d5dc.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-2ddbd195729fbb92e4c082dab8a4b29dac48046a.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-37bbf65b466e5ec91101090eed79e2bd5fc1643c.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-423cfc18946eb0698b694482028eaaed747555f4.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-44b07be58971483320e80614feaf88b29cffc237.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-44de178821cde3c1540a627a3e5e02728ea991ee.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-5417d97a53c609e55d7e157b1bfda61b8df09625.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-547ff7c7fdac97796db259805a244af8d58ba9e3.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-5fee8f0307a9ec74b73c917fb49f35d639c1709c.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-68c4ad23606545c32310bded97f7b8b3b9a4d3a3.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-696ce06e6c0901d79c748b644bce548ffd7ae548.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-6e6584baf4f6eb53d74314a3a28a0ceedaaea8ba.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-7a35e0760610450573ee55d7f9bd4b3e610a6059.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-879901cc1d48f82db24e4d0d6788b93389040929.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-a2c5e523dad5904b0bce547076200364ca7617ca.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-bcf30f295c073cf1df3dc1c0f95680d632325bae.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-c0b224252032246d5154931bffd1dffc3c3306e7.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-c5ccb3e128b3efd5cd7a5b078d7e8cf626e82598.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-cac0498649e83daf78cb6b0b7133630629eb98c3.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-ce611600b0536e816f9cf218ce854f6f014ed4e4.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-ceb2d11e26f03767cdb78367cfcf70ac919e15a4.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-d63dff8eb9abf6edf9522f77bf8a00726a446c1f.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-e61b1df2a99a4f2d8d480564f44915f1468ea10d.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-e6b0073a0d6affc4b325ef927f354250615a6a3a.json 2 bytes ✅ dados_csv/cache/stooq-monthclose-f33fc7772217864c1c83b9c08a3a5182ff4822b0.json 2 bytes ✅ dados_csv/converter.php 10888 bytes ✅ dados_csv/dadosacoes.csv 20258 bytes ✅ dados_csv/extrato-revolut.csv 59378 bytes ✅ dados_csv/filipe/extrato-revolut.csv 17561 bytes ✅ dados_csv/filipe/lucro-mensal.json 43267 bytes ✅ dados_csv/filipe/movimentos-caixa.csv 8762 bytes ✅ dados_csv/filipe/transacoes-acoes.csv 7267 bytes ✅ dados_csv/historico-ativos.csv 3416 bytes ✅ dados_csv/historico-cambio-date.txt 10 bytes ✅ dados_csv/historico-cambio.json 44530 bytes ✅ dados_csv/historico-precos-mensal.json 99027 bytes ✅ dados_csv/maria/extrato-revolut.csv 1636 bytes ✅ dados_csv/maria/lucro-mensal.json 38309 bytes ✅ dados_csv/maria/movimentos-caixa.csv 91 bytes ✅ dados_csv/maria/transacoes-acoes.csv 182 bytes ✅ dados_csv/movimentos-caixa.csv 17894 bytes ✅ dados_csv/precos-atuais.json 2046 bytes ✅ dados_csv/prevclose-cache.json 3242 bytes ✅ dados_csv/tiago/extrato-revolut.csv 59378 bytes ✅ dados_csv/tiago/historico-ativos.csv 3416 bytes ✅ dados_csv/tiago/historico-cambio-date.txt 19 bytes ✅ dados_csv/tiago/historico-cambio.json 8403 bytes ✅ dados_csv/tiago/lucro-mensal.json 46810 bytes ✅ dados_csv/tiago/movimentos-caixa.csv 16668 bytes ✅ dados_csv/tiago/precos-atuais.json 831 bytes ✅ dados_csv/tiago/transacoes-acoes.csv 29472 bytes ✅ dados_csv/tiago/transacoes-vistos.json 66 bytes ✅ dados_csv/transacoes-acoes.csv 29114 bytes ✅ dados_csv/transacoes-vistos.json 66 bytes ✅ dados_csv/variacao-dia.json 2328 bytes ✅ debug-env.php 1882 bytes ✅ edf_links.csv 19900 bytes ✅ edf_simple_page_v2.html 4529 bytes ✅ estilos-backend.css 6586 bytes ✅ exportar_projeto.php 2764 bytes ✅ extrato-revolut.csv 59378 bytes ✅ gerar_movimentos_caixa.php 4083 bytes ✅ gravar_historico_mensal.php 4452 bytes ✅ historico-carteira.json 2 bytes ✅ importar-revolut.js 4576 bytes ✅ importar_revolut.php 3998 bytes ✅ index.html 12631 bytes ✅ info.php 81 bytes ✅ irs.html 25346 bytes ✅ lucro-mensal-grafico.html 33130 bytes ✅ manifest.webmanifest 565 bytes ✅ pwa-register.js 306 bytes ✅ resumo.html 63352 bytes ✅ roteiro-amesterdao-belgica-mapa.html 27968 bytes ✅ sw.js 1320 bytes ✅ transacoes-acoes.csv 45543 bytes ✅ transacoes.html 25559 bytes ✅ verificar-revolut.html 28043 bytes ✅ verificar_diferencas_revolut.php 23201 bytes ---------------------------------------------------------------------------------------- ✅ 280 OK | ⌠0 Faltam | 📈 100% ======================================================================================== 💾 CONTEÚDO DOS FICHEIROS ======================================================================================== ======================================================================================== FICHEIRO: ai.php Tamanho: 9544 bytes ======================================================================================== Processando ficheiro: $file_path\n"; echo " (Backup criado em: $backup_path)\n"; $content = file_get_contents($file_path); $new_content = $content; $corrections_made = 0; // ----------------------------------------------------------------- // CORREÇÕES PARA: verificar-revolut.html // ----------------------------------------------------------------- if ($file_path === 'verificar-revolut.html') { // --- CORREÇÃO 1.1: Adicionar função para formatar números --- $search1_1 = <<<'EOD' const verificarUrl = 'verificar_diferencas_revolut.php'; EOD; $replace1_1 = <<<'EOD' function formatNumber(num) { if (num === null || num === undefined) return '-'; return String(num).replace('.', ','); } const verificarUrl = 'verificar_diferencas_revolut.php'; EOD; $new_content = str_replace($search1_1, $replace1_1, $new_content, $count); if ($count > 0) { echo " [OK] Adicionada função 'formatNumber' para formatação de números.\n"; $corrections_made++; } // --- CORREÇÃO 1.2: Aplicar formatação de números na apresentação dos detalhes --- $search1_2 = <<<'EOD' // Sugestão COMPRA if (item.sugestaocompra) { html += `
✅ Sugestão Revolut (COMPRA):
`; } // Sugestão VENDA if (item.sugestaovenda) { html += `
📊 Sugestão Revolut (VENDA):
`; } EOD; $replace1_2 = <<<'EOD' // Sugestão COMPRA if (item.sugestaocompra) { html += `
✅ Sugestão Revolut (COMPRA):
`; } // Sugestão VENDA if (item.sugestaovenda) { html += `
📊 Sugestão Revolut (VENDA):
`; } EOD; $new_content = str_replace($search1_2, $replace1_2, $new_content, $count); if ($count > 0) { echo " [OK] Aplicada formatação de números nas sugestões de Compra/Venda.\n"; $corrections_made++; } // --- CORREÇÃO 1.3: Corrigir lógica de atualização automática (Tx Compra/Venda) --- $search1_3 = <<<'EOD' if (itemData.sugestaocompra) { cols[1] = itemData.sugestaocompra.data; // DataCompra cols[4] = String(itemData.sugestaocompra.quantidade); // NumAcoes cols[6] = String(itemData.sugestaocompra.custo); // CustoInicial if (itemData.sugestaocompra.fx) { cols[8] = String(itemData.sugestaocompra.fx); // TaxaCompra (FX Rate) } } if (itemData.sugestaovenda) { cols[2] = itemData.sugestaovenda.data; // DataVenda cols[7] = String(itemData.sugestaovenda.custo); // CustoFinal if (itemData.sugestaovenda.fx) { cols[9] = String(itemData.sugestaovenda.fx); // TaxaVenda (FX Rate) } } EOD; $replace1_3 = <<<'EOD' if (itemData.sugestaocompra) { cols[1] = itemData.sugestaocompra.data; // DataCompra cols[4] = String(itemData.sugestaocompra.quantidade); // NumAcoes cols[6] = String(itemData.sugestaocompra.custo); // CustoInicial // Corrigido para lidar com fx ausente, nulo ou zero cols[8] = (itemData.sugestaocompra.fx !== null && itemData.sugestaocompra.fx !== undefined) ? String(itemData.sugestaocompra.fx) : ''; } if (itemData.sugestaovenda) { cols[2] = itemData.sugestaovenda.data; // DataVenda cols[7] = String(itemData.sugestaovenda.custo); // CustoFinal // Corrigido para lidar com fx ausente, nulo ou zero cols[9] = (itemData.sugestaovenda.fx !== null && itemData.sugestaovenda.fx !== undefined) ? String(itemData.sugestaovenda.fx) : ''; } EOD; $new_content = str_replace($search1_3, $replace1_3, $new_content, $count); if ($count > 0) { echo " [OK] Melhorada a lógica da correção automática para Taxa de Compra e Venda.\n"; $corrections_made++; } } // ----------------------------------------------------------------- // CORREÇÕES PARA: verificar_diferencas_revolut.php // ----------------------------------------------------------------- if ($file_path === 'verificar_diferencas_revolut.php') { // --- CORREÇÃO 2.1: Adicionar verificação de quantidade na venda --- $search2_1 = <<<'EOD' if ($vendaEncontrada) { if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} → {$vendaEncontrada['valor']}"; } } else { EOD; $replace2_1 = <<<'EOD' if ($vendaEncontrada) { if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } if (abs($vendaEncontrada['quantidade'] - $t['numAcoes']) > 0.00001) { $diferencasCount++; $detalhes[] = "Qtd Venda: {$t['numAcoes']} → {$vendaEncontrada['quantidade']}"; } if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} → {$vendaEncontrada['valor']}"; } } else { EOD; $new_content = str_replace($search2_1, $replace2_1, $new_content, $count); if ($count > 0) { echo " [OK] Adicionada verificação da quantidade (Nº Ações) para transações de Venda.\n"; $corrections_made++; } // --- CORREÇÃO 2.2: Adicionar 'quantidade' à sugestão de venda --- $search2_2 = <<<'EOD' 'sugestaovenda' => $vendaEncontrada ? [ 'data' => $vendaEncontrada['data'], 'custo' => $vendaEncontrada['valor'], 'fx' => $vendaEncontrada['fx'] ?? null, ] : null EOD; $replace2_2 = <<<'EOD' 'sugestaovenda' => $vendaEncontrada ? [ 'data' => $vendaEncontrada['data'], 'quantidade' => $vendaEncontrada['quantidade'], 'custo' => $vendaEncontrada['valor'], 'fx' => $vendaEncontrada['fx'] ?? null, ] : null EOD; $new_content = str_replace($search2_2, $replace2_2, $new_content, $count); if ($count > 0) { echo " [OK] Adicionado campo 'quantidade' na sugestão de Venda para consistência.\n"; $corrections_made++; } } // --- GRAVAR ALTERAÇÕES --- if ($corrections_made > 0) { if ($new_content !== $content) { if (file_put_contents($file_path, $new_content)) { echo " -> SUCESSO: Ficheiro '$file_path' corrigido e guardado.\n\n"; } else { echo " -> ERRO: Falha ao guardar as alterações em '$file_path'.\n\n"; } } else { echo " -> AVISO: Nenhuma alteração real foi feita, apesar das correções terem sido aplicadas (o ficheiro pode já estar corrigido).\n\n"; } } else { echo " -> AVISO: Nenhuma correção foi aplicada. O ficheiro pode já estar atualizado ou o código-fonte difere do esperado.\n\n"; } } echo "=======================================\n"; echo "## CORREÇÃO CONCLUÃDA ##\n"; ?> ======================================================================================== FICHEIRO: alfa/api/bootstrap/bootstrap.php Tamanho: 1205 bytes ======================================================================================== file = $file; $dir = dirname($file); if (!is_dir($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } } public function info(string $msg, array $ctx = []): void { $this->write('info', $msg, $ctx); } public function error(string $msg, array $ctx = []): void { $this->write('error', $msg, $ctx); } private function write(string $level, string $msg, array $ctx): void { $row = [ 'ts' => date('Y-m-d H:i:s'), 'level' => $level, 'msg' => $msg, 'ctx' => $ctx, ]; @file_put_contents( $this->file, json_encode($row, JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND | LOCK_EX ); } } ======================================================================================== FICHEIRO: alfa/api/bootstrap/simbolos.php Tamanho: 13793 bytes ======================================================================================== metadados // - "interno": usado em cálculos, JSON de preços e normalizações // - "json": chave dentro de dadoscsvprecos-atuais.json (normalmente igual ao interno) // - "tabela": símbolo com prefixo de bolsa usado nas tabelas (frontend / histórico) // - "aliases": maneiras alternativas de escrever o mesmo ativo (Revolut, CSV, etc.) // - "nome": nome mais usado / amigável para mostrar na UI const MAPA_SIMBOLOS = [ // ------------- CORE / AÇÕES US ------------- 'AAPL' => [ 'nome' => 'Apple', 'json' => 'AAPL', 'tabela' => 'Apple', 'aliases' => ['AAPL', 'NASDAQ:AAPL', 'Apple'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['aapl.us'], 'twelve' => ['AAPL'], 'manual' => 0, ], 'NVDA' => [ 'nome' => 'NVIDIA', 'json' => 'NVDA', 'tabela' => 'NVIDIA', 'aliases' => ['NVDA', 'NASDAQ:NVDA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nvda.us'], 'twelve' => ['NVDA'], 'manual' => 0, ], 'GOOGL' => [ 'nome' => 'Google', 'json' => 'GOOGL', 'tabela' => 'Google', 'aliases' => ['GOOGL', 'NASDAQ:GOOGL', 'GOOG', 'NASDAQ:GOOG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['googl.us'], 'twelve' => ['GOOGL'], 'manual' => 0, ], 'AMZN' => [ 'nome' => 'Amazon', 'json' => 'AMZN', 'tabela' => 'Amazon', 'aliases' => ['AMZN', 'NASDAQ:AMZN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amzn.us'], 'twelve' => ['AMZN'], 'manual' => 0, ], 'ADBE' => [ 'nome' => 'Adobe', 'json' => 'ADBE', 'tabela' => 'Adobe', 'aliases' => ['ADBE', 'NASDAQ:ADBE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['adbe.us'], 'twelve' => ['ADBE'], 'manual' => 0, ], 'TSLA' => [ 'nome' => 'Tesla', 'json' => 'TSLA', 'tabela' => 'Tesla', 'aliases' => ['TSLA', 'NASDAQ:TSLA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsla.us'], 'twelve' => ['TSLA'], 'manual' => 0, ], 'MSFT' => [ 'nome' => 'Microsoft', 'json' => 'MSFT', 'tabela' => 'Microsoft', 'aliases' => ['MSFT', 'NASDAQ:MSFT'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['msft.us'], 'twelve' => ['MSFT'], 'manual' => 0, ], 'NFLX' => [ 'nome' => 'Netflix', 'json' => 'NFLX', 'tabela' => 'Netflix', 'aliases' => ['NFLX', 'NASDAQ:NFLX'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nflx.us'], 'twelve' => ['NFLX'], 'manual' => 0, ], 'AMD' => [ 'nome' => 'Advanced Micro Devices', 'json' => 'AMD', 'tabela' => 'Advanced Micro Devices', 'aliases' => ['AMD', 'NASDAQ:AMD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amd.us'], 'twelve' => ['AMD'], 'manual' => 0, ], 'ZM' => [ 'nome' => 'Zoom Video', 'json' => 'ZM', 'tabela' => 'Zoom Video', 'aliases' => ['ZM', 'NASDAQ:ZM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['zm.us'], 'twelve' => ['ZM'], 'manual' => 0, ], 'Z' => [ 'nome' => 'Zillow', 'json' => 'Z', 'tabela' => 'Zillow', 'aliases' => ['Z', 'NASDAQ:Z'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['z.us'], 'twelve' => ['Z'], 'manual' => 0, ], 'MRNA' => [ 'nome' => 'Moderna', 'json' => 'MRNA', 'tabela' => 'Moderna', 'aliases' => ['MRNA', 'NASDAQ:MRNA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mrna.us'], 'twelve' => ['MRNA'], 'manual' => 0, ], 'PLUG' => [ 'nome' => 'Plug Power', 'json' => 'PLUG', 'tabela' => 'Plug Power', 'aliases' => ['PLUG', 'NASDAQ:PLUG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['plug.us'], 'twelve' => ['PLUG'], 'manual' => 0, ], 'PYPL' => [ 'nome' => 'PayPal', 'json' => 'PYPL', 'tabela' => 'PayPal', 'aliases' => ['PYPL', 'NASDAQ:PYPL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['pypl.us'], 'twelve' => ['PYPL'], 'manual' => 0, ], 'ANSS' => [ 'nome' => 'ANSYS', 'json' => 'ANSS', 'tabela' => 'ANSYS', 'aliases' => ['ANSS', 'NASDAQ:ANSS'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['anss.us'], 'twelve' => ['ANSS'], 'manual' => 0, ], 'QCOM' => [ 'nome' => 'Qualcomm', 'json' => 'QCOM', 'tabela' => 'Qualcomm', 'aliases' => ['QCOM', 'NASDAQ:QCOM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['qcom.us'], 'twelve' => ['QCOM'], 'manual' => 0, ], 'UAL' => [ 'nome' => 'United Airlines', 'json' => 'UAL', 'tabela' => 'United Airlines', 'aliases' => ['UAL', 'NASDAQ:UAL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ual.us'], 'twelve' => ['UAL'], 'manual' => 0, ], // ------------- FINANCE / PAYMENT ------------- 'MA' => [ 'nome' => 'Mastercard', 'json' => 'MA', 'tabela' => 'Mastercard', 'aliases' => ['MA', 'NYSE:MA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ma.us'], 'twelve' => ['MA'], 'manual' => 0, ], 'SQ' => [ 'nome' => 'Square', 'json' => 'SQ', 'tabela' => 'Square', 'aliases' => ['SQ', 'NYSE:SQ'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['sq.us'], 'twelve' => ['SQ'], 'manual' => 0, ], 'BAC' => [ 'nome' => 'Bank of America', 'json' => 'BAC', 'tabela' => 'Bank of America', 'aliases' => ['BAC', 'NYSE:BAC'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['bac.us'], 'twelve' => ['BAC'], 'manual' => 0, ], 'TSM' => [ 'nome' => 'Taiwan Semiconductor', 'json' => 'TSM', 'tabela' => 'Taiwan Semiconductor', 'aliases' => ['TSM', 'NYSE:TSM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsm.us'], 'twelve' => ['TSM'], 'manual' => 0, ], 'BABA' => [ 'nome' => 'Alibaba Group', 'json' => 'BABA', 'tabela' => 'Alibaba Group', 'aliases' => ['BABA', 'NYSE:BABA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['baba.us'], 'twelve' => ['BABA'], 'manual' => 0, ], 'BRKB' => [ 'nome' => 'Berkshire Hathaway', 'json' => 'BRKB', 'tabela' => 'Berkshire Hathaway', 'aliases' => ['BRKB', 'BRK.B', 'NYSE:BRK.B'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['brk-b.us'], 'twelve' => ['BRK.B', 'BRKB'], 'manual' => 0, ], // ------------- CONSUMO / OUTROS ------------- 'MCD' => [ 'nome' => 'McDonald\'s', 'json' => 'MCD', 'tabela' => 'McDonald\'s', 'aliases' => ['MCD', 'NYSE:MCD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mcd.us'], 'twelve' => ['MCD'], 'manual' => 0, ], 'KO' => [ 'nome' => 'Coca-Cola', 'json' => 'KO', 'tabela' => 'Coca-Cola', 'aliases' => ['KO', 'NYSE:KO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ko.us'], 'twelve' => ['KO'], 'manual' => 0, ], 'SPCE' => [ 'nome' => 'Virgin Galactic', 'json' => 'SPCE', 'tabela' => 'Virgin Galactic', 'aliases' => ['SPCE', 'NYSE:SPCE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['spce.us'], 'twelve' => ['SPCE'], 'manual' => 0, ], 'O' => [ 'nome' => 'Realty Income', 'json' => 'O', 'tabela' => 'Realty Income', 'aliases' => ['O', 'NYSE:O'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['o.us'], 'twelve' => ['O'], 'manual' => 0, ], 'TWTR' => [ 'nome' => 'Twitter', 'json' => 'TWTR', 'tabela' => 'Twitter', 'aliases' => ['TWTR', 'NYSE:TWTR'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['twtr.us'], 'twelve' => ['TWTR'], 'manual' => 0, ], 'NIO' => [ 'nome' => 'NIO', 'json' => 'NIO', 'tabela' => 'NIO', 'aliases' => ['NIO', 'NYSE:NIO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nio.us'], 'twelve' => ['NIO'], 'manual' => 0, ], 'RIVN' => [ 'nome' => 'Rivian', 'json' => 'RIVN', 'tabela' => 'Rivian', 'aliases' => ['RIVN', 'NASDAQ:RIVN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['rivn.us'], 'twelve' => ['RIVN'], 'manual' => 0, ], 'XYZ' => [ 'nome' => 'XYZ', 'json' => 'XYZ', 'tabela' => 'XYZ', 'aliases' => ['XYZ'], // placeholder sem providers ], // ------------- ETFs / RIVN / VUSA / XYZ e OURO ------------- 'VUSA' => [ 'nome' => 'VUSA - Vanguard S&P 500 Dist ETF (Revolut)', 'json' => 'VUSA', 'tabela' => 'VUSA S&P 500', 'aliases' => ['VUSA', 'LSE:VUSA', 'AMS:VUSA', 'VUSA.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'], 'perplexityquery' => 'Current price Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'perplexityclosequery' => 'Previous close Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'manual' => 0, ], 'IWDA' => [ 'nome' => 'IWDA - iShares Core MSCI World Acc ETF (Revolut)', 'json' => 'IWDA', 'tabela' => 'EUNL MSCI World', 'aliases' => ['IWDA', 'EUNL', 'AMS:IWDA', 'EUNL.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'], 'yahoo' => ['EUNL.DE', 'IWDA.AS'], 'perplexityquery' => 'Current price EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'perplexityclosequery' => 'Previous close EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'manual' => 0, ], 'NDXEX' => [ 'nome' => 'NDXEX - iShares Nasdaq 100 UCITS ETF (Dist) (Revolut)', 'json' => 'NDXEX', 'tabela' => 'EXXT Nasdaq-100', 'aliases' => ['NDXEX', 'NDX', 'INDEXNASDAQ:NDX', 'EXXT', 'EQQQ', 'EXXT.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'], 'yahoo' => ['EXXT.DE', 'EQQQ.L'], 'perplexityquery' => 'Current price iShares NASDAQ-100 UCITS ETF (DE) (EXXT.DE) (yahoo)', 'perplexityclosequery' => 'Previous close EXXT.DE iShares NASDAQ-100 UCITS ETF (DE) EUR (yahoo)', 'manual' => 0, ], 'XAUEUR' => [ 'nome' => 'Ouro (XAU/EUR)', 'json' => 'XAUEUR', 'tabela' => 'Ouro', 'moeda' => 'EUR', 'aliases' => ['XAUEUR', 'XAU/EUR', 'XAU EUR', 'OURO', 'GOLD','XAUEUR','XAU'], 'tipo' => 'ouro', 'stooq' => ['xaueur'], 'twelve' => ['XAU/EUR'], 'perplexityquery' => 'Current price, GOLD XAU/EUR', 'perplexityclosequery' => 'Previous close price for GOLD XAU/EUR', 'manual' => 0, ], ]; // Função genérica: dado um ticker qualquer (Revolut, CSV, etc.), devolve o ticker interno function normalizarTickerGlobal(string $raw): ?string { $n = strtoupper(trim($raw)); if ($n === '') { return null; } // 1) Remover prefixos de bolsa mais comuns $n = preg_replace('/^(NASDAQ|NYSE|AMS|INDEXNASDAQ|XETRA|LSE):?/', '', $n); // 2) BRK.B -> BRKB (remover pontos) $n = str_replace('.', '', $n); // 3) Remover qualquer coisa que não seja A–Z ou 0–9 $n = preg_replace('/[^A-Z0-9]/', '', $n); // 4) Procurar primeiro por match direto de interno if (isset(MAPA_SIMBOLOS[$n])) { return $n; } // 5) Procurar nos aliases foreach (MAPA_SIMBOLOS as $interno => $info) { if (!empty($info['aliases']) && in_array($n, $info['aliases'], true)) { return $interno; } } // 6) Fallback: devolve o limpo (permite lidar com ativos novos ainda não registados) return $n; } $simbolos = MAPA_SIMBOLOS; // Se este ficheiro foi chamado diretamente (não via include), enviar JSON if (realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME'] ?? '')) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(MAPA_SIMBOLOS, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } ======================================================================================== FICHEIRO: alfa/api/bootstrap/simplecache.php Tamanho: 963 bytes ======================================================================================== dir = rtrim($dir, '/'); if (!is_dir($this->dir)) { @mkdir($this->dir, 0775, true); @chmod($this->dir, 0775); } } private function path(string $key): string { return $this->dir . '/' . sha1($key) . '.json'; } public function get(string $key, int $ttlSeconds): ?array { $p = $this->path($key); if (!is_file($p)) return null; $age = time() - (int)@filemtime($p); if ($age > $ttlSeconds) return null; $raw = @file_get_contents($p); if (!is_string($raw) || $raw === '') return null; $data = json_decode($raw, true); return is_array($data) ? $data : null; } public function set(string $key, array $value): void { $p = $this->path($key); @file_put_contents($p, json_encode($value, JSON_UNESCAPED_UNICODE), LOCK_EX); } } ======================================================================================== FICHEIRO: alfa/api/bootstrap/utilizador.php Tamanho: 1147 bytes ======================================================================================== /.../dados_csv/tiago/transacoes-acoes.csv [file:1] */ function userFilePath(string $baseName): string { $baseName = ltrim($baseName, '/'); $user = getUserId(); return ROOT . '/dados_csv/' . $user .'/'. $baseName; } ======================================================================================== FICHEIRO: alfa/api/bootstrap/validacao.php Tamanho: 1044 bytes ======================================================================================== false, 'erro' => $msg, 'timestamp' => date('Y-m-d H:i:s'), ], $extra), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } function v_enum(?string $value, array $allowed, string $field = 'valor'): string { $v = trim((string)$value); if ($v === '' || !in_array($v, $allowed, true)) { api_json_error("Campo inválido: $field", 400, ['field' => $field]); } return $v; } function v_user_id(?string $value): string { $v = trim((string)$value); if ($v === '' || !preg_match('/^[a-z0-9_]{1,32}$/', $v)) { api_json_error('User inválido.', 400); } return $v; } function v_moeda(?string $value): string { $v = strtoupper(trim((string)$value)); return v_enum($v, ['EUR', 'USD'], 'moeda'); } ======================================================================================== FICHEIRO: alfa/api/calculos.php Tamanho: 122942 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; // Perplexity removido — substituído por Alpha Vantage como provider principal require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** Alpha Vantage - GLOBAL_QUOTE (price + previous close) */ function obterQuoteAlphaVantage(string $symbol, string $apikey): ?array { $url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 15); if (!is_array($data) || !isset($data['Global Quote']) || !is_array($data['Global Quote'])) { return null; } $q = $data['Global Quote']; $price = isset($q['05. price']) && is_numeric($q['05. price']) ? (float)$q['05. price'] : null; $prevclose = isset($q['08. previous close']) && is_numeric($q['08. previous close']) ? (float)$q['08. previous close'] : null; $changePct = isset($q['10. change percent']) ? $q['10. change percent'] : null; if ($price !== null && $price > 0) { return [ 'price' => $price, 'prevclose' => ($prevclose !== null && $prevclose > 0) ? $prevclose : null, 'pctdia' => $changePct, ]; } return null; } /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** Yahoo Finance - Previous close via chart API */ function obterPrevCloseYahooFinance(string $symbol): ?float { $url = 'https://query1.finance.yahoo.com/v8/finance/chart/' . urlencode($symbol) . '?range=5d&interval=1d&includePrePost=false'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 12, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: application/json\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; $data = json_decode($raw, true); $result = $data['chart']['result'][0] ?? null; if (!is_array($result)) return null; $meta = $result['meta'] ?? []; if (isset($meta['previousClose']) && is_numeric($meta['previousClose']) && (float)$meta['previousClose'] > 0) { return (float)$meta['previousClose']; } $closes = $result['indicators']['quote'][0]['close'] ?? null; if (!is_array($closes)) return null; $valid = []; foreach ($closes as $c) { if (is_numeric($c) && (float)$c > 0) $valid[] = (float)$c; } if (count($valid) >= 2) { return $valid[count($valid) - 2]; } return null; } /** EODHD - Real-time (usa close em vez de price) */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $price = floatval($data['close']); return ($price > 0 && is_finite($price)) ? $price : null; } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } /** Stooq - Diário (usa /q/d/l/ que funciona sem JS) */ function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; // Usar endpoint diário que ainda funciona sem JS/anti-bot $url = "https://stooq.com/q/d/l/?s=" . urlencode($sym) . "&i=d"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; // Verificar se é HTML (bloqueio anti-bot) if (stripos($csv, '= 1; $i--) { $trimmed = trim($lines[$i]); if ($trimmed !== '') { $lastLine = $trimmed; break; } } if ($lastLine === null) return null; $cols = str_getcsv($lastLine); if (count($cols) < 5) return null; $dateStr = trim((string)($cols[0] ?? "")); $close = $cols[4] ?? null; // Coluna "Close" no daily // Validar data (últimos 7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - 1ï¸âƒ£ Alpha Vantage (GLOBAL_QUOTE) — funciona para tudo (ações, ETFs, XAU) * - 2ï¸âƒ£ TwelveData (ações/ouro) * - 3ï¸âƒ£ Stooq (diário, grátis) * - 4ï¸âƒ£ EODHD (ETFs) * - 5ï¸âƒ£ Último preço disponível no cache (fallback) * - 6ï¸âƒ£ Manual (valor fixo) */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1ï¸âƒ£ Alpha Vantage (principal — funciona para tudo) if ($price === null && $apikey_av !== '') { // Determinar símbolo para Alpha Vantage $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { // Mapear símbolo EODHD para Alpha Vantage (ex: VUSA.DE → VUSA.DE) $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['price']) && $quote['price'] > 0) { $price = $quote['price']; $source = "alphavantage:$avSymbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $price = $quote['price'] / $taxaCambio; $moeda = 'EUR'; $source = "alphavantage:$avSymbol→EUR"; } } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve']) && $apikey_twelve !== '') { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3ï¸âƒ£ Stooq (grátis, diário) if ($price === null && isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $p = obterPrecoAtualStooq($symbol); if ($p !== null && $p > 0) { $price = $p; $source = "stooq:$symbol"; break; } } } // 4ï¸âƒ£ EODHD (só ETFs) if ($price === null && $tipo === 'etf' && isset($cfg['eodhd']) && $apikey_eodhd !== '') { foreach ($cfg['eodhd'] as $symbol) { $p = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($p !== null && $p > 0) { $price = $p; $source = "eodhd:$symbol"; break; } } } // 5ï¸âƒ£ Último preço disponível no cache (fallback) if ($price === null || $price <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedPrice = $cached['precos'][$ticker]['preco'] ?? null; if ($cachedPrice !== null && $cachedPrice > 0) { $price = $cachedPrice; $source = 'cache:ultimo_disponivel'; } } } // 6ï¸âƒ£ Manual (valor fixo) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de fecho (previous close) para cálculo de % dia * Hierarquia: * - 1ï¸âƒ£ Alpha Vantage (previous close do GLOBAL_QUOTE) * - 2ï¸âƒ£ Stooq (daily) * - 3ï¸âƒ£ TwelveData (quote → previous_close) * - 4ï¸âƒ£ EODHD (previous close para ETFs) * - 5ï¸âƒ£ Yahoo Finance (meta.previousClose / chart) * - 6ï¸âƒ£ prevclose-cache.json (última data disponível, depois dia anterior) * - 7ï¸âƒ£ precos-atuais.json (último fallback) */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { global $ROOT; $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1) Alpha Vantage (previous close do GLOBAL_QUOTE) if ($closePrice === null && $apikey_av !== '') { $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['prevclose']) && $quote['prevclose'] > 0) { $closePrice = $quote['prevclose']; if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } } } } // 2) STOOQ (previous close via daily) if ($closePrice === null && isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 3) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf' && $apikeytwelve !== '') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf' && $apikeyeodhd !== '') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } // 5) Yahoo Finance (previous close) if ($closePrice === null || $closePrice <= 0) { $yahooSymbols = []; if (!empty($cfg['yahoo']) && is_array($cfg['yahoo'])) { $yahooSymbols = $cfg['yahoo']; } elseif (!empty($cfg['eodhd']) && is_array($cfg['eodhd'])) { $yahooSymbols = $cfg['eodhd']; } elseif (!empty($cfg['twelve']) && is_array($cfg['twelve'])) { $yahooSymbols = $cfg['twelve']; } else { $yahooSymbols = [$ticker]; } if ($ticker === 'XAUEUR') { $yahooSymbols = ['GC=F']; } foreach ($yahooSymbols as $symbol) { $symbol = trim((string)$symbol); if ($symbol === '') continue; $closePrice = obterPrevCloseYahooFinance($symbol); if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'GC=F') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } // 6) Fallback real: prevclose-cache.json (última data disponível, depois dia anterior) if ($closePrice === null || $closePrice <= 0) { $cacheFile = rtrim($ROOT, '/') . '/dados_csv/prevclose-cache.json'; if (is_file($cacheFile) && is_readable($cacheFile)) { $raw = @file_get_contents($cacheFile); $cache = $raw ? json_decode($raw, true) : null; if (is_array($cache) && !empty($cache)) { $datas = array_keys($cache); rsort($datas); $candidatas = []; $ontem = date('Y-m-d', strtotime('-1 day')); if (isset($cache[$ontem]) && is_array($cache[$ontem])) { $candidatas[] = $ontem; } foreach ($datas as $d) { if (!in_array($d, $candidatas, true) && isset($cache[$d]) && is_array($cache[$d])) { $candidatas[] = $d; } } $aliases = [$ticker]; if (!empty($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $s) $aliases[] = $s; } if (!empty($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $s) $aliases[] = $s; } if (!empty($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $s) $aliases[] = $s; } if (!empty($cfg['alphavantage'])) { $aliases[] = $cfg['alphavantage']; } if (!empty($cfg['yahoo']) && is_array($cfg['yahoo'])) { foreach ($cfg['yahoo'] as $s) $aliases[] = $s; } if ($ticker === 'XAUEUR') { $aliases[] = 'XAUUSD'; $aliases[] = 'GC=F'; } $aliases = array_values(array_unique(array_filter(array_map( static fn($v) => trim((string)$v), $aliases )))); foreach ($candidatas as $dataRef) { $bucket = $cache[$dataRef] ?? null; if (!is_array($bucket)) continue; foreach ($aliases as $alias) { if (!array_key_exists($alias, $bucket)) continue; $entry = $bucket[$alias]; if (is_array($entry)) { $valor = fnum($entry['prev_close'] ?? ($entry['prevclose'] ?? ($entry['close'] ?? 0))); } else { $valor = fnum($entry); } if ($valor > 0) { $closePrice = $valor; if ($ticker === 'XAUEUR' && (stripos($alias, 'XAUUSD') !== false || stripos($alias, 'GC=F') !== false) && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } break 2; } } } } } } // 7) Último fallback: precos-atuais.json já existente if ($closePrice === null || $closePrice <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedInfo = $cached['precos'][$ticker]; $cachedPrev = fnum($cachedInfo['prevclose'] ?? ($cachedInfo['close'] ?? 0)); if ($cachedPrev > 0) { $closePrice = $cachedPrev; } } } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[4] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; $APIKEYALPHAVANTAGE = getenv('ALPHAVANTAGE_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $jsonDir = dirname($jsonFile); if (!is_dir($jsonDir)) { if (!@mkdir($jsonDir, 0775, true) && !is_dir($jsonDir)) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao criar diretório de precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'diretorio' => $jsonDir, 'timestamp' => $timestamp ]; } } if (file_exists($jsonFile) && !is_writable($jsonFile)) { return [ 'ok' => false, 'erro' => 'Ficheiro precos-atuais.json sem permissão de escrita', 'detalhe' => 'Verifique owner/grupo/permissões do ficheiro.', 'ficheiro' => $jsonFile, 'timestamp' => $timestamp ]; } if (!file_exists($jsonFile) && !is_writable($jsonDir)) { return [ 'ok' => false, 'erro' => 'Diretório sem permissão de escrita para criar precos-atuais.json', 'detalhe' => 'Verifique owner/grupo/permissões da pasta dados_csv.', 'diretorio' => $jsonDir, 'timestamp' => $timestamp ]; } $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes !== false) { @chmod($jsonFile, 0664); } if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'ficheiro' => $jsonFile, 'diretorio' => $jsonDir, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'totalativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: alfa/api/calculos.php.bak.20260615 Tamanho: 115450 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; // Perplexity removido — substituído por Alpha Vantage como provider principal require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** Alpha Vantage - GLOBAL_QUOTE (price + previous close) */ function obterQuoteAlphaVantage(string $symbol, string $apikey): ?array { $url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 15); if (!is_array($data) || !isset($data['Global Quote']) || !is_array($data['Global Quote'])) { return null; } $q = $data['Global Quote']; $price = isset($q['05. price']) && is_numeric($q['05. price']) ? (float)$q['05. price'] : null; $prevclose = isset($q['08. previous close']) && is_numeric($q['08. previous close']) ? (float)$q['08. previous close'] : null; $changePct = isset($q['10. change percent']) ? $q['10. change percent'] : null; if ($price !== null && $price > 0) { return [ 'price' => $price, 'prevclose' => ($prevclose !== null && $prevclose > 0) ? $prevclose : null, 'pctdia' => $changePct, ]; } return null; } /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time (usa close em vez de price) */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $price = floatval($data['close']); return ($price > 0 && is_finite($price)) ? $price : null; } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } /** Stooq - Diário (usa /q/d/l/ que funciona sem JS) */ function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; // Usar endpoint diário que ainda funciona sem JS/anti-bot $url = "https://stooq.com/q/d/l/?s=" . urlencode($sym) . "&i=d"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; // Verificar se é HTML (bloqueio anti-bot) if (stripos($csv, '= 1; $i--) { $trimmed = trim($lines[$i]); if ($trimmed !== '') { $lastLine = $trimmed; break; } } if ($lastLine === null) return null; $cols = str_getcsv($lastLine); if (count($cols) < 5) return null; $dateStr = trim((string)($cols[0] ?? "")); $close = $cols[4] ?? null; // Coluna "Close" no daily // Validar data (últimos 7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - 1ï¸âƒ£ Alpha Vantage (GLOBAL_QUOTE) — funciona para tudo (ações, ETFs, XAU) * - 2ï¸âƒ£ TwelveData (ações/ouro) * - 3ï¸âƒ£ Stooq (diário, grátis) * - 4ï¸âƒ£ EODHD (ETFs) * - 5ï¸âƒ£ Último preço disponível no cache (fallback) * - 6ï¸âƒ£ Manual (valor fixo) */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1ï¸âƒ£ Alpha Vantage (principal — funciona para tudo) if ($price === null && $apikey_av !== '') { // Determinar símbolo para Alpha Vantage $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { // Mapear símbolo EODHD para Alpha Vantage (ex: VUSA.DE → VUSA.DE) $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['price']) && $quote['price'] > 0) { $price = $quote['price']; $source = "alphavantage:$avSymbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $price = $quote['price'] / $taxaCambio; $moeda = 'EUR'; $source = "alphavantage:$avSymbol→EUR"; } } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve']) && $apikey_twelve !== '') { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3ï¸âƒ£ Stooq (grátis, diário) if ($price === null && isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $p = obterPrecoAtualStooq($symbol); if ($p !== null && $p > 0) { $price = $p; $source = "stooq:$symbol"; break; } } } // 4ï¸âƒ£ EODHD (só ETFs) if ($price === null && $tipo === 'etf' && isset($cfg['eodhd']) && $apikey_eodhd !== '') { foreach ($cfg['eodhd'] as $symbol) { $p = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($p !== null && $p > 0) { $price = $p; $source = "eodhd:$symbol"; break; } } } // 5ï¸âƒ£ Último preço disponível no cache (fallback) if ($price === null || $price <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedPrice = $cached['precos'][$ticker]['preco'] ?? null; if ($cachedPrice !== null && $cachedPrice > 0) { $price = $cachedPrice; $source = 'cache:ultimo_disponivel'; } } } // 6ï¸âƒ£ Manual (valor fixo) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de fecho (previous close) para cálculo de % dia * Hierarquia: * - 1ï¸âƒ£ Alpha Vantage (previous close do GLOBAL_QUOTE) * - 2ï¸âƒ£ Stooq (daily) * - 3ï¸âƒ£ TwelveData (quote → previous_close) * - 4ï¸âƒ£ EODHD (previous close para ETFs) */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1) Alpha Vantage (previous close do GLOBAL_QUOTE) if ($closePrice === null && $apikey_av !== '') { $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['prevclose']) && $quote['prevclose'] > 0) { $closePrice = $quote['prevclose']; if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } } } } // 2) STOOQ (previous close via daily) if ($closePrice === null && isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 3) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf' && $apikeytwelve !== '') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf' && $apikeyeodhd !== '') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; $APIKEYALPHAVANTAGE = getenv('ALPHAVANTAGE_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: alfa/api/calculos.php.bak.pre-yahoo Tamanho: 115450 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; // Perplexity removido — substituído por Alpha Vantage como provider principal require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** Alpha Vantage - GLOBAL_QUOTE (price + previous close) */ function obterQuoteAlphaVantage(string $symbol, string $apikey): ?array { $url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 15); if (!is_array($data) || !isset($data['Global Quote']) || !is_array($data['Global Quote'])) { return null; } $q = $data['Global Quote']; $price = isset($q['05. price']) && is_numeric($q['05. price']) ? (float)$q['05. price'] : null; $prevclose = isset($q['08. previous close']) && is_numeric($q['08. previous close']) ? (float)$q['08. previous close'] : null; $changePct = isset($q['10. change percent']) ? $q['10. change percent'] : null; if ($price !== null && $price > 0) { return [ 'price' => $price, 'prevclose' => ($prevclose !== null && $prevclose > 0) ? $prevclose : null, 'pctdia' => $changePct, ]; } return null; } /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time (usa close em vez de price) */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $price = floatval($data['close']); return ($price > 0 && is_finite($price)) ? $price : null; } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } /** Stooq - Diário (usa /q/d/l/ que funciona sem JS) */ function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; // Usar endpoint diário que ainda funciona sem JS/anti-bot $url = "https://stooq.com/q/d/l/?s=" . urlencode($sym) . "&i=d"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; // Verificar se é HTML (bloqueio anti-bot) if (stripos($csv, '= 1; $i--) { $trimmed = trim($lines[$i]); if ($trimmed !== '') { $lastLine = $trimmed; break; } } if ($lastLine === null) return null; $cols = str_getcsv($lastLine); if (count($cols) < 5) return null; $dateStr = trim((string)($cols[0] ?? "")); $close = $cols[4] ?? null; // Coluna "Close" no daily // Validar data (últimos 7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - 1ï¸âƒ£ Alpha Vantage (GLOBAL_QUOTE) — funciona para tudo (ações, ETFs, XAU) * - 2ï¸âƒ£ TwelveData (ações/ouro) * - 3ï¸âƒ£ Stooq (diário, grátis) * - 4ï¸âƒ£ EODHD (ETFs) * - 5ï¸âƒ£ Último preço disponível no cache (fallback) * - 6ï¸âƒ£ Manual (valor fixo) */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1ï¸âƒ£ Alpha Vantage (principal — funciona para tudo) if ($price === null && $apikey_av !== '') { // Determinar símbolo para Alpha Vantage $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { // Mapear símbolo EODHD para Alpha Vantage (ex: VUSA.DE → VUSA.DE) $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['price']) && $quote['price'] > 0) { $price = $quote['price']; $source = "alphavantage:$avSymbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $price = $quote['price'] / $taxaCambio; $moeda = 'EUR'; $source = "alphavantage:$avSymbol→EUR"; } } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve']) && $apikey_twelve !== '') { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3ï¸âƒ£ Stooq (grátis, diário) if ($price === null && isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $p = obterPrecoAtualStooq($symbol); if ($p !== null && $p > 0) { $price = $p; $source = "stooq:$symbol"; break; } } } // 4ï¸âƒ£ EODHD (só ETFs) if ($price === null && $tipo === 'etf' && isset($cfg['eodhd']) && $apikey_eodhd !== '') { foreach ($cfg['eodhd'] as $symbol) { $p = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($p !== null && $p > 0) { $price = $p; $source = "eodhd:$symbol"; break; } } } // 5ï¸âƒ£ Último preço disponível no cache (fallback) if ($price === null || $price <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedPrice = $cached['precos'][$ticker]['preco'] ?? null; if ($cachedPrice !== null && $cachedPrice > 0) { $price = $cachedPrice; $source = 'cache:ultimo_disponivel'; } } } // 6ï¸âƒ£ Manual (valor fixo) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de fecho (previous close) para cálculo de % dia * Hierarquia: * - 1ï¸âƒ£ Alpha Vantage (previous close do GLOBAL_QUOTE) * - 2ï¸âƒ£ Stooq (daily) * - 3ï¸âƒ£ TwelveData (quote → previous_close) * - 4ï¸âƒ£ EODHD (previous close para ETFs) */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1) Alpha Vantage (previous close do GLOBAL_QUOTE) if ($closePrice === null && $apikey_av !== '') { $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['prevclose']) && $quote['prevclose'] > 0) { $closePrice = $quote['prevclose']; if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } } } } // 2) STOOQ (previous close via daily) if ($closePrice === null && isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 3) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf' && $apikeytwelve !== '') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf' && $apikeyeodhd !== '') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; $APIKEYALPHAVANTAGE = getenv('ALPHAVANTAGE_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: alfa/api/calculos.php.bak.pre-yahoo-20260616 Tamanho: 115450 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; // Perplexity removido — substituído por Alpha Vantage como provider principal require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** Alpha Vantage - GLOBAL_QUOTE (price + previous close) */ function obterQuoteAlphaVantage(string $symbol, string $apikey): ?array { $url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 15); if (!is_array($data) || !isset($data['Global Quote']) || !is_array($data['Global Quote'])) { return null; } $q = $data['Global Quote']; $price = isset($q['05. price']) && is_numeric($q['05. price']) ? (float)$q['05. price'] : null; $prevclose = isset($q['08. previous close']) && is_numeric($q['08. previous close']) ? (float)$q['08. previous close'] : null; $changePct = isset($q['10. change percent']) ? $q['10. change percent'] : null; if ($price !== null && $price > 0) { return [ 'price' => $price, 'prevclose' => ($prevclose !== null && $prevclose > 0) ? $prevclose : null, 'pctdia' => $changePct, ]; } return null; } /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time (usa close em vez de price) */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $price = floatval($data['close']); return ($price > 0 && is_finite($price)) ? $price : null; } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } /** Stooq - Diário (usa /q/d/l/ que funciona sem JS) */ function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; // Usar endpoint diário que ainda funciona sem JS/anti-bot $url = "https://stooq.com/q/d/l/?s=" . urlencode($sym) . "&i=d"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; // Verificar se é HTML (bloqueio anti-bot) if (stripos($csv, '= 1; $i--) { $trimmed = trim($lines[$i]); if ($trimmed !== '') { $lastLine = $trimmed; break; } } if ($lastLine === null) return null; $cols = str_getcsv($lastLine); if (count($cols) < 5) return null; $dateStr = trim((string)($cols[0] ?? "")); $close = $cols[4] ?? null; // Coluna "Close" no daily // Validar data (últimos 7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - 1ï¸âƒ£ Alpha Vantage (GLOBAL_QUOTE) — funciona para tudo (ações, ETFs, XAU) * - 2ï¸âƒ£ TwelveData (ações/ouro) * - 3ï¸âƒ£ Stooq (diário, grátis) * - 4ï¸âƒ£ EODHD (ETFs) * - 5ï¸âƒ£ Último preço disponível no cache (fallback) * - 6ï¸âƒ£ Manual (valor fixo) */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1ï¸âƒ£ Alpha Vantage (principal — funciona para tudo) if ($price === null && $apikey_av !== '') { // Determinar símbolo para Alpha Vantage $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { // Mapear símbolo EODHD para Alpha Vantage (ex: VUSA.DE → VUSA.DE) $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['price']) && $quote['price'] > 0) { $price = $quote['price']; $source = "alphavantage:$avSymbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $price = $quote['price'] / $taxaCambio; $moeda = 'EUR'; $source = "alphavantage:$avSymbol→EUR"; } } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve']) && $apikey_twelve !== '') { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3ï¸âƒ£ Stooq (grátis, diário) if ($price === null && isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $p = obterPrecoAtualStooq($symbol); if ($p !== null && $p > 0) { $price = $p; $source = "stooq:$symbol"; break; } } } // 4ï¸âƒ£ EODHD (só ETFs) if ($price === null && $tipo === 'etf' && isset($cfg['eodhd']) && $apikey_eodhd !== '') { foreach ($cfg['eodhd'] as $symbol) { $p = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($p !== null && $p > 0) { $price = $p; $source = "eodhd:$symbol"; break; } } } // 5ï¸âƒ£ Último preço disponível no cache (fallback) if ($price === null || $price <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedPrice = $cached['precos'][$ticker]['preco'] ?? null; if ($cachedPrice !== null && $cachedPrice > 0) { $price = $cachedPrice; $source = 'cache:ultimo_disponivel'; } } } // 6ï¸âƒ£ Manual (valor fixo) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de fecho (previous close) para cálculo de % dia * Hierarquia: * - 1ï¸âƒ£ Alpha Vantage (previous close do GLOBAL_QUOTE) * - 2ï¸âƒ£ Stooq (daily) * - 3ï¸âƒ£ TwelveData (quote → previous_close) * - 4ï¸âƒ£ EODHD (previous close para ETFs) */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1) Alpha Vantage (previous close do GLOBAL_QUOTE) if ($closePrice === null && $apikey_av !== '') { $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['prevclose']) && $quote['prevclose'] > 0) { $closePrice = $quote['prevclose']; if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } } } } // 2) STOOQ (previous close via daily) if ($closePrice === null && isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 3) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf' && $apikeytwelve !== '') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf' && $apikeyeodhd !== '') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; $APIKEYALPHAVANTAGE = getenv('ALPHAVANTAGE_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: alfa/api/calculos.php.bak.pre-yahoo2 Tamanho: 115450 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; // Perplexity removido — substituído por Alpha Vantage como provider principal require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** Alpha Vantage - GLOBAL_QUOTE (price + previous close) */ function obterQuoteAlphaVantage(string $symbol, string $apikey): ?array { $url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 15); if (!is_array($data) || !isset($data['Global Quote']) || !is_array($data['Global Quote'])) { return null; } $q = $data['Global Quote']; $price = isset($q['05. price']) && is_numeric($q['05. price']) ? (float)$q['05. price'] : null; $prevclose = isset($q['08. previous close']) && is_numeric($q['08. previous close']) ? (float)$q['08. previous close'] : null; $changePct = isset($q['10. change percent']) ? $q['10. change percent'] : null; if ($price !== null && $price > 0) { return [ 'price' => $price, 'prevclose' => ($prevclose !== null && $prevclose > 0) ? $prevclose : null, 'pctdia' => $changePct, ]; } return null; } /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time (usa close em vez de price) */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $price = floatval($data['close']); return ($price > 0 && is_finite($price)) ? $price : null; } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } /** Stooq - Diário (usa /q/d/l/ que funciona sem JS) */ function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; // Usar endpoint diário que ainda funciona sem JS/anti-bot $url = "https://stooq.com/q/d/l/?s=" . urlencode($sym) . "&i=d"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; // Verificar se é HTML (bloqueio anti-bot) if (stripos($csv, '= 1; $i--) { $trimmed = trim($lines[$i]); if ($trimmed !== '') { $lastLine = $trimmed; break; } } if ($lastLine === null) return null; $cols = str_getcsv($lastLine); if (count($cols) < 5) return null; $dateStr = trim((string)($cols[0] ?? "")); $close = $cols[4] ?? null; // Coluna "Close" no daily // Validar data (últimos 7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - 1ï¸âƒ£ Alpha Vantage (GLOBAL_QUOTE) — funciona para tudo (ações, ETFs, XAU) * - 2ï¸âƒ£ TwelveData (ações/ouro) * - 3ï¸âƒ£ Stooq (diário, grátis) * - 4ï¸âƒ£ EODHD (ETFs) * - 5ï¸âƒ£ Último preço disponível no cache (fallback) * - 6ï¸âƒ£ Manual (valor fixo) */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1ï¸âƒ£ Alpha Vantage (principal — funciona para tudo) if ($price === null && $apikey_av !== '') { // Determinar símbolo para Alpha Vantage $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { // Mapear símbolo EODHD para Alpha Vantage (ex: VUSA.DE → VUSA.DE) $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['price']) && $quote['price'] > 0) { $price = $quote['price']; $source = "alphavantage:$avSymbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $price = $quote['price'] / $taxaCambio; $moeda = 'EUR'; $source = "alphavantage:$avSymbol→EUR"; } } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve']) && $apikey_twelve !== '') { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3ï¸âƒ£ Stooq (grátis, diário) if ($price === null && isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $p = obterPrecoAtualStooq($symbol); if ($p !== null && $p > 0) { $price = $p; $source = "stooq:$symbol"; break; } } } // 4ï¸âƒ£ EODHD (só ETFs) if ($price === null && $tipo === 'etf' && isset($cfg['eodhd']) && $apikey_eodhd !== '') { foreach ($cfg['eodhd'] as $symbol) { $p = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($p !== null && $p > 0) { $price = $p; $source = "eodhd:$symbol"; break; } } } // 5ï¸âƒ£ Último preço disponível no cache (fallback) if ($price === null || $price <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedPrice = $cached['precos'][$ticker]['preco'] ?? null; if ($cachedPrice !== null && $cachedPrice > 0) { $price = $cachedPrice; $source = 'cache:ultimo_disponivel'; } } } // 6ï¸âƒ£ Manual (valor fixo) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de fecho (previous close) para cálculo de % dia * Hierarquia: * - 1ï¸âƒ£ Alpha Vantage (previous close do GLOBAL_QUOTE) * - 2ï¸âƒ£ Stooq (daily) * - 3ï¸âƒ£ TwelveData (quote → previous_close) * - 4ï¸âƒ£ EODHD (previous close para ETFs) */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1) Alpha Vantage (previous close do GLOBAL_QUOTE) if ($closePrice === null && $apikey_av !== '') { $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['prevclose']) && $quote['prevclose'] > 0) { $closePrice = $quote['prevclose']; if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } } } } // 2) STOOQ (previous close via daily) if ($closePrice === null && isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 3) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf' && $apikeytwelve !== '') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf' && $apikeyeodhd !== '') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; $APIKEYALPHAVANTAGE = getenv('ALPHAVANTAGE_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: alfa/api/calculos.php.bak.stable Tamanho: 115450 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; // Perplexity removido — substituído por Alpha Vantage como provider principal require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** Alpha Vantage - GLOBAL_QUOTE (price + previous close) */ function obterQuoteAlphaVantage(string $symbol, string $apikey): ?array { $url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 15); if (!is_array($data) || !isset($data['Global Quote']) || !is_array($data['Global Quote'])) { return null; } $q = $data['Global Quote']; $price = isset($q['05. price']) && is_numeric($q['05. price']) ? (float)$q['05. price'] : null; $prevclose = isset($q['08. previous close']) && is_numeric($q['08. previous close']) ? (float)$q['08. previous close'] : null; $changePct = isset($q['10. change percent']) ? $q['10. change percent'] : null; if ($price !== null && $price > 0) { return [ 'price' => $price, 'prevclose' => ($prevclose !== null && $prevclose > 0) ? $prevclose : null, 'pctdia' => $changePct, ]; } return null; } /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time (usa close em vez de price) */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $price = floatval($data['close']); return ($price > 0 && is_finite($price)) ? $price : null; } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } /** Stooq - Diário (usa /q/d/l/ que funciona sem JS) */ function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; // Usar endpoint diário que ainda funciona sem JS/anti-bot $url = "https://stooq.com/q/d/l/?s=" . urlencode($sym) . "&i=d"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; // Verificar se é HTML (bloqueio anti-bot) if (stripos($csv, '= 1; $i--) { $trimmed = trim($lines[$i]); if ($trimmed !== '') { $lastLine = $trimmed; break; } } if ($lastLine === null) return null; $cols = str_getcsv($lastLine); if (count($cols) < 5) return null; $dateStr = trim((string)($cols[0] ?? "")); $close = $cols[4] ?? null; // Coluna "Close" no daily // Validar data (últimos 7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - 1ï¸âƒ£ Alpha Vantage (GLOBAL_QUOTE) — funciona para tudo (ações, ETFs, XAU) * - 2ï¸âƒ£ TwelveData (ações/ouro) * - 3ï¸âƒ£ Stooq (diário, grátis) * - 4ï¸âƒ£ EODHD (ETFs) * - 5ï¸âƒ£ Último preço disponível no cache (fallback) * - 6ï¸âƒ£ Manual (valor fixo) */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1ï¸âƒ£ Alpha Vantage (principal — funciona para tudo) if ($price === null && $apikey_av !== '') { // Determinar símbolo para Alpha Vantage $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { // Mapear símbolo EODHD para Alpha Vantage (ex: VUSA.DE → VUSA.DE) $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['price']) && $quote['price'] > 0) { $price = $quote['price']; $source = "alphavantage:$avSymbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $price = $quote['price'] / $taxaCambio; $moeda = 'EUR'; $source = "alphavantage:$avSymbol→EUR"; } } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve']) && $apikey_twelve !== '') { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3ï¸âƒ£ Stooq (grátis, diário) if ($price === null && isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $p = obterPrecoAtualStooq($symbol); if ($p !== null && $p > 0) { $price = $p; $source = "stooq:$symbol"; break; } } } // 4ï¸âƒ£ EODHD (só ETFs) if ($price === null && $tipo === 'etf' && isset($cfg['eodhd']) && $apikey_eodhd !== '') { foreach ($cfg['eodhd'] as $symbol) { $p = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($p !== null && $p > 0) { $price = $p; $source = "eodhd:$symbol"; break; } } } // 5ï¸âƒ£ Último preço disponível no cache (fallback) if ($price === null || $price <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedPrice = $cached['precos'][$ticker]['preco'] ?? null; if ($cachedPrice !== null && $cachedPrice > 0) { $price = $cachedPrice; $source = 'cache:ultimo_disponivel'; } } } // 6ï¸âƒ£ Manual (valor fixo) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de fecho (previous close) para cálculo de % dia * Hierarquia: * - 1ï¸âƒ£ Alpha Vantage (previous close do GLOBAL_QUOTE) * - 2ï¸âƒ£ Stooq (daily) * - 3ï¸âƒ£ TwelveData (quote → previous_close) * - 4ï¸âƒ£ EODHD (previous close para ETFs) */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1) Alpha Vantage (previous close do GLOBAL_QUOTE) if ($closePrice === null && $apikey_av !== '') { $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['prevclose']) && $quote['prevclose'] > 0) { $closePrice = $quote['prevclose']; if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } } } } // 2) STOOQ (previous close via daily) if ($closePrice === null && isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 3) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf' && $apikeytwelve !== '') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf' && $apikeyeodhd !== '') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; $APIKEYALPHAVANTAGE = getenv('ALPHAVANTAGE_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: alfa/api/calculos.php.bak.stable-permissions Tamanho: 116004 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; // Perplexity removido — substituído por Alpha Vantage como provider principal require_once ROOT . '/api/bootstrap/simbolos.php'; require_once ROOT . '/api/yahoo-helper.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** Alpha Vantage - GLOBAL_QUOTE (price + previous close) */ function obterQuoteAlphaVantage(string $symbol, string $apikey): ?array { $url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 15); if (!is_array($data) || !isset($data['Global Quote']) || !is_array($data['Global Quote'])) { return null; } $q = $data['Global Quote']; $price = isset($q['05. price']) && is_numeric($q['05. price']) ? (float)$q['05. price'] : null; $prevclose = isset($q['08. previous close']) && is_numeric($q['08. previous close']) ? (float)$q['08. previous close'] : null; $changePct = isset($q['10. change percent']) ? $q['10. change percent'] : null; if ($price !== null && $price > 0) { return [ 'price' => $price, 'prevclose' => ($prevclose !== null && $prevclose > 0) ? $prevclose : null, 'pctdia' => $changePct, ]; } return null; } /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time (usa close em vez de price) */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $price = floatval($data['close']); return ($price > 0 && is_finite($price)) ? $price : null; } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } /** Stooq - Diário (usa /q/d/l/ que funciona sem JS) */ function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; // Usar endpoint diário que ainda funciona sem JS/anti-bot $url = "https://stooq.com/q/d/l/?s=" . urlencode($sym) . "&i=d"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; // Verificar se é HTML (bloqueio anti-bot) if (stripos($csv, '= 1; $i--) { $trimmed = trim($lines[$i]); if ($trimmed !== '') { $lastLine = $trimmed; break; } } if ($lastLine === null) return null; $cols = str_getcsv($lastLine); if (count($cols) < 5) return null; $dateStr = trim((string)($cols[0] ?? "")); $close = $cols[4] ?? null; // Coluna "Close" no daily // Validar data (últimos 7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - 1ï¸âƒ£ Alpha Vantage (GLOBAL_QUOTE) — funciona para tudo (ações, ETFs, XAU) * - 2ï¸âƒ£ TwelveData (ações/ouro) * - 3ï¸âƒ£ Stooq (diário, grátis) * - 4ï¸âƒ£ EODHD (ETFs) * - 5ï¸âƒ£ Último preço disponível no cache (fallback) * - 6ï¸âƒ£ Manual (valor fixo) */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 0ï¸âƒ£ Yahoo Finance (preço atual) $yahooPreco = obterPrecoYahoo($ticker, $taxaCambio); if ($yahooPreco !== null && $yahooPreco['preco'] > 0) { $price = $yahooPreco['preco']; $moeda = $yahooPreco['moeda'] ?? $moeda; $source = $yahooPreco['fonte']; } // 1ï¸âƒ£ Alpha Vantage (principal — funciona para tudo) if ($price === null && $apikey_av !== '') { // Determinar símbolo para Alpha Vantage $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { // Mapear símbolo EODHD para Alpha Vantage (ex: VUSA.DE → VUSA.DE) $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['price']) && $quote['price'] > 0) { $price = $quote['price']; $source = "alphavantage:$avSymbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $price = $quote['price'] / $taxaCambio; $moeda = 'EUR'; $source = "alphavantage:$avSymbol→EUR"; } } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve']) && $apikey_twelve !== '') { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3ï¸âƒ£ Stooq (grátis, diário) if ($price === null && isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $p = obterPrecoAtualStooq($symbol); if ($p !== null && $p > 0) { $price = $p; $source = "stooq:$symbol"; break; } } } // 4ï¸âƒ£ EODHD (só ETFs) if ($price === null && $tipo === 'etf' && isset($cfg['eodhd']) && $apikey_eodhd !== '') { foreach ($cfg['eodhd'] as $symbol) { $p = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($p !== null && $p > 0) { $price = $p; $source = "eodhd:$symbol"; break; } } } // 5ï¸âƒ£ Último preço disponível no cache (fallback) if ($price === null || $price <= 0) { $cached = carregarPrecosAtuais(); if (is_array($cached) && isset($cached['precos'][$ticker])) { $cachedPrice = $cached['precos'][$ticker]['preco'] ?? null; if ($cachedPrice !== null && $cachedPrice > 0) { $price = $cachedPrice; $source = 'cache:ultimo_disponivel'; } } } // 6ï¸âƒ£ Manual (valor fixo) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de fecho (previous close) para cálculo de % dia * Hierarquia: * - 1ï¸âƒ£ Alpha Vantage (previous close do GLOBAL_QUOTE) * - 2ï¸âƒ£ Stooq (daily) * - 3ï¸âƒ£ TwelveData (quote → previous_close) * - 4ï¸âƒ£ EODHD (previous close para ETFs) */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; // 0) Yahoo Finance (penúltimo close) $yahooPrevclose = obterPrevCloseYahoo($ticker, $taxaCambio); if ($yahooPrevclose !== null && $yahooPrevclose > 0) { $closePrice = $yahooPrevclose; } $apikey_av = getenv('ALPHAVANTAGE_APIKEY') ?: $_ENV['ALPHAVANTAGE_APIKEY'] ?: ''; // 1) Alpha Vantage (previous close do GLOBAL_QUOTE) if ($closePrice === null && $apikey_av !== '') { $avSymbol = null; if (isset($cfg['alphavantage'])) { $avSymbol = $cfg['alphavantage']; } elseif ($tipo === 'etf' && isset($cfg['eodhd'])) { $avSymbol = $cfg['eodhd'][0]; } elseif ($tipo === 'acao' && isset($cfg['twelve'])) { $avSymbol = $cfg['twelve'][0]; } elseif ($ticker === 'XAUEUR') { $avSymbol = 'XAUUSD'; } else { $avSymbol = $ticker; } if ($avSymbol) { $quote = obterQuoteAlphaVantage($avSymbol, $apikey_av); if (is_array($quote) && isset($quote['prevclose']) && $quote['prevclose'] > 0) { $closePrice = $quote['prevclose']; if ($ticker === 'XAUEUR' && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } } } } // 2) STOOQ (previous close via daily) if ($closePrice === null && isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 3) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf' && $apikeytwelve !== '') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf' && $apikeyeodhd !== '') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; $APIKEYALPHAVANTAGE = getenv('ALPHAVANTAGE_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: alfa/api/converter.php Tamanho: 10959 bytes ======================================================================================== = 70 ? '19' : '20') . $year; } return sprintf('%04d-%02d', (int)$year, (int)$m[2]); } function parseDecimal(?string $value): ?float { if ($value === null) { return null; } $value = trim($value); if ($value === '' || $value === '-' || strtoupper($value) === 'NULL') { return null; } $value = str_replace(' ', '', $value); $value = str_replace('.', '', $value); $value = str_replace(',', '.', $value); if (!is_numeric($value)) { return null; } return (float)$value; } function normalizeTicker(string $raw): array { $raw = strtoupper(trim($raw)); $manualMap = [ 'AAPL' => ['ticker' => 'AAPL', 'stooq' => 'aapl.us', 'moeda' => 'USD'], 'TSLA' => ['ticker' => 'TSLA', 'stooq' => 'tsla.us', 'moeda' => 'USD'], 'PYPL' => ['ticker' => 'PYPL', 'stooq' => 'pypl.us', 'moeda' => 'USD'], 'GOOGL' => ['ticker' => 'GOOGL', 'stooq' => 'googl.us', 'moeda' => 'USD'], 'AMZN' => ['ticker' => 'AMZN', 'stooq' => 'amzn.us', 'moeda' => 'USD'], 'KO' => ['ticker' => 'KO', 'stooq' => 'ko.us', 'moeda' => 'USD'], 'BAC' => ['ticker' => 'BAC', 'stooq' => 'bac.us', 'moeda' => 'USD'], 'ANSS' => ['ticker' => 'ANSS', 'stooq' => 'anss.us', 'moeda' => 'USD'], 'AMD' => ['ticker' => 'AMD', 'stooq' => 'amd.us', 'moeda' => 'USD'], 'NVDA' => ['ticker' => 'NVDA', 'stooq' => 'nvda.us', 'moeda' => 'USD'], 'ADBE' => ['ticker' => 'ADBE', 'stooq' => 'adbe.us', 'moeda' => 'USD'], 'MSFT' => ['ticker' => 'MSFT', 'stooq' => 'msft.us', 'moeda' => 'USD'], 'SPCE' => ['ticker' => 'SPCE', 'stooq' => 'spce.us', 'moeda' => 'USD'], 'MRNA' => ['ticker' => 'MRNA', 'stooq' => 'mrna.us', 'moeda' => 'USD'], 'SQ' => ['ticker' => 'SQ', 'stooq' => 'sq.us', 'moeda' => 'USD'], 'NFLX' => ['ticker' => 'NFLX', 'stooq' => 'nflx.us', 'moeda' => 'USD'], 'NIO' => ['ticker' => 'NIO', 'stooq' => 'nio.us', 'moeda' => 'USD'], 'BRKB' => ['ticker' => 'BRKB', 'stooq' => 'brk-b.us', 'moeda' => 'USD'], 'PLUG' => ['ticker' => 'PLUG', 'stooq' => 'plug.us', 'moeda' => 'USD'], 'MA' => ['ticker' => 'MA', 'stooq' => 'ma.us', 'moeda' => 'USD'], 'MCD' => ['ticker' => 'MCD', 'stooq' => 'mcd.us', 'moeda' => 'USD'], 'UAL' => ['ticker' => 'UAL', 'stooq' => 'ual.us', 'moeda' => 'USD'], 'ZM' => ['ticker' => 'ZM', 'stooq' => 'zm.us', 'moeda' => 'USD'], 'BABA' => ['ticker' => 'BABA', 'stooq' => 'baba.us', 'moeda' => 'USD'], 'Z' => ['ticker' => 'Z', 'stooq' => 'z.us', 'moeda' => 'USD'], 'O' => ['ticker' => 'O', 'stooq' => 'o.us', 'moeda' => 'USD'], 'TWTR' => ['ticker' => 'TWTR', 'stooq' => 'twtr.us', 'moeda' => 'USD'], 'IWDA' => ['ticker' => 'IWDA', 'stooq' => 'eunl.de', 'moeda' => 'EUR'], 'QCOM' => ['ticker' => 'QCOM', 'stooq' => 'qcom.us', 'moeda' => 'USD'], 'TSM' => ['ticker' => 'TSM', 'stooq' => 'tsm.us', 'moeda' => 'USD'], 'NDXEX' => ['ticker' => 'NDXEX', 'stooq' => 'exxt.de', 'moeda' => 'EUR'], 'VUSA' => ['ticker' => 'VUSA', 'stooq' => 'vusa.de', 'moeda' => 'EUR'], 'XAUEUR' => ['ticker' => 'XAUEUR', 'stooq' => 'xaueur', 'moeda' => 'EUR'], ]; $aliasMap = [ 'NASDAQ:AAP' => 'AAPL', 'NASDAQ:PYP' => 'PYPL', 'NASDAQ:GOO' => 'GOOGL', 'NASDAQ:AMZ' => 'AMZN', 'NASDAQ:ANS' => 'ANSS', 'NASDAQ:NVD' => 'NVDA', 'NASDAQ:ADB' => 'ADBE', 'NASDAQ:MSF' => 'MSFT', 'NASDAQ:MRN' => 'MRNA', 'NASDAQ:NFL' => 'NFLX', 'NASDAQ:PLU' => 'PLUG', 'NASDAQ:QCO' => 'QCOM', 'NYSE:BRK.B' => 'BRKB', 'AMS:IWDA' => 'IWDA', 'AMS:VUSA' => 'VUSA', 'INDEXNASDAQ:NDX' => 'NDXEX', 'CURRENCY:XAUEUR' => 'XAUEUR', ]; if (isset($aliasMap[$raw])) { return $manualMap[$aliasMap[$raw]]; } $parts = strpos($raw, ':') !== false ? explode(':', $raw, 2) : ['', $raw]; $market = strtoupper(trim($parts[0] ?? '')); $ticker = strtoupper(trim($parts[1] ?? $raw)); $ticker = preg_replace('/[^A-Z0-9.\-]/', '', $ticker) ?: $ticker; if ($ticker === 'BRK.B') { $ticker = 'BRKB'; } $shortAliases = [ 'AAP' => 'AAPL', 'PYP' => 'PYPL', 'GOO' => 'GOOGL', 'AMZ' => 'AMZN', 'ANS' => 'ANSS', 'NVD' => 'NVDA', 'ADB' => 'ADBE', 'MSF' => 'MSFT', 'MRN' => 'MRNA', 'NFL' => 'NFLX', 'PLU' => 'PLUG', 'QCO' => 'QCOM', 'XAU' => 'XAUEUR', 'GOLD' => 'XAUEUR', 'OURO' => 'XAUEUR', 'XAUEUR' => 'XAUEUR', ]; if (isset($shortAliases[$ticker])) { $ticker = $shortAliases[$ticker]; } if (isset($manualMap[$ticker])) { return $manualMap[$ticker]; } $suffixByMarket = [ 'NASDAQ' => '.us', 'NYSE' => '.us', 'AMEX' => '.us', 'ARCA' => '.us', 'BATS' => '.us', 'AMS' => '.de', 'XETR' => '.de', 'ETR' => '.de', 'FWB' => '.de', 'DE' => '.de', 'EURONEXT' => '.eu', 'CURRENCY' => '', 'INDEX' => '', ]; $moedaByMarket = [ 'AMS' => 'EUR', 'XETR' => 'EUR', 'ETR' => 'EUR', 'FWB' => 'EUR', 'DE' => 'EUR', 'CURRENCY' => 'EUR', 'INDEX' => 'EUR', ]; $moeda = $moedaByMarket[$market] ?? 'USD'; $suffix = $suffixByMarket[$market] ?? '.us'; $tickerClean = str_replace('.', '', $ticker); $stooqTicker = strtolower($tickerClean . $suffix); return [ 'ticker' => $tickerClean, 'stooq' => $stooqTicker, 'moeda' => $moeda, ]; } function buildDateColumnMap(array $header): array { $map = []; foreach ($header as $index => $cell) { $monthKey = parseMonthKey((string)$cell); if ($monthKey !== null) { $map[$index] = $monthKey; } } return $map; } function createMeta(int $totalTickers): array { return [ 'user' => 'tiago', 'todos' => false, 'encerradas' => false, 'mindatacompra' => '2019-10-15', 'minmesguardado' => '2019-10', 'debugtickersamostra' => ['AAPL', 'NVDA'], 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => 2592000, 'forcar' => false, 'stats' => [ 'totaltickers' => $totalTickers, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ], 'timestamp' => date('Y-m-d H:i:s'), ]; } try { header('Content-Type: application/json; charset=utf-8'); $projectRoot = dirname(__DIR__); $csvPath = $projectRoot . '/dados_csv/dadosacoes.csv'; $outputDir = $projectRoot . '/dados_csv'; $jsonPath = $outputDir . '/historico-precos-mensal.json'; if (!is_file($csvPath)) { throw new RuntimeException("Ficheiro CSV não encontrado em: {$csvPath}"); } if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) { throw new RuntimeException("Não foi possível criar a pasta: {$outputDir}"); } $content = readFileUtf8($csvPath); $lines = preg_split('/\R/', trim($content)); if (!$lines || count($lines) < 5) { throw new RuntimeException('O CSV não tem linhas suficientes para ser processado.'); } $header = parseCsvLine($lines[0]); $dateColumnMap = buildDateColumnMap($header); if (!$dateColumnMap) { throw new RuntimeException('Não foi possível detetar colunas de datas no CSV.'); } $ativos = []; foreach ($lines as $lineNumber => $line) { if ($lineNumber < 4) { continue; } $line = trim($line); if ($line === '') { continue; } $cols = parseCsvLine($line); $symbolRaw = strtoupper(trim((string)($cols[1] ?? ''))); if ($symbolRaw === '') { continue; } $looksLikeSymbol = strpos($symbolRaw, ':') !== false || in_array($symbolRaw, ['XAU', 'XAUEUR', 'GOLD', 'OURO'], true) || str_starts_with($symbolRaw, 'INDEX') || str_starts_with($symbolRaw, 'CURRENCY'); if (!$looksLikeSymbol) { continue; } $mapped = normalizeTicker($symbolRaw); $mensal = []; foreach ($dateColumnMap as $index => $monthKey) { $value = parseDecimal($cols[$index] ?? null); if ($value !== null) { $mensal[$monthKey] = $value; } } if (!$mensal) { continue; } ksort($mensal); $ativos[$mapped['ticker']] = [ 'stooq' => $mapped['stooq'], 'moeda' => $mapped['moeda'], 'mensal' => $mensal, ]; } ksort($ativos); $result = [ 'meta' => createMeta(count($ativos)), 'ativos' => $ativos, ]; $json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); if ($json === false) { throw new RuntimeException('Falha ao gerar JSON.'); } if (file_put_contents($jsonPath, $json . PHP_EOL) === false) { throw new RuntimeException("Não foi possível gravar o ficheiro JSON em: {$jsonPath}"); } echo $json; } catch (Throwable $e) { http_response_code(500); echo json_encode([ 'erro' => $e->getMessage(), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); } ======================================================================================== FICHEIRO: alfa/api/downloadacoes.php Tamanho: 560 bytes ======================================================================================== false, 'error' => 'Nenhuma ação pedida. Use atualizar_caixa=1 e/ou atualizar_acoes=1' ]); exit; } // Ficheiro de extrato por utilizador $ficheiroExtrato = userFilePath('extrato-revolut.csv'); if (!file_exists($ficheiroExtrato)) { echo json_encode([ 'ok' => false, 'error' => "Extrato Revolut não encontrado para utilizador '$user'. Carregue primeiro via Importar Revolut." ]); exit; } // Helpers function extrairValor($texto) { if (preg_match('/(USD|EUR)\s*([+-]?[0-9.,]+)/', $texto, $m)) { return (float) str_replace(',', '', $m[2]); } return 0.0; } function extrairMoeda($texto) { if (preg_match('/(USD|EUR)/', $texto, $m)) { return $m[1]; } return 'USD'; } function mapearTipoCaixa($tipoRevolut) { $tipo = strtoupper(trim($tipoRevolut)); if (strpos($tipo, 'CASH TOP-UP') !== false) return 'Depósito'; if (strpos($tipo, 'CASH WITHDRAWAL') !== false) return 'Levantamento'; if (strpos($tipo, 'DIVIDEND') !== false) return 'Dividendo'; if (strpos($tipo, 'CUSTODY FEE') !== false) return 'Outros'; if (strpos($tipo, 'TRANSFER') !== false) return 'Outros'; return 'Outros'; } function eLinhaCaixa($ticker, $tipoRevolut) { $tipo = strtoupper(trim($tipoRevolut)); // Mesma lógica do JS: só caixa se NÃO tiver ticker // ou se for CASH/DIVIDEND/CUSTODY FEE/TRANSFER e não MARKET. $incluir = (empty($ticker) || strpos($tipo, 'CASH') !== false || strpos($tipo, 'DIVIDEND') !== false || strpos($tipo, 'CUSTODY FEE') !== false || strpos($tipo, 'TRANSFER') !== false); return $incluir && (strpos($tipo, 'MARKET') === false); } function eLinhaAcao($ticker, $tipoRevolut) { if (empty($ticker)) return false; $tipo = strtoupper(trim($tipoRevolut)); return (strpos($tipo, 'BUY') !== false || strpos($tipo, 'SELL') !== false); } function converterDataISO($dataISO) { // "2020-09-17T12:27:15.160488Z" -> "2020-09-17" return substr(trim($dataISO), 0, 10); } // Ler extrato $fh = fopen($ficheiroExtrato, 'r'); if (!$fh) { echo json_encode([ 'ok' => false, 'error' => 'Não foi possível abrir o extrato Revolut.' ]); exit; } // Cabeçalho (esperado): Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate $header = fgetcsv($fh); $map = array_flip($header ?: []); $idxDate = $map['Date'] ?? 0; $idxTicker = $map['Ticker'] ?? 1; $idxType = $map['Type'] ?? 2; $idxQty = $map['Quantity'] ?? 3; $idxTotal = $map['Total Amount'] ?? 5; $idxCurTxt = $map['Currency'] ?? 6; $idxFx = $map['FX Rate'] ?? 7; // Acumuladores $movimentosCaixa = []; $transacoesAcoes = []; $ordemCaixa = 1; $ordemAcoes = 1; while (($cols = fgetcsv($fh)) !== false) { if (count($cols) < 8) continue; $dataISO = $cols[$idxDate] ?? ''; $ticker = trim($cols[$idxTicker] ?? ''); $tipoRevolut = $cols[$idxType] ?? ''; $qtyTxt = $cols[$idxQty] ?? ''; $totalTxt = $cols[$idxTotal] ?? ''; $moedaTxt = $cols[$idxCurTxt] ?? ''; $fxRate = trim($cols[$idxFx] ?? ''); if (trim($dataISO) === '') continue; $data = converterDataISO($dataISO); // Valor e moeda vindos de "Total Amount" (ex: "USD 371.31") $valorBruto = extrairValor($totalTxt); if ($valorBruto == 0.0) { // ainda assim tentar moeda só pelo campo Currency $moeda = extrairMoeda($moedaTxt); } else { $moeda = extrairMoeda($totalTxt); } // 1) Movimentos de CAIXA if ($doCaixa && eLinhaCaixa($ticker, $tipoRevolut) && $valorBruto != 0.0) { $descricao = $ticker ? ($ticker . ' ' . $tipoRevolut) : strtoupper(trim($tipoRevolut)); $movimentosCaixa[] = [ 'ordem' => $ordemCaixa++, 'data' => $data, 'tipo' => mapearTipoCaixa($tipoRevolut), 'valor' => $valorBruto, 'moeda' => $moeda, 'descricao' => $descricao, 'taxa' => $fxRate, ]; } // 2) Transações de AÇÕES if ($doAcoes && eLinhaAcao($ticker, $tipoRevolut) && $valorBruto != 0.0) { $tipoUpper = strtoupper(trim($tipoRevolut)); $qtd = (float) str_replace(',', '.', $qtyTxt); // Normalizar sinal: consideramos valor positivo para custo/receita $valorAbs = abs($valorBruto); $dataCompra = ''; $dataVenda = ''; $custoInicial = 0.0; $custoFinal = 0.0; $taxaCompra = ''; $taxaVenda = ''; if (strpos($tipoUpper, 'BUY') !== false) { // COMPRA $dataCompra = $data; $custoInicial = $valorAbs; $taxaCompra = $fxRate; } elseif (strpos($tipoUpper, 'SELL') !== false) { // VENDA $dataVenda = $data; $custoFinal = $valorAbs; $taxaVenda = $fxRate; } else { // Não reconhecido como BUY/SELL continue; } $transacoesAcoes[] = [ 'ordem' => $ordemAcoes++, 'dataCompra' => $dataCompra, 'dataVenda' => $dataVenda, 'nomeAcao' => $ticker, 'numAcoes' => $qtd, 'comissoes' => 0.0, 'custoInicial' => $custoInicial, 'custoFinal' => $custoFinal, 'taxaCompra' => $taxaCompra, 'taxaVenda' => $taxaVenda, 'moeda' => $moeda, ]; } } fclose($fh); // Gravar ficheiros $result = [ 'ok' => true, 'user' => $user, 'movimentos_caixa'=> 0, 'transacoes_acoes'=> 0, 'ficheiros' => [], ]; if ($doCaixa) { $csv = "Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio\n"; foreach ($movimentosCaixa as $mov) { $valor = number_format($mov['valor'], 2, '.', ''); $taxa = $mov['taxa'] !== '' ? $mov['taxa'] : ''; $desc = str_replace('"', '""', $mov['descricao']); $csv .= "{$mov['ordem']},{$mov['data']},{$mov['tipo']},{$valor},{$mov['moeda']},\"{$desc}\",{$taxa}\n"; } $ficheiroCaixa = userFilePath('movimentos-caixa.csv'); file_put_contents($ficheiroCaixa, $csv); $result['movimentos_caixa'] = count($movimentosCaixa); $result['ficheiros'][] = basename($ficheiroCaixa); } if ($doAcoes) { // 1) Agrupar COMPRA/VENDA com o mesmo NomeAcao e NumAcoes $agrupadas = []; foreach ($transacoesAcoes as $t) { // chave: mesmo nome de ação e mesma quantidade $chave = $t['nomeAcao'] . '|' . number_format($t['numAcoes'], 6, '.', ''); if (!isset($agrupadas[$chave])) { $agrupadas[$chave] = $t; continue; } // Já existe uma linha para esta ação+quantidade → juntar dados $exist = &$agrupadas[$chave]; if ($exist['dataCompra'] === '' && $t['dataCompra'] !== '') { $exist['dataCompra'] = $t['dataCompra']; } if ($exist['dataVenda'] === '' && $t['dataVenda'] !== '') { $exist['dataVenda'] = $t['dataVenda']; } if ((float)$exist['custoInicial'] == 0.0 && (float)$t['custoInicial'] != 0.0) { $exist['custoInicial'] = $t['custoInicial']; } if ((float)$exist['custoFinal'] == 0.0 && (float)$t['custoFinal'] != 0.0) { $exist['custoFinal'] = $t['custoFinal']; } if ($exist['taxaCompra'] === '' && $t['taxaCompra'] !== '') { $exist['taxaCompra'] = $t['taxaCompra']; } if ($exist['taxaVenda'] === '' && $t['taxaVenda'] !== '') { $exist['taxaVenda'] = $t['taxaVenda']; } unset($exist); // limpar referência } // 2) Recriar lista final com novas ordens $transacoesCombinadas = []; $ordem = 1; foreach ($agrupadas as $t) { $t['ordem'] = $ordem++; $transacoesCombinadas[] = $t; } // 3) Gerar CSV $csv = "Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda\n"; foreach ($transacoesCombinadas as $t) { $numAcoes = number_format($t['numAcoes'], 6, '.', ''); $comissoes = number_format($t['comissoes'], 2, '.', ''); $custoInicial = number_format($t['custoInicial'], 2, '.', ''); $custoFinal = number_format($t['custoFinal'], 2, '.', ''); $taxaCompra = $t['taxaCompra'] !== '' ? $t['taxaCompra'] : ''; $taxaVenda = $t['taxaVenda'] !== '' ? $t['taxaVenda'] : ''; $nomeEscapado = str_replace(',', ' ', $t['nomeAcao']); $csv .= $t['ordem'] . ',' . $t['dataCompra'] . ',' . $t['dataVenda'] . ',' . $nomeEscapado . ',' . $numAcoes . ',' . $comissoes . ',' . $custoInicial . ',' . $custoFinal . ',' . $taxaCompra . ',' . $taxaVenda . ',' . $t['moeda'] . "\n"; } $ficheiroAcoes = userFilePath('transacoes-acoes.csv'); file_put_contents($ficheiroAcoes, $csv); $result['transacoes_acoes'] = count($transacoesCombinadas); $result['ficheiros'][] = basename($ficheiroAcoes); } echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); ?> ======================================================================================== FICHEIRO: alfa/api/listar_ficheiros.php Tamanho: 1310 bytes ======================================================================================== true, 'ficheiros' => $ficheiros, 'total' => count($ficheiros), 'timestamp' => date('Y-m-d H:i:s') )); ?> ======================================================================================== FICHEIRO: alfa/api/obterprecosatuais.php Tamanho: 1245 bytes ======================================================================================== false, 'erro' => 'Não foi possível carregar preços atuais.', 'ficheiro_user' => $userPath, 'ficheiro_global' => $globalPath, 'timestamp' => date('Y-m-d H:i:s') ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode([ 'ok' => true, 'source' => ($dados === lerJsonSeguro($userPath)) ? 'user' : 'global', 'dados' => $dados, 'timestamp' => date('Y-m-d H:i:s') ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: alfa/api/obtervariacaodia.php Tamanho: 1173 bytes ======================================================================================== false, 'erro' => 'Não foi possível carregar a variação do dia.', 'ficheiro_user' => $userPath, 'ficheiro_global' => $globalPath, 'timestamp' => date('Y-m-d H:i:s') ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode([ 'ok' => true, 'dados' => $dados, 'timestamp' => date('Y-m-d H:i:s') ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: alfa/api/simbolos.php Tamanho: 13712 bytes ======================================================================================== metadados // - "interno": usado em cálculos, JSON de preços e normalizações // - "json": chave dentro de dadoscsvprecos-atuais.json (normalmente igual ao interno) // - "tabela": símbolo com prefixo de bolsa usado nas tabelas (frontend / histórico) // - "aliases": maneiras alternativas de escrever o mesmo ativo (Revolut, CSV, etc.) // - "nome": nome mais usado / amigável para mostrar na UI const MAPA_SIMBOLOS = [ // ------------- CORE / AÇÕES US ------------- 'AAPL' => [ 'nome' => 'Apple', 'json' => 'AAPL', 'tabela' => 'Apple', 'aliases' => ['AAPL', 'NASDAQ:AAPL', 'Apple'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['aapl.us'], 'twelve' => ['AAPL'], 'manual' => 0, ], 'NVDA' => [ 'nome' => 'NVIDIA', 'json' => 'NVDA', 'tabela' => 'NVIDIA', 'aliases' => ['NVDA', 'NASDAQ:NVDA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nvda.us'], 'twelve' => ['NVDA'], 'manual' => 0, ], 'GOOGL' => [ 'nome' => 'Google', 'json' => 'GOOGL', 'tabela' => 'Google', 'aliases' => ['GOOGL', 'NASDAQ:GOOGL', 'GOOG', 'NASDAQ:GOOG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['googl.us'], 'twelve' => ['GOOGL'], 'manual' => 0, ], 'AMZN' => [ 'nome' => 'Amazon', 'json' => 'AMZN', 'tabela' => 'Amazon', 'aliases' => ['AMZN', 'NASDAQ:AMZN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amzn.us'], 'twelve' => ['AMZN'], 'manual' => 0, ], 'ADBE' => [ 'nome' => 'Adobe', 'json' => 'ADBE', 'tabela' => 'Adobe', 'aliases' => ['ADBE', 'NASDAQ:ADBE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['adbe.us'], 'twelve' => ['ADBE'], 'manual' => 0, ], 'TSLA' => [ 'nome' => 'Tesla', 'json' => 'TSLA', 'tabela' => 'Tesla', 'aliases' => ['TSLA', 'NASDAQ:TSLA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsla.us'], 'twelve' => ['TSLA'], 'manual' => 0, ], 'MSFT' => [ 'nome' => 'Microsoft', 'json' => 'MSFT', 'tabela' => 'Microsoft', 'aliases' => ['MSFT', 'NASDAQ:MSFT'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['msft.us'], 'twelve' => ['MSFT'], 'manual' => 0, ], 'NFLX' => [ 'nome' => 'Netflix', 'json' => 'NFLX', 'tabela' => 'Netflix', 'aliases' => ['NFLX', 'NASDAQ:NFLX'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nflx.us'], 'twelve' => ['NFLX'], 'manual' => 0, ], 'AMD' => [ 'nome' => 'Advanced Micro Devices', 'json' => 'AMD', 'tabela' => 'Advanced Micro Devices', 'aliases' => ['AMD', 'NASDAQ:AMD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amd.us'], 'twelve' => ['AMD'], 'manual' => 0, ], 'ZM' => [ 'nome' => 'Zoom Video', 'json' => 'ZM', 'tabela' => 'Zoom Video', 'aliases' => ['ZM', 'NASDAQ:ZM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['zm.us'], 'twelve' => ['ZM'], 'manual' => 0, ], 'Z' => [ 'nome' => 'Zillow', 'json' => 'Z', 'tabela' => 'Zillow', 'aliases' => ['Z', 'NASDAQ:Z'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['z.us'], 'twelve' => ['Z'], 'manual' => 0, ], 'MRNA' => [ 'nome' => 'Moderna', 'json' => 'MRNA', 'tabela' => 'Moderna', 'aliases' => ['MRNA', 'NASDAQ:MRNA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mrna.us'], 'twelve' => ['MRNA'], 'manual' => 0, ], 'PLUG' => [ 'nome' => 'Plug Power', 'json' => 'PLUG', 'tabela' => 'Plug Power', 'aliases' => ['PLUG', 'NASDAQ:PLUG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['plug.us'], 'twelve' => ['PLUG'], 'manual' => 0, ], 'PYPL' => [ 'nome' => 'PayPal', 'json' => 'PYPL', 'tabela' => 'PayPal', 'aliases' => ['PYPL', 'NASDAQ:PYPL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['pypl.us'], 'twelve' => ['PYPL'], 'manual' => 0, ], 'ANSS' => [ 'nome' => 'ANSYS', 'json' => 'ANSS', 'tabela' => 'ANSYS', 'aliases' => ['ANSS', 'NASDAQ:ANSS'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['anss.us'], 'twelve' => ['ANSS'], 'manual' => 0, ], 'QCOM' => [ 'nome' => 'Qualcomm', 'json' => 'QCOM', 'tabela' => 'Qualcomm', 'aliases' => ['QCOM', 'NASDAQ:QCOM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['qcom.us'], 'twelve' => ['QCOM'], 'manual' => 0, ], 'UAL' => [ 'nome' => 'United Airlines', 'json' => 'UAL', 'tabela' => 'United Airlines', 'aliases' => ['UAL', 'NASDAQ:UAL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ual.us'], 'twelve' => ['UAL'], 'manual' => 0, ], // ------------- FINANCE / PAYMENT ------------- 'MA' => [ 'nome' => 'Mastercard', 'json' => 'MA', 'tabela' => 'Mastercard', 'aliases' => ['MA', 'NYSE:MA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ma.us'], 'twelve' => ['MA'], 'manual' => 0, ], 'SQ' => [ 'nome' => 'Square', 'json' => 'SQ', 'tabela' => 'Square', 'aliases' => ['SQ', 'NYSE:SQ'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['sq.us'], 'twelve' => ['SQ'], 'manual' => 0, ], 'BAC' => [ 'nome' => 'Bank of America', 'json' => 'BAC', 'tabela' => 'Bank of America', 'aliases' => ['BAC', 'NYSE:BAC'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['bac.us'], 'twelve' => ['BAC'], 'manual' => 0, ], 'TSM' => [ 'nome' => 'Taiwan Semiconductor', 'json' => 'TSM', 'tabela' => 'Taiwan Semiconductor', 'aliases' => ['TSM', 'NYSE:TSM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsm.us'], 'twelve' => ['TSM'], 'manual' => 0, ], 'BABA' => [ 'nome' => 'Alibaba Group', 'json' => 'BABA', 'tabela' => 'Alibaba Group', 'aliases' => ['BABA', 'NYSE:BABA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['baba.us'], 'twelve' => ['BABA'], 'manual' => 0, ], 'BRKB' => [ 'nome' => 'Berkshire Hathaway', 'json' => 'BRKB', 'tabela' => 'Berkshire Hathaway', 'aliases' => ['BRKB', 'BRK.B', 'NYSE:BRK.B'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['brk-b.us'], 'twelve' => ['BRK.B', 'BRKB'], 'manual' => 0, ], // ------------- CONSUMO / OUTROS ------------- 'MCD' => [ 'nome' => 'McDonald\'s', 'json' => 'MCD', 'tabela' => 'McDonald\'s', 'aliases' => ['MCD', 'NYSE:MCD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mcd.us'], 'twelve' => ['MCD'], 'manual' => 0, ], 'KO' => [ 'nome' => 'Coca-Cola', 'json' => 'KO', 'tabela' => 'Coca-Cola', 'aliases' => ['KO', 'NYSE:KO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ko.us'], 'twelve' => ['KO'], 'manual' => 0, ], 'SPCE' => [ 'nome' => 'Virgin Galactic', 'json' => 'SPCE', 'tabela' => 'Virgin Galactic', 'aliases' => ['SPCE', 'NYSE:SPCE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['spce.us'], 'twelve' => ['SPCE'], 'manual' => 0, ], 'O' => [ 'nome' => 'Realty Income', 'json' => 'O', 'tabela' => 'Realty Income', 'aliases' => ['O', 'NYSE:O'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['o.us'], 'twelve' => ['O'], 'manual' => 0, ], 'TWTR' => [ 'nome' => 'Twitter', 'json' => 'TWTR', 'tabela' => 'Twitter', 'aliases' => ['TWTR', 'NYSE:TWTR'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['twtr.us'], 'twelve' => ['TWTR'], 'manual' => 0, ], 'NIO' => [ 'nome' => 'NIO', 'json' => 'NIO', 'tabela' => 'NIO', 'aliases' => ['NIO', 'NYSE:NIO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nio.us'], 'twelve' => ['NIO'], 'manual' => 0, ], 'RIVN' => [ 'nome' => 'Rivian', 'json' => 'RIVN', 'tabela' => 'Rivian', 'aliases' => ['RIVN', 'NASDAQ:RIVN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['rivn.us'], 'twelve' => ['RIVN'], 'manual' => 0, ], 'XYZ' => [ 'nome' => 'XYZ', 'json' => 'XYZ', 'tabela' => 'XYZ', 'aliases' => ['XYZ'], // placeholder sem providers ], // ------------- ETFs / RIVN / VUSA / XYZ e OURO ------------- 'VUSA' => [ 'nome' => 'VUSA - Vanguard S&P 500 Dist ETF (Revolut)', 'json' => 'VUSA', 'tabela' => 'VUSA S&P 500', 'aliases' => ['VUSA', 'LSE:VUSA', 'AMS:VUSA', 'VUSA.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'], 'perplexityquery' => 'Current price Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'perplexityclosequery' => 'Previous close Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'manual' => 0, ], 'IWDA' => [ 'nome' => 'IWDA - iShares Core MSCI World Acc ETF (Revolut)', 'json' => 'IWDA', 'tabela' => 'EUNL MSCI World', 'aliases' => ['IWDA', 'EUNL', 'AMS:IWDA', 'EUNL.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'], 'perplexityquery' => 'Current price EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'perplexityclosequery' => 'Previous close EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'manual' => 0, ], 'NDXEX' => [ 'nome' => 'NDXEX - iShares Nasdaq 100 UCITS ETF (Dist) (Revolut)', 'json' => 'NDXEX', 'tabela' => 'EXXT Nasdaq-100', 'aliases' => ['NDXEX', 'NDX', 'INDEXNASDAQ:NDX', 'EXXT', 'EQQQ', 'EXXT.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'], 'perplexityquery' => 'Current price iShares NASDAQ-100 UCITS ETF (DE) (EXXT.DE) (yahoo)', 'perplexityclosequery' => 'Previous close EXXT.DE iShares NASDAQ-100 UCITS ETF (DE) EUR (yahoo)', 'manual' => 0, ], 'XAUEUR' => [ 'nome' => 'Ouro (XAU/EUR)', 'json' => 'XAUEUR', 'tabela' => 'Ouro', 'moeda' => 'EUR', 'aliases' => ['XAUEUR', 'XAU/EUR', 'XAU EUR', 'OURO', 'GOLD','XAUEUR','XAU'], 'tipo' => 'ouro', 'stooq' => ['xaueur'], 'twelve' => ['XAU/EUR'], 'perplexityquery' => 'Current price, GOLD XAU/EUR', 'perplexityclosequery' => 'Previous close price for GOLD XAU/EUR', 'manual' => 0, ], ]; // Função genérica: dado um ticker qualquer (Revolut, CSV, etc.), devolve o ticker interno function normalizarTickerGlobal(string $raw): ?string { $n = strtoupper(trim($raw)); if ($n === '') { return null; } // 1) Remover prefixos de bolsa mais comuns $n = preg_replace('/^(NASDAQ|NYSE|AMS|INDEXNASDAQ|XETRA|LSE):?/', '', $n); // 2) BRK.B -> BRKB (remover pontos) $n = str_replace('.', '', $n); // 3) Remover qualquer coisa que não seja A–Z ou 0–9 $n = preg_replace('/[^A-Z0-9]/', '', $n); // 4) Procurar primeiro por match direto de interno if (isset(MAPA_SIMBOLOS[$n])) { return $n; } // 5) Procurar nos aliases foreach (MAPA_SIMBOLOS as $interno => $info) { if (!empty($info['aliases']) && in_array($n, $info['aliases'], true)) { return $interno; } } // 6) Fallback: devolve o limpo (permite lidar com ativos novos ainda não registados) return $n; } $simbolos = MAPA_SIMBOLOS; // Se este ficheiro foi chamado diretamente (não via include), enviar JSON if (realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME'] ?? '')) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(MAPA_SIMBOLOS, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } ======================================================================================== FICHEIRO: alfa/api/transacoesvistos.php Tamanho: 4202 bytes ======================================================================================== devolve transacoes-vistos.json do utilizador * POST -> marca/desmarca um visto por (tipo, id) * * Estrutura esperada (compatível com vistoCheck no verificador): * { * "versao": "1.0", * "ultimaAtualizacao": "YYYY-MM-DD HH:MM:SS", * "vistos": { * "alterarlinha": { "L:12": true }, * "adicionartransacao": {}, * "removertransacao": {} * } * } */ // Se este ficheiro estiver em /api/, o apiutilizador.php está 1 nível acima. $bootstrap = __DIR__ . '/../api/utilizador.php'; // Fallback: caso este ficheiro esteja na raiz (sem pasta api) if (!is_file($bootstrap)) $bootstrap = __DIR__ . '/api/utilizador.php'; require_once $bootstrap; function readJsonFile(string $path): array { if (!is_file($path)) return []; $raw = @file_get_contents($path); if (!is_string($raw) || trim($raw) === '') return []; $j = json_decode($raw, true); return is_array($j) ? $j : []; } function writeJsonFile(string $path, array $data): bool { $dir = dirname($path); if (!is_dir($dir)) @mkdir($dir, 0775, true); $raw = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($raw)) return false; return @file_put_contents($path, $raw, LOCK_EX) !== false; } function ensureSchema(array $j): array { if (!isset($j['versao'])) $j['versao'] = '1.0'; if (!isset($j['vistos']) || !is_array($j['vistos'])) $j['vistos'] = []; foreach (['alterarlinha', 'adicionartransacao', 'removertransacao'] as $t) { if (!isset($j['vistos'][$t]) || !is_array($j['vistos'][$t])) { $j['vistos'][$t] = []; } } if (!isset($j['ultimaAtualizacao'])) $j['ultimaAtualizacao'] = date('Y-m-d H:i:s'); return $j; } $ficheiro = userFilePath('transacoes-vistos.json'); if ($_SERVER['REQUEST_METHOD'] === 'GET') { $j = ensureSchema(readJsonFile($ficheiro)); echo json_encode($j, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $raw = file_get_contents('php://input'); $input = json_decode((string)$raw, true); if (!is_array($input)) { echo json_encode(['ok' => false, 'error' => 'JSON inválido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // Novo formato: tipo + id $tipo = isset($input['tipo']) ? trim((string)$input['tipo']) : ''; $id = isset($input['id']) ? trim((string)$input['id']) : ''; // Compatibilidade mínima com chamadas antigas: {linha:"L:12"} ou {linha:"12"} if (($tipo === '' || $id === '') && isset($input['linha'])) { $tipo = $tipo !== '' ? $tipo : 'alterarlinha'; $linha = trim((string)$input['linha']); if ($linha !== '') { $id = (strpos($linha, 'L:') === 0) ? $linha : ('L:' . $linha); } } if (!in_array($tipo, ['alterarlinha', 'adicionartransacao', 'removertransacao'], true)) { echo json_encode(['ok' => false, 'error' => 'Tipo inválido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if ($id === '') { echo json_encode(['ok' => false, 'error' => 'ID não fornecido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } $marcar = true; if (isset($input['ok'])) $marcar = (bool)$input['ok']; if (isset($input['marcar'])) $marcar = (bool)$input['marcar']; // alias $j = ensureSchema(readJsonFile($ficheiro)); if ($marcar) { $j['vistos'][$tipo][$id] = true; } else { if (isset($j['vistos'][$tipo][$id])) unset($j['vistos'][$tipo][$id]); } $j['ultimaAtualizacao'] = date('Y-m-d H:i:s'); $ok = writeJsonFile($ficheiro, $j); echo json_encode([ 'ok' => $ok, 'tipo' => $tipo, 'id' => $id, 'marcar' => $marcar, 'user' => getUserId(), 'ficheiro' => basename($ficheiro) ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } echo json_encode(['ok' => false, 'error' => 'Método não suportado'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; ======================================================================================== FICHEIRO: alfa/api/upload-dadosacoes.php Tamanho: 3263 bytes ======================================================================================== true, 'fileName' => $originalName, 'destino' => 'dados_csv/dadosacoes.csv', 'backup' => $backupPath ? basename($backupPath) : null, 'timestamp' => date('Y-m-d H:i:s'), ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); } catch (Throwable $e) { http_response_code(400); echo json_encode([ 'ok' => false, 'erro' => $e->getMessage(), ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); } ======================================================================================== FICHEIRO: alfa/api/uploadacoes.php Tamanho: 1600 bytes ======================================================================================== false, 'error' => 'CSV vazio.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } // Validação leve: garantir que parece um CSV de transações if (stripos($csv, 'Ordem,') !== 0) { echo json_encode(['ok' => false, 'error' => 'Cabeçalho CSV inválido (esperado começar por "Ordem,").'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $ficheiro = userFilePath('transacoes-acoes.csv'); $dir = dirname($ficheiro); if (!is_dir($dir) && !@mkdir($dir, 0775, true)) { echo json_encode(['ok' => false, 'error' => 'Falha ao criar diretório do utilizador.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0775, true); } // Backup do ficheiro anterior (se existir) if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/transacoes-acoes-' . date('YmdHis') . '.csv'); } $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { echo json_encode(['ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode(['ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId()], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: alfa/api/uploadcaixa.php Tamanho: 2578 bytes ======================================================================================== false, 'error' => 'CSV vazio.']); } // Validação leve: cabeçalho esperado para movimentos-caixa if (stripos($csv, "Ordem,Data,Tipo,Valor,Moeda,Descricao") !== 0) { responder([ 'ok' => false, 'error' => 'Cabeçalho CSV inválido (caixa). Esperado: Ordem,Data,Tipo,Valor,Moeda,Descricao,...' ]); } $user = function_exists('getUserId') ? getUserId() : null; // ✅ ficheiro correto $ficheiro = userFilePath('movimentos-caixa.csv'); $dir = dirname($ficheiro); // Garantir pasta do utilizador if (!is_dir($dir)) { if (!@mkdir($dir, 0775, true)) { $e = error_get_last(); responder([ 'ok' => false, 'error' => 'Falha ao criar diretório do utilizador.', 'dir' => $dir, 'detalhe' => $e['message'] ?? null, 'user' => $user ]); } } // Backups $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0777, true); } // Diagnóstico de permissões clearstatcache(true, $dir); clearstatcache(true, $ficheiro); $diag = [ 'dir' => $dir, 'dir_existe' => is_dir($dir), 'dir_writable' => is_writable($dir), 'ficheiro' => $ficheiro, 'ficheiro_existe' => is_file($ficheiro), 'ficheiro_writable' => is_file($ficheiro) ? is_writable($ficheiro) : null, 'php_user' => function_exists('get_current_user') ? get_current_user() : null, ]; // Backup do ficheiro anterior se existir (não deve bloquear a gravação) if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/movimentos-caixa-' . date('YmdHis') . '.csv'); } // Gravar $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { $e = error_get_last(); responder([ 'ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.', 'detalhe' => $e['message'] ?? null, 'diag' => $diag, 'user' => $user ]); } @chmod($ficheiro, 0777); responder([ 'ok' => true, 'ficheiro' => basename($ficheiro), 'bytes' => $ok, 'diag' => $diag, 'user' => $user ]); ======================================================================================== FICHEIRO: alfa/api/uploadextratorevolut.php Tamanho: 1143 bytes ======================================================================================== false, 'error' => 'Nenhum conteúdo recebido (CSV vazio).', ]); exit; } // Caminho do ficheiro por utilizador: dados_csv//extrato-revolut.csv $ficheiro = userFilePath('extrato-revolut.csv'); $dir = dirname($ficheiro); // Garantir diretório do utilizador if (!is_dir($dir)) { mkdir($dir, 0775, true); } // Pasta de backups $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { mkdir($backupDir, 0775, true); } // Backup do ficheiro anterior (se existir) if (file_exists($ficheiro)) { @copy($ficheiro, $backupDir . '/extrato-revolut-' . date('YmdHis') . '.csv'); } // Gravar extrato atual file_put_contents($ficheiro, $csv); echo json_encode([ 'ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId(), ]); ?> ======================================================================================== FICHEIRO: alfa/api/uploadhistoricoativos.php Tamanho: 1289 bytes ======================================================================================== false, 'error' => 'CSV vazio.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $ficheiro = userFilePath('historico-ativos.csv'); $dir = dirname($ficheiro); if (!is_dir($dir) && !@mkdir($dir, 0775, true)) { echo json_encode(['ok' => false, 'error' => 'Falha ao criar diretório do utilizador.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0775, true); } if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/historico-ativos-' . date('YmdHis') . '.csv'); } $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { echo json_encode(['ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode(['ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId()], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: alfa/api/utilizador.php Tamanho: 1042 bytes ======================================================================================== / // Ex.: dados_csv/tiago/transacoes-acoes.csv, dados_csv/maria/movimentos-caixa.csv function getUserId(): string { // Aceita ?user=tiago ou ?user=maria na query string ou no corpo POST $user = $_GET['user'] ?? ($_POST['user'] ?? 'tiago'); $user = strtolower($user); // Sanitizar: apenas letras, números, _ e - $user = preg_replace('/[^a-z0-9_\-]/', '', $user); if ($user === '' || $user === null) { $user = 'tiago'; } return $user; } function getUserDataDir(): string { // Este ficheiro está em /api, por isso dirname(__DIR__) = raiz do projeto $root = dirname(__DIR__); $user = getUserId(); $dir = $root . '/dados_csv/' . $user; if (!is_dir($dir)) { @mkdir($dir, 0755, true); } return $dir; } function userFilePath(string $fileName): string { return getUserDataDir() . '/' . $fileName; } ?> ======================================================================================== FICHEIRO: alfa/aprovacao.json Tamanho: 23736 bytes ======================================================================================== { "metadata": { "criado_em": "2026-06-04T00:00:00Z", "site_dir": "/DATA/AppData/site/alfa/", "nota": "Editar estado para: aprovado | rejeitado | rever. Campo 'detalhe' descreve ficheiros/codigo afetados." }, "aprovacoes": { "SEC-01": { "estado": "pendente", "notas": "Remover PHP nao utilizados — so os confirmadamente sem valor", "detalhe": "ANALISE COMPLETA (frontend + dependencias entre PHP):\n\nREGRAS:\n1. Frontend (HTML/JS) faz fetch() a endpoints PHP — nao remover os que sao usados\n2. Alguns PHP sao incluidos por outros PHP (require/include) — nao remover dependencias\n3. Muitos PHP 'nao usados' sao ferramentas de teste/desenvolvimento — analisar codigo antes\n\nDEPENDENCIAS ENCONTRADAS:\n- api/calculos.php inclui: api/bootstrap/bootstrap.php, api/perplexity.php, api/bootstrap/simbolos.php\n- api/bootstrap/bootstrap.php inclui: validacao.php, logger.php, simplecache.php, utilizador.php, simbolos.php\n- api/utilizador.php (raiz) e incluido por: importar_revolut.php, verificar_diferencas_revolut.php, api/downloadacoes.php, api/downloadcaixa.php, api/downloadhistoricoativos.php, api/gerar_de_extrato.php, api/transacoesvistos.php, api/uploadacoes.php, api/uploadcaixa.php, api/uploadextratorevolut.php, api/uploadhistoricoativos.php, api/bootstrap/bootstrap.php\n- api/perplexity.php e incluido por: api/calculos.php (nao diretamente pelo frontend)\n- api/simbolos.php (raiz api/) so se inclui a si mesmo — nao e incluido por nenhum outro\n- auth.php, login.php, logout.php — nao sao incluidos por nenhum PHP atualmente\n\nPHP SEGUROS PARA REMOVER (confirmadamente sem uso nem dependencias):\n- nginx.conf — configuracao do servidor exposta na raiz publica\n- info.php — healthcheck JSON, nao referenciado por nenhum HTML/JS/PHP\n- dados_csv/converter.php — executavel publicamente, nao referenciado\n- dados_csv/backups/calculos.php — executavel publicamente, nao referenciado\n- dados_csv/backups/atualizarprecosacoes.php — executavel publicamente, nao referenciado\n\nPHP QUE DEVEM SER MANTIDOS (dependencias de outros ou ferramentas ativas):\n- api/perplexity.php — incluido por api/calculos.php (fallback de precos)\n- api/utilizador.php (raiz) — incluido por 12+ PHP (multi-utilizador)\n- api/simbolos.php (raiz) — manter por enquanto (pode ser alternativa ao bootstrap/simbolos.php)\n- auth.php — sistema de autenticacao (sera usado quando SEC-03 for implementado)\n- login.php — pagina de login (sera usado quando SEC-03 for implementado)\n- logout.php — logout (sera usado quando SEC-03 for implementado)\n- importar_revolut.php — ferramenta de importacao Revolut (inclui api/utilizador.php)\n- verificar_diferencas_revolut.php — ferramenta de conciliacao (inclui api/utilizador.php)\n- gerar_movimentos_caixa.php — processa extrato Revolut\n- gravar_historico_mensal.php — gera historico mensal\n- exportar_projeto.php — exportacao de projeto V2.2\n- ai.php — ferramenta de correcao automatica de codigo\n- converter.php (raiz) — manter (pode ser usado para conversoes)\n- api/obterprecosatuais.php — manter (pode ser alternativa ao calculos.php)\n- api/obtervariacaodia.php — manter (pode ser alternativa ao calculos.php)\n- api/downloadhistoricoativos.php — manter (pode ser usado indiretamente)\n- api/uploadhistoricoativos.php — manter (pode ser usado indiretamente)\n\nAcao: Remover apenas os 5 ficheiros 'SEGUROS' listados acima." }, "SEC-02": { "estado": "pendente", "notas": "Proteger funcoes PHP perigosas — so nos ficheiros que ficam", "detalhe": "ANALISE: Funcoes perigosas encontradas nos PHP.\n\nFicheiros com funcoes perigosas que DEVEM SER PROTEGIDOS (nao removidos — sao usados ou dependencias):\n- api/calculos.php — shell_exec para chamadas a APIs externas (Stooq, TwelveData, EODHD). PROTEGER: sanitizar inputs, desativar funcoes no php.ini\n- api_atualizar.php — include de ficheiro temporario via acao=executar (RCE critico, linha 225). PROTEGER: remover bloco acao=executar\n- api/perplexity.php — incluido por calculos.php. PROTEGER: funcoes de API externas\n\nFicheiros com funcoes perigosos que PODEM SER REMOVIDOS (nao usados, sem dependencias):\n- ai.php — file_put_contents (escrita de ficheiros). NAO e incluido por nenhum outro PHP. Remover.\n- dados_csv/converter.php — executavel publicamente. Remover.\n- dados_csv/backups/calculos.php — executavel publicamente. Remover.\n- dados_csv/backups/atualizarprecosacoes.php — executavel publicamente. Remover.\n\nFicheiros com funcoes perigosas que DEVEM SER MANTIDOS (ferramentas ativas):\n- importar_revolut.php — file_put_contents (escrita de CSV). Manter — ferramenta de importacao.\n- verificar_diferencas_revolut.php — file_get_contents, json_decode. Manter — ferramenta de conciliacao.\n- gerar_movimentos_caixa.php — fgetcsv, file handling. Manter — processamento de extrato.\n- gravar_historico_mensal.php — file_get_contents, file_put_contents. Manter — gera historico.\n- exportar_projeto.php — scandir, file handling. Manter — exportacao de projeto.\n\nAcao:\n1. Remover ai.php e dados_csv/*.php (4 ficheiros)\n2. Proteger calculos.php e api_atualizar.php (sanitizar inputs, remover RCE)\n3. Manter os restantes (ferramentas ativas)" }, "SEC-03": { "estado": "implementado", "notas": "Autenticacao nos endpoints PHP — auth.php ja existe", "detalhe": "ANALISE: O sistema de autenticacao ja existe (auth.php, login.php, logout.php) mas nao esta integrado nos endpoints.\n\nEstado atual:\n- auth.php — verifica $_SESSION['user'], retorna 401 se nao autenticado\n- login.php — login com email/password contra users.json (password_hash/password_verify)\n- logout.php — session_destroy() + redirect para login.php\n- Nenhum endpoint PHP inclui auth.php atualmente\n\nEndpoints que PRECISAM de autenticacao (todos usados pelo frontend):\n- api/calculos.php — dados financeiros (precos, variacao, cambio, lucro, resumo, dashboard)\n- api/downloadacoes.php — download CSV transacoes\n- api/downloadcaixa.php — download CSV caixa\n- api/uploadacoes.php — upload CSV transacoes\n- api/uploadcaixa.php — upload CSV caixa\n- api/transacoesvistos.php — transacoes vistos\n- api/gerar_de_extrato.php — gerar extrato\n- api/uploadextratorevolut.php — upload extrato Revolut\n- api/listar_ficheiros.php — listar ficheiros\n- api_atualizar.php — atualizar preços (RCE removido em SEC-02)\n\nNota: api/bootstrap/simbolos.php e api/bootstrap/bootstrap.php nao precisam de auth diretamente\n(saO incluidos por calculos.php que ja tera auth).\n\nAcao:\n1. Adicionar require_once(__DIR__.'/auth.php') no topo de cada endpoint listado acima\n2. O frontend ja envia cookies de sessao automaticamente via fetch()\n3. Utilizador precisa fazer login via login.php antes de usar o site" }, "SEC-04": { "estado": "implementado", "notas": "Sistema de login: super-admin + login individual por carteira", "detalhe": "ARQUITETURA: Dois tipos de conta — super-admin (vai a todas as carteiras) e user (so a sua).\n\nESTRUTURA users.json:\n{\n \"tiago\": {\n \"email\": \"tiago@example.com\",\n \"password_hash\": \"$2y$10$...\",\n \"role\": \"admin\",\n \"carteiras\": [\"tiago\", \"filipe\", \"maria\", \"agostinha\"]\n },\n \"filipe\": {\n \"email\": \"filipe@example.com\",\n \"password_hash\": \"$2y$10$...\",\n \"role\": \"user\",\n \"carteiras\": [\"filipe\"]\n },\n \"maria\": {\n \"email\": \"maria@example.com\",\n \"password_hash\": \"$2y$10$...\",\n \"role\": \"user\",\n \"carteiras\": [\"maria\"]\n },\n \"agostinha\": {\n \"email\": \"agostinha@example.com\",\n \"password_hash\": \"$2y$10$...\",\n \"role\": \"user\",\n \"carteiras\": [\"agostinha\"]\n }\n}\n\nFLUXO:\n- Login admin (tiago) → sessao com role=admin + carteiras=[todas] → seletor de carteiras + painel admin\n- Login user (filipe) → sessao com role=user + carteiras=[filipe] → direto para sua carteira, sem seletor\n- auth.php valida: if (carteira_pedida NOT IN user.carteiras) → 403 Forbidden\n\nFICHEIROS A CRIAR/ALTERAR:\n1) users.json — adicionar role + carteiras[] a cada utilizador\n2) login.php — criar sessao com role e carteiras; redirect conforme role\n3) auth.php — verificar role + validar carteira pertence ao user\n4) api/utilizador.php — usar $_SESSION em vez de ?user=\n5) resumo.html — admin vê seletor carteiras + link admin; user não vê\n6) admin.php (NOVO) — painel para criar/editar/remover utilizadores\n7) criar_conta.php (NOVO) — formulario admin para criar novos users\n8) logout.php — melhorar logout com cookie expire\n\nSEGURANCA:\n- Rate limiting no login (5 tentativas / 15 min)\n- CSRF token nos forms\n- Cookies: Secure + HttpOnly + SameSite=Strict\n- Session timeout 30min + regeneracao 5min\n- Password: PASSWORD_ARGON2ID\n- Log de logins em /var/log/site-login.log\n\nMIGRACAO:\n1) Backup users.json\n2) Adicionar role=carteiras a cada user existente\n3) Tiago fica com role=admin e acesso a todas\n4) Filipe/maria/agostinha ficam com role=user e so a sua carteira" }, "SEC-05": { "estado": "implementado", "notas": "Proteger credenciais e chaves API", "detalhe": "IMPLEMENTADO" }, "SEC-06": { "estado": "pendente", "notas": "Desativar exibicao de erros PHP", "detalhe": "Ficheiros afetados:\n- debug-env.php — display_errors = On — mudar para Off\n- info.php — retorna JSON com info do sistema — remover ou proteger\n- php.ini — display_errors = Off, log_errors = On\n- Remover operadores @ de supressao em todos os .php" }, "SEC-07": { "estado": "nao_aplicavel", "notas": "Protecao SQL injection", "detalhe": "Ficheiros: api/calculos.php, api/obterprecosatuais.php, api/obtervariacaodia.php, api/transacoesvistos.php\n- Acao: substituir mysqli_query() por prepared statements ($pdo->prepare() + execute())" }, "SEC-08": { "estado": "implementado", "notas": "Sanitizacao de inputs", "detalhe": "IMPLEMENTADO:\n- irs.html: Removido user via GET, agora usa sessao\n- irs.html: Adicionada validacao de sessao com session.php\n- irs.html: Adicionado link para logout\n- irs.html: Adicionado link para admin (so para admins)" }, "SEC-09": { "estado": "pendente", "notas": "Uploads seguros", "detalhe": "Ficheiros: api/uploadacoes.php, api/uploadcaixa.php, api/uploadextratorevolut.php, api/uploadhistoricoativos.php\n- Acao: validar MIME type (apenas .csv/.json), rejeitar .php, limitar tamanho, chmod 0644" }, "SEC-10": { "estado": "pendente", "notas": "CSRF protection", "detalhe": "Ficheiros: login.php, api/utilizador.php, api_atualizar.php\n- Acao: bin2hex(random_bytes(32)) na sessao, em cada form, validar em POST" }, "SEC-11": { "estado": "pendente", "notas": "Cookies de sessao seguros", "detalhe": "Ficheiros: login.php, auth.php\n- Acao: session_set_cookie_params([secure=>true, httponly=>true, samesite=>Strict]) antes de session_start()" }, "SEC-12": { "estado": "pendente", "notas": "Cabecalhos de seguranca no Nginx", "detalhe": "Ficheiro: nginx.conf\n- Acao: add_header CSP, X-Content-Type-Options nosniff, X-Frame-Options DENY, X-XSS-Protection, HSTS, Referrer-Policy, Permissions-Policy" }, "SEC-13": { "estado": "pendente", "notas": "CSP via Nginx", "detalhe": "Ficheiro: nginx.conf\n- Acao: add_header Content-Security-Policy 'default-src self; script-src self nonce-...' no bloco server {}" }, "SEC-14": { "estado": "pendente", "notas": "CORS restritivo", "detalhe": "Ficheiros: api/*.php, nginx.conf\n- Acao: substituir Access-Control-Allow-Origin: * por https://site.ttodobom.duckdns.org" }, "SEC-15": { "estado": "pendente", "notas": "Protecao de diretorios sensiveis", "detalhe": "Ficheiros: backup/.htaccess (criar), dados_csv/.htaccess (criar), nginx.conf\n- Acao: .htaccess 'deny from all' + nginx 'location ~ ^/(backup|dados_csv|.env|secure) { deny all; }' + autoindex off" }, "SEC-16": { "estado": "pendente", "notas": "Permissoes de ficheiros e diretorios", "detalhe": "Ficheiros: todos os .php (chmod 0640), diretorios (chmod 0750), backup/ (chmod 0700), users.json (chmod 0600), extrato-revolut.csv (chmod 0640), transacoes-acoes.csv (chmod 0640)\n- Acao: find + chmod em lote; php.ini open_basedir" }, "SEC-17": { "estado": "pendente", "notas": "Rate limiting e Fail2Ban", "detalhe": "Ficheiros: nginx.conf, /etc/fail2ban/jail.local\n- Acao: limit_req_zone api 10r/s, login 3r/m + jail Fail2Ban (maxretry=5, bantime=3600)" }, "SEC-18": { "estado": "pendente", "notas": "Tamanho maximo de requests", "detalhe": "Ficheiros: nginx.conf, api/upload*.php\n- Acao: client_max_body_size 5M + filesize() < 5MB nos uploads" }, "SEC-19": { "estado": "pendente", "notas": "Desativar metodos HTTP desnecessarios", "detalhe": "Ficheiro: nginx.conf\n- Acao: if ($request_method !~ ^(GET|HEAD|POST)$) { return 405; }" }, "SEC-20": { "estado": "pendente", "notas": "Remover scripts nao utilizados", "detalhe": "Ficheiros a REMOVER: exportar_projeto.php, gerar_movimentos_caixa.php, nginx.conf (raiz), converter.php (raiz)\n- Acao: backup + rm dos ficheiros desnecessarios" }, "SEC-21": { "estado": "pendente", "notas": "HTTPS", "detalhe": "Ficheiro: nginx.conf\n- Acao: bloco server 443 ssl http2 + redirect HTTP->HTTPS + Let's Encrypt" }, "SEC-22": { "estado": "pendente", "notas": "Monitorizacao e auditoria", "detalhe": "Ficheiros: api/*.php, api_atualizar.php\n- Acao: file_put_contents em /var/log/site-api.log + audit log para acoes executar" }, "SEC-23": { "estado": "pendente", "notas": "Verificacao de integridade", "detalhe": "Ficheiros: site-state.json (atualizar hashes SHA256), criar alteracoes-site.json\n- Acao: script Python para gerar/comparar hashes + SRI nos scripts externos" }, "SEC-24": { "estado": "pendente", "notas": "Compressao e performance", "detalhe": "Ficheiro: nginx.conf\n- Acao: gzip on + brotli on + listen 443 ssl http2" }, "SEC-25": { "estado": "pendente", "notas": "Logrotate", "detalhe": "Ficheiro: /etc/logrotate.d/site-alfa\n- Acao: daily, rotate 14, compress, create 0640 www-data adm" }, "SEC-26": { "estado": "implementado", "notas": "robots.txt", "detalhe": "Ficheiro: robots.txt (criar na raiz)\n- Conteudo: User-agent: * / Disallow: /backup/ /dados_csv/ /api/ /.env /debug-env.php /secure/ /users.json" }, "SEC-27": { "estado": "pendente", "notas": "Framework de roteamento", "detalhe": "Ficheiros: todos os .php\n- Acao: refatorar para front controller (index.php unico) + router.php + controllers/" }, "SEC-28": { "estado": "pendente", "notas": "Linting e testes", "detalhe": "Ficheiros: phpcs.xml, phpstan.neon, tests/\n- Acao: PHP_CodeSniffer + PHPStan + PHPUnit" }, "SEC-29": { "estado": "pendente", "notas": "Link para .php nao listados", "detalhe": "Ficheiros: resumo.html, base-dados-dinheiro.html\n- Acao: adicionar seccao Outros com links no menu" }, "SEC-30": { "estado": "pendente", "notas": "Grafico lucro mensal", "detalhe": "Ficheiro: lucro-mensal-grafico.html\n- Acao: options.scales.y.min = 0 no Chart.js" }, "SEC-31": { "estado": "pendente", "notas": "Chaves API hard-coded em obtervariacaodia.php", "detalhe": "Ficheiro: api/obtervariacaodia.php\n- Acao: mover chaves TwelveData (10ae5539...) e EODHD (6924b805...) para .env" }, "SEC-32": { "estado": "pendente", "notas": "Listagem completa de ficheiros em listar_ficheiros.php", "detalhe": "Ficheiro: api/listar_ficheiros.php\n- Acao: adicionar autenticacao OU remover OU restringir com whitelist" }, "SEC-33": { "estado": "pendente", "notas": "Permissoes 0777 em ficheiros enviados", "detalhe": "Ficheiro: api/uploadcaixa.php\n- Acao: substituir chmod($file, 0777) por chmod($file, 0644)" }, "SEC-34": { "estado": "pendente", "notas": "Copia de debug-env.php em secure/.hidden/", "detalhe": "Ficheiro: secure/.hidden/debug-env.php\n- Acao: remover OU proteger pasta secure/ com .htaccess deny" }, "SEC-35": { "estado": "pendente", "notas": "Exportar_projeto.php expoe codigo e dados sem autenticacao", "detalhe": "Ficheiro: exportar_projeto.php\n- Acao: REMOVER (incluido em SEC-20) OU proteger com autenticacao" }, "SEC-36": { "estado": "pendente", "notas": "Execucao remota de codigo em api_atualizar.php", "detalhe": "Ficheiro: api_atualizar.php\n- Acao: REMOVER bloco if ($_POST['acao'] == 'executar') — RCE critico via include() de codigo POST" }, "SEC-37": { "estado": "pendente", "notas": "Acesso direto a dados_csv/ sem protecao", "detalhe": "Ficheiros: dados_csv/.htaccess (criar), nginx.conf\n- Acao: .htaccess deny + nginx location ~ ^/dados_csv/ { deny all; }" }, "SEC-38": { "estado": "pendente", "notas": "CSP do Nginx bloqueia scripts inline", "detalhe": "Ficheiro: nginx.conf\n- Acao: ajustar CSP para 'script-src self nonce-... unsafe-inline; style-src self unsafe-inline'" }, "SEC-39": { "estado": "pendente", "notas": "users.json com permissoes 0777 e credenciais expostas", "detalhe": "Ficheiro: users.json\n- Acao: MOVER para fora do publico OU .htaccess deny + chmod 0600" }, "SEC-40": { "estado": "pendente", "notas": "PHP files em dados_csv/ executaveis publicamente", "detalhe": "Ficheiros: dados_csv/converter.php, dados_csv/backups/calculos.php, dados_csv/backups/atualizarprecosacoes.php\n- Acao: remover PHP de dados_csv/ OU bloquear via Nginx" }, "SEC-41": { "estado": "pendente", "notas": "nginx.conf exposto na raiz publica do site", "detalhe": "Ficheiro: nginx.conf (raiz do site)\n- Acao: MOVER para /etc/nginx/sites-available/site-alfa.conf" }, "SEC-42": { "estado": "pendente", "notas": "info.php ainda acessivel publicamente", "detalhe": "Ficheiro: info.php\n- Acao: REMOVER ou proteger com autenticacao" }, "SEC-43": { "estado": "pendente", "notas": "Multi-utilizador via GET sem autenticacao real", "detalhe": "Ficheiro: api/utilizador.php\n- Acao: session_start() + verificar $_SESSION['user'] === $_GET['user']" }, "SEC-44": { "estado": "pendente", "notas": "api_atualizar.php permite execucao remota de codigo (RCE)", "detalhe": "Ficheiro: api_atualizar.php\n- Acao: REMOVER endpoint acao=executar (duplicado de SEC-36)" }, "SEC-45": { "estado": "pendente", "notas": "Chave API Perplexity hard-coded em api_atualizar.php", "detalhe": "Ficheiro: api_atualizar.php (linha ~149)\n- Acao: mover chave pplx-... para .env, usar getenv('PERPLEXITY_KEY')" }, "SEC-46": { "estado": "pendente", "notas": "Chaves TwelveData e EODHD hard-coded em multiplos ficheiros", "detalhe": "Ficheiros: api/calculos.php, dados_csv/backups/atualizarprecosacoes.php, api/obtervariacaodia.php\n- Acao: centralizar todas as chaves em .env, substituir por getenv()" }, "SEC-47": { "estado": "pendente", "notas": "Logout nao limpa cookies de sessao", "detalhe": "Ficheiro: logout.php\n- Acao: setcookie(session_name(), '', time() - 3600, '/') antes de session_destroy()" }, "SEC-48": { "estado": "pendente", "notas": "Ficheiro de log calculos-atualizar.log cresce sem controlo", "detalhe": "Ficheiro: api/calculos-atualizar.log\n- Acao: adicionar ao logrotate (ver SEC-25) ou rotacao automatica" }, "SEC-49": { "estado": "pendente", "notas": "ai.php modifica ficheiros sem autenticacao", "detalhe": "Ficheiro: ai.php\n- Acao: REMOVER ou proteger com autenticacao + whitelist" }, "SEC-50": { "estado": "pendente", "notas": "backup/ expoe espelho completo do site", "detalhe": "Ficheiro: backup/\n- Acao: nginx location ~ ^/backup/ { deny all; } + .htaccess deny" }, "SEC-51": { "estado": "pendente", "notas": "Ficheiros CSV sensiveis na raiz publica com permissoes 0777", "detalhe": "Ficheiros: extrato-revolut.csv (775 linhas), transacoes-acoes.csv (434 linhas)\n- Acao: MOVER para dados_csv/ + chmod 0640" }, "SEC-52": { "estado": "pendente", "notas": "users.json criado na raiz publica com password hashes e permissoes 0777", "detalhe": "Ficheiro: users.json\n- Acao: MOVER para fora do publico + chmod 0600 + .htaccess (duplicado SEC-39)" }, "SEC-53": { "estado": "pendente", "notas": "base-dados-dinheiro.html acessivel sem autenticacao", "detalhe": "Ficheiro: base-dados-dinheiro.html\n- Acao: adicionar include('auth.php') no inicio" }, "SEC-54": { "estado": "pendente", "notas": "converter.php duplicado na raiz publica", "detalhe": "Ficheiro: converter.php (raiz)\n- Acao: REMOVER (duplicado, incluido em SEC-20)" }, "SEC-55": { "estado": "pendente", "notas": "manifest.webmanifest expoe utilizador padrao no start_url", "detalhe": "Ficheiro: manifest.webmanifest\n- Acao: remover parametro user do start_url, usar '/resumo.html'" }, "SEC-56": { "estado": "pendente", "notas": "Service Worker pode cachear dados sensiveis", "detalhe": "Ficheiro: sw.js\n- Acao: excluir /api/, /dados_csv/, ?user= do cache" }, "SEC-57": { "estado": "pendente", "notas": "historico-carteira.json vazio na raiz com permissoes 0777", "detalhe": "Ficheiro: historico-carteira.json\n- Acao: MOVER para dados_csv/ OU REMOVER" }, "SEC-58": { "estado": "pendente", "notas": "Paginas HTML sem meta tags de seguranca", "detalhe": "Ficheiros: atualizar.html, caixa.html, irs.html, lucro-mensal-grafico.html, resumo.html, transacoes.html\n- Acao: adicionar meta tags CSP, X-Content-Type-Options, X-Frame-Options" }, "SEC-59": { "estado": "implementado", "notas": "Organizacao de ferramentas em pasta tools/", "detalhe": "IMPLEMENTADO:\n- Criada pasta tools/ para ferramentas isoladas\n- Movidos: converter.php, gerar_movimentos_caixa.php, gravar_historico_mensal.php, importar_revolut.php\n- .htaccess em tools/ bloqueia acesso direto\n- Adicionada secao Ferramentas no admin.php\n- Link 'Ferramentas' no resumo.html (so para admin)" }, "SEC-60": { "estado": "implementado", "notas": "Limpeza de ficheiros orfaos e debug", "detalhe": "IMPLEMENTADO:\n- Movido ai.php para tools/\n- Movido info.php para tools/\n- Removido historico-carteira.json (vazio)\n- Removido debug_session.php\n- Removido env_check.php\n- Admin.php atualizado com novas ferramentas" }, "SEC-61": { "estado": "implementado", "notas": "Reorganizacao de HTMLs orfaos", "detalhe": "IMPLEMENTADO:\n- Removido debug.html (debug temporario)\n- Movido irs.html para tools/\n- Movido atualizar.html para tools/\n- Movido verificar-revolut.html para tools/\n- Adicionadas ferramentas no admin.php\n- Adicionado link IRS no menu do resumo.html\n- Atualizados links relativos no irs.html" } } } ======================================================================================== FICHEIRO: alfa/base-dados-dinheiro.html Tamanho: 16609 bytes ======================================================================================== Base de dados de Dinheiro

Transações de Dinheiro

Dados calculados automaticamente a partir do ficheiro de transações guardado no servidor.

+ Adicionar linha
Nº Data Tipo Valor Moeda Descrição Taxa Câmbio Ações
======================================================================================== FICHEIRO: alfa/caixa.html Tamanho: 29056 bytes ======================================================================================== Folha de Caixa

Folha de Caixa

Controlo de saldo disponível e origem dos fundos

Saldo em EUR
0,00 €
Dinheiro disponível em Euros
Saldo em USD
0,00 $
Dinheiro disponível em Dólares
Total (convertido)
0,00 €
Saldo total convertido para EUR

Origem dos Fundos (EUR)

+ Depósitos 0,00 €
- Levantamentos 0,00 €
- Compras Ações 0,00 €
+ Vendas Ações 0,00 €
+ Dividendos 0,00 €
- Taxas 0,00 €
= Saldo EUR 0,00 €

Origem dos Fundos (USD)

+ Depósitos 0,00 $
- Levantamentos 0,00 $
- Compras Ações 0,00 $
+ Vendas Ações 0,00 $
+ Dividendos 0,00 $
- Taxas 0,00 $
= Saldo USD 0,00 $

Histórico de Movimentos Recentes

Data Tipo Descrição Moeda Valor Saldo Acumulado
======================================================================================== FICHEIRO: alfa/converter.php Tamanho: 71 bytes ======================================================================================== EUR", "fonte_prevclose": null, "ts_preco": "2025-12-14 00:06:18" } } } ======================================================================================== FICHEIRO: alfa/estilos-backend.css Tamanho: 6586 bytes ======================================================================================== /* ======================================== estilos-backend.css - SISTEMA MODULAR ========================================*/ /* ========================================*/ /* 1. ESTILO BASE DA PÃGINA */ .body-padrao { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font-size: 13px; color: #111827; background: #f3f4f6; margin: 0; padding: 20px; line-height: 1.5; min-height: 100vh; } /* ========================================*/ /* 2 Card padrao */ .card-padrao { background: #ffffff; border-radius: 20px; border: 1px solid #e5e7eb; padding: 24px; max-width: 1100px; margin: 0 auto 20px auto; } /* RESPONSIVO */ @media (max-width: 768px) { .body-padrao { padding: 12px; } } /* ========================================*/ /* 3. TÃTULOS PADRÃO */ .titulo-padrao h1 { font-size: 24px; letter-spacing: -0.03em; margin: 0 0 4px 0; font-weight: 700; color: #111827; } .titulo-padrao h2 { font-size: 16px; letter-spacing: -0.02em; margin-top: 12px; margin-bottom: 4px; } .titulo-padrao p.small { font-size: 13px; color: #6b7280; margin: 0 0 16px 0; } /* ======================================== 4. header-padrao - HEADER FLEX (ESQUERDA/DIREITA) ======================================== */ .header-padrao { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; } /* ======================================== tabs-padrao - ABAS (dentro do header Dirieta) ======================================== */ .tabs-padrao { display: flex; gap: 8px; margin: 0; } .tabs-padrao .tab-button { padding: 6px 12px; border-radius: 999px; border: 1px solid #d1d5db; background: #f9fafb; font-size: 12px; cursor: pointer; font-weight: 500; transition: all 0.2s ease; } .tabs-padrao .tab-button.tab-active { background: #2563eb; color: #f9fafb; border-color: #1d4ed8; } .tabs-padrao .tab-button:hover:not(.tab-active) { background: #eff6ff; transform: translateY(-1px); } /* ======================================== toolbar-direita - BOTÕES AZUL/BRANCO ======================================== REGRA AUTOMÃTICA: = AZUL |
A carregar dados fiscais...
Saldo fiscal vendas
0,00 €
Ano selecionado
Imposto estimado
0,00 €
Estimativa
Dividendos registados
0,00 €
Convertidos para EUR

Vendas de ações / ETF

  • Lista apenas vendas com data no ano escolhido.
  • Converte para EUR usando taxa da linha ou histórico cambial.
  • Mostra uma base prática para preencher o IRS.

Dividendos

  • Usa os movimentos de caixa marcados como Dividendo.
  • Mostra valor recebido e convertido para EUR.
  • Verificar se é necessário declarar dividendos.

Vendas no ano selecionado

Venda Ativo Compra Dias Aquisição EUR Realização EUR Ganho/Perda EUR Taxa Nota

Dividendos no ano selecionado

Data Descrição Moeda Valor EUR Observação

Checklist

  1. Selecionar o ano fiscal pretendido.
  2. Usar a tabela de vendas como base para preencher as operações realizadas.
  3. Usar a tabela de dividendos como base de conferência.
  4. Confirmar o extrato do broker/banco antes da submissão final.
======================================================================================== FICHEIRO: alfa/lucro-mensal-grafico.html Tamanho: 34273 bytes ======================================================================================== Lucro Mensal (Gráfico)

Gráfico Detalhado

ΔRealizado + ΔNãoRealizado + dividendos - taxas

A carregar…
Lucro Total
€0,00
—
Lucro (último mês)
€0,00
—
Rentabilidade
0,0%
Janela selecionada
Meses
0
—
Lucro (mês) Lucro Total Valor Carteira Invest. Inicial
======================================================================================== FICHEIRO: alfa/manifest.webmanifest Tamanho: 565 bytes ======================================================================================== { "name": "Site Financeiro", "short_name": "Financeiro", "description": "Resumo da carteira e transações financeiras em formato app.", "start_url": "/resumo.html?user=tiago", "scope": "/", "display": "standalone", "background_color": "#f3f4f6", "theme_color": "#22c55e", "lang": "pt-PT", "icons": [ { "src": "/icon.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { "src": "/icon.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" } ] } ======================================================================================== FICHEIRO: alfa/pwa-register.js Tamanho: 306 bytes ======================================================================================== (function registerPwa() { if (!('serviceWorker' in navigator)) { return; } window.addEventListener('load', function () { navigator.serviceWorker .register('/sw.js') .catch(function (error) { console.warn('Falha ao registar Service Worker:', error); }); }); })(); ======================================================================================== FICHEIRO: alfa/resumo.html Tamanho: 64152 bytes ======================================================================================== Resumo da Carteira

Resumo da Carteira

Dados calculados automaticamente a partir do ficheiro de transações guardado no servidor.

Carregando taxas de câmbio... Carregando preços...
Valor da Carteira
0,00 €
Somatório do valor final apenas das ações não vendidas.
Investimento Inicial
0,00 €
Dinheiro Investido.
Lucro / Prejuízo da Carteira
0,00 € (0,00%)
Lucro não realizado das posições que ainda estão abertas.
Saldo em Caixa
EUR: 0,00 €
USD: 0,00 $
Dinheiro disponível para investido.

Resumo por Ação

Nome da Ação Nº Ações Preço Médio Compra Preço Atual % Dia Valor Mercado Valor Ganhos % Ganho
Nome da Ação Investido Valor Ganho
Total 0,00 - - 0,00% 0,00 € 0,00 € -
Total 0,00 € 0,00 € 0,00 €

Variaçao por Ativo

A carregar...
======================================================================================== FICHEIRO: alfa/sw.js Tamanho: 1320 bytes ======================================================================================== const CACHE_VERSION = 'site-financeiro-v1'; const STATIC_ASSETS = [ '/', '/index.html', '/resumo.html', '/estilos-backend.css', '/icon.png', '/manifest.webmanifest', '/pwa-register.js' ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_VERSION).then((cache) => cache.addAll(STATIC_ASSETS)) ); self.skipWaiting(); }); self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all( keys .filter((key) => key !== CACHE_VERSION) .map((key) => caches.delete(key)) ) ) ); self.clients.claim(); }); self.addEventListener('fetch', (event) => { const { request } = event; if (request.method !== 'GET') { return; } event.respondWith( caches.match(request).then((cachedResponse) => { if (cachedResponse) { return cachedResponse; } return fetch(request) .then((networkResponse) => { if (request.url.startsWith(self.location.origin) && networkResponse.ok) { const copy = networkResponse.clone(); caches.open(CACHE_VERSION).then((cache) => cache.put(request, copy)); } return networkResponse; }) .catch(() => caches.match('/index.html')); }) ); }); ======================================================================================== FICHEIRO: alfa/transacoes.html Tamanho: 25559 bytes ======================================================================================== Base de dados de compras e vendas

Transações de Ações

Dados calculados automaticamente a partir do ficheiro de transações guardado no servidor.

+ Adicionar linha
Nº Data Compra Data Venda Nome da Ação Nº Ações V. Inicial V. Final Comissão Custo Inical Custo Final Ganho % Ganho Tx Compra Tx Venda Moeda Ativas
======================================================================================== FICHEIRO: alfa/upload-dadosacoes.html Tamanho: 10525 bytes ======================================================================================== Carregar dadosacoes.csv

Carregar dadosacoes.csv

Substitui o ficheiro mensal em dados_csv/dadosacoes.csv e corre o conversor teÌcnico agora centralizado em api/converter.php.

Voltar às Ferramentas

1. Enviar novo CSV

Nenhum ficheiro selecionado.

O endpoint grava sempre o ficheiro com o nome dadosacoes.csv, cria backup do ficheiro anterior e prepara o JSON mensal.

2. Resultado do conversor

Depois do upload, podes executar o conversor sem sair desta paÌgina.

Aguardando execução…
======================================================================================== FICHEIRO: alfa/verificar-revolut.html Tamanho: 28043 bytes ======================================================================================== Verificar Diferenças Revolut

🔠Verificar Diferenças Revolut

📊 Resumo

Resumo Caixa

Detalhes Caixa

📋 Detalhes das Diferenças

🔧 w Completo (Debug)

Clique em "Verificar" para ver os dados...
======================================================================================== FICHEIRO: alfa/verificar-revolut.html.bak Tamanho: 28043 bytes ======================================================================================== Verificar Diferenças Revolut

🔠Verificar Diferenças Revolut

📊 Resumo

Resumo Caixa

Detalhes Caixa

📋 Detalhes das Diferenças

🔧 w Completo (Debug)

Clique em "Verificar" para ver os dados...
======================================================================================== FICHEIRO: alfa/verificar_diferencas_revolut.php Tamanho: 23201 bytes ======================================================================================== require_once __DIR__ . '/api/utilizador.php'; // getUserId() e userFilePath() vêm de api/utilizador.php function vistosLoad(): array { $path = userFilePath('transacoes-vistos.json'); if (!is_file($path)) return ['vistos' => []]; $raw = @file_get_contents($path); $j = json_decode((string)$raw, true); if (!is_array($j)) $j = []; $vistos = $j['vistos'] ?? []; if (!is_array($vistos)) $vistos = []; foreach (['alterarlinha', 'adicionartransacao', 'removertransacao'] as $t) { if (!isset($vistos[$t]) || !is_array($vistos[$t])) $vistos[$t] = []; } return ['vistos' => $vistos]; } function vistoCheck(array $vistos, string $tipo, string $id): bool { return isset($vistos['vistos'][$tipo]) && is_array($vistos['vistos'][$tipo]) && !empty($vistos['vistos'][$tipo][$id]); } function vistoIdLinha($linha): string { return 'L:' . trim((string)$linha); } // Ficheiros específicos do utilizador atual $ficheiroRevolut = userFilePath('extrato-revolut.csv'); $ficheiroTransacoes = userFilePath('transacoes-acoes.csv'); $ficheiroCaixa = userFilePath('movimentos-caixa.csv'); // Filtro opcional por ano (?ano=2020, 2021, ...) $anoFiltro = isset($_GET['ano']) && preg_match('/^\d{4}$/', $_GET['ano']) ? $_GET['ano'] : null; // Verificações iniciais if (!file_exists($ficheiroRevolut)) { echo json_encode([ 'ok' => false, 'error' => 'Extrato Revolut não encontrado para este utilizador. Importe primeiro o ficheiro (extrato-revolut.csv).', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if (!file_exists($ficheiroTransacoes)) { echo json_encode([ 'ok' => false, 'error' => 'Ficheiro de transações (transacoes-acoes.csv) não encontrado para este utilizador.', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // FILTRO POR ANO function filtrarPorAno($items, $ano) { if (!$ano || empty($items)) return $items; return array_filter($items, function($item) use ($ano) { $camposData = ['data', 'dataCompra', 'dataVenda']; foreach ($camposData as $campo) { if (isset($item[$campo]) && !empty($item[$campo])) { if (preg_match('/^' . $ano . '[-\/]/', $item[$campo])) { return true; } } } return false; }); } // ✅ NORMALIZAR TICKER - VERSÃO COMPLETA COM TODOS OS MAPEAMENTOS function normalizarTicker($nomeAcao) { $n = strtoupper(trim($nomeAcao)); // ✅ MAPEAMENTO EXPLÃCITO DE ETFs if (strpos($n, 'IWDA') !== false || strpos($n, 'EUNL') !== false) { return 'IWDA'; } if (strpos($n, 'NDX') !== false || strpos($n, 'EXXT') !== false || strpos($n, 'EQQQ') !== false) { return 'EQQQ'; } // ✅ MAPEAMENTO DE AÇÕES ESPECÃFICAS $mapa = [ 'SQ' => 'SQ', // Block (Square) 'Z' => 'Z', // Zillow 'BRK.B' => 'BRKB', // Berkshire Hathaway 'BRKB' => 'BRKB', // Já normalizado 'AAPL' => 'AAPL', 'NVDA' => 'NVDA', 'TSLA' => 'TSLA', 'GOOGL' => 'GOOGL', 'AMZN' => 'AMZN', 'MSFT' => 'MSFT', 'TSM' => 'TSM', 'BAC' => 'BAC', 'O' => 'O', 'KO' => 'KO', ]; // Remove prefixos de bolsa $n = preg_replace('/^(NASDAQ|NYSE|INDEXNASDAQ|AMS):?/', '', $n); // Remove caracteres especiais e pontos $n = preg_replace('/[^A-Z0-9]/', '', $n); // Verifica se está no mapa if (isset($mapa[$n])) { return $mapa[$n]; } return $n; } // LER REVOLUT (extrato) function lerRevolut($ficheiro) { if (!file_exists($ficheiro)) { return ['error' => 'Ficheiro não encontrado: ' . basename($ficheiro)]; } $fh = fopen($ficheiro, 'r'); if (!$fh) { return ['error' => 'Erro ao abrir: ' . basename($ficheiro)]; } // Cabeçalho: // Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate fgetcsv($fh, 0, ','); $movimentos = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 8) continue; $dataCompleta = trim($row[0]); $data = substr($dataCompleta, 0, 10); // YYYY-MM-DD $ticker = trim($row[1]); $tipo = trim($row[2]); $quantidade = trim($row[3]); $preco = trim($row[4]); $totalAmount = trim($row[5]); $moeda = trim($row[6]); $fxRaw = trim($row[7]); // Limpeza de valor total $valorLimpo = preg_replace('/[A-Z]{3}\s*/', '', $totalAmount); $valorLimpo = str_replace(',', '.', $valorLimpo); $valorNum = floatval($valorLimpo); // Limpeza de preço $precoLimpo = preg_replace('/[A-Z]{3}\s*/', '', $preco); $precoLimpo = str_replace(',', '.', $precoLimpo); $precoNum = floatval($precoLimpo); // FX rate $fxNum = $fxRaw !== '' ? floatval(str_replace(',', '.', $fxRaw)) : null; $movimentos[] = [ 'data' => $data, 'ticker' => strtoupper($ticker), 'tipo' => $tipo, 'quantidade' => floatval(str_replace(',', '.', $quantidade)), 'preco' => $precoNum, 'valor' => $valorNum, 'moeda' => $moeda, 'fx' => $fxNum, ]; } fclose($fh); return $movimentos; } // LER TRANSAÇÕES (formato novo: 11 colunas) function lerTransacoesAtuais($ficheiro) { if (!file_exists($ficheiro)) return []; $fh = fopen($ficheiro, 'r'); if (!$fh) return []; // Cabeçalho: Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes, // CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda fgetcsv($fh, 0, ','); $transacoes = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 11) continue; $transacoes[] = [ 'ordem' => trim($row[0]), 'dataCompra' => trim($row[1]), 'dataVenda' => trim($row[2]), 'nomeAcao' => trim($row[3]), 'numAcoes' => floatval(str_replace(',', '.', $row[4])), 'comissoes' => floatval(str_replace(',', '.', $row[5])), 'custoInicial' => floatval(str_replace(',', '.', $row[6])), 'custoFinal' => floatval(str_replace(',', '.', $row[7])), 'taxaCompra' => isset($row[8]) ? floatval(str_replace(',', '.', $row[8])) : 0.0, 'taxaVenda' => isset($row[9]) ? floatval(str_replace(',', '.', $row[9])) : 0.0, 'moeda' => trim($row[10]), ]; } fclose($fh); return $transacoes; } // COMPARAR COM LÓGICA RESTRITIVA function compararDados($revolut, $transacoesAtuais, $vistos) { $diferencas = [ 'duplicatasexatas' => [], 'alterarlinha' => [], 'adicionartransacao' => [], 'removertransacao' => [], 'totais' => [ 'revolutcompras' => 0, 'revolutvendas' => 0, 'transacoestotal' => count($transacoesAtuais) ] ]; // Agrupar Revolut por ticker $revolutPorTicker = []; foreach ($revolut as $mov) { $ticker = strtoupper($mov['ticker']); if (!isset($revolutPorTicker[$ticker])) { $revolutPorTicker[$ticker] = ['compras' => [], 'vendas' => []]; } if (stripos($mov['tipo'], 'BUY') !== false) { $revolutPorTicker[$ticker]['compras'][] = $mov; $diferencas['totais']['revolutcompras']++; } elseif (stripos($mov['tipo'], 'SELL') !== false) { $revolutPorTicker[$ticker]['vendas'][] = $mov; $diferencas['totais']['revolutvendas']++; } } // Verificar cada transação do CSV foreach ($transacoesAtuais as $t) { $linhaId = vistoIdLinha($t['ordem']); $tickerNormalizado = normalizarTicker($t['nomeAcao']); if (!isset($revolutPorTicker[$tickerNormalizado])) { // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'removertransacao', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'] ?? '', 'status' => 'OK' ]; continue; } $diferencas['removertransacao'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Ticker não encontrado no Revolut (normalizado: ' . $tickerNormalizado . ')' ]; continue; } $comprasTicker = $revolutPorTicker[$tickerNormalizado]['compras']; $vendasTicker = $revolutPorTicker[$tickerNormalizado]['vendas']; // ✅ PROCURAR COMPRA (tolerância: 0 dias, 1€) $compraEncontrada = null; foreach ($comprasTicker as $compra) { $diasDiff = abs(strtotime($compra['data']) - strtotime($t['dataCompra'])) / 86400; $custoDiff = abs($compra['valor'] - $t['custoInicial']); if ($diasDiff <= 0 && $custoDiff <= 1) { $compraEncontrada = $compra; break; } } // ✅ PROCURAR VENDA (tolerância: 0 dias, 1€) $vendaEncontrada = null; $temDataVendaCSV = !empty($t['dataVenda']); if ($temDataVendaCSV) { foreach ($vendasTicker as $venda) { $diasDiff = abs(strtotime($venda['data']) - strtotime($t['dataVenda'])) / 86400; $custoDiff = abs($venda['valor'] - $t['custoFinal']); if ($diasDiff <= 0 && $custoDiff <= 1) { $vendaEncontrada = $venda; break; } } } // Se não existe compra no Revolut e (não há venda no CSV ou também não existe venda no Revolut), // então esta linha do CSV muito provavelmente não corresponde a nada no extrato => remover. $naoExisteCompra = ($compraEncontrada === null); $naoExisteVenda = ($temDataVendaCSV && $vendaEncontrada === null); if ($naoExisteCompra && (!$temDataVendaCSV || $naoExisteVenda)) { $diferencas['removertransacao'][] = [ 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Compra e venda não encontradas no Revolut. Provável linha extra no CSV.' ]; continue; } // ✅ ANÃLISE DE DIFERENÇAS (DETALHADA) $diferencasCount = 0; $detalhes = []; if ($compraEncontrada) { // Data compra if ($compraEncontrada['data'] !== $t['dataCompra']) { $diferencasCount++; $detalhes[] = "Data Compra: {$t['dataCompra']} → {$compraEncontrada['data']}"; } // Quantidade if (abs($compraEncontrada['quantidade'] - $t['numAcoes']) > 0.00001) { $diferencasCount++; $detalhes[] = "Qtd: {$t['numAcoes']} → {$compraEncontrada['quantidade']}"; } // Custo compra if (abs($compraEncontrada['valor'] - $t['custoInicial']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Compra: {$t['custoInicial']} € → {$compraEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "COMPRA não encontrada no Revolut"; } if ($temDataVendaCSV) { if ($vendaEncontrada) { // Data venda if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } // Custo venda if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} € → {$vendaEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "VENDA não encontrada no Revolut"; } } // ✅ RESULTADO POR LINHA if ($diferencasCount === 0) { // Match perfeito $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $item = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'dataCompra' => $t['dataCompra'], 'dataVenda' => $t['dataVenda'], 'diferencas' => $diferencasCount, 'detalhes' => implode(' | ', $detalhes), 'valoratualcompra' => $t['custoInicial'], 'valoratualvenda' => $t['custoFinal'], 'sugestaocompra' => null, 'sugestaovenda' => null ]; // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'alterarlinha', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $diferencas['alterarlinha'][] = $item; } } // <-- ESTA chaveta é a que te falta (fecha o else do diferencasCount) } // fecha foreach ($transacoesAtuais as $t) return $diferencas; } // ========================== // NOVO: COMPARAR CAIXA // movimentos-caixa.csv <-> extrato-revolut.csv (CASH TOP-UP / CASH WITHDRAWAL / DIVIDEND / FEES) // ========================== function fnum_local($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([' ', "\t"], '', $s); // Se vier "USD -1.25" ou "EUR 493.36" $s = preg_replace('/^[A-Z]{3}/', '', $s); $s = trim($s); // vírgulas para ponto $s = str_replace(',', '.', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function normCaixaTipo($tipo): string { $t = mb_strtolower(trim((string)$tipo), 'UTF-8'); // Fallback manual (caso iconv falhe ou não exista translit completo) $t = strtr($t, [ 'á'=>'a','à'=>'a','â'=>'a','ã'=>'a', 'é'=>'e','ê'=>'e', 'í'=>'i', 'ó'=>'o','ô'=>'o','õ'=>'o', 'ú'=>'u', 'ç'=>'c' ]); // Tentar translit (se funcionar, melhora ainda mais) $tt = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $t); if ($tt !== false && $tt !== null && $tt !== '') { $t = $tt; } $t = preg_replace('/[^a-z0-9]+/', ' ', (string)$t); // Depósito (apanha "deposito", "deposit", "top up", "cash top-up", etc.) if (strpos($t, 'depos') !== false || strpos($t, 'deposit') !== false || strpos($t, 'top up') !== false || strpos($t, 'topup') !== false || strpos($t, 'cash top up') !== false || strpos($t, 'cash topup') !== false) { return 'Depósito'; } if (strpos($t, 'levant') !== false || strpos($t, 'withdraw') !== false) return 'Levantamento'; if (strpos($t, 'divid') !== false || strpos($t, 'dividend') !== false) return 'Dividendo'; return 'Outros'; } function mapRevolutCashTypeToCaixaTipo(string $type): ?string { $t = strtoupper(trim($type)); if ($t === '') return null; // Tipos típicos vistos no extrato if (strpos($t, 'CASH TOP-UP') !== false) return 'Depósito'; if (strpos($t, 'CASH WITHDRAWAL') !== false) return 'Levantamento'; if (strpos($t, 'DIVIDEND') !== false) return 'Dividendo'; // Fees e afins if (strpos($t, 'FEE') !== false || strpos($t, 'TAX') !== false || strpos($t, 'COMMISSION') !== false) return 'Outros'; if (strpos($t, 'CUSTODY FEE') !== false) return 'Outros'; return null; // não é movimento de caixa que nos interesse aqui } function filtrarRevolutCaixa(array $revolutMovs): array { $out = []; foreach ($revolutMovs as $m) { $type = (string)($m['tipo'] ?? ''); $tipoCaixa = mapRevolutCashTypeToCaixaTipo($type); if ($tipoCaixa === null) continue; $data = (string)($m['data'] ?? ''); $moeda = strtoupper(trim((string)($m['moeda'] ?? ''))); $valor = (float)($m['valor'] ?? 0.0); $ticker = trim((string)($m['ticker'] ?? '')); $descricao = strtoupper(trim($type)); if ($ticker !== '' && strpos($descricao, 'DIVIDEND') !== false) { $descricao = $ticker . ' DIVIDEND'; } $out[] = [ 'data' => $data, 'tipo' => $tipoCaixa, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $descricao, ]; } return $out; } function lerMovimentosCaixaCSV(string $ficheiroCaixa): array { if (!file_exists($ficheiroCaixa)) return ['_erro' => 'movimentos-caixa.csv não encontrado.']; $fh = fopen($ficheiroCaixa, 'r'); if (!$fh) return ['_erro' => 'Não foi possível abrir movimentos-caixa.csv.']; $cab = fgetcsv($fh, 0, ','); // Ordem,Data,Tipo,Valor,Moeda,Descricao $rows = []; while (($r = fgetcsv($fh, 0, ',')) !== false) { if (count($r) < 6) continue; $ordem = trim((string)$r[0]); $data = substr(trim((string)$r[1]), 0, 10); $tipo = normCaixaTipo($r[2] ?? ''); $valor = fnum_local($r[3] ?? 0); $moeda = strtoupper(trim((string)($r[4] ?? ''))); $desc = trim((string)($r[5] ?? '')); if ($data === '' || strlen($data) < 10) continue; $rows[] = [ 'ordem' => $ordem, 'data' => $data, 'tipo' => $tipo, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $desc, ]; } fclose($fh); return $rows; } function compararCaixaComRevolut(array $revolutMovs, string $ficheiroCaixa): array { $revCaixa = filtrarRevolutCaixa($revolutMovs); $caixaCsv = lerMovimentosCaixaCSV($ficheiroCaixa); if (isset($caixaCsv['_erro'])) { return [ 'resumo' => ['duplicatas' => 0, 'alterar' => 0, 'adicionar' => 0, 'remover' => 0], 'detalhes' => ['duplicatasexatas' => [], 'alterarlinha' => [], 'adicionar' => [], 'remover' => []], 'aviso' => $caixaCsv['_erro'], ]; } // Vamos “consumir†linhas do CSV à medida que casam, para evitar reuso. $usado = array_fill(0, count($caixaCsv), false); $duplicatas = []; $alterar = []; $adicionar = []; $remover = []; // 1) Revolut -> procurar no movimentos-caixa.csv foreach ($revCaixa as $rc) { $matchIdx = null; $match = null; // Tentativa A: data + moeda + valor (tolerância) for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $c = $caixaCsv[$i]; if ($c['moeda'] !== $rc['moeda']) continue; $dias = abs(strtotime($c['data']) - strtotime($rc['data'])) / 86400; if ($dias > 0) continue; if (abs(((float)$c['valor']) - ((float)$rc['valor'])) > 0.01) continue; $matchIdx = $i; $match = $c; break; } if ($matchIdx === null) { $adicionar[] = [ 'origem' => 'Revolut', 'motivo' => 'Movimento de caixa não encontrado em movimentos-caixa.csv', 'sugestao' => $rc, ]; continue; } $usado[$matchIdx] = true; // Comparar tipo (e opcionalmente descrição) $diffs = []; if ($match['tipo'] !== $rc['tipo']) { $diffs[] = "Tipo: CSV={$match['tipo']} vs Revolut={$rc['tipo']}"; } if (count($diffs) === 0) { $duplicatas[] = [ 'data' => $rc['data'], 'tipo' => $rc['tipo'], 'valor' => $rc['valor'], 'moeda' => $rc['moeda'], 'status' => 'OK', ]; } else { $alterar[] = [ 'linha' => $match['ordem'], 'data' => $rc['data'], 'diferencas' => count($diffs), 'detalhes' => implode(' | ', $diffs), 'csv' => $match, 'revolut' => $rc, ]; } } // 2) Tudo o que ficou no CSV sem match -> remover/rever for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $remover[] = [ 'origem' => 'CSV', 'linha' => $caixaCsv[$i]['ordem'], 'motivo' => 'Movimento existe em movimentos-caixa.csv mas não aparece no extrato Revolut (tipos de caixa)', 'csv' => $caixaCsv[$i], ]; } return [ 'resumo' => [ 'duplicatas' => count($duplicatas), 'alterar' => count($alterar), 'adicionar' => count($adicionar), 'remover' => count($remover), ], 'detalhes' => [ 'duplicatasexatas' => $duplicatas, 'alterarlinha' => $alterar, 'adicionar' => $adicionar, 'remover' => $remover, ], ]; } $revolut = lerRevolut($ficheiroRevolut); if (isset($revolut['error'])) { echo json_encode(['ok' => false, 'error' => $revolut['error'], 'user' => getUserId()], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // Normalizar tickers do Revolut para casar com normalizarTicker() foreach ($revolut as &$m) { if (isset($m['ticker']) && $m['ticker'] !== '') { $m['ticker'] = normalizarTicker($m['ticker']); } } unset($m); $revolut = filtrarPorAno($revolut, $anoFiltro); $transacoesAtuais = lerTransacoesAtuais($ficheiroTransacoes); $transacoesAtuais = filtrarPorAno($transacoesAtuais, $anoFiltro); $vistos = vistosLoad(); $diferencas = compararDados($revolut, $transacoesAtuais, $vistos); // --- NOVO: comparar CAIXA (movimentos-caixa.csv) com extrato-revolut.csv --- $caixaDiff = compararCaixaComRevolut($revolut, $ficheiroCaixa); echo json_encode([ 'ok' => true, 'ficheirorevolut' => basename($ficheiroRevolut), 'utilizador' => getUserId(), 'anofiltro' => $anoFiltro ? $anoFiltro : 'TODOS', 'dataverificacao' => date('Y-m-d H:i:s'), // (mantém o resumo/detalhes das AÇÕES como está no teu ficheiro) 'resumo' => [ 'duplicatas' => count($diferencas['duplicatasexatas'] ?? []), 'alterar' => count($diferencas['alterarlinha'] ?? []), 'adicionar' => count($diferencas['adicionartransacao'] ?? []), 'remover' => count($diferencas['removertransacao'] ?? []), ], 'detalhes' => $diferencas, // --- NOVO: resultados de CAIXA --- 'caixa' => $caixaDiff, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; ======================================================================================== FICHEIRO: alfa/verificar_diferencas_revolut.php.bak Tamanho: 23201 bytes ======================================================================================== require_once __DIR__ . '/api/utilizador.php'; // getUserId() e userFilePath() vêm de api/utilizador.php function vistosLoad(): array { $path = userFilePath('transacoes-vistos.json'); if (!is_file($path)) return ['vistos' => []]; $raw = @file_get_contents($path); $j = json_decode((string)$raw, true); if (!is_array($j)) $j = []; $vistos = $j['vistos'] ?? []; if (!is_array($vistos)) $vistos = []; foreach (['alterarlinha', 'adicionartransacao', 'removertransacao'] as $t) { if (!isset($vistos[$t]) || !is_array($vistos[$t])) $vistos[$t] = []; } return ['vistos' => $vistos]; } function vistoCheck(array $vistos, string $tipo, string $id): bool { return isset($vistos['vistos'][$tipo]) && is_array($vistos['vistos'][$tipo]) && !empty($vistos['vistos'][$tipo][$id]); } function vistoIdLinha($linha): string { return 'L:' . trim((string)$linha); } // Ficheiros específicos do utilizador atual $ficheiroRevolut = userFilePath('extrato-revolut.csv'); $ficheiroTransacoes = userFilePath('transacoes-acoes.csv'); $ficheiroCaixa = userFilePath('movimentos-caixa.csv'); // Filtro opcional por ano (?ano=2020, 2021, ...) $anoFiltro = isset($_GET['ano']) && preg_match('/^\d{4}$/', $_GET['ano']) ? $_GET['ano'] : null; // Verificações iniciais if (!file_exists($ficheiroRevolut)) { echo json_encode([ 'ok' => false, 'error' => 'Extrato Revolut não encontrado para este utilizador. Importe primeiro o ficheiro (extrato-revolut.csv).', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if (!file_exists($ficheiroTransacoes)) { echo json_encode([ 'ok' => false, 'error' => 'Ficheiro de transações (transacoes-acoes.csv) não encontrado para este utilizador.', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // FILTRO POR ANO function filtrarPorAno($items, $ano) { if (!$ano || empty($items)) return $items; return array_filter($items, function($item) use ($ano) { $camposData = ['data', 'dataCompra', 'dataVenda']; foreach ($camposData as $campo) { if (isset($item[$campo]) && !empty($item[$campo])) { if (preg_match('/^' . $ano . '[-\/]/', $item[$campo])) { return true; } } } return false; }); } // ✅ NORMALIZAR TICKER - VERSÃO COMPLETA COM TODOS OS MAPEAMENTOS function normalizarTicker($nomeAcao) { $n = strtoupper(trim($nomeAcao)); // ✅ MAPEAMENTO EXPLÃCITO DE ETFs if (strpos($n, 'IWDA') !== false || strpos($n, 'EUNL') !== false) { return 'IWDA'; } if (strpos($n, 'NDX') !== false || strpos($n, 'EXXT') !== false || strpos($n, 'EQQQ') !== false) { return 'EQQQ'; } // ✅ MAPEAMENTO DE AÇÕES ESPECÃFICAS $mapa = [ 'SQ' => 'SQ', // Block (Square) 'Z' => 'Z', // Zillow 'BRK.B' => 'BRKB', // Berkshire Hathaway 'BRKB' => 'BRKB', // Já normalizado 'AAPL' => 'AAPL', 'NVDA' => 'NVDA', 'TSLA' => 'TSLA', 'GOOGL' => 'GOOGL', 'AMZN' => 'AMZN', 'MSFT' => 'MSFT', 'TSM' => 'TSM', 'BAC' => 'BAC', 'O' => 'O', 'KO' => 'KO', ]; // Remove prefixos de bolsa $n = preg_replace('/^(NASDAQ|NYSE|INDEXNASDAQ|AMS):?/', '', $n); // Remove caracteres especiais e pontos $n = preg_replace('/[^A-Z0-9]/', '', $n); // Verifica se está no mapa if (isset($mapa[$n])) { return $mapa[$n]; } return $n; } // LER REVOLUT (extrato) function lerRevolut($ficheiro) { if (!file_exists($ficheiro)) { return ['error' => 'Ficheiro não encontrado: ' . basename($ficheiro)]; } $fh = fopen($ficheiro, 'r'); if (!$fh) { return ['error' => 'Erro ao abrir: ' . basename($ficheiro)]; } // Cabeçalho: // Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate fgetcsv($fh, 0, ','); $movimentos = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 8) continue; $dataCompleta = trim($row[0]); $data = substr($dataCompleta, 0, 10); // YYYY-MM-DD $ticker = trim($row[1]); $tipo = trim($row[2]); $quantidade = trim($row[3]); $preco = trim($row[4]); $totalAmount = trim($row[5]); $moeda = trim($row[6]); $fxRaw = trim($row[7]); // Limpeza de valor total $valorLimpo = preg_replace('/[A-Z]{3}\s*/', '', $totalAmount); $valorLimpo = str_replace(',', '.', $valorLimpo); $valorNum = floatval($valorLimpo); // Limpeza de preço $precoLimpo = preg_replace('/[A-Z]{3}\s*/', '', $preco); $precoLimpo = str_replace(',', '.', $precoLimpo); $precoNum = floatval($precoLimpo); // FX rate $fxNum = $fxRaw !== '' ? floatval(str_replace(',', '.', $fxRaw)) : null; $movimentos[] = [ 'data' => $data, 'ticker' => strtoupper($ticker), 'tipo' => $tipo, 'quantidade' => floatval(str_replace(',', '.', $quantidade)), 'preco' => $precoNum, 'valor' => $valorNum, 'moeda' => $moeda, 'fx' => $fxNum, ]; } fclose($fh); return $movimentos; } // LER TRANSAÇÕES (formato novo: 11 colunas) function lerTransacoesAtuais($ficheiro) { if (!file_exists($ficheiro)) return []; $fh = fopen($ficheiro, 'r'); if (!$fh) return []; // Cabeçalho: Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes, // CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda fgetcsv($fh, 0, ','); $transacoes = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 11) continue; $transacoes[] = [ 'ordem' => trim($row[0]), 'dataCompra' => trim($row[1]), 'dataVenda' => trim($row[2]), 'nomeAcao' => trim($row[3]), 'numAcoes' => floatval(str_replace(',', '.', $row[4])), 'comissoes' => floatval(str_replace(',', '.', $row[5])), 'custoInicial' => floatval(str_replace(',', '.', $row[6])), 'custoFinal' => floatval(str_replace(',', '.', $row[7])), 'taxaCompra' => isset($row[8]) ? floatval(str_replace(',', '.', $row[8])) : 0.0, 'taxaVenda' => isset($row[9]) ? floatval(str_replace(',', '.', $row[9])) : 0.0, 'moeda' => trim($row[10]), ]; } fclose($fh); return $transacoes; } // COMPARAR COM LÓGICA RESTRITIVA function compararDados($revolut, $transacoesAtuais, $vistos) { $diferencas = [ 'duplicatasexatas' => [], 'alterarlinha' => [], 'adicionartransacao' => [], 'removertransacao' => [], 'totais' => [ 'revolutcompras' => 0, 'revolutvendas' => 0, 'transacoestotal' => count($transacoesAtuais) ] ]; // Agrupar Revolut por ticker $revolutPorTicker = []; foreach ($revolut as $mov) { $ticker = strtoupper($mov['ticker']); if (!isset($revolutPorTicker[$ticker])) { $revolutPorTicker[$ticker] = ['compras' => [], 'vendas' => []]; } if (stripos($mov['tipo'], 'BUY') !== false) { $revolutPorTicker[$ticker]['compras'][] = $mov; $diferencas['totais']['revolutcompras']++; } elseif (stripos($mov['tipo'], 'SELL') !== false) { $revolutPorTicker[$ticker]['vendas'][] = $mov; $diferencas['totais']['revolutvendas']++; } } // Verificar cada transação do CSV foreach ($transacoesAtuais as $t) { $linhaId = vistoIdLinha($t['ordem']); $tickerNormalizado = normalizarTicker($t['nomeAcao']); if (!isset($revolutPorTicker[$tickerNormalizado])) { // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'removertransacao', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'] ?? '', 'status' => 'OK' ]; continue; } $diferencas['removertransacao'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Ticker não encontrado no Revolut (normalizado: ' . $tickerNormalizado . ')' ]; continue; } $comprasTicker = $revolutPorTicker[$tickerNormalizado]['compras']; $vendasTicker = $revolutPorTicker[$tickerNormalizado]['vendas']; // ✅ PROCURAR COMPRA (tolerância: 0 dias, 1€) $compraEncontrada = null; foreach ($comprasTicker as $compra) { $diasDiff = abs(strtotime($compra['data']) - strtotime($t['dataCompra'])) / 86400; $custoDiff = abs($compra['valor'] - $t['custoInicial']); if ($diasDiff <= 0 && $custoDiff <= 1) { $compraEncontrada = $compra; break; } } // ✅ PROCURAR VENDA (tolerância: 0 dias, 1€) $vendaEncontrada = null; $temDataVendaCSV = !empty($t['dataVenda']); if ($temDataVendaCSV) { foreach ($vendasTicker as $venda) { $diasDiff = abs(strtotime($venda['data']) - strtotime($t['dataVenda'])) / 86400; $custoDiff = abs($venda['valor'] - $t['custoFinal']); if ($diasDiff <= 0 && $custoDiff <= 1) { $vendaEncontrada = $venda; break; } } } // Se não existe compra no Revolut e (não há venda no CSV ou também não existe venda no Revolut), // então esta linha do CSV muito provavelmente não corresponde a nada no extrato => remover. $naoExisteCompra = ($compraEncontrada === null); $naoExisteVenda = ($temDataVendaCSV && $vendaEncontrada === null); if ($naoExisteCompra && (!$temDataVendaCSV || $naoExisteVenda)) { $diferencas['removertransacao'][] = [ 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Compra e venda não encontradas no Revolut. Provável linha extra no CSV.' ]; continue; } // ✅ ANÃLISE DE DIFERENÇAS (DETALHADA) $diferencasCount = 0; $detalhes = []; if ($compraEncontrada) { // Data compra if ($compraEncontrada['data'] !== $t['dataCompra']) { $diferencasCount++; $detalhes[] = "Data Compra: {$t['dataCompra']} → {$compraEncontrada['data']}"; } // Quantidade if (abs($compraEncontrada['quantidade'] - $t['numAcoes']) > 0.00001) { $diferencasCount++; $detalhes[] = "Qtd: {$t['numAcoes']} → {$compraEncontrada['quantidade']}"; } // Custo compra if (abs($compraEncontrada['valor'] - $t['custoInicial']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Compra: {$t['custoInicial']} € → {$compraEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "COMPRA não encontrada no Revolut"; } if ($temDataVendaCSV) { if ($vendaEncontrada) { // Data venda if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } // Custo venda if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} € → {$vendaEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "VENDA não encontrada no Revolut"; } } // ✅ RESULTADO POR LINHA if ($diferencasCount === 0) { // Match perfeito $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $item = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'dataCompra' => $t['dataCompra'], 'dataVenda' => $t['dataVenda'], 'diferencas' => $diferencasCount, 'detalhes' => implode(' | ', $detalhes), 'valoratualcompra' => $t['custoInicial'], 'valoratualvenda' => $t['custoFinal'], 'sugestaocompra' => null, 'sugestaovenda' => null ]; // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'alterarlinha', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $diferencas['alterarlinha'][] = $item; } } // <-- ESTA chaveta é a que te falta (fecha o else do diferencasCount) } // fecha foreach ($transacoesAtuais as $t) return $diferencas; } // ========================== // NOVO: COMPARAR CAIXA // movimentos-caixa.csv <-> extrato-revolut.csv (CASH TOP-UP / CASH WITHDRAWAL / DIVIDEND / FEES) // ========================== function fnum_local($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([' ', "\t"], '', $s); // Se vier "USD -1.25" ou "EUR 493.36" $s = preg_replace('/^[A-Z]{3}/', '', $s); $s = trim($s); // vírgulas para ponto $s = str_replace(',', '.', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function normCaixaTipo($tipo): string { $t = mb_strtolower(trim((string)$tipo), 'UTF-8'); // Fallback manual (caso iconv falhe ou não exista translit completo) $t = strtr($t, [ 'á'=>'a','à'=>'a','â'=>'a','ã'=>'a', 'é'=>'e','ê'=>'e', 'í'=>'i', 'ó'=>'o','ô'=>'o','õ'=>'o', 'ú'=>'u', 'ç'=>'c' ]); // Tentar translit (se funcionar, melhora ainda mais) $tt = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $t); if ($tt !== false && $tt !== null && $tt !== '') { $t = $tt; } $t = preg_replace('/[^a-z0-9]+/', ' ', (string)$t); // Depósito (apanha "deposito", "deposit", "top up", "cash top-up", etc.) if (strpos($t, 'depos') !== false || strpos($t, 'deposit') !== false || strpos($t, 'top up') !== false || strpos($t, 'topup') !== false || strpos($t, 'cash top up') !== false || strpos($t, 'cash topup') !== false) { return 'Depósito'; } if (strpos($t, 'levant') !== false || strpos($t, 'withdraw') !== false) return 'Levantamento'; if (strpos($t, 'divid') !== false || strpos($t, 'dividend') !== false) return 'Dividendo'; return 'Outros'; } function mapRevolutCashTypeToCaixaTipo(string $type): ?string { $t = strtoupper(trim($type)); if ($t === '') return null; // Tipos típicos vistos no extrato if (strpos($t, 'CASH TOP-UP') !== false) return 'Depósito'; if (strpos($t, 'CASH WITHDRAWAL') !== false) return 'Levantamento'; if (strpos($t, 'DIVIDEND') !== false) return 'Dividendo'; // Fees e afins if (strpos($t, 'FEE') !== false || strpos($t, 'TAX') !== false || strpos($t, 'COMMISSION') !== false) return 'Outros'; if (strpos($t, 'CUSTODY FEE') !== false) return 'Outros'; return null; // não é movimento de caixa que nos interesse aqui } function filtrarRevolutCaixa(array $revolutMovs): array { $out = []; foreach ($revolutMovs as $m) { $type = (string)($m['tipo'] ?? ''); $tipoCaixa = mapRevolutCashTypeToCaixaTipo($type); if ($tipoCaixa === null) continue; $data = (string)($m['data'] ?? ''); $moeda = strtoupper(trim((string)($m['moeda'] ?? ''))); $valor = (float)($m['valor'] ?? 0.0); $ticker = trim((string)($m['ticker'] ?? '')); $descricao = strtoupper(trim($type)); if ($ticker !== '' && strpos($descricao, 'DIVIDEND') !== false) { $descricao = $ticker . ' DIVIDEND'; } $out[] = [ 'data' => $data, 'tipo' => $tipoCaixa, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $descricao, ]; } return $out; } function lerMovimentosCaixaCSV(string $ficheiroCaixa): array { if (!file_exists($ficheiroCaixa)) return ['_erro' => 'movimentos-caixa.csv não encontrado.']; $fh = fopen($ficheiroCaixa, 'r'); if (!$fh) return ['_erro' => 'Não foi possível abrir movimentos-caixa.csv.']; $cab = fgetcsv($fh, 0, ','); // Ordem,Data,Tipo,Valor,Moeda,Descricao $rows = []; while (($r = fgetcsv($fh, 0, ',')) !== false) { if (count($r) < 6) continue; $ordem = trim((string)$r[0]); $data = substr(trim((string)$r[1]), 0, 10); $tipo = normCaixaTipo($r[2] ?? ''); $valor = fnum_local($r[3] ?? 0); $moeda = strtoupper(trim((string)($r[4] ?? ''))); $desc = trim((string)($r[5] ?? '')); if ($data === '' || strlen($data) < 10) continue; $rows[] = [ 'ordem' => $ordem, 'data' => $data, 'tipo' => $tipo, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $desc, ]; } fclose($fh); return $rows; } function compararCaixaComRevolut(array $revolutMovs, string $ficheiroCaixa): array { $revCaixa = filtrarRevolutCaixa($revolutMovs); $caixaCsv = lerMovimentosCaixaCSV($ficheiroCaixa); if (isset($caixaCsv['_erro'])) { return [ 'resumo' => ['duplicatas' => 0, 'alterar' => 0, 'adicionar' => 0, 'remover' => 0], 'detalhes' => ['duplicatasexatas' => [], 'alterarlinha' => [], 'adicionar' => [], 'remover' => []], 'aviso' => $caixaCsv['_erro'], ]; } // Vamos “consumir†linhas do CSV à medida que casam, para evitar reuso. $usado = array_fill(0, count($caixaCsv), false); $duplicatas = []; $alterar = []; $adicionar = []; $remover = []; // 1) Revolut -> procurar no movimentos-caixa.csv foreach ($revCaixa as $rc) { $matchIdx = null; $match = null; // Tentativa A: data + moeda + valor (tolerância) for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $c = $caixaCsv[$i]; if ($c['moeda'] !== $rc['moeda']) continue; $dias = abs(strtotime($c['data']) - strtotime($rc['data'])) / 86400; if ($dias > 0) continue; if (abs(((float)$c['valor']) - ((float)$rc['valor'])) > 0.01) continue; $matchIdx = $i; $match = $c; break; } if ($matchIdx === null) { $adicionar[] = [ 'origem' => 'Revolut', 'motivo' => 'Movimento de caixa não encontrado em movimentos-caixa.csv', 'sugestao' => $rc, ]; continue; } $usado[$matchIdx] = true; // Comparar tipo (e opcionalmente descrição) $diffs = []; if ($match['tipo'] !== $rc['tipo']) { $diffs[] = "Tipo: CSV={$match['tipo']} vs Revolut={$rc['tipo']}"; } if (count($diffs) === 0) { $duplicatas[] = [ 'data' => $rc['data'], 'tipo' => $rc['tipo'], 'valor' => $rc['valor'], 'moeda' => $rc['moeda'], 'status' => 'OK', ]; } else { $alterar[] = [ 'linha' => $match['ordem'], 'data' => $rc['data'], 'diferencas' => count($diffs), 'detalhes' => implode(' | ', $diffs), 'csv' => $match, 'revolut' => $rc, ]; } } // 2) Tudo o que ficou no CSV sem match -> remover/rever for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $remover[] = [ 'origem' => 'CSV', 'linha' => $caixaCsv[$i]['ordem'], 'motivo' => 'Movimento existe em movimentos-caixa.csv mas não aparece no extrato Revolut (tipos de caixa)', 'csv' => $caixaCsv[$i], ]; } return [ 'resumo' => [ 'duplicatas' => count($duplicatas), 'alterar' => count($alterar), 'adicionar' => count($adicionar), 'remover' => count($remover), ], 'detalhes' => [ 'duplicatasexatas' => $duplicatas, 'alterarlinha' => $alterar, 'adicionar' => $adicionar, 'remover' => $remover, ], ]; } $revolut = lerRevolut($ficheiroRevolut); if (isset($revolut['error'])) { echo json_encode(['ok' => false, 'error' => $revolut['error'], 'user' => getUserId()], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // Normalizar tickers do Revolut para casar com normalizarTicker() foreach ($revolut as &$m) { if (isset($m['ticker']) && $m['ticker'] !== '') { $m['ticker'] = normalizarTicker($m['ticker']); } } unset($m); $revolut = filtrarPorAno($revolut, $anoFiltro); $transacoesAtuais = lerTransacoesAtuais($ficheiroTransacoes); $transacoesAtuais = filtrarPorAno($transacoesAtuais, $anoFiltro); $vistos = vistosLoad(); $diferencas = compararDados($revolut, $transacoesAtuais, $vistos); // --- NOVO: comparar CAIXA (movimentos-caixa.csv) com extrato-revolut.csv --- $caixaDiff = compararCaixaComRevolut($revolut, $ficheiroCaixa); echo json_encode([ 'ok' => true, 'ficheirorevolut' => basename($ficheiroRevolut), 'utilizador' => getUserId(), 'anofiltro' => $anoFiltro ? $anoFiltro : 'TODOS', 'dataverificacao' => date('Y-m-d H:i:s'), // (mantém o resumo/detalhes das AÇÕES como está no teu ficheiro) 'resumo' => [ 'duplicatas' => count($diferencas['duplicatasexatas'] ?? []), 'alterar' => count($diferencas['alterarlinha'] ?? []), 'adicionar' => count($diferencas['adicionartransacao'] ?? []), 'remover' => count($diferencas['removertransacao'] ?? []), ], 'detalhes' => $diferencas, // --- NOVO: resultados de CAIXA --- 'caixa' => $caixaDiff, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; ======================================================================================== FICHEIRO: api/bootstrap/bootstrap.php Tamanho: 443 bytes ======================================================================================== file = $file; $dir = dirname($file); if (!is_dir($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } } public function info(string $msg, array $ctx = []): void { $this->write('info', $msg, $ctx); } public function error(string $msg, array $ctx = []): void { $this->write('error', $msg, $ctx); } private function write(string $level, string $msg, array $ctx): void { $row = [ 'ts' => date('Y-m-d H:i:s'), 'level' => $level, 'msg' => $msg, 'ctx' => $ctx, ]; @file_put_contents( $this->file, json_encode($row, JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND | LOCK_EX ); } } ======================================================================================== FICHEIRO: api/bootstrap/simbolos.php Tamanho: 13712 bytes ======================================================================================== metadados // - "interno": usado em cálculos, JSON de preços e normalizações // - "json": chave dentro de dadoscsvprecos-atuais.json (normalmente igual ao interno) // - "tabela": símbolo com prefixo de bolsa usado nas tabelas (frontend / histórico) // - "aliases": maneiras alternativas de escrever o mesmo ativo (Revolut, CSV, etc.) // - "nome": nome mais usado / amigável para mostrar na UI const MAPA_SIMBOLOS = [ // ------------- CORE / AÇÕES US ------------- 'AAPL' => [ 'nome' => 'Apple', 'json' => 'AAPL', 'tabela' => 'Apple', 'aliases' => ['AAPL', 'NASDAQ:AAPL', 'Apple'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['aapl.us'], 'twelve' => ['AAPL'], 'manual' => 0, ], 'NVDA' => [ 'nome' => 'NVIDIA', 'json' => 'NVDA', 'tabela' => 'NVIDIA', 'aliases' => ['NVDA', 'NASDAQ:NVDA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nvda.us'], 'twelve' => ['NVDA'], 'manual' => 0, ], 'GOOGL' => [ 'nome' => 'Google', 'json' => 'GOOGL', 'tabela' => 'Google', 'aliases' => ['GOOGL', 'NASDAQ:GOOGL', 'GOOG', 'NASDAQ:GOOG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['googl.us'], 'twelve' => ['GOOGL'], 'manual' => 0, ], 'AMZN' => [ 'nome' => 'Amazon', 'json' => 'AMZN', 'tabela' => 'Amazon', 'aliases' => ['AMZN', 'NASDAQ:AMZN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amzn.us'], 'twelve' => ['AMZN'], 'manual' => 0, ], 'ADBE' => [ 'nome' => 'Adobe', 'json' => 'ADBE', 'tabela' => 'Adobe', 'aliases' => ['ADBE', 'NASDAQ:ADBE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['adbe.us'], 'twelve' => ['ADBE'], 'manual' => 0, ], 'TSLA' => [ 'nome' => 'Tesla', 'json' => 'TSLA', 'tabela' => 'Tesla', 'aliases' => ['TSLA', 'NASDAQ:TSLA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsla.us'], 'twelve' => ['TSLA'], 'manual' => 0, ], 'MSFT' => [ 'nome' => 'Microsoft', 'json' => 'MSFT', 'tabela' => 'Microsoft', 'aliases' => ['MSFT', 'NASDAQ:MSFT'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['msft.us'], 'twelve' => ['MSFT'], 'manual' => 0, ], 'NFLX' => [ 'nome' => 'Netflix', 'json' => 'NFLX', 'tabela' => 'Netflix', 'aliases' => ['NFLX', 'NASDAQ:NFLX'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nflx.us'], 'twelve' => ['NFLX'], 'manual' => 0, ], 'AMD' => [ 'nome' => 'Advanced Micro Devices', 'json' => 'AMD', 'tabela' => 'Advanced Micro Devices', 'aliases' => ['AMD', 'NASDAQ:AMD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amd.us'], 'twelve' => ['AMD'], 'manual' => 0, ], 'ZM' => [ 'nome' => 'Zoom Video', 'json' => 'ZM', 'tabela' => 'Zoom Video', 'aliases' => ['ZM', 'NASDAQ:ZM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['zm.us'], 'twelve' => ['ZM'], 'manual' => 0, ], 'Z' => [ 'nome' => 'Zillow', 'json' => 'Z', 'tabela' => 'Zillow', 'aliases' => ['Z', 'NASDAQ:Z'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['z.us'], 'twelve' => ['Z'], 'manual' => 0, ], 'MRNA' => [ 'nome' => 'Moderna', 'json' => 'MRNA', 'tabela' => 'Moderna', 'aliases' => ['MRNA', 'NASDAQ:MRNA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mrna.us'], 'twelve' => ['MRNA'], 'manual' => 0, ], 'PLUG' => [ 'nome' => 'Plug Power', 'json' => 'PLUG', 'tabela' => 'Plug Power', 'aliases' => ['PLUG', 'NASDAQ:PLUG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['plug.us'], 'twelve' => ['PLUG'], 'manual' => 0, ], 'PYPL' => [ 'nome' => 'PayPal', 'json' => 'PYPL', 'tabela' => 'PayPal', 'aliases' => ['PYPL', 'NASDAQ:PYPL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['pypl.us'], 'twelve' => ['PYPL'], 'manual' => 0, ], 'ANSS' => [ 'nome' => 'ANSYS', 'json' => 'ANSS', 'tabela' => 'ANSYS', 'aliases' => ['ANSS', 'NASDAQ:ANSS'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['anss.us'], 'twelve' => ['ANSS'], 'manual' => 0, ], 'QCOM' => [ 'nome' => 'Qualcomm', 'json' => 'QCOM', 'tabela' => 'Qualcomm', 'aliases' => ['QCOM', 'NASDAQ:QCOM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['qcom.us'], 'twelve' => ['QCOM'], 'manual' => 0, ], 'UAL' => [ 'nome' => 'United Airlines', 'json' => 'UAL', 'tabela' => 'United Airlines', 'aliases' => ['UAL', 'NASDAQ:UAL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ual.us'], 'twelve' => ['UAL'], 'manual' => 0, ], // ------------- FINANCE / PAYMENT ------------- 'MA' => [ 'nome' => 'Mastercard', 'json' => 'MA', 'tabela' => 'Mastercard', 'aliases' => ['MA', 'NYSE:MA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ma.us'], 'twelve' => ['MA'], 'manual' => 0, ], 'SQ' => [ 'nome' => 'Square', 'json' => 'SQ', 'tabela' => 'Square', 'aliases' => ['SQ', 'NYSE:SQ'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['sq.us'], 'twelve' => ['SQ'], 'manual' => 0, ], 'BAC' => [ 'nome' => 'Bank of America', 'json' => 'BAC', 'tabela' => 'Bank of America', 'aliases' => ['BAC', 'NYSE:BAC'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['bac.us'], 'twelve' => ['BAC'], 'manual' => 0, ], 'TSM' => [ 'nome' => 'Taiwan Semiconductor', 'json' => 'TSM', 'tabela' => 'Taiwan Semiconductor', 'aliases' => ['TSM', 'NYSE:TSM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsm.us'], 'twelve' => ['TSM'], 'manual' => 0, ], 'BABA' => [ 'nome' => 'Alibaba Group', 'json' => 'BABA', 'tabela' => 'Alibaba Group', 'aliases' => ['BABA', 'NYSE:BABA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['baba.us'], 'twelve' => ['BABA'], 'manual' => 0, ], 'BRKB' => [ 'nome' => 'Berkshire Hathaway', 'json' => 'BRKB', 'tabela' => 'Berkshire Hathaway', 'aliases' => ['BRKB', 'BRK.B', 'NYSE:BRK.B'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['brk-b.us'], 'twelve' => ['BRK.B', 'BRKB'], 'manual' => 0, ], // ------------- CONSUMO / OUTROS ------------- 'MCD' => [ 'nome' => 'McDonald\'s', 'json' => 'MCD', 'tabela' => 'McDonald\'s', 'aliases' => ['MCD', 'NYSE:MCD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mcd.us'], 'twelve' => ['MCD'], 'manual' => 0, ], 'KO' => [ 'nome' => 'Coca-Cola', 'json' => 'KO', 'tabela' => 'Coca-Cola', 'aliases' => ['KO', 'NYSE:KO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ko.us'], 'twelve' => ['KO'], 'manual' => 0, ], 'SPCE' => [ 'nome' => 'Virgin Galactic', 'json' => 'SPCE', 'tabela' => 'Virgin Galactic', 'aliases' => ['SPCE', 'NYSE:SPCE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['spce.us'], 'twelve' => ['SPCE'], 'manual' => 0, ], 'O' => [ 'nome' => 'Realty Income', 'json' => 'O', 'tabela' => 'Realty Income', 'aliases' => ['O', 'NYSE:O'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['o.us'], 'twelve' => ['O'], 'manual' => 0, ], 'TWTR' => [ 'nome' => 'Twitter', 'json' => 'TWTR', 'tabela' => 'Twitter', 'aliases' => ['TWTR', 'NYSE:TWTR'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['twtr.us'], 'twelve' => ['TWTR'], 'manual' => 0, ], 'NIO' => [ 'nome' => 'NIO', 'json' => 'NIO', 'tabela' => 'NIO', 'aliases' => ['NIO', 'NYSE:NIO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nio.us'], 'twelve' => ['NIO'], 'manual' => 0, ], 'RIVN' => [ 'nome' => 'Rivian', 'json' => 'RIVN', 'tabela' => 'Rivian', 'aliases' => ['RIVN', 'NASDAQ:RIVN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['rivn.us'], 'twelve' => ['RIVN'], 'manual' => 0, ], 'XYZ' => [ 'nome' => 'XYZ', 'json' => 'XYZ', 'tabela' => 'XYZ', 'aliases' => ['XYZ'], // placeholder sem providers ], // ------------- ETFs / RIVN / VUSA / XYZ e OURO ------------- 'VUSA' => [ 'nome' => 'VUSA - Vanguard S&P 500 Dist ETF (Revolut)', 'json' => 'VUSA', 'tabela' => 'VUSA S&P 500', 'aliases' => ['VUSA', 'LSE:VUSA', 'AMS:VUSA', 'VUSA.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'], 'perplexityquery' => 'Current price Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'perplexityclosequery' => 'Previous close Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'manual' => 0, ], 'IWDA' => [ 'nome' => 'IWDA - iShares Core MSCI World Acc ETF (Revolut)', 'json' => 'IWDA', 'tabela' => 'EUNL MSCI World', 'aliases' => ['IWDA', 'EUNL', 'AMS:IWDA', 'EUNL.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'], 'perplexityquery' => 'Current price EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'perplexityclosequery' => 'Previous close EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'manual' => 0, ], 'NDXEX' => [ 'nome' => 'NDXEX - iShares Nasdaq 100 UCITS ETF (Dist) (Revolut)', 'json' => 'NDXEX', 'tabela' => 'EXXT Nasdaq-100', 'aliases' => ['NDXEX', 'NDX', 'INDEXNASDAQ:NDX', 'EXXT', 'EQQQ', 'EXXT.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'], 'perplexityquery' => 'Current price iShares NASDAQ-100 UCITS ETF (DE) (EXXT.DE) (yahoo)', 'perplexityclosequery' => 'Previous close EXXT.DE iShares NASDAQ-100 UCITS ETF (DE) EUR (yahoo)', 'manual' => 0, ], 'XAUEUR' => [ 'nome' => 'Ouro (XAU/EUR)', 'json' => 'XAUEUR', 'tabela' => 'Ouro', 'moeda' => 'EUR', 'aliases' => ['XAUEUR', 'XAU/EUR', 'XAU EUR', 'OURO', 'GOLD','XAUEUR','XAU'], 'tipo' => 'ouro', 'stooq' => ['xaueur'], 'twelve' => ['XAU/EUR'], 'perplexityquery' => 'Current price, GOLD XAU/EUR', 'perplexityclosequery' => 'Previous close price for GOLD XAU/EUR', 'manual' => 0, ], ]; // Função genérica: dado um ticker qualquer (Revolut, CSV, etc.), devolve o ticker interno function normalizarTickerGlobal(string $raw): ?string { $n = strtoupper(trim($raw)); if ($n === '') { return null; } // 1) Remover prefixos de bolsa mais comuns $n = preg_replace('/^(NASDAQ|NYSE|AMS|INDEXNASDAQ|XETRA|LSE):?/', '', $n); // 2) BRK.B -> BRKB (remover pontos) $n = str_replace('.', '', $n); // 3) Remover qualquer coisa que não seja A–Z ou 0–9 $n = preg_replace('/[^A-Z0-9]/', '', $n); // 4) Procurar primeiro por match direto de interno if (isset(MAPA_SIMBOLOS[$n])) { return $n; } // 5) Procurar nos aliases foreach (MAPA_SIMBOLOS as $interno => $info) { if (!empty($info['aliases']) && in_array($n, $info['aliases'], true)) { return $interno; } } // 6) Fallback: devolve o limpo (permite lidar com ativos novos ainda não registados) return $n; } $simbolos = MAPA_SIMBOLOS; // Se este ficheiro foi chamado diretamente (não via include), enviar JSON if (realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME'] ?? '')) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(MAPA_SIMBOLOS, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } ======================================================================================== FICHEIRO: api/bootstrap/simplecache.php Tamanho: 963 bytes ======================================================================================== dir = rtrim($dir, '/'); if (!is_dir($this->dir)) { @mkdir($this->dir, 0775, true); @chmod($this->dir, 0775); } } private function path(string $key): string { return $this->dir . '/' . sha1($key) . '.json'; } public function get(string $key, int $ttlSeconds): ?array { $p = $this->path($key); if (!is_file($p)) return null; $age = time() - (int)@filemtime($p); if ($age > $ttlSeconds) return null; $raw = @file_get_contents($p); if (!is_string($raw) || $raw === '') return null; $data = json_decode($raw, true); return is_array($data) ? $data : null; } public function set(string $key, array $value): void { $p = $this->path($key); @file_put_contents($p, json_encode($value, JSON_UNESCAPED_UNICODE), LOCK_EX); } } ======================================================================================== FICHEIRO: api/bootstrap/utilizador.php Tamanho: 1147 bytes ======================================================================================== /.../dados_csv/tiago/transacoes-acoes.csv [file:1] */ function userFilePath(string $baseName): string { $baseName = ltrim($baseName, '/'); $user = getUserId(); return ROOT . '/dados_csv/' . $user .'/'. $baseName; } ======================================================================================== FICHEIRO: api/bootstrap/validacao.php Tamanho: 1044 bytes ======================================================================================== false, 'erro' => $msg, 'timestamp' => date('Y-m-d H:i:s'), ], $extra), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } function v_enum(?string $value, array $allowed, string $field = 'valor'): string { $v = trim((string)$value); if ($v === '' || !in_array($v, $allowed, true)) { api_json_error("Campo inválido: $field", 400, ['field' => $field]); } return $v; } function v_user_id(?string $value): string { $v = trim((string)$value); if ($v === '' || !preg_match('/^[a-z0-9_]{1,32}$/', $v)) { api_json_error('User inválido.', 400); } return $v; } function v_moeda(?string $value): string { $v = strtoupper(trim((string)$value)); return v_enum($v, ['EUR', 'USD'], 'moeda'); } ======================================================================================== FICHEIRO: api/calculos-atualizar.log Tamanho: 15056 bytes ======================================================================================== { "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 326, "ultima_taxa": 1.17 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (indisponivel)", "IWDA (indisponivel)", "NDXEX (indisponivel)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-22 21:30:02", "bytes_escritos": 2028 } }, "duracao_segundos": 10.93, "timestamp": "2025-12-22 21:30:12" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 12:30:01", "bytes_escritos": 2099 } }, "duracao_segundos": 5.8, "timestamp": "2025-12-26 12:30:06" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 12:45:02", "bytes_escritos": 2098 } }, "duracao_segundos": 6.11, "timestamp": "2025-12-26 12:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:00:02", "bytes_escritos": 2099 } }, "duracao_segundos": 5.95, "timestamp": "2025-12-26 13:00:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:15:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.06, "timestamp": "2025-12-26 13:15:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:30:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.17, "timestamp": "2025-12-26 13:30:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:45:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.09, "timestamp": "2025-12-26 13:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:00:02", "bytes_escritos": 2099 } }, "duracao_segundos": 5.99, "timestamp": "2025-12-26 14:00:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:15:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.11, "timestamp": "2025-12-26 14:15:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:30:03", "bytes_escritos": 2099 } }, "duracao_segundos": 6.1, "timestamp": "2025-12-26 14:30:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:45:02", "bytes_escritos": 2101 } }, "duracao_segundos": 5.87, "timestamp": "2025-12-26 14:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:00:02", "bytes_escritos": 2097 } }, "duracao_segundos": 5.89, "timestamp": "2025-12-26 15:00:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 326, "ultima_taxa": 1.1773 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:15:02", "bytes_escritos": 2098 } }, "duracao_segundos": 5.89, "timestamp": "2025-12-26 15:15:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 326, "ultima_taxa": 1.1773 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:30:03", "bytes_escritos": 2100 } }, "duracao_segundos": 6.85, "timestamp": "2025-12-26 15:30:08" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:45:02", "bytes_escritos": 2103 } }, "duracao_segundos": 5.81, "timestamp": "2025-12-26 15:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:00:05", "bytes_escritos": 2099 } }, "duracao_segundos": 9.44, "timestamp": "2025-12-26 16:00:11" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:15:02", "bytes_escritos": 2103 } }, "duracao_segundos": 5.8, "timestamp": "2025-12-26 16:15:06" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:30:02", "bytes_escritos": 2101 } }, "duracao_segundos": 5.94, "timestamp": "2025-12-26 16:30:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:45:02", "bytes_escritos": 2102 } }, "duracao_segundos": 6.19, "timestamp": "2025-12-26 16:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 17:00:02", "bytes_escritos": 2100 } }, "duracao_segundos": 7.77, "timestamp": "2025-12-26 17:00:09" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 17:15:02", "bytes_escritos": 2102 } }, "duracao_segundos": 8.57, "timestamp": "2025-12-26 17:15:09" } ======================================================================================== FICHEIRO: api/calculos.php Tamanho: 111631 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; require_once ROOT . '/api/perplexity.php'; require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; $lines = preg_split("/\\r\\n|\\n|\\r/", $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if ($dataLine === "") return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; $dateStr = trim((string)($cols[1] ?? "")); $close = $cols[6] ?? null; // ✅ 7 DIAS FLEXÃVEL $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - AÇÕES: Stooq → TwelveData → Manual * - ETFs: Stooq → EODHD → Manual * - XAU: Stooq → TwelveData → Manual */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; // 1ï¸âƒ£ Stooq (SEMPRE PRIMEIRO - grátis) if (isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $price = obterPrecoAtualStooq($symbol); if ($price !== null && $price > 0) { $source = "stooq:$symbol"; break; } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, '') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3) EODHD – só ETFs - última opção antes de Perplexity if ($price === null && $tipo === 'etf' && isset($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { $price = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($price !== null && $price > 0) { $source = "eodhd:$symbol"; break; } } } // 4) Perplexity (fallback) – antes do Manual if (($price === null || $price <= 0) && function_exists('obterPrecoAtualPerplexity')) { // Query configurável por ticker (opcional) // Ex: 'perplexity_query' => 'IWDA ETF price (iShares Core MSCI World UCITS ETF) Xetra' $q = $cfg['perplexityquery'] ?? ($ticker . ' stock price'); $dbg = null; $p = obterPrecoAtualPerplexity($q, $moeda, $dbg); if ($p !== null && $p > 0) { $price = $p; $source = 'perplexity-api'; } } // 5) Manual (valor anterior) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de abertura (close) do dia atual * Hierarquia: * - AÇÕES: Stooq → TwelveData → Perplexity → Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; // 1) STOOQ (previous close via daily) if (isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 2) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); // Preferir prevClose; fallback para close se existir if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } // Converter XAUUSD -> XAUEUR se necessário (taxaCambio = EURUSD) if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 3) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) PERPLEXITY fallback (se existir) if (($closePrice === null || $closePrice <= 0) && function_exists('obterPrevClosePerplexity')) { $query = $cfg['perplexityclosequery'] ?? ($ticker . ' previous close price'); $moeda = $cfg['moeda'] ?? 'USD'; $debug = null; $p = obterPrevClosePerplexity($query, $moeda, $debug); if ($p !== null && $p > 0) $closePrice = $p; } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: api/downloadacoes.php Tamanho: 560 bytes ======================================================================================== false, 'error' => 'Nenhuma ação pedida. Use atualizar_caixa=1 e/ou atualizar_acoes=1' ]); exit; } // Ficheiro de extrato por utilizador $ficheiroExtrato = userFilePath('extrato-revolut.csv'); if (!file_exists($ficheiroExtrato)) { echo json_encode([ 'ok' => false, 'error' => "Extrato Revolut não encontrado para utilizador '$user'. Carregue primeiro via Importar Revolut." ]); exit; } // Helpers function extrairValor($texto) { if (preg_match('/(USD|EUR)\s*([+-]?[0-9.,]+)/', $texto, $m)) { return (float) str_replace(',', '', $m[2]); } return 0.0; } function extrairMoeda($texto) { if (preg_match('/(USD|EUR)/', $texto, $m)) { return $m[1]; } return 'USD'; } function mapearTipoCaixa($tipoRevolut) { $tipo = strtoupper(trim($tipoRevolut)); if (strpos($tipo, 'CASH TOP-UP') !== false) return 'Depósito'; if (strpos($tipo, 'CASH WITHDRAWAL') !== false) return 'Levantamento'; if (strpos($tipo, 'DIVIDEND') !== false) return 'Dividendo'; if (strpos($tipo, 'CUSTODY FEE') !== false) return 'Outros'; if (strpos($tipo, 'TRANSFER') !== false) return 'Outros'; return 'Outros'; } function eLinhaCaixa($ticker, $tipoRevolut) { $tipo = strtoupper(trim($tipoRevolut)); // Mesma lógica do JS: só caixa se NÃO tiver ticker // ou se for CASH/DIVIDEND/CUSTODY FEE/TRANSFER e não MARKET. $incluir = (empty($ticker) || strpos($tipo, 'CASH') !== false || strpos($tipo, 'DIVIDEND') !== false || strpos($tipo, 'CUSTODY FEE') !== false || strpos($tipo, 'TRANSFER') !== false); return $incluir && (strpos($tipo, 'MARKET') === false); } function eLinhaAcao($ticker, $tipoRevolut) { if (empty($ticker)) return false; $tipo = strtoupper(trim($tipoRevolut)); return (strpos($tipo, 'BUY') !== false || strpos($tipo, 'SELL') !== false); } function converterDataISO($dataISO) { // "2020-09-17T12:27:15.160488Z" -> "2020-09-17" return substr(trim($dataISO), 0, 10); } // Ler extrato $fh = fopen($ficheiroExtrato, 'r'); if (!$fh) { echo json_encode([ 'ok' => false, 'error' => 'Não foi possível abrir o extrato Revolut.' ]); exit; } // Cabeçalho (esperado): Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate $header = fgetcsv($fh); $map = array_flip($header ?: []); $idxDate = $map['Date'] ?? 0; $idxTicker = $map['Ticker'] ?? 1; $idxType = $map['Type'] ?? 2; $idxQty = $map['Quantity'] ?? 3; $idxTotal = $map['Total Amount'] ?? 5; $idxCurTxt = $map['Currency'] ?? 6; $idxFx = $map['FX Rate'] ?? 7; // Acumuladores $movimentosCaixa = []; $transacoesAcoes = []; $ordemCaixa = 1; $ordemAcoes = 1; while (($cols = fgetcsv($fh)) !== false) { if (count($cols) < 8) continue; $dataISO = $cols[$idxDate] ?? ''; $ticker = trim($cols[$idxTicker] ?? ''); $tipoRevolut = $cols[$idxType] ?? ''; $qtyTxt = $cols[$idxQty] ?? ''; $totalTxt = $cols[$idxTotal] ?? ''; $moedaTxt = $cols[$idxCurTxt] ?? ''; $fxRate = trim($cols[$idxFx] ?? ''); if (trim($dataISO) === '') continue; $data = converterDataISO($dataISO); // Valor e moeda vindos de "Total Amount" (ex: "USD 371.31") $valorBruto = extrairValor($totalTxt); if ($valorBruto == 0.0) { // ainda assim tentar moeda só pelo campo Currency $moeda = extrairMoeda($moedaTxt); } else { $moeda = extrairMoeda($totalTxt); } // 1) Movimentos de CAIXA if ($doCaixa && eLinhaCaixa($ticker, $tipoRevolut) && $valorBruto != 0.0) { $descricao = $ticker ? ($ticker . ' ' . $tipoRevolut) : strtoupper(trim($tipoRevolut)); $movimentosCaixa[] = [ 'ordem' => $ordemCaixa++, 'data' => $data, 'tipo' => mapearTipoCaixa($tipoRevolut), 'valor' => $valorBruto, 'moeda' => $moeda, 'descricao' => $descricao, 'taxa' => $fxRate, ]; } // 2) Transações de AÇÕES if ($doAcoes && eLinhaAcao($ticker, $tipoRevolut) && $valorBruto != 0.0) { $tipoUpper = strtoupper(trim($tipoRevolut)); $qtd = (float) str_replace(',', '.', $qtyTxt); // Normalizar sinal: consideramos valor positivo para custo/receita $valorAbs = abs($valorBruto); $dataCompra = ''; $dataVenda = ''; $custoInicial = 0.0; $custoFinal = 0.0; $taxaCompra = ''; $taxaVenda = ''; if (strpos($tipoUpper, 'BUY') !== false) { // COMPRA $dataCompra = $data; $custoInicial = $valorAbs; $taxaCompra = $fxRate; } elseif (strpos($tipoUpper, 'SELL') !== false) { // VENDA $dataVenda = $data; $custoFinal = $valorAbs; $taxaVenda = $fxRate; } else { // Não reconhecido como BUY/SELL continue; } $transacoesAcoes[] = [ 'ordem' => $ordemAcoes++, 'dataCompra' => $dataCompra, 'dataVenda' => $dataVenda, 'nomeAcao' => $ticker, 'numAcoes' => $qtd, 'comissoes' => 0.0, 'custoInicial' => $custoInicial, 'custoFinal' => $custoFinal, 'taxaCompra' => $taxaCompra, 'taxaVenda' => $taxaVenda, 'moeda' => $moeda, ]; } } fclose($fh); // Gravar ficheiros $result = [ 'ok' => true, 'user' => $user, 'movimentos_caixa'=> 0, 'transacoes_acoes'=> 0, 'ficheiros' => [], ]; if ($doCaixa) { $csv = "Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio\n"; foreach ($movimentosCaixa as $mov) { $valor = number_format($mov['valor'], 2, '.', ''); $taxa = $mov['taxa'] !== '' ? $mov['taxa'] : ''; $desc = str_replace('"', '""', $mov['descricao']); $csv .= "{$mov['ordem']},{$mov['data']},{$mov['tipo']},{$valor},{$mov['moeda']},\"{$desc}\",{$taxa}\n"; } $ficheiroCaixa = userFilePath('movimentos-caixa.csv'); file_put_contents($ficheiroCaixa, $csv); $result['movimentos_caixa'] = count($movimentosCaixa); $result['ficheiros'][] = basename($ficheiroCaixa); } if ($doAcoes) { // 1) Agrupar COMPRA/VENDA com o mesmo NomeAcao e NumAcoes $agrupadas = []; foreach ($transacoesAcoes as $t) { // chave: mesmo nome de ação e mesma quantidade $chave = $t['nomeAcao'] . '|' . number_format($t['numAcoes'], 6, '.', ''); if (!isset($agrupadas[$chave])) { $agrupadas[$chave] = $t; continue; } // Já existe uma linha para esta ação+quantidade → juntar dados $exist = &$agrupadas[$chave]; if ($exist['dataCompra'] === '' && $t['dataCompra'] !== '') { $exist['dataCompra'] = $t['dataCompra']; } if ($exist['dataVenda'] === '' && $t['dataVenda'] !== '') { $exist['dataVenda'] = $t['dataVenda']; } if ((float)$exist['custoInicial'] == 0.0 && (float)$t['custoInicial'] != 0.0) { $exist['custoInicial'] = $t['custoInicial']; } if ((float)$exist['custoFinal'] == 0.0 && (float)$t['custoFinal'] != 0.0) { $exist['custoFinal'] = $t['custoFinal']; } if ($exist['taxaCompra'] === '' && $t['taxaCompra'] !== '') { $exist['taxaCompra'] = $t['taxaCompra']; } if ($exist['taxaVenda'] === '' && $t['taxaVenda'] !== '') { $exist['taxaVenda'] = $t['taxaVenda']; } unset($exist); // limpar referência } // 2) Recriar lista final com novas ordens $transacoesCombinadas = []; $ordem = 1; foreach ($agrupadas as $t) { $t['ordem'] = $ordem++; $transacoesCombinadas[] = $t; } // 3) Gerar CSV $csv = "Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda\n"; foreach ($transacoesCombinadas as $t) { $numAcoes = number_format($t['numAcoes'], 6, '.', ''); $comissoes = number_format($t['comissoes'], 2, '.', ''); $custoInicial = number_format($t['custoInicial'], 2, '.', ''); $custoFinal = number_format($t['custoFinal'], 2, '.', ''); $taxaCompra = $t['taxaCompra'] !== '' ? $t['taxaCompra'] : ''; $taxaVenda = $t['taxaVenda'] !== '' ? $t['taxaVenda'] : ''; $nomeEscapado = str_replace(',', ' ', $t['nomeAcao']); $csv .= $t['ordem'] . ',' . $t['dataCompra'] . ',' . $t['dataVenda'] . ',' . $nomeEscapado . ',' . $numAcoes . ',' . $comissoes . ',' . $custoInicial . ',' . $custoFinal . ',' . $taxaCompra . ',' . $taxaVenda . ',' . $t['moeda'] . "\n"; } $ficheiroAcoes = userFilePath('transacoes-acoes.csv'); file_put_contents($ficheiroAcoes, $csv); $result['transacoes_acoes'] = count($transacoesCombinadas); $result['ficheiros'][] = basename($ficheiroAcoes); } echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); ?> ======================================================================================== FICHEIRO: api/listar_ficheiros.php Tamanho: 1310 bytes ======================================================================================== true, 'ficheiros' => $ficheiros, 'total' => count($ficheiros), 'timestamp' => date('Y-m-d H:i:s') )); ?> ======================================================================================== FICHEIRO: api/obterprecosatuais.php Tamanho: 2674 bytes ======================================================================================== $jsonKey, 'info' => MAPA_SIMBOLOS[$jsonKey], ]; } // Match por campo 'json' foreach (MAPA_SIMBOLOS as $interno => $info) { $k = $info['json'] ?? $interno; if ($k === $jsonKey) { return [ 'interno' => $interno, 'info' => $info, ]; } } return null; } $precosTabela = []; // 1) DEVOLVER TUDO o que estiver no JSON foreach ($dados['precos'] as $jsonKey => $entry) { if (!is_array($entry)) continue; $hit = encontrarInfoPorJsonKey((string)$jsonKey); $interno = $hit ? ($hit['interno'] ?? (string)$jsonKey) : (string)$jsonKey; $info = $hit ? ($hit['info'] ?? []) : []; $tabelaKey = $info['tabela'] ?? $interno; $preco = isset($entry['preco']) ? (float)$entry['preco'] : null; $moeda = $entry['moeda'] ?? ($info['moeda'] ?? 'EUR'); $ts = $entry['timestamp'] ?? null; $fonte = $entry['fonte'] ?? null; $precosTabela[$tabelaKey] = [ 'ticker_interno' => $interno, 'json_key' => (string)$jsonKey, 'nome' => $info['nome'] ?? $interno, 'preco' => $preco, 'moeda' => $moeda, 'timestamp' => $ts, 'fonte' => $fonte, ]; } // 2) ADICIONAR CÂMBIO (se existir no JSON) if (isset($dados['cambio']) && is_array($dados['cambio'])) { $precosTabela['cambio'] = $dados['cambio']; } echo json_encode($precosTabela, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); ======================================================================================== FICHEIRO: api/obtervariacaodia.php Tamanho: 11452 bytes ======================================================================================== [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n" ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function numOrNull($v): ?float { if ($v === null) return null; if (!is_numeric($v)) return null; $n = floatval($v); if (!is_finite($n)) return null; return $n; } function lastKnownPct(array $cache, string $ticker): ?float { // cache esperado: { ok, timestamp, variacao: { TICKER: { pct_dia: x, ... } } } if (!isset($cache['variacao']) || !is_array($cache['variacao'])) return null; if (!isset($cache['variacao'][$ticker]) || !is_array($cache['variacao'][$ticker])) return null; $v = $cache['variacao'][$ticker]['pct_dia'] ?? null; return numOrNull($v); } /* ------------------------- CACHE DIÃRIO PREVCLOSE ------------------------- */ function prevCacheLoad(string $file): array { $data = readJson($file); return is_array($data) ? $data : []; } function prevCacheSave(string $file, array $cache): void { writeJson($file, $cache); } function prevCacheGet(string $file, string $ticker): ?array { $cache = prevCacheLoad($file); $hoje = date('Y-m-d'); if (isset($cache[$hoje]) && is_array($cache[$hoje]) && isset($cache[$hoje][$ticker]) && is_array($cache[$hoje][$ticker])) { return $cache[$hoje][$ticker]; } return null; } function prevCacheSet(string $file, string $ticker, array $val): void { $cache = prevCacheLoad($file); $hoje = date('Y-m-d'); if (!isset($cache[$hoje]) || !is_array($cache[$hoje])) $cache[$hoje] = []; $cache[$hoje][$ticker] = $val + ['cached_at' => date('Y-m-d H:i:s')]; // manter só últimos 7 dias $dias = array_keys($cache); sort($dias); while (count($dias) > 7) { $d = array_shift($dias); unset($cache[$d]); } prevCacheSave($file, $cache); } /* ------------------------- PREVCLOSE PROVIDERS ------------------------- */ function obterPrevCloseTwelveData(string $symbol, string $apikey): ?array { $url = 'https://api.twelvedata.com/quote?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 12); if (!is_array($data)) return null; if (isset($data['status']) && $data['status'] === 'error') return null; if (!isset($data['previous_close']) || !is_numeric($data['previous_close'])) return null; return [ 'prev_close' => floatval($data['previous_close']), 'moeda' => isset($data['currency']) ? (string)$data['currency'] : null, 'fonte' => 'twelve' . $symbol ]; } function obterPrevCloseTwelveDataMulti(array $symbols, string $apikey): ?array { foreach ($symbols as $s) { $s = strtoupper(trim((string)$s)); if ($s === '') continue; $r = obterPrevCloseTwelveData($s, $apikey); if (is_array($r) && !empty($r['prev_close']) && floatval($r['prev_close']) > 0) return $r; } return null; } function obterPrevCloseEODHD(string $code, string $apikey): ?array { // busca 2 candles EOD e usa o anterior como prev_close $code = strtoupper(trim($code)); if ($code === '') return null; $url = 'https://eodhd.com/api/eod/' . urlencode($code) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 12); if (!is_array($data) || count($data) < 2) return null; $prev = $data[1] ?? null; // [0]=mais recente, [1]=anterior if (!is_array($prev) || !isset($prev['close']) || !is_numeric($prev['close'])) return null; return [ 'prev_close' => floatval($prev['close']), 'moeda' => null, 'fonte' => 'eodhd:' . $code ]; } function obterPrevCloseEODHDMulti(array $codes, string $apikey): ?array { foreach ($codes as $c) { $c = strtoupper(trim((string)$c)); if ($c === '') continue; $r = obterPrevCloseEODHD($c, $apikey); if (is_array($r) && !empty($r['prev_close']) && floatval($r['prev_close']) > 0) return $r; } return null; } function obterPrevCloseStooq(string $symbol): ?array { // CSV diário: Date,Open,High,Low,Close,Volume $symbol = strtolower(trim($symbol)); if ($symbol === '') return null; $url = 'https://stooq.com/q/d/l/?s=' . urlencode($symbol) . '&i=d'; $csv = @file_get_contents($url); if ($csv === false || trim($csv) === '') return null; $linhas = explode("\n", trim($csv)); if (count($linhas) < 3) return null; // header + pelo menos 2 dias $penultima = str_getcsv(trim($linhas[count($linhas) - 2])); if (count($penultima) < 5 || !is_numeric($penultima[4])) return null; return [ 'prev_close' => floatval($penultima[4]), 'moeda' => null, 'fonte' => 'stooq:' . $symbol ]; } function obterPrevCloseStooqMulti(array $symbols): ?array { foreach ($symbols as $s) { $s = strtolower(trim((string)$s)); if ($s === '') continue; $r = obterPrevCloseStooq($s); if (is_array($r) && !empty($r['prev_close']) && floatval($r['prev_close']) > 0) return $r; } return null; } /* ------------------------- 0) CACHE CURTO FINAL ------------------------- */ if (!$force && $OUT_TTL > 0 && file_exists($outCacheFile)) { $cache = readJson($outCacheFile); if (is_array($cache) && isset($cache['timestamp'])) { $ts = strtotime((string)$cache['timestamp']); if ($ts !== false && (time() - $ts) >= 0 && (time() - $ts) < $OUT_TTL) { responder($cache); } } } /* ------------------------- 1) LER PREÇOS ATUAIS ------------------------- */ $dados = readJson($precosFile); if (!is_array($dados)) { responder(['ok' => false, 'error' => 'precos-atuais.json não encontrado ou inválido'], 404); } $precos = (isset($dados['precos']) && is_array($dados['precos'])) ? $dados['precos'] : []; $cacheAnterior = readJson($outCacheFile); if (!is_array($cacheAnterior)) $cacheAnterior = []; $timestamp = date('Y-m-d H:i:s'); /* Mapa: ações -> TwelveData | ETFs -> Stooq (principal) + EODHD (fallback) Nota: Stooq symbols confirmados (exemplos): eunl.de, exxt.de, vusa.de [web sources fora deste ficheiro] */ $map = [ // AÇÕES 'AAPL' => ['tipo' => 'acao', 'twelvedata' => ['AAPL']], 'NVDA' => ['tipo' => 'acao', 'twelvedata' => ['NVDA']], 'GOOGL' => ['tipo' => 'acao', 'twelvedata' => ['GOOGL']], // METALS (EUR) – Ouro // Nota: o ticker interno do projeto é "XAUEUR" (key no precos-atuais.json), // mas o símbolo no TwelveData é "XAU/EUR". 'XAUEUR' => ['tipo' => 'acao', 'twelvedata' => ['XAU/EUR']], // ETFs (EUR) 'IWDA' => [ 'tipo' => 'etf', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'] ], 'NDXEX' => [ 'tipo' => 'etf', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'] ], 'VUSA' => [ 'tipo' => 'etf', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'] ], ]; $out = [ 'ok' => true, 'timestamp' => $timestamp, 'variacao' => [] ]; foreach ($precos as $ticker => $info) { if (!is_array($info)) continue; $preco = numOrNull($info['preco'] ?? null); $moeda = isset($info['moeda']) ? (string)$info['moeda'] : null; if ($preco === null || $preco <= 0) continue; // 1) Preferir % já vinda do preço (se existir) $pctDia = numOrNull($info['pct_dia'] ?? ($info['pct'] ?? null)); $prevClose = null; $fontePrev = null; // 2) Se não houver, tentar prev_close no próprio JSON if ($pctDia === null) { $prevCloseLocal = numOrNull($info['prev_close'] ?? ($info['prevclose'] ?? null)); if ($prevCloseLocal !== null && $prevCloseLocal > 0) { $prevClose = $prevCloseLocal; $fontePrev = 'precos-atuais.json'; } } // 3) Se ainda não houver, ir buscar prevclose (com cache diário) if ($pctDia === null && ($prevClose === null || $prevClose <= 0)) { $cached = prevCacheGet($prevCacheFile, $ticker); if (!$force && is_array($cached) && !empty($cached['prev_close']) && floatval($cached['prev_close']) > 0) { $prevClose = floatval($cached['prev_close']); $fontePrev = $cached['fonte'] ?? 'cache'; } else { $conf = $map[$ticker] ?? null; $prevInfo = null; // Ações: Twelve Data if ($conf && ($conf['tipo'] ?? '') === 'acao') { $prevInfo = obterPrevCloseTwelveDataMulti($conf['twelvedata'] ?? [$ticker], $APIKEY_TWELVEDATA); } // ETFs: Stooq principal if (!$prevInfo && $conf && ($conf['tipo'] ?? '') === 'etf') { $prevInfo = obterPrevCloseStooqMulti($conf['stooq'] ?? []); } // ETFs: fallback EODHD if (!$prevInfo && $conf && ($conf['tipo'] ?? '') === 'etf') { $prevInfo = obterPrevCloseEODHDMulti($conf['eodhd'] ?? [], $APIKEY_EODHD); } if ($prevInfo && !empty($prevInfo['prev_close']) && floatval($prevInfo['prev_close']) > 0) { $prevClose = floatval($prevInfo['prev_close']); $fontePrev = $prevInfo['fonte'] ?? null; prevCacheSet($prevCacheFile, $ticker, [ 'prev_close' => $prevClose, 'fonte' => $fontePrev, 'moeda' => $prevInfo['moeda'] ?? null ]); } } } // 4) Calcular % dia se já tiver prevclose if ($pctDia === null && $prevClose !== null && $prevClose > 0) { $pctDia = (($preco - $prevClose) / $prevClose) * 100.0; } // 5) Se ainda não houver, usar último valor válido para evitar '-' / null if ($pctDia === null) { $pctDia = lastKnownPct($cacheAnterior, $ticker); } // 6) Último fallback: 0 if ($pctDia === null) $pctDia = 0.0; $out['variacao'][$ticker] = [ 'ticker' => $ticker, 'moeda' => $moeda, 'preco' => $preco, 'pct_dia' => round($pctDia, 4), 'prev_close' => ($prevClose !== null ? round($prevClose, 6) : null), 'fonte_preco' => $info['fonte'] ?? null, 'fonte_prevclose' => $fontePrev, 'ts_preco' => $info['timestamp'] ?? null ]; } writeJson($outCacheFile, $out); responder($out); ======================================================================================== FICHEIRO: api/perplexity.php Tamanho: 7835 bytes ======================================================================================== false, 'http_code' => null, 'curl_error' => null, 'api_key_set' => ($apiKey !== ''), 'raw' => null, 'parsed_content' => null, ]; if ($apiKey === '' || $query === '') return null; $url = 'https://api.perplexity.ai/chat/completions'; // Prompt ultra restritivo para facilitar parsing $prompt = "Given this asset description: \"{$query}\", " . "return ONLY ONE number: the latest market price in {$moeda}. " . "Use dot as decimal separator. No symbols, no text, no explanation."; $payload = [ 'model' => 'sonar-pro', 'messages' => [ ['role' => 'system', 'content' => 'Return only the requested numeric value.'], ['role' => 'user', 'content' => $prompt], ], 'max_tokens' => 30, 'temperature' => 0.0, ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 25, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey, ], CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), ]); $resp = curl_exec($ch); $err = curl_error($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $debugOut['http_code'] = $code; $debugOut['curl_error'] = $err ?: null; $debugOut['raw'] = is_string($resp) ? $resp : null; if ($err) return null; if ($code < 200 || $code >= 300) return null; if (!is_string($resp) || trim($resp) === '') return null; $data = json_decode($resp, true); if (!is_array($data)) return null; $content = $data['choices'][0]['message']['content'] ?? null; if (!is_string($content) || trim($content) === '') return null; $debugOut['parsed_content'] = $content; $debugOut['ok_http'] = true; // Extrair primeiro número $clean = trim(str_replace(',', '.', $content)); if (preg_match('/[-+]?[0-9]*\\.?[0-9]+/', $clean, $m)) { $v = (float)$m[0]; if (is_finite($v) && $v > 0) return $v; } return null; } /** * Obter taxa de câmbio EUR/USD via Perplexity API * Usa a constante PPLX_API_KEY definida no início do ficheiro */ function obterTaxaCambioPerplexity(string $query, &$debug = null): ?float { // Usar a constante já definida $apiKey = pplx_api_key(); if ($apiKey === '') { $debug = ['erro' => 'PPLXAPIKEY em falta (env do PHP-FPM)']; return null; } $prompt = "Given this forex description: \"{$query}\", " . "return ONLY ONE number: the current EUR/USD exchange rate with 4 decimals " . "(for example: 1.0534). Use dot as decimal separator. " . "No symbols, no text, no explanation."; $postData = [ 'model' => 'sonar', 'messages' => [ [ 'role' => 'system', 'content' => 'Return only the requested numeric value.' ], [ 'role' => 'user', 'content' => $prompt ] ], 'temperature' => 0.1, 'max_tokens' => 20 ]; $ch = curl_init('https://api.perplexity.ai/chat/completions'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey ], CURLOPT_POSTFIELDS => json_encode($postData), CURLOPT_TIMEOUT => 15, CURLOPT_SSL_VERIFYPEER => true ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); curl_close($ch); if ($httpCode !== 200) { $debug = [ 'erro' => 'HTTP ' . $httpCode, 'curl_error' => $curlError, 'api_key_prefix' => substr($apiKey, 0, 15) . '...' ]; return null; } if (!$response) { $debug = ['erro' => 'Resposta vazia', 'curl_error' => $curlError]; return null; } $data = json_decode($response, true); if (!isset($data['choices'][0]['message']['content'])) { $debug = ['erro' => 'Resposta inválida da API', 'response' => $data]; return null; } $content = trim($data['choices'][0]['message']['content']); // Extrair número (suporta formatos: 1.0534, "1.0534", "The rate is 1.0534") if (preg_match('/(\d+\.\d{2,4})/', $content, $matches)) { $taxa = floatval($matches[1]); // Validação EUR/USD razoável (entre 0.85 e 1.30) if ($taxa >= 0.85 && $taxa <= 1.30) { $debug = [ 'success' => true, 'content' => $content, 'taxa' => $taxa, 'model' => 'sonar' ]; return round($taxa, 4); } else { $debug = [ 'erro' => 'Taxa fora do intervalo válido (0.85-1.30)', 'taxa_recebida' => $taxa, 'content' => $content ]; return null; } } $debug = [ 'erro' => 'Não foi possível extrair número da resposta', 'content' => $content ]; return null; } /** * Obter previous close de ativo via Perplexity * * @param string $query Query (ex: "AAPL previous close price") * @param string $moeda Moeda esperada (EUR ou USD) * @return float|null Previous close ou null */ function obterPrevClosePerplexity(string $query, string $moeda = ''): ?float { $apiKey = pplx_api_key(); if (!$apiKey) return null; $prompt = "Given this asset description: \"{$query}\", " . "return ONLY ONE number: the previous day closing price in {$moeda}. " . "Use dot as decimal separator. No symbols, no text, no explanation."; $postData = [ 'model' => 'sonar', 'messages' => [ [ 'role' => 'system', 'content' => 'Return only the requested numeric value.' ], [ 'role' => 'user', 'content' => $prompt ] ], 'temperature' => 0.1, 'max_tokens' => 50 ]; $ch = curl_init('https://api.perplexity.ai/chat/completions'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey ], CURLOPT_POSTFIELDS => json_encode($postData), CURLOPT_TIMEOUT => 15 ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200 || !$response) { return null; } $data = json_decode($response, true); if (!isset($data['choices'][0]['message']['content'])) { return null; } $content = trim($data['choices'][0]['message']['content']); // Extrair número if (preg_match('/(\d+[\.,]\d+)/', $content, $matches)) { $price = floatval(str_replace(',', '.', $matches[1])); if ($price > 0) { return round($price, 6); } } return null; } ======================================================================================== FICHEIRO: api/simbolos.php Tamanho: 13712 bytes ======================================================================================== metadados // - "interno": usado em cálculos, JSON de preços e normalizações // - "json": chave dentro de dadoscsvprecos-atuais.json (normalmente igual ao interno) // - "tabela": símbolo com prefixo de bolsa usado nas tabelas (frontend / histórico) // - "aliases": maneiras alternativas de escrever o mesmo ativo (Revolut, CSV, etc.) // - "nome": nome mais usado / amigável para mostrar na UI const MAPA_SIMBOLOS = [ // ------------- CORE / AÇÕES US ------------- 'AAPL' => [ 'nome' => 'Apple', 'json' => 'AAPL', 'tabela' => 'Apple', 'aliases' => ['AAPL', 'NASDAQ:AAPL', 'Apple'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['aapl.us'], 'twelve' => ['AAPL'], 'manual' => 0, ], 'NVDA' => [ 'nome' => 'NVIDIA', 'json' => 'NVDA', 'tabela' => 'NVIDIA', 'aliases' => ['NVDA', 'NASDAQ:NVDA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nvda.us'], 'twelve' => ['NVDA'], 'manual' => 0, ], 'GOOGL' => [ 'nome' => 'Google', 'json' => 'GOOGL', 'tabela' => 'Google', 'aliases' => ['GOOGL', 'NASDAQ:GOOGL', 'GOOG', 'NASDAQ:GOOG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['googl.us'], 'twelve' => ['GOOGL'], 'manual' => 0, ], 'AMZN' => [ 'nome' => 'Amazon', 'json' => 'AMZN', 'tabela' => 'Amazon', 'aliases' => ['AMZN', 'NASDAQ:AMZN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amzn.us'], 'twelve' => ['AMZN'], 'manual' => 0, ], 'ADBE' => [ 'nome' => 'Adobe', 'json' => 'ADBE', 'tabela' => 'Adobe', 'aliases' => ['ADBE', 'NASDAQ:ADBE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['adbe.us'], 'twelve' => ['ADBE'], 'manual' => 0, ], 'TSLA' => [ 'nome' => 'Tesla', 'json' => 'TSLA', 'tabela' => 'Tesla', 'aliases' => ['TSLA', 'NASDAQ:TSLA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsla.us'], 'twelve' => ['TSLA'], 'manual' => 0, ], 'MSFT' => [ 'nome' => 'Microsoft', 'json' => 'MSFT', 'tabela' => 'Microsoft', 'aliases' => ['MSFT', 'NASDAQ:MSFT'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['msft.us'], 'twelve' => ['MSFT'], 'manual' => 0, ], 'NFLX' => [ 'nome' => 'Netflix', 'json' => 'NFLX', 'tabela' => 'Netflix', 'aliases' => ['NFLX', 'NASDAQ:NFLX'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nflx.us'], 'twelve' => ['NFLX'], 'manual' => 0, ], 'AMD' => [ 'nome' => 'Advanced Micro Devices', 'json' => 'AMD', 'tabela' => 'Advanced Micro Devices', 'aliases' => ['AMD', 'NASDAQ:AMD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amd.us'], 'twelve' => ['AMD'], 'manual' => 0, ], 'ZM' => [ 'nome' => 'Zoom Video', 'json' => 'ZM', 'tabela' => 'Zoom Video', 'aliases' => ['ZM', 'NASDAQ:ZM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['zm.us'], 'twelve' => ['ZM'], 'manual' => 0, ], 'Z' => [ 'nome' => 'Zillow', 'json' => 'Z', 'tabela' => 'Zillow', 'aliases' => ['Z', 'NASDAQ:Z'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['z.us'], 'twelve' => ['Z'], 'manual' => 0, ], 'MRNA' => [ 'nome' => 'Moderna', 'json' => 'MRNA', 'tabela' => 'Moderna', 'aliases' => ['MRNA', 'NASDAQ:MRNA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mrna.us'], 'twelve' => ['MRNA'], 'manual' => 0, ], 'PLUG' => [ 'nome' => 'Plug Power', 'json' => 'PLUG', 'tabela' => 'Plug Power', 'aliases' => ['PLUG', 'NASDAQ:PLUG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['plug.us'], 'twelve' => ['PLUG'], 'manual' => 0, ], 'PYPL' => [ 'nome' => 'PayPal', 'json' => 'PYPL', 'tabela' => 'PayPal', 'aliases' => ['PYPL', 'NASDAQ:PYPL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['pypl.us'], 'twelve' => ['PYPL'], 'manual' => 0, ], 'ANSS' => [ 'nome' => 'ANSYS', 'json' => 'ANSS', 'tabela' => 'ANSYS', 'aliases' => ['ANSS', 'NASDAQ:ANSS'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['anss.us'], 'twelve' => ['ANSS'], 'manual' => 0, ], 'QCOM' => [ 'nome' => 'Qualcomm', 'json' => 'QCOM', 'tabela' => 'Qualcomm', 'aliases' => ['QCOM', 'NASDAQ:QCOM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['qcom.us'], 'twelve' => ['QCOM'], 'manual' => 0, ], 'UAL' => [ 'nome' => 'United Airlines', 'json' => 'UAL', 'tabela' => 'United Airlines', 'aliases' => ['UAL', 'NASDAQ:UAL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ual.us'], 'twelve' => ['UAL'], 'manual' => 0, ], // ------------- FINANCE / PAYMENT ------------- 'MA' => [ 'nome' => 'Mastercard', 'json' => 'MA', 'tabela' => 'Mastercard', 'aliases' => ['MA', 'NYSE:MA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ma.us'], 'twelve' => ['MA'], 'manual' => 0, ], 'SQ' => [ 'nome' => 'Square', 'json' => 'SQ', 'tabela' => 'Square', 'aliases' => ['SQ', 'NYSE:SQ'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['sq.us'], 'twelve' => ['SQ'], 'manual' => 0, ], 'BAC' => [ 'nome' => 'Bank of America', 'json' => 'BAC', 'tabela' => 'Bank of America', 'aliases' => ['BAC', 'NYSE:BAC'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['bac.us'], 'twelve' => ['BAC'], 'manual' => 0, ], 'TSM' => [ 'nome' => 'Taiwan Semiconductor', 'json' => 'TSM', 'tabela' => 'Taiwan Semiconductor', 'aliases' => ['TSM', 'NYSE:TSM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsm.us'], 'twelve' => ['TSM'], 'manual' => 0, ], 'BABA' => [ 'nome' => 'Alibaba Group', 'json' => 'BABA', 'tabela' => 'Alibaba Group', 'aliases' => ['BABA', 'NYSE:BABA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['baba.us'], 'twelve' => ['BABA'], 'manual' => 0, ], 'BRKB' => [ 'nome' => 'Berkshire Hathaway', 'json' => 'BRKB', 'tabela' => 'Berkshire Hathaway', 'aliases' => ['BRKB', 'BRK.B', 'NYSE:BRK.B'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['brk-b.us'], 'twelve' => ['BRK.B', 'BRKB'], 'manual' => 0, ], // ------------- CONSUMO / OUTROS ------------- 'MCD' => [ 'nome' => 'McDonald\'s', 'json' => 'MCD', 'tabela' => 'McDonald\'s', 'aliases' => ['MCD', 'NYSE:MCD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mcd.us'], 'twelve' => ['MCD'], 'manual' => 0, ], 'KO' => [ 'nome' => 'Coca-Cola', 'json' => 'KO', 'tabela' => 'Coca-Cola', 'aliases' => ['KO', 'NYSE:KO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ko.us'], 'twelve' => ['KO'], 'manual' => 0, ], 'SPCE' => [ 'nome' => 'Virgin Galactic', 'json' => 'SPCE', 'tabela' => 'Virgin Galactic', 'aliases' => ['SPCE', 'NYSE:SPCE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['spce.us'], 'twelve' => ['SPCE'], 'manual' => 0, ], 'O' => [ 'nome' => 'Realty Income', 'json' => 'O', 'tabela' => 'Realty Income', 'aliases' => ['O', 'NYSE:O'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['o.us'], 'twelve' => ['O'], 'manual' => 0, ], 'TWTR' => [ 'nome' => 'Twitter', 'json' => 'TWTR', 'tabela' => 'Twitter', 'aliases' => ['TWTR', 'NYSE:TWTR'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['twtr.us'], 'twelve' => ['TWTR'], 'manual' => 0, ], 'NIO' => [ 'nome' => 'NIO', 'json' => 'NIO', 'tabela' => 'NIO', 'aliases' => ['NIO', 'NYSE:NIO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nio.us'], 'twelve' => ['NIO'], 'manual' => 0, ], 'RIVN' => [ 'nome' => 'Rivian', 'json' => 'RIVN', 'tabela' => 'Rivian', 'aliases' => ['RIVN', 'NASDAQ:RIVN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['rivn.us'], 'twelve' => ['RIVN'], 'manual' => 0, ], 'XYZ' => [ 'nome' => 'XYZ', 'json' => 'XYZ', 'tabela' => 'XYZ', 'aliases' => ['XYZ'], // placeholder sem providers ], // ------------- ETFs / RIVN / VUSA / XYZ e OURO ------------- 'VUSA' => [ 'nome' => 'VUSA - Vanguard S&P 500 Dist ETF (Revolut)', 'json' => 'VUSA', 'tabela' => 'VUSA S&P 500', 'aliases' => ['VUSA', 'LSE:VUSA', 'AMS:VUSA', 'VUSA.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'], 'perplexityquery' => 'Current price Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'perplexityclosequery' => 'Previous close Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'manual' => 0, ], 'IWDA' => [ 'nome' => 'IWDA - iShares Core MSCI World Acc ETF (Revolut)', 'json' => 'IWDA', 'tabela' => 'EUNL MSCI World', 'aliases' => ['IWDA', 'EUNL', 'AMS:IWDA', 'EUNL.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'], 'perplexityquery' => 'Current price EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'perplexityclosequery' => 'Previous close EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'manual' => 0, ], 'NDXEX' => [ 'nome' => 'NDXEX - iShares Nasdaq 100 UCITS ETF (Dist) (Revolut)', 'json' => 'NDXEX', 'tabela' => 'EXXT Nasdaq-100', 'aliases' => ['NDXEX', 'NDX', 'INDEXNASDAQ:NDX', 'EXXT', 'EQQQ', 'EXXT.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'], 'perplexityquery' => 'Current price iShares NASDAQ-100 UCITS ETF (DE) (EXXT.DE) (yahoo)', 'perplexityclosequery' => 'Previous close EXXT.DE iShares NASDAQ-100 UCITS ETF (DE) EUR (yahoo)', 'manual' => 0, ], 'XAUEUR' => [ 'nome' => 'Ouro (XAU/EUR)', 'json' => 'XAUEUR', 'tabela' => 'Ouro', 'moeda' => 'EUR', 'aliases' => ['XAUEUR', 'XAU/EUR', 'XAU EUR', 'OURO', 'GOLD','XAUEUR','XAU'], 'tipo' => 'ouro', 'stooq' => ['xaueur'], 'twelve' => ['XAU/EUR'], 'perplexityquery' => 'Current price, GOLD XAU/EUR', 'perplexityclosequery' => 'Previous close price for GOLD XAU/EUR', 'manual' => 0, ], ]; // Função genérica: dado um ticker qualquer (Revolut, CSV, etc.), devolve o ticker interno function normalizarTickerGlobal(string $raw): ?string { $n = strtoupper(trim($raw)); if ($n === '') { return null; } // 1) Remover prefixos de bolsa mais comuns $n = preg_replace('/^(NASDAQ|NYSE|AMS|INDEXNASDAQ|XETRA|LSE):?/', '', $n); // 2) BRK.B -> BRKB (remover pontos) $n = str_replace('.', '', $n); // 3) Remover qualquer coisa que não seja A–Z ou 0–9 $n = preg_replace('/[^A-Z0-9]/', '', $n); // 4) Procurar primeiro por match direto de interno if (isset(MAPA_SIMBOLOS[$n])) { return $n; } // 5) Procurar nos aliases foreach (MAPA_SIMBOLOS as $interno => $info) { if (!empty($info['aliases']) && in_array($n, $info['aliases'], true)) { return $interno; } } // 6) Fallback: devolve o limpo (permite lidar com ativos novos ainda não registados) return $n; } $simbolos = MAPA_SIMBOLOS; // Se este ficheiro foi chamado diretamente (não via include), enviar JSON if (realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME'] ?? '')) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(MAPA_SIMBOLOS, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } ======================================================================================== FICHEIRO: api/transacoesvistos.php Tamanho: 4202 bytes ======================================================================================== devolve transacoes-vistos.json do utilizador * POST -> marca/desmarca um visto por (tipo, id) * * Estrutura esperada (compatível com vistoCheck no verificador): * { * "versao": "1.0", * "ultimaAtualizacao": "YYYY-MM-DD HH:MM:SS", * "vistos": { * "alterarlinha": { "L:12": true }, * "adicionartransacao": {}, * "removertransacao": {} * } * } */ // Se este ficheiro estiver em /api/, o apiutilizador.php está 1 nível acima. $bootstrap = __DIR__ . '/../api/utilizador.php'; // Fallback: caso este ficheiro esteja na raiz (sem pasta api) if (!is_file($bootstrap)) $bootstrap = __DIR__ . '/api/utilizador.php'; require_once $bootstrap; function readJsonFile(string $path): array { if (!is_file($path)) return []; $raw = @file_get_contents($path); if (!is_string($raw) || trim($raw) === '') return []; $j = json_decode($raw, true); return is_array($j) ? $j : []; } function writeJsonFile(string $path, array $data): bool { $dir = dirname($path); if (!is_dir($dir)) @mkdir($dir, 0775, true); $raw = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($raw)) return false; return @file_put_contents($path, $raw, LOCK_EX) !== false; } function ensureSchema(array $j): array { if (!isset($j['versao'])) $j['versao'] = '1.0'; if (!isset($j['vistos']) || !is_array($j['vistos'])) $j['vistos'] = []; foreach (['alterarlinha', 'adicionartransacao', 'removertransacao'] as $t) { if (!isset($j['vistos'][$t]) || !is_array($j['vistos'][$t])) { $j['vistos'][$t] = []; } } if (!isset($j['ultimaAtualizacao'])) $j['ultimaAtualizacao'] = date('Y-m-d H:i:s'); return $j; } $ficheiro = userFilePath('transacoes-vistos.json'); if ($_SERVER['REQUEST_METHOD'] === 'GET') { $j = ensureSchema(readJsonFile($ficheiro)); echo json_encode($j, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $raw = file_get_contents('php://input'); $input = json_decode((string)$raw, true); if (!is_array($input)) { echo json_encode(['ok' => false, 'error' => 'JSON inválido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // Novo formato: tipo + id $tipo = isset($input['tipo']) ? trim((string)$input['tipo']) : ''; $id = isset($input['id']) ? trim((string)$input['id']) : ''; // Compatibilidade mínima com chamadas antigas: {linha:"L:12"} ou {linha:"12"} if (($tipo === '' || $id === '') && isset($input['linha'])) { $tipo = $tipo !== '' ? $tipo : 'alterarlinha'; $linha = trim((string)$input['linha']); if ($linha !== '') { $id = (strpos($linha, 'L:') === 0) ? $linha : ('L:' . $linha); } } if (!in_array($tipo, ['alterarlinha', 'adicionartransacao', 'removertransacao'], true)) { echo json_encode(['ok' => false, 'error' => 'Tipo inválido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if ($id === '') { echo json_encode(['ok' => false, 'error' => 'ID não fornecido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } $marcar = true; if (isset($input['ok'])) $marcar = (bool)$input['ok']; if (isset($input['marcar'])) $marcar = (bool)$input['marcar']; // alias $j = ensureSchema(readJsonFile($ficheiro)); if ($marcar) { $j['vistos'][$tipo][$id] = true; } else { if (isset($j['vistos'][$tipo][$id])) unset($j['vistos'][$tipo][$id]); } $j['ultimaAtualizacao'] = date('Y-m-d H:i:s'); $ok = writeJsonFile($ficheiro, $j); echo json_encode([ 'ok' => $ok, 'tipo' => $tipo, 'id' => $id, 'marcar' => $marcar, 'user' => getUserId(), 'ficheiro' => basename($ficheiro) ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } echo json_encode(['ok' => false, 'error' => 'Método não suportado'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; ======================================================================================== FICHEIRO: api/uploadacoes.php Tamanho: 1600 bytes ======================================================================================== false, 'error' => 'CSV vazio.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } // Validação leve: garantir que parece um CSV de transações if (stripos($csv, 'Ordem,') !== 0) { echo json_encode(['ok' => false, 'error' => 'Cabeçalho CSV inválido (esperado começar por "Ordem,").'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $ficheiro = userFilePath('transacoes-acoes.csv'); $dir = dirname($ficheiro); if (!is_dir($dir) && !@mkdir($dir, 0775, true)) { echo json_encode(['ok' => false, 'error' => 'Falha ao criar diretório do utilizador.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0775, true); } // Backup do ficheiro anterior (se existir) if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/transacoes-acoes-' . date('YmdHis') . '.csv'); } $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { echo json_encode(['ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode(['ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId()], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: api/uploadcaixa.php Tamanho: 2578 bytes ======================================================================================== false, 'error' => 'CSV vazio.']); } // Validação leve: cabeçalho esperado para movimentos-caixa if (stripos($csv, "Ordem,Data,Tipo,Valor,Moeda,Descricao") !== 0) { responder([ 'ok' => false, 'error' => 'Cabeçalho CSV inválido (caixa). Esperado: Ordem,Data,Tipo,Valor,Moeda,Descricao,...' ]); } $user = function_exists('getUserId') ? getUserId() : null; // ✅ ficheiro correto $ficheiro = userFilePath('movimentos-caixa.csv'); $dir = dirname($ficheiro); // Garantir pasta do utilizador if (!is_dir($dir)) { if (!@mkdir($dir, 0775, true)) { $e = error_get_last(); responder([ 'ok' => false, 'error' => 'Falha ao criar diretório do utilizador.', 'dir' => $dir, 'detalhe' => $e['message'] ?? null, 'user' => $user ]); } } // Backups $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0777, true); } // Diagnóstico de permissões clearstatcache(true, $dir); clearstatcache(true, $ficheiro); $diag = [ 'dir' => $dir, 'dir_existe' => is_dir($dir), 'dir_writable' => is_writable($dir), 'ficheiro' => $ficheiro, 'ficheiro_existe' => is_file($ficheiro), 'ficheiro_writable' => is_file($ficheiro) ? is_writable($ficheiro) : null, 'php_user' => function_exists('get_current_user') ? get_current_user() : null, ]; // Backup do ficheiro anterior se existir (não deve bloquear a gravação) if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/movimentos-caixa-' . date('YmdHis') . '.csv'); } // Gravar $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { $e = error_get_last(); responder([ 'ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.', 'detalhe' => $e['message'] ?? null, 'diag' => $diag, 'user' => $user ]); } @chmod($ficheiro, 0777); responder([ 'ok' => true, 'ficheiro' => basename($ficheiro), 'bytes' => $ok, 'diag' => $diag, 'user' => $user ]); ======================================================================================== FICHEIRO: api/uploadextratorevolut.php Tamanho: 1143 bytes ======================================================================================== false, 'error' => 'Nenhum conteúdo recebido (CSV vazio).', ]); exit; } // Caminho do ficheiro por utilizador: dados_csv//extrato-revolut.csv $ficheiro = userFilePath('extrato-revolut.csv'); $dir = dirname($ficheiro); // Garantir diretório do utilizador if (!is_dir($dir)) { mkdir($dir, 0775, true); } // Pasta de backups $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { mkdir($backupDir, 0775, true); } // Backup do ficheiro anterior (se existir) if (file_exists($ficheiro)) { @copy($ficheiro, $backupDir . '/extrato-revolut-' . date('YmdHis') . '.csv'); } // Gravar extrato atual file_put_contents($ficheiro, $csv); echo json_encode([ 'ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId(), ]); ?> ======================================================================================== FICHEIRO: api/uploadhistoricoativos.php Tamanho: 1289 bytes ======================================================================================== false, 'error' => 'CSV vazio.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $ficheiro = userFilePath('historico-ativos.csv'); $dir = dirname($ficheiro); if (!is_dir($dir) && !@mkdir($dir, 0775, true)) { echo json_encode(['ok' => false, 'error' => 'Falha ao criar diretório do utilizador.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0775, true); } if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/historico-ativos-' . date('YmdHis') . '.csv'); } $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { echo json_encode(['ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode(['ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId()], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: api/utilizador.php Tamanho: 1042 bytes ======================================================================================== / // Ex.: dados_csv/tiago/transacoes-acoes.csv, dados_csv/maria/movimentos-caixa.csv function getUserId(): string { // Aceita ?user=tiago ou ?user=maria na query string ou no corpo POST $user = $_GET['user'] ?? ($_POST['user'] ?? 'tiago'); $user = strtolower($user); // Sanitizar: apenas letras, números, _ e - $user = preg_replace('/[^a-z0-9_\-]/', '', $user); if ($user === '' || $user === null) { $user = 'tiago'; } return $user; } function getUserDataDir(): string { // Este ficheiro está em /api, por isso dirname(__DIR__) = raiz do projeto $root = dirname(__DIR__); $user = getUserId(); $dir = $root . '/dados_csv/' . $user; if (!is_dir($dir)) { @mkdir($dir, 0755, true); } return $dir; } function userFilePath(string $fileName): string { return getUserDataDir() . '/' . $fileName; } ?> ======================================================================================== FICHEIRO: api_atualizar.php Tamanho: 8599 bytes ======================================================================================== false, 'error' => $e->getMessage())); } exit; function listarFicheiros($dir) { $ficheiros = array(); $ignorar = array('atualizar.html', 'index.html', 'api_atualizar.php', 'icon.png', 'nginx.conf'); $scan = scandir($dir); foreach ($scan as $item) { if ($item === '.' || $item === '..') continue; if (is_dir($dir . '/' . $item)) continue; if (in_array($item, $ignorar)) continue; $ficheiros[] = $item; } sort($ficheiros); return json_encode(array('ok' => true, 'ficheiros' => $ficheiros, 'total' => count($ficheiros))); } function analisar($dir, $input) { if (!isset($input['descricao']) || empty($input['descricao'])) { throw new Exception('Descricao nao fornecida'); } $ficheiros = isset($input['ficheiros']) ? $input['ficheiros'] : array(); if (empty($ficheiros)) { throw new Exception('Nenhum ficheiro selecionado'); } $log = array('ANALISE DO SITE', '', 'PROBLEMA:', $input['descricao'], '', 'FICHEIROS (' . count($ficheiros) . '):'); $conteudos = array(); $encontrados = 0; foreach ($ficheiros as $ficheiro) { $caminho = $dir . '/' . $ficheiro; if (!file_exists($caminho)) { $log[] = '- ' . $ficheiro . ' NAO ENCONTRADO'; continue; } $tamanho = filesize($caminho); $log[] = '- ' . $ficheiro . ' (' . number_format($tamanho) . ' bytes)'; $conteudos[$ficheiro] = file_get_contents($caminho, false, null, 0, 51200); $encontrados++; } if ($encontrados === 0) { throw new Exception('Nenhum ficheiro encontrado'); } $log[] = ''; $log[] = 'Analise concluida - ' . $encontrados . ' ficheiros processados'; return json_encode(array('ok' => true, 'analise' => implode("\n", $log), 'ficheiros_analisados' => $ficheiros, 'conteudos' => $conteudos)); } function gerarPrompt($input) { if (!isset($input['analise'])) { throw new Exception('Analise nao fornecida'); } $analise = $input['analise']; $ficheiros = isset($analise['ficheiros_analisados']) ? $analise['ficheiros_analisados'] : array(); $conteudos = isset($analise['conteudos']) ? $analise['conteudos'] : array(); $prompt = array(); $prompt[] = '# CORRECAO AUTOMATICA'; $prompt[] = ''; $prompt[] = '## PROBLEMA:'; $prompt[] = $analise['analise']; $prompt[] = ''; $prompt[] = '## FICHEIROS:'; foreach ($ficheiros as $ficheiro) { if (isset($conteudos[$ficheiro])) { $prompt[] = ''; $prompt[] = '### ' . $ficheiro; $prompt[] = '--- INICIO DO CODIGO ---'; $prompt[] = $conteudos[$ficheiro]; $prompt[] = '--- FIM DO CODIGO ---'; } } $prompt[] = ''; $prompt[] = '## TAREFA:'; $prompt[] = 'Criar um script unico PHP que corrija o problema descrito acima. Para colar e executar'; return json_encode(array('ok' => true, 'prompt' => implode("\n", $prompt))); } function gerarCodigoPerplexity($input) { // Reaproveitar a lógica de gerarPrompt para construir o texto do prompt if (!isset($input['analise'])) { throw new Exception('Analise nao fornecida'); } // 1) Obter o prompt de texto já montado $jsonPrompt = json_decode(gerarPrompt($input), true); if (!$jsonPrompt || !isset($jsonPrompt['prompt'])) { throw new Exception('Falha ao gerar prompt de base'); } $promptTexto = $jsonPrompt['prompt']; // 2) CHAMAR A API DA PERPLEXITY // Troque "SUA_API_KEY_AQUI" pela sua chave real $apiKey = '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'; $url = 'https://api.perplexity.ai/chat/completions'; $payload = [ 'model' => 'sonar-reasoning-pro', 'messages' => [ [ 'role' => 'system', 'content' => 'És um assistente especializado em gerar scripts PHP de correção automática. Responde SEM explicações, apenas com o código PHP completo, pronto a ser colado e executado.' ], [ 'role' => 'user', 'content' => $promptTexto ] ], 'max_tokens' => 2000, 'temperature' => 0.2, ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey, ], CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_TIMEOUT => 60, ]); $resposta = curl_exec($ch); $erroCurl = curl_error($ch); curl_close($ch); if ($erroCurl) { throw new Exception('Erro na chamada à API Perplexity: ' . $erroCurl); } $data = json_decode($resposta, true); if (!is_array($data) || empty($data['choices'][0]['message']['content'])) { return json_encode([ 'ok' => false, 'error' => 'Resposta inesperada da API Perplexity', 'raw' => $resposta, 'prompt' => $promptTexto, ]); } $codigoGerado = $data['choices'][0]['message']['content']; return json_encode([ 'ok' => true, 'codigo' => $codigoGerado, 'prompt' => $promptTexto, 'raw' => $resposta, ]); } function executar($dir, $backupDir, $input) { if (!isset($input['codigo']) || empty($input['codigo'])) { throw new Exception('Codigo nao fornecido'); } $timestamp = date('Ymd_His'); if (!file_exists($backupDir)) { @mkdir($backupDir, 0755, true); } $backupFile = $backupDir . 'backup_' . $timestamp . '.tar.gz'; $cmd = 'cd ' . escapeshellarg($dir) . ' && tar -czf ' . escapeshellarg($backupFile) . ' *.html *.php *.csv *.json 2>&1'; @shell_exec($cmd); $tempFile = $dir . '/temp_' . $timestamp . '.php'; file_put_contents($tempFile, $input['codigo']); ob_start(); try { include $tempFile; $output = ob_get_clean(); } catch (Exception $e) { ob_end_clean(); $output = 'ERRO: ' . $e->getMessage(); } @unlink($tempFile); return json_encode(array('ok' => true, 'log' => $output ? $output : 'Executado com sucesso', 'backup' => basename($backupFile))); } function verificar($dir) { $log = array('VERIFICACAO DE INTEGRIDADE', ''); $ok = 0; $ficheirosEssenciais = array('resumo.html', 'transacoes.html', 'base-dados-dinheiro.html'); foreach ($ficheirosEssenciais as $ficheiro) { $caminho = $dir . '/' . $ficheiro; if (file_exists($caminho)) { $log[] = 'OK: ' . $ficheiro . ' (' . filesize($caminho) . ' bytes)'; $ok++; } else { $log[] = 'ERRO: ' . $ficheiro . ' - NAO ENCONTRADO'; } } $log[] = ''; $log[] = 'Total OK: ' . $ok . '/' . count($ficheirosEssenciais); return json_encode(array('ok' => true, 'relatorio' => implode("\n", $log), 'total_ok' => $ok)); } ?> ======================================================================================== FICHEIRO: atualizar.html Tamanho: 18589 bytes ======================================================================================== 🔧 Sistema de Atualização Automática

🔧 Sistema de Atualização Automática

Descreva o problema ou alteração desejada e o sistema gera um prompt otimizado para correção automática

📋 Descreva o Problema PASSO 1

Selecione ficheiros:

Carregando...

📊 Resultado da Análise

Aguardando análise...

🤖 Prompt Gerado PASSO 2

Clique em Gerar Prompt...

â„¹ï¸ Instruções

1. Copie o prompt

Use o botão acima

2. Cole no Claude/ChatGPT

A IA gera o código

3. Cole o código retornado

No próximo passo

4. Execute

⚡ Cole o Código PASSO 3

📠Log

Aguardando execução...
======================================================================================== FICHEIRO: backup_20260611_153533/ai.php Tamanho: 9544 bytes ======================================================================================== Processando ficheiro: $file_path\n"; echo " (Backup criado em: $backup_path)\n"; $content = file_get_contents($file_path); $new_content = $content; $corrections_made = 0; // ----------------------------------------------------------------- // CORREÇÕES PARA: verificar-revolut.html // ----------------------------------------------------------------- if ($file_path === 'verificar-revolut.html') { // --- CORREÇÃO 1.1: Adicionar função para formatar números --- $search1_1 = <<<'EOD' const verificarUrl = 'verificar_diferencas_revolut.php'; EOD; $replace1_1 = <<<'EOD' function formatNumber(num) { if (num === null || num === undefined) return '-'; return String(num).replace('.', ','); } const verificarUrl = 'verificar_diferencas_revolut.php'; EOD; $new_content = str_replace($search1_1, $replace1_1, $new_content, $count); if ($count > 0) { echo " [OK] Adicionada função 'formatNumber' para formatação de números.\n"; $corrections_made++; } // --- CORREÇÃO 1.2: Aplicar formatação de números na apresentação dos detalhes --- $search1_2 = <<<'EOD' // Sugestão COMPRA if (item.sugestaocompra) { html += `
✅ Sugestão Revolut (COMPRA):
  • Data: ${item.sugestaocompra.data}
  • Quantidade: ${item.sugestaocompra.quantidade}
  • Custo Total: ${item.sugestaocompra.custo} EUR
  • Taxa câmbio (FX): ${item.sugestaocompra.fx ?? '-'}
`; } // Sugestão VENDA if (item.sugestaovenda) { html += `
📊 Sugestão Revolut (VENDA):
  • Data: ${item.sugestaovenda.data}
  • Custo Total: ${item.sugestaovenda.custo} EUR
  • Taxa câmbio (FX): ${item.sugestaovenda.fx ?? '-'}
`; } EOD; $replace1_2 = <<<'EOD' // Sugestão COMPRA if (item.sugestaocompra) { html += `
✅ Sugestão Revolut (COMPRA):
  • Data: ${item.sugestaocompra.data}
  • Quantidade: ${formatNumber(item.sugestaocompra.quantidade)}
  • Custo Total: ${formatNumber(item.sugestaocompra.custo)} EUR
  • Taxa câmbio (FX): ${formatNumber(item.sugestaocompra.fx)}
`; } // Sugestão VENDA if (item.sugestaovenda) { html += `
📊 Sugestão Revolut (VENDA):
  • Data: ${item.sugestaovenda.data}
  • Custo Total: ${formatNumber(item.sugestaovenda.custo)} EUR
  • Taxa câmbio (FX): ${formatNumber(item.sugestaovenda.fx)}
`; } EOD; $new_content = str_replace($search1_2, $replace1_2, $new_content, $count); if ($count > 0) { echo " [OK] Aplicada formatação de números nas sugestões de Compra/Venda.\n"; $corrections_made++; } // --- CORREÇÃO 1.3: Corrigir lógica de atualização automática (Tx Compra/Venda) --- $search1_3 = <<<'EOD' if (itemData.sugestaocompra) { cols[1] = itemData.sugestaocompra.data; // DataCompra cols[4] = String(itemData.sugestaocompra.quantidade); // NumAcoes cols[6] = String(itemData.sugestaocompra.custo); // CustoInicial if (itemData.sugestaocompra.fx) { cols[8] = String(itemData.sugestaocompra.fx); // TaxaCompra (FX Rate) } } if (itemData.sugestaovenda) { cols[2] = itemData.sugestaovenda.data; // DataVenda cols[7] = String(itemData.sugestaovenda.custo); // CustoFinal if (itemData.sugestaovenda.fx) { cols[9] = String(itemData.sugestaovenda.fx); // TaxaVenda (FX Rate) } } EOD; $replace1_3 = <<<'EOD' if (itemData.sugestaocompra) { cols[1] = itemData.sugestaocompra.data; // DataCompra cols[4] = String(itemData.sugestaocompra.quantidade); // NumAcoes cols[6] = String(itemData.sugestaocompra.custo); // CustoInicial // Corrigido para lidar com fx ausente, nulo ou zero cols[8] = (itemData.sugestaocompra.fx !== null && itemData.sugestaocompra.fx !== undefined) ? String(itemData.sugestaocompra.fx) : ''; } if (itemData.sugestaovenda) { cols[2] = itemData.sugestaovenda.data; // DataVenda cols[7] = String(itemData.sugestaovenda.custo); // CustoFinal // Corrigido para lidar com fx ausente, nulo ou zero cols[9] = (itemData.sugestaovenda.fx !== null && itemData.sugestaovenda.fx !== undefined) ? String(itemData.sugestaovenda.fx) : ''; } EOD; $new_content = str_replace($search1_3, $replace1_3, $new_content, $count); if ($count > 0) { echo " [OK] Melhorada a lógica da correção automática para Taxa de Compra e Venda.\n"; $corrections_made++; } } // ----------------------------------------------------------------- // CORREÇÕES PARA: verificar_diferencas_revolut.php // ----------------------------------------------------------------- if ($file_path === 'verificar_diferencas_revolut.php') { // --- CORREÇÃO 2.1: Adicionar verificação de quantidade na venda --- $search2_1 = <<<'EOD' if ($vendaEncontrada) { if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} → {$vendaEncontrada['valor']}"; } } else { EOD; $replace2_1 = <<<'EOD' if ($vendaEncontrada) { if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } if (abs($vendaEncontrada['quantidade'] - $t['numAcoes']) > 0.00001) { $diferencasCount++; $detalhes[] = "Qtd Venda: {$t['numAcoes']} → {$vendaEncontrada['quantidade']}"; } if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} → {$vendaEncontrada['valor']}"; } } else { EOD; $new_content = str_replace($search2_1, $replace2_1, $new_content, $count); if ($count > 0) { echo " [OK] Adicionada verificação da quantidade (Nº Ações) para transações de Venda.\n"; $corrections_made++; } // --- CORREÇÃO 2.2: Adicionar 'quantidade' à sugestão de venda --- $search2_2 = <<<'EOD' 'sugestaovenda' => $vendaEncontrada ? [ 'data' => $vendaEncontrada['data'], 'custo' => $vendaEncontrada['valor'], 'fx' => $vendaEncontrada['fx'] ?? null, ] : null EOD; $replace2_2 = <<<'EOD' 'sugestaovenda' => $vendaEncontrada ? [ 'data' => $vendaEncontrada['data'], 'quantidade' => $vendaEncontrada['quantidade'], 'custo' => $vendaEncontrada['valor'], 'fx' => $vendaEncontrada['fx'] ?? null, ] : null EOD; $new_content = str_replace($search2_2, $replace2_2, $new_content, $count); if ($count > 0) { echo " [OK] Adicionado campo 'quantidade' na sugestão de Venda para consistência.\n"; $corrections_made++; } } // --- GRAVAR ALTERAÇÕES --- if ($corrections_made > 0) { if ($new_content !== $content) { if (file_put_contents($file_path, $new_content)) { echo " -> SUCESSO: Ficheiro '$file_path' corrigido e guardado.\n\n"; } else { echo " -> ERRO: Falha ao guardar as alterações em '$file_path'.\n\n"; } } else { echo " -> AVISO: Nenhuma alteração real foi feita, apesar das correções terem sido aplicadas (o ficheiro pode já estar corrigido).\n\n"; } } else { echo " -> AVISO: Nenhuma correção foi aplicada. O ficheiro pode já estar atualizado ou o código-fonte difere do esperado.\n\n"; } } echo "=======================================\n"; echo "## CORREÇÃO CONCLUÃDA ##\n"; ?> ======================================================================================== FICHEIRO: backup_20260611_153533/api/bootstrap/bootstrap.php Tamanho: 443 bytes ======================================================================================== file = $file; $dir = dirname($file); if (!is_dir($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } } public function info(string $msg, array $ctx = []): void { $this->write('info', $msg, $ctx); } public function error(string $msg, array $ctx = []): void { $this->write('error', $msg, $ctx); } private function write(string $level, string $msg, array $ctx): void { $row = [ 'ts' => date('Y-m-d H:i:s'), 'level' => $level, 'msg' => $msg, 'ctx' => $ctx, ]; @file_put_contents( $this->file, json_encode($row, JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND | LOCK_EX ); } } ======================================================================================== FICHEIRO: backup_20260611_153533/api/bootstrap/simbolos.php Tamanho: 13712 bytes ======================================================================================== metadados // - "interno": usado em cálculos, JSON de preços e normalizações // - "json": chave dentro de dadoscsvprecos-atuais.json (normalmente igual ao interno) // - "tabela": símbolo com prefixo de bolsa usado nas tabelas (frontend / histórico) // - "aliases": maneiras alternativas de escrever o mesmo ativo (Revolut, CSV, etc.) // - "nome": nome mais usado / amigável para mostrar na UI const MAPA_SIMBOLOS = [ // ------------- CORE / AÇÕES US ------------- 'AAPL' => [ 'nome' => 'Apple', 'json' => 'AAPL', 'tabela' => 'Apple', 'aliases' => ['AAPL', 'NASDAQ:AAPL', 'Apple'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['aapl.us'], 'twelve' => ['AAPL'], 'manual' => 0, ], 'NVDA' => [ 'nome' => 'NVIDIA', 'json' => 'NVDA', 'tabela' => 'NVIDIA', 'aliases' => ['NVDA', 'NASDAQ:NVDA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nvda.us'], 'twelve' => ['NVDA'], 'manual' => 0, ], 'GOOGL' => [ 'nome' => 'Google', 'json' => 'GOOGL', 'tabela' => 'Google', 'aliases' => ['GOOGL', 'NASDAQ:GOOGL', 'GOOG', 'NASDAQ:GOOG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['googl.us'], 'twelve' => ['GOOGL'], 'manual' => 0, ], 'AMZN' => [ 'nome' => 'Amazon', 'json' => 'AMZN', 'tabela' => 'Amazon', 'aliases' => ['AMZN', 'NASDAQ:AMZN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amzn.us'], 'twelve' => ['AMZN'], 'manual' => 0, ], 'ADBE' => [ 'nome' => 'Adobe', 'json' => 'ADBE', 'tabela' => 'Adobe', 'aliases' => ['ADBE', 'NASDAQ:ADBE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['adbe.us'], 'twelve' => ['ADBE'], 'manual' => 0, ], 'TSLA' => [ 'nome' => 'Tesla', 'json' => 'TSLA', 'tabela' => 'Tesla', 'aliases' => ['TSLA', 'NASDAQ:TSLA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsla.us'], 'twelve' => ['TSLA'], 'manual' => 0, ], 'MSFT' => [ 'nome' => 'Microsoft', 'json' => 'MSFT', 'tabela' => 'Microsoft', 'aliases' => ['MSFT', 'NASDAQ:MSFT'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['msft.us'], 'twelve' => ['MSFT'], 'manual' => 0, ], 'NFLX' => [ 'nome' => 'Netflix', 'json' => 'NFLX', 'tabela' => 'Netflix', 'aliases' => ['NFLX', 'NASDAQ:NFLX'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nflx.us'], 'twelve' => ['NFLX'], 'manual' => 0, ], 'AMD' => [ 'nome' => 'Advanced Micro Devices', 'json' => 'AMD', 'tabela' => 'Advanced Micro Devices', 'aliases' => ['AMD', 'NASDAQ:AMD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amd.us'], 'twelve' => ['AMD'], 'manual' => 0, ], 'ZM' => [ 'nome' => 'Zoom Video', 'json' => 'ZM', 'tabela' => 'Zoom Video', 'aliases' => ['ZM', 'NASDAQ:ZM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['zm.us'], 'twelve' => ['ZM'], 'manual' => 0, ], 'Z' => [ 'nome' => 'Zillow', 'json' => 'Z', 'tabela' => 'Zillow', 'aliases' => ['Z', 'NASDAQ:Z'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['z.us'], 'twelve' => ['Z'], 'manual' => 0, ], 'MRNA' => [ 'nome' => 'Moderna', 'json' => 'MRNA', 'tabela' => 'Moderna', 'aliases' => ['MRNA', 'NASDAQ:MRNA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mrna.us'], 'twelve' => ['MRNA'], 'manual' => 0, ], 'PLUG' => [ 'nome' => 'Plug Power', 'json' => 'PLUG', 'tabela' => 'Plug Power', 'aliases' => ['PLUG', 'NASDAQ:PLUG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['plug.us'], 'twelve' => ['PLUG'], 'manual' => 0, ], 'PYPL' => [ 'nome' => 'PayPal', 'json' => 'PYPL', 'tabela' => 'PayPal', 'aliases' => ['PYPL', 'NASDAQ:PYPL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['pypl.us'], 'twelve' => ['PYPL'], 'manual' => 0, ], 'ANSS' => [ 'nome' => 'ANSYS', 'json' => 'ANSS', 'tabela' => 'ANSYS', 'aliases' => ['ANSS', 'NASDAQ:ANSS'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['anss.us'], 'twelve' => ['ANSS'], 'manual' => 0, ], 'QCOM' => [ 'nome' => 'Qualcomm', 'json' => 'QCOM', 'tabela' => 'Qualcomm', 'aliases' => ['QCOM', 'NASDAQ:QCOM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['qcom.us'], 'twelve' => ['QCOM'], 'manual' => 0, ], 'UAL' => [ 'nome' => 'United Airlines', 'json' => 'UAL', 'tabela' => 'United Airlines', 'aliases' => ['UAL', 'NASDAQ:UAL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ual.us'], 'twelve' => ['UAL'], 'manual' => 0, ], // ------------- FINANCE / PAYMENT ------------- 'MA' => [ 'nome' => 'Mastercard', 'json' => 'MA', 'tabela' => 'Mastercard', 'aliases' => ['MA', 'NYSE:MA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ma.us'], 'twelve' => ['MA'], 'manual' => 0, ], 'SQ' => [ 'nome' => 'Square', 'json' => 'SQ', 'tabela' => 'Square', 'aliases' => ['SQ', 'NYSE:SQ'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['sq.us'], 'twelve' => ['SQ'], 'manual' => 0, ], 'BAC' => [ 'nome' => 'Bank of America', 'json' => 'BAC', 'tabela' => 'Bank of America', 'aliases' => ['BAC', 'NYSE:BAC'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['bac.us'], 'twelve' => ['BAC'], 'manual' => 0, ], 'TSM' => [ 'nome' => 'Taiwan Semiconductor', 'json' => 'TSM', 'tabela' => 'Taiwan Semiconductor', 'aliases' => ['TSM', 'NYSE:TSM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsm.us'], 'twelve' => ['TSM'], 'manual' => 0, ], 'BABA' => [ 'nome' => 'Alibaba Group', 'json' => 'BABA', 'tabela' => 'Alibaba Group', 'aliases' => ['BABA', 'NYSE:BABA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['baba.us'], 'twelve' => ['BABA'], 'manual' => 0, ], 'BRKB' => [ 'nome' => 'Berkshire Hathaway', 'json' => 'BRKB', 'tabela' => 'Berkshire Hathaway', 'aliases' => ['BRKB', 'BRK.B', 'NYSE:BRK.B'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['brk-b.us'], 'twelve' => ['BRK.B', 'BRKB'], 'manual' => 0, ], // ------------- CONSUMO / OUTROS ------------- 'MCD' => [ 'nome' => 'McDonald\'s', 'json' => 'MCD', 'tabela' => 'McDonald\'s', 'aliases' => ['MCD', 'NYSE:MCD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mcd.us'], 'twelve' => ['MCD'], 'manual' => 0, ], 'KO' => [ 'nome' => 'Coca-Cola', 'json' => 'KO', 'tabela' => 'Coca-Cola', 'aliases' => ['KO', 'NYSE:KO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ko.us'], 'twelve' => ['KO'], 'manual' => 0, ], 'SPCE' => [ 'nome' => 'Virgin Galactic', 'json' => 'SPCE', 'tabela' => 'Virgin Galactic', 'aliases' => ['SPCE', 'NYSE:SPCE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['spce.us'], 'twelve' => ['SPCE'], 'manual' => 0, ], 'O' => [ 'nome' => 'Realty Income', 'json' => 'O', 'tabela' => 'Realty Income', 'aliases' => ['O', 'NYSE:O'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['o.us'], 'twelve' => ['O'], 'manual' => 0, ], 'TWTR' => [ 'nome' => 'Twitter', 'json' => 'TWTR', 'tabela' => 'Twitter', 'aliases' => ['TWTR', 'NYSE:TWTR'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['twtr.us'], 'twelve' => ['TWTR'], 'manual' => 0, ], 'NIO' => [ 'nome' => 'NIO', 'json' => 'NIO', 'tabela' => 'NIO', 'aliases' => ['NIO', 'NYSE:NIO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nio.us'], 'twelve' => ['NIO'], 'manual' => 0, ], 'RIVN' => [ 'nome' => 'Rivian', 'json' => 'RIVN', 'tabela' => 'Rivian', 'aliases' => ['RIVN', 'NASDAQ:RIVN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['rivn.us'], 'twelve' => ['RIVN'], 'manual' => 0, ], 'XYZ' => [ 'nome' => 'XYZ', 'json' => 'XYZ', 'tabela' => 'XYZ', 'aliases' => ['XYZ'], // placeholder sem providers ], // ------------- ETFs / RIVN / VUSA / XYZ e OURO ------------- 'VUSA' => [ 'nome' => 'VUSA - Vanguard S&P 500 Dist ETF (Revolut)', 'json' => 'VUSA', 'tabela' => 'VUSA S&P 500', 'aliases' => ['VUSA', 'LSE:VUSA', 'AMS:VUSA', 'VUSA.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'], 'perplexityquery' => 'Current price Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'perplexityclosequery' => 'Previous close Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'manual' => 0, ], 'IWDA' => [ 'nome' => 'IWDA - iShares Core MSCI World Acc ETF (Revolut)', 'json' => 'IWDA', 'tabela' => 'EUNL MSCI World', 'aliases' => ['IWDA', 'EUNL', 'AMS:IWDA', 'EUNL.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'], 'perplexityquery' => 'Current price EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'perplexityclosequery' => 'Previous close EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'manual' => 0, ], 'NDXEX' => [ 'nome' => 'NDXEX - iShares Nasdaq 100 UCITS ETF (Dist) (Revolut)', 'json' => 'NDXEX', 'tabela' => 'EXXT Nasdaq-100', 'aliases' => ['NDXEX', 'NDX', 'INDEXNASDAQ:NDX', 'EXXT', 'EQQQ', 'EXXT.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'], 'perplexityquery' => 'Current price iShares NASDAQ-100 UCITS ETF (DE) (EXXT.DE) (yahoo)', 'perplexityclosequery' => 'Previous close EXXT.DE iShares NASDAQ-100 UCITS ETF (DE) EUR (yahoo)', 'manual' => 0, ], 'XAUEUR' => [ 'nome' => 'Ouro (XAU/EUR)', 'json' => 'XAUEUR', 'tabela' => 'Ouro', 'moeda' => 'EUR', 'aliases' => ['XAUEUR', 'XAU/EUR', 'XAU EUR', 'OURO', 'GOLD','XAUEUR','XAU'], 'tipo' => 'ouro', 'stooq' => ['xaueur'], 'twelve' => ['XAU/EUR'], 'perplexityquery' => 'Current price, GOLD XAU/EUR', 'perplexityclosequery' => 'Previous close price for GOLD XAU/EUR', 'manual' => 0, ], ]; // Função genérica: dado um ticker qualquer (Revolut, CSV, etc.), devolve o ticker interno function normalizarTickerGlobal(string $raw): ?string { $n = strtoupper(trim($raw)); if ($n === '') { return null; } // 1) Remover prefixos de bolsa mais comuns $n = preg_replace('/^(NASDAQ|NYSE|AMS|INDEXNASDAQ|XETRA|LSE):?/', '', $n); // 2) BRK.B -> BRKB (remover pontos) $n = str_replace('.', '', $n); // 3) Remover qualquer coisa que não seja A–Z ou 0–9 $n = preg_replace('/[^A-Z0-9]/', '', $n); // 4) Procurar primeiro por match direto de interno if (isset(MAPA_SIMBOLOS[$n])) { return $n; } // 5) Procurar nos aliases foreach (MAPA_SIMBOLOS as $interno => $info) { if (!empty($info['aliases']) && in_array($n, $info['aliases'], true)) { return $interno; } } // 6) Fallback: devolve o limpo (permite lidar com ativos novos ainda não registados) return $n; } $simbolos = MAPA_SIMBOLOS; // Se este ficheiro foi chamado diretamente (não via include), enviar JSON if (realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME'] ?? '')) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(MAPA_SIMBOLOS, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } ======================================================================================== FICHEIRO: backup_20260611_153533/api/bootstrap/simplecache.php Tamanho: 963 bytes ======================================================================================== dir = rtrim($dir, '/'); if (!is_dir($this->dir)) { @mkdir($this->dir, 0775, true); @chmod($this->dir, 0775); } } private function path(string $key): string { return $this->dir . '/' . sha1($key) . '.json'; } public function get(string $key, int $ttlSeconds): ?array { $p = $this->path($key); if (!is_file($p)) return null; $age = time() - (int)@filemtime($p); if ($age > $ttlSeconds) return null; $raw = @file_get_contents($p); if (!is_string($raw) || $raw === '') return null; $data = json_decode($raw, true); return is_array($data) ? $data : null; } public function set(string $key, array $value): void { $p = $this->path($key); @file_put_contents($p, json_encode($value, JSON_UNESCAPED_UNICODE), LOCK_EX); } } ======================================================================================== FICHEIRO: backup_20260611_153533/api/bootstrap/utilizador.php Tamanho: 1147 bytes ======================================================================================== /.../dados_csv/tiago/transacoes-acoes.csv [file:1] */ function userFilePath(string $baseName): string { $baseName = ltrim($baseName, '/'); $user = getUserId(); return ROOT . '/dados_csv/' . $user .'/'. $baseName; } ======================================================================================== FICHEIRO: backup_20260611_153533/api/bootstrap/validacao.php Tamanho: 1044 bytes ======================================================================================== false, 'erro' => $msg, 'timestamp' => date('Y-m-d H:i:s'), ], $extra), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } function v_enum(?string $value, array $allowed, string $field = 'valor'): string { $v = trim((string)$value); if ($v === '' || !in_array($v, $allowed, true)) { api_json_error("Campo inválido: $field", 400, ['field' => $field]); } return $v; } function v_user_id(?string $value): string { $v = trim((string)$value); if ($v === '' || !preg_match('/^[a-z0-9_]{1,32}$/', $v)) { api_json_error('User inválido.', 400); } return $v; } function v_moeda(?string $value): string { $v = strtoupper(trim((string)$value)); return v_enum($v, ['EUR', 'USD'], 'moeda'); } ======================================================================================== FICHEIRO: backup_20260611_153533/api/calculos-atualizar.log Tamanho: 15056 bytes ======================================================================================== { "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 326, "ultima_taxa": 1.17 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (indisponivel)", "IWDA (indisponivel)", "NDXEX (indisponivel)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-22 21:30:02", "bytes_escritos": 2028 } }, "duracao_segundos": 10.93, "timestamp": "2025-12-22 21:30:12" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 12:30:01", "bytes_escritos": 2099 } }, "duracao_segundos": 5.8, "timestamp": "2025-12-26 12:30:06" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 12:45:02", "bytes_escritos": 2098 } }, "duracao_segundos": 6.11, "timestamp": "2025-12-26 12:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:00:02", "bytes_escritos": 2099 } }, "duracao_segundos": 5.95, "timestamp": "2025-12-26 13:00:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:15:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.06, "timestamp": "2025-12-26 13:15:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:30:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.17, "timestamp": "2025-12-26 13:30:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 13:45:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.09, "timestamp": "2025-12-26 13:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:00:02", "bytes_escritos": 2099 } }, "duracao_segundos": 5.99, "timestamp": "2025-12-26 14:00:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:15:02", "bytes_escritos": 2099 } }, "duracao_segundos": 6.11, "timestamp": "2025-12-26 14:15:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:30:03", "bytes_escritos": 2099 } }, "duracao_segundos": 6.1, "timestamp": "2025-12-26 14:30:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 14:45:02", "bytes_escritos": 2101 } }, "duracao_segundos": 5.87, "timestamp": "2025-12-26 14:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:00:02", "bytes_escritos": 2097 } }, "duracao_segundos": 5.89, "timestamp": "2025-12-26 15:00:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 326, "ultima_taxa": 1.1773 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:15:02", "bytes_escritos": 2098 } }, "duracao_segundos": 5.89, "timestamp": "2025-12-26 15:15:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 326, "ultima_taxa": 1.1773 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:30:03", "bytes_escritos": 2100 } }, "duracao_segundos": 6.85, "timestamp": "2025-12-26 15:30:08" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 15:45:02", "bytes_escritos": 2103 } }, "duracao_segundos": 5.81, "timestamp": "2025-12-26 15:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:00:05", "bytes_escritos": 2099 } }, "duracao_segundos": 9.44, "timestamp": "2025-12-26 16:00:11" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:15:02", "bytes_escritos": 2103 } }, "duracao_segundos": 5.8, "timestamp": "2025-12-26 16:15:06" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:30:02", "bytes_escritos": 2101 } }, "duracao_segundos": 5.94, "timestamp": "2025-12-26 16:30:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 16:45:02", "bytes_escritos": 2102 } }, "duracao_segundos": 6.19, "timestamp": "2025-12-26 16:45:07" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 17:00:02", "bytes_escritos": 2100 } }, "duracao_segundos": 7.77, "timestamp": "2025-12-26 17:00:09" }{ "ok": true, "detalhes": { "cambio": { "ok": true, "registos": 327, "ultima_taxa": 1.18 }, "precos": { "ok": true, "atualizadas": [ "AAPL (stooq:aapl.us)", "NVDA (stooq:nvda.us)", "GOOGL (stooq:googl.us)", "VUSA (stooq:vusa.de)", "IWDA (stooq:eunl.de)", "NDXEX (stooq:exxt.de)", "XAUEUR (stooq:xaueur)" ], "total": 7, "timestamp": "2025-12-26 17:15:02", "bytes_escritos": 2102 } }, "duracao_segundos": 8.57, "timestamp": "2025-12-26 17:15:09" } ======================================================================================== FICHEIRO: backup_20260611_153533/api/calculos.php Tamanho: 111631 bytes ======================================================================================== 'calculos.php', * 'versao' => '1.0', * 'endpoints' => [ * 'precos' => '?acao=precos', (Ok, retornar preços atuais à data, hora de agora, sem cambio) * 'precosfechoanterior' =>?acao=precosfechoanterior', (OK, criar acao para criar os presos de abertura) * 'variacaodia' => '?acao=variacaodia', (OK, verifcar calculo, retornar valor variação e %variação do dia hoje, calculado com precos atual e precos da abertura) * 'caixa' => '?acao=caixa&moeda=EUR', (OK, valores de caixa por moeda) * 'carteira' => '?acao=carteira&moeda=EUR', (OK, valores da carteira em euros) * 'investimento' => '?acao=investimento&moeda=EUR', (OK, valores do investimento em euros) * 'resumo' => '?acao=resumo&moeda=EUR', (verificar o que está a fazer) * 'dashboard' => '?acao=dashboard&moeda=EUR', (verificar o que está a fazer) * 'cambio_historico' => '?acao=cambio_historico', (OK, historio de cambio USD/EUR) * 'cambio_atual' => '?acao=cambio_atual', (OK, cambio atual à data, hora de pelo perplexity USD/EUR). * 'lucromensla => '?acao=lucromensal', (falta, lucro mensa para o html Gráfico Detalhado ΔRealizado + ΔNãoRealizado + dividendos - taxas) * 'atualizar' => '?acao=atualizar', (atualizar todas os funções do calculos.php) * NOVA arquitetura: * - AÇÕES: Stooq → TwelveData → Perplexity - Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual * * * Mantém compatibilidade total com endpoints existentes. */ header('Content-Type: application/json; charset=utf-8'); error_reporting(0); $ROOT = realpath(__DIR__ . '/..') ?: dirname(__DIR__); if (!defined('ROOT')) define('ROOT', $ROOT); require_once ROOT . '/api/bootstrap/bootstrap.php'; require_once ROOT . '/api/perplexity.php'; require_once ROOT . '/api/bootstrap/simbolos.php'; // ========================= CONFIGURAÇÃO ========================= /* ========================= HELPERS BASE ========================= */ function httpGetJson(string $url, int $timeout = 10): ?array { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; // Remove espaços e tabs $s = str_replace([' ', "\t"], '', $s); // Se tiver 1 vírgula e 0 pontos, assume decimal PT (ex: 12,34) if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } // Remove separadores de milhar em vírgula (ex: 1,234.56) $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } /* ========================= PROVIDERS ========================= */ /** TwelveData - Price */ function obterPrecoAtualTwelveData(string $symbol, string $apikey): ?float { $url = 'https://api.twelvedata.com/price?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** TwelveData - Quote (price + close) */ function obterQuoteTwelveData(string $symbol, string $apikey): ?array { $url = "https://api.twelvedata.com/quote?symbol=" . urlencode($symbol) . "&apikey=" . urlencode($apikey); $data = httpGetJson($url, 10); if (!is_array($data)) return null; return [ 'price' => (isset($data['price']) && is_numeric($data['price'])) ? (float)$data['price'] : null, 'close' => (isset($data['close']) && is_numeric($data['close'])) ? (float)$data['close'] : null, 'prevclose' => (isset($data['previous_close']) && is_numeric($data['previous_close'])) ? (float)$data['previous_close'] : null, ]; } /** EODHD - Real-time */ function obterPrecoAtualEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/real-time/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json'; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['price']) || !is_numeric($data['price'])) { return null; } return floatval($data['price']); } /** EODHD - Previous close */ function obterPrevCloseEODHD(string $symbol, string $apikey): ?float { $url = 'https://eodhd.com/api/eod/' . urlencode($symbol) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 10); if (!is_array($data) || count($data) < 2) return null; $yesterday = $data[1]; return isset($yesterday['close']) && is_numeric($yesterday['close']) ? (float)$yesterday['close'] : null; } function obterPrecoAtualStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if ($sym === "") return null; $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create([ "http" => ["timeout" => 10, "header" => "User-Agent: Mozilla/5.0\r\n"] ]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if ($csv === "") return null; $lines = preg_split("/\\r\\n|\\n|\\r/", $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if ($dataLine === "") return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; $dateStr = trim((string)($cols[1] ?? "")); $close = $cols[6] ?? null; // ✅ 7 DIAS FLEXÃVEL $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) return null; if (!is_numeric($close)) return null; $price = (float)$close; if (!is_finite($price) || $price <= 0) return null; return $price; } /* ========================= PREÇO ATUAL (NOVA LÓGICA) ========================= */ /** * Busca preço atual com prioridades: * - AÇÕES: Stooq → TwelveData → Manual * - ETFs: Stooq → EODHD → Manual * - XAU: Stooq → TwelveData → Manual */ function buscarPrecoAtual(string $ticker, array $cfg, float $taxaCambio, string $apikey_twelve, string $apikey_eodhd): array { $price = null; $source = 'indisponivel'; $moeda = $cfg['moeda'] ?? 'EUR'; $tipo = $cfg['tipo'] ?? 'acao'; // 1ï¸âƒ£ Stooq (SEMPRE PRIMEIRO - grátis) if (isset($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { $price = obterPrecoAtualStooq($symbol); if ($price !== null && $price > 0) { $source = "stooq:$symbol"; break; } } } // 2ï¸âƒ£ TwelveData (ações/ouro, não ETFs) if ($price === null && $tipo !== 'etf' && isset($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $p = obterPrecoAtualTwelveData($symbol, $apikey_twelve); if ($p !== null && $p > 0) { $price = $p; $source = "twelve:$symbol"; // XAU/USD → XAU/EUR if ($ticker === 'XAUEUR' && strpos($symbol, '') !== false && $taxaCambio > 0) { $price = $p / $taxaCambio; $moeda = 'EUR'; $source = "twelve:$symbol→EUR"; } break; } } } // 3) EODHD – só ETFs - última opção antes de Perplexity if ($price === null && $tipo === 'etf' && isset($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { $price = obterPrecoAtualEODHD($symbol, $apikey_eodhd); if ($price !== null && $price > 0) { $source = "eodhd:$symbol"; break; } } } // 4) Perplexity (fallback) – antes do Manual if (($price === null || $price <= 0) && function_exists('obterPrecoAtualPerplexity')) { // Query configurável por ticker (opcional) // Ex: 'perplexity_query' => 'IWDA ETF price (iShares Core MSCI World UCITS ETF) Xetra' $q = $cfg['perplexityquery'] ?? ($ticker . ' stock price'); $dbg = null; $p = obterPrecoAtualPerplexity($q, $moeda, $dbg); if ($p !== null && $p > 0) { $price = $p; $source = 'perplexity-api'; } } // 5) Manual (valor anterior) if ($price === null || $price <= 0) { $price = $cfg['manual'] ?? 0; $source = $price > 0 ? 'manual' : 'indisponivel'; } return [ 'preco' => $price, 'moeda' => $moeda, 'fonte' => $source, ]; } /** * Busca preço de abertura (close) do dia atual * Hierarquia: * - AÇÕES: Stooq → TwelveData → Perplexity → Manual * - ETFs: Stooq → EODHD → Perplexity → Manual * - XAU: Stooq → TwelveData → Perplexity → Manual */ function buscarPrecoFecho( string $ticker, array $cfg, float $taxaCambio, string $apikeytwelve, string $apikeyeodhd ): ?float { $closePrice = null; $tipo = $cfg['tipo'] ?? 'acao'; // 1) STOOQ (previous close via daily) if (isset($cfg['stooq']) && is_array($cfg['stooq'])) { foreach ($cfg['stooq'] as $symbol) { if (function_exists('obterPrevCloseStooq')) { $closePrice = obterPrevCloseStooq($symbol); } if ($closePrice !== null && $closePrice > 0) break; } } // 2) TWELVEDATA (quote -> previousclose / close) - não ETFs if (($closePrice === null || $closePrice <= 0) && $tipo !== 'etf') { if (isset($cfg['twelve']) && is_array($cfg['twelve'])) { foreach ($cfg['twelve'] as $symbol) { $quote = obterQuoteTwelveData($symbol, $apikeytwelve); // Preferir prevClose; fallback para close se existir if (is_array($quote)) { if (isset($quote['prevclose']) && is_numeric($quote['prevclose']) && (float)$quote['prevclose'] > 0) { $closePrice = (float)$quote['prevclose']; } elseif (isset($quote['close']) && is_numeric($quote['close']) && (float)$quote['close'] > 0) { $closePrice = (float)$quote['close']; } } // Converter XAUUSD -> XAUEUR se necessário (taxaCambio = EURUSD) if ($closePrice !== null && $closePrice > 0 && $ticker === 'XAUEUR' && strpos($symbol, 'USD') !== false && $taxaCambio > 0) { $closePrice = $closePrice / $taxaCambio; } if ($closePrice !== null && $closePrice > 0) break; } } } // 3) EODHD (previous close) - ETFs if (($closePrice === null || $closePrice <= 0) && $tipo === 'etf') { if (isset($cfg['eodhd']) && is_array($cfg['eodhd'])) { foreach ($cfg['eodhd'] as $symbol) { if (function_exists('obterPrevCloseEODHD')) { $closePrice = obterPrevCloseEODHD($symbol, $apikeyeodhd); } if ($closePrice !== null && $closePrice > 0) break; } } } // 4) PERPLEXITY fallback (se existir) if (($closePrice === null || $closePrice <= 0) && function_exists('obterPrevClosePerplexity')) { $query = $cfg['perplexityclosequery'] ?? ($ticker . ' previous close price'); $moeda = $cfg['moeda'] ?? 'USD'; $debug = null; $p = obterPrevClosePerplexity($query, $moeda, $debug); if ($p !== null && $p > 0) $closePrice = $p; } return ($closePrice !== null && $closePrice > 0) ? $closePrice : null; } function obterPrecoFechoStooq(string $symbol): ?float { $sym = strtolower(trim($symbol)); if (!$sym) return null; // CSV intraday: Symbol,Date,Time,Close,High,Low,Close,Volume $url = "https://stooq.com/q/l/?s=" . urlencode($sym) . "&f=sd2t2ohlcv&h&e=csv"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); if (!$lines || count($lines) < 2) return null; $dataLine = trim($lines[1]); if (!$dataLine) return null; $cols = str_getcsv($dataLine); if (count($cols) < 8) return null; // Validar que é do dia de hoje $date = trim(strval($cols[1] ?? '')); $today = date('Y-m-d'); // ✅ FLEXÃVEL (7 dias) $dateObj = DateTime::createFromFormat('Y-m-d', trim(strval($cols[1] ?? ''))); if (!$dateObj) { return obterPrecoFechoStooqDaily($sym); } $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return obterPrecoFechoStooqDaily($sym); } $close = $cols[3] ?? null; // Coluna "Close" if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Fallback: Obter preço de abertura do Stooq Daily (última linha recente) */ function obterPrecoFechoStooqDaily(string $symbol): ?float { $url = "https://stooq.com/q/d/l/?s=" . urlencode(strtolower(trim($symbol))) . "&i=d"; $ctx = stream_context_create(['http' => [ 'timeout' => 10, 'header' => "User-Agent: Mozilla/5.0" ]]); $csv = @file_get_contents($url, false, $ctx); if ($csv === false) return null; $csv = trim($csv); if (!$csv) return null; $lines = preg_split('/\r\n|\n|\r/', $csv); $lines = array_values(array_filter(array_map('trim', $lines), fn($l) => $l !== '')); if (count($lines) < 2) return null; // Última linha = dados mais recentes $last = $lines[count($lines) - 1]; $cols = str_getcsv($last); if (count($cols) < 5) return null; $dateStr = trim(strval($cols[0] ?? '')); $close = $cols[1] ?? null; // Coluna "Close" no daily // ✅ VALIDAÇÃO FLEXÃVEL: últimos 7 dias $dateObj = DateTime::createFromFormat('Y-m-d', $dateStr); if (!$dateObj) return null; $today = new DateTime(); $diff = $today->diff($dateObj)->days; if ($diff > 7 || $dateObj > $today) { return null; // Data muito antiga ou futura } if (!is_numeric($close)) return null; $price = (float) $close; if (!is_finite($price) || $price <= 0) return null; return $price; } /** * Previous close Stooq - CHAMADA PRINCIPAL da buscarPrecoFecho() */ function obterPrevCloseStooq(string $symbol): ?float { // 1º Tenta intraday (último close do dia) $price = obterPrecoFechoStooq($symbol); if ($price !== null && $price > 0) { return $price; } // 2º Fallback: daily (última linha recente) return obterPrecoFechoStooqDaily($symbol); } /** * Obter preço de abertura do EODHD (campo "close" da API real-time) */ function obterPrecoFechoEODHD(string $symbol, string $apikey): ?float { $url = "https://eodhd.com/api/real-time/" . urlencode($symbol) . "?api_token=" . urlencode($apikey) . "&fmt=json"; $data = httpGetJson($url, 10); if (!is_array($data) || !isset($data['close']) || !is_numeric($data['close'])) { return null; } $close = (float) $data['close']; return ($close > 0) ? $close : null; } /* ========================= ATUALIZAR PREÇOS (NOVA) ========================= */ function atualizarPrecosECambio(): array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; $timestamp = date('Y-m-d H:i:s'); // Config APIs $APIKEYTWELVEDATA = getenv('TWELVEDATA_APIKEY') ?: ''; $APIKEYEODHD = getenv('EODHD_APIKEY') ?: ''; // Câmbio (tem de ser o mesmo valor do /api/calculos.php?acao=cambio_atual) $taxaCambio = 1.10; $taxaCambioFonte = 'fallback'; // 1) Prioridade: endpoint cambio_atual do próprio calculos.php try { $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $scheme = $isHttps ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // Caminho do próprio script (ex.: /api/calculos.php) $selfPath = $_SERVER['SCRIPT_NAME'] ?? '/api/calculos.php'; // Construir URL absoluto para evitar problemas de relative paths $urlCambioAtual = $scheme . $host . $selfPath . '?acao=cambio_atual'; $respCambio = httpGetJson($urlCambioAtual, 15); if (is_array($respCambio) && !empty($respCambio['ok'])) { // Suportar vários nomes possíveis, para não partir se o JSON variar $eurusd = (isset($respCambio['EURUSD']) && is_numeric($respCambio['EURUSD'])) ? floatval($respCambio['EURUSD']) : ((isset($respCambio['taxaeurusd']) && is_numeric($respCambio['taxaeurusd'])) ? floatval($respCambio['taxaeurusd']) : ((isset($respCambio['taxaeurparausd']) && is_numeric($respCambio['taxaeurparausd'])) ? floatval($respCambio['taxaeurparausd']) : 0.0)); if (is_finite($eurusd) && $eurusd > 0) { $taxaCambio = round($eurusd, 4); $taxaCambioFonte = 'calculos.php?acao=cambio_atual'; } } } catch (\Throwable $e) { // ignora e faz fallback abaixo } // 2) Fallback: histórico local (caso o cambio_atual falhe) if (empty($taxaCambioFonte) || $taxaCambioFonte === 'fallback') { $historicoCambioFile = $ROOT . '/dados_csv/historico-cambio.json'; if (file_exists($historicoCambioFile)) { $historicoCambio = json_decode(@file_get_contents($historicoCambioFile), true); if (is_array($historicoCambio) && !empty($historicoCambio)) { $hoje = date('Y-m-d'); $taxaCambio = isset($historicoCambio[$hoje]) ? $historicoCambio[$hoje] : end($historicoCambio); $taxaCambio = round(floatval($taxaCambio), 4); $taxaCambioFonte = 'historico-cambio.json (fallback)'; } } } // 3) Preparar apenas símbolos com posições ativas (TODOS os utilizadores) + providers do MAPA_SIMBOLOS $ativos = obterAcoesAtivasDeTodosOsUtilizadores(); $ativosMap = array_fill_keys($ativos, true); $simbolosParaAtualizar = []; foreach (MAPA_SIMBOLOS as $interno => $meta) { if (!isset($ativosMap[$interno])) continue; // só posições ativas $temProvider = (!empty($meta['stooq']) && is_array($meta['stooq'])) || (!empty($meta['twelve']) && is_array($meta['twelve'])) || (!empty($meta['eodhd']) && is_array($meta['eodhd'])) || (!empty($meta['perplexityquery']) && is_array($meta['perplexityquery'])) || (!empty($meta['perplexityclosequery']) || !empty($meta['perplexityclosequery'])); if (!$temProvider) continue; $simbolosParaAtualizar[$interno] = $meta; } // Buscar preços $precosFinais = []; $atualizadas = []; foreach ($simbolosParaAtualizar as $ticker => $cfg) { $result = buscarPrecoAtual($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); $prevclose = buscarPrecoFecho($ticker, $cfg, $taxaCambio, $APIKEYTWELVEDATA, $APIKEYEODHD); // Calcular % do dia (se existir prevclose) $pctDia = null; if ($result['preco'] !== null && is_numeric($result['preco']) && (float)$result['preco'] > 0 && $prevclose !== null && $prevclose > 0) { $pctDia = (((float)$result['preco'] - (float)$prevclose) / (float)$prevclose) * 100.0; } $precosFinais[$ticker] = [ 'preco' => $result['preco'], 'moeda' => $result['moeda'], 'timestamp' => $timestamp, 'fonte' => $result['fonte'], // Campo standard do teu JSON (usado no resumo.html) 'prevclose' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, // Compatibilidade: alguns trechos antigos procuram "close" 'close' => ($prevclose !== null && $prevclose > 0) ? round($prevclose, 6) : null, 'pctdia' => ($pctDia !== null) ? round($pctDia, 4) : null, ]; $atualizadas[] = "$ticker ({$result['fonte']})"; } // Gravar JSON $dadosCompletos = [ 'precos' => $precosFinais, 'cambio' => [ 'EURUSD' => $taxaCambio, 'USDEUR' => round(1 / ($taxaCambio > 0 ? $taxaCambio : 1.10), 4), 'fonte' => $taxaCambioFonte, 'timestamp' => $timestamp, ], 'ultima_atualizacao' => $timestamp, ]; $jsonContent = json_encode($dadosCompletos, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $bytes = @file_put_contents($jsonFile, $jsonContent, LOCK_EX); if ($bytes === false) { $err = error_get_last(); return [ 'ok' => false, 'erro' => 'Falha ao gravar precos-atuais.json', 'detalhe' => $err['message'] ?? null, 'timestamp' => $timestamp ]; } return [ 'ok' => true, 'atualizadas' => $atualizadas, 'total' => count($atualizadas), 'timestamp' => $timestamp, 'bytes_escritos' => (int)$bytes, ]; } /* ========================= VARIAÇÃO DIÃRIA ========================= */ function calcularVariacaoDia(): array { $today = date('Y-m-d'); $ts = date('Y-m-d H:i:s'); $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro (precos-atuais.json em falta ou invalido).', 'date' => $today, 'timestamp' => $ts ]; } $precos = $dadosPrecos['precos']; $variacoes = []; foreach ($precos as $ticker => $info) { $priceNow = fnum($info['preco'] ?? 0); $close = fnum($info['prevclose'] ?? ($info['close'] ?? 0)); $moeda = $info['moeda'] ?? null; if ($priceNow <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'indisponivel', 'moeda' => $moeda ]; continue; } if ($close <= 0) { $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => 0, 'variacao' => 0, 'percentual' => 0, 'status' => 'semfecho', 'moeda' => $moeda ]; continue; } $change = $priceNow - $close; $changePercent = ($close != 0) ? ($change / $close * 100) : 0; $variacoes[$ticker] = [ 'atual' => round($priceNow, 6), 'anterior' => round($close, 6), 'variacao' => round($change, 6), 'percentual' => round($changePercent, 4), 'status' => 'ok', 'moeda' => $moeda ]; } return [ 'ok' => true, 'date' => $today, 'timestamp' => $ts, 'variacoes' => $variacoes, 'fontes' => [ 'precos' => 'dados_csv/precos-atuais.json', ] ]; } /* ========================= FUNÇÕES EXISTENTES ========================= */ function obterAcoesAtivasDoUtilizador(): array { if (!function_exists('userFilePath')) return []; if (!function_exists('normalizarTickerGlobal')) return []; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) return []; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) return []; $ativos = []; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) $ativos[$interno] = true; } return array_keys($ativos); } /** * Devolve lista de tickers internos com posições ativas * para TODOS os utilizadores conhecidos (ex.: tiago, filipe, maria, agostinha). * Reutiliza a função obterAcoesAtivasDoUtilizador(), mudando temporariamente o user. */ function obterAcoesAtivasDeTodosOsUtilizadores(): array { if (!function_exists('userFilePath') || !function_exists('normalizarTickerGlobal') || !function_exists('getUserId')) { return obterAcoesAtivasDoUtilizador(); } $users = ['tiago', 'filipe', 'maria', 'agostinha']; $ativosGlobais = []; $originalUser = getUserId(); foreach ($users as $u) { $_GET['user'] = $u; $ficheiro = userFilePath('transacoes-acoes.csv'); if (!file_exists($ficheiro)) continue; $linhas = @file($ficheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$linhas || count($linhas) < 2) continue; for ($i = 1; $i < count($linhas); $i++) { $cols = str_getcsv($linhas[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); if ($dataCompra === '' || $nomeAcao === '') continue; if ($dataVenda !== '') continue; $interno = normalizarTickerGlobal($nomeAcao); if ($interno) { $ativosGlobais[$interno] = true; } } } $_GET['user'] = $originalUser; return array_keys($ativosGlobais); } /* ========================= CAMBIO EURUSD (INTEGRADO) ========================= * Integra /api/cambio.php dentro do calculos.php: * - Histórico via Frankfurter * - Taxa live do dia via exchangerate-api * - Cache local em dados_csv/historico-cambio.json + dados_csv/historico-cambio-date.txt */ function cambio_paths(): array { $dir = rtrim(ROOT, '/') . '/dados_csv'; return [ 'dir' => $dir, 'cacheFile' => $dir . '/historico-cambio.json', 'cacheDateFile' => $dir . '/historico-cambio-date.txt', ]; } function cambio_obterHistoricoCache(): array { $p = cambio_paths(); if (file_exists($p['cacheFile'])) { $cache = json_decode(@file_get_contents($p['cacheFile']), true); if (is_array($cache) && !empty($cache)) return $cache; } return []; } function cambio_guardarHistoricoCache(array $historico): void { $p = cambio_paths(); cambio_ensure_dir(); // Ordenar por data ksort($historico); $json = json_encode($historico, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($json) || $json === '') return; @file_put_contents($p['cacheFile'], $json, LOCK_EX); // Marca “última atualização†(usado pelo cambio_verificarEAtualizar) @file_put_contents($p['cacheDateFile'], date('Y-m-d'), LOCK_EX); } function cambio_ensure_dir(): void { $p = cambio_paths(); if (!is_dir($p['dir'])) { @mkdir($p['dir'], 0777, true); } // Não fazer chmod aqui (para não voltar a apertar permissões). } function cambio_carregarFrankfurter(): array { try { $hoje = date('Y-m-d'); $inicio = '2019-10-01'; $url = "https://api.frankfurter.app/{$inicio}..{$hoje}?from=EUR&to=USD"; $ctx = stream_context_create([ 'http' => ['timeout' => 30, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return []; $data = json_decode($response, true); if (!is_array($data) || !isset($data['rates']) || !is_array($data['rates'])) return []; $historico = []; foreach ($data['rates'] as $dataCambio => $rates) { if (isset($rates['USD']) && is_numeric($rates['USD'])) { $historico[$dataCambio] = round((float)$rates['USD'], 4); } } return $historico; } catch (Exception $e) { return []; } } function cambio_obterTaxaExchangeRateLive(): ?float { try { $url = "https://api.exchangerate-api.com/v4/latest/EUR"; $ctx = stream_context_create([ 'http' => ['timeout' => 10, 'header' => "User-Agent: Mozilla/5.0\r\n"] ]); $response = @file_get_contents($url, false, $ctx); if (!$response) return null; $data = json_decode($response, true); if (is_array($data) && isset($data['rates']['USD']) && is_numeric($data['rates']['USD'])) { $v = round((float)$data['rates']['USD'], 4); return ($v > 0 ? $v : null); } } catch (Exception $e) { // ignore } return null; } function cambio_atualizarCacheCompleto(): array { // 1) histórico Frankfurter $historico = cambio_carregarFrankfurter(); // 2) taxa live hoje (exchangerate-api) $taxaHoje = cambio_obterTaxaExchangeRateLive(); if ($taxaHoje !== null && $taxaHoje > 0) { $historico[date('Y-m-d')] = round($taxaHoje, 4); } // 3) gravar if (!empty($historico)) { cambio_guardarHistoricoCache($historico); } return $historico; } function cambio_verificarEAtualizar(): array { $p = cambio_paths(); $historico = cambio_obterHistoricoCache(); $dataAtual = date('Y-m-d'); $ultimaAtualizacao = @file_get_contents($p['cacheDateFile']); $ultimaAtualizacao = is_string($ultimaAtualizacao) ? $ultimaAtualizacao : ''; // Atualiza se cache vazio ou se for um novo dia if (empty($historico) || strpos($ultimaAtualizacao, $dataAtual) === false) { $historico = cambio_atualizarCacheCompleto(); } return is_array($historico) ? $historico : []; } /** * Taxa EUR->USD para uma data (com fallback 7 dias). * Mantém assinatura usada pelo resto do calculos.php. */ function obterTaxaCambio($data = null): float { $historico = cambio_verificarEAtualizar(); if (empty($historico)) return 1.10; // Sem última taxa disponível if (!$data) { $datas = array_keys($historico); rsort($datas); $v = $historico[$datas[0]] ?? 1.10; return (is_numeric($v) && $v > 0) ? (float)$v : 1.10; } // Data exata if (isset($historico[$data]) && is_numeric($historico[$data]) && $historico[$data] > 0) { return (float)$historico[$data]; } // Fallback 7 dias para trás $dt = new DateTime($data); for ($i = 1; $i <= 7; $i++) { $dt->modify('-1 day'); $d = $dt->format('Y-m-d'); if (isset($historico[$d]) && is_numeric($historico[$d]) && $historico[$d] > 0) { return (float)$historico[$d]; } } return 1.10; } /** * Info live para usar no precos-atuais.json (marca a fonte como live). * Também grava a taxa de hoje no cache local. */ function cambio_obterTaxaHojeInfo(): array { $taxaLive = cambio_obterTaxaExchangeRateLive(); if ($taxaLive !== null && $taxaLive > 0) { // garante cache existe e escreve a taxa de hoje $historico = cambio_verificarEAtualizar(); if (!is_array($historico)) $historico = []; $historico[date('Y-m-d')] = round((float)$taxaLive, 4); cambio_guardarHistoricoCache($historico); return ['taxa' => round((float)$taxaLive, 4), 'fonte' => 'Exchange Rate API (live)']; } // fallback: cache/histórico $taxa = obterTaxaCambio(date('Y-m-d')); return ['taxa' => round((float)$taxa, 4), 'fonte' => 'historico-cambio.json']; } function converterMoeda($valor, $moedaOrigem, $moedaDestino, $data = null, $taxaFixa = null): float { $valor = floatval($valor); $moedaOrigem = strtoupper(trim((string)$moedaOrigem)); $moedaDestino = strtoupper(trim((string)$moedaDestino)); if ($moedaOrigem === '' || $moedaDestino === '') return $valor; if ($moedaOrigem === $moedaDestino) return $valor; if ($taxaFixa !== null && floatval($taxaFixa) > 0) { $taxa = floatval($taxaFixa); } else { $taxa = obterTaxaCambio($data); } if ($moedaOrigem === 'EUR' && $moedaDestino === 'USD') return $valor * $taxa; if ($moedaOrigem === 'USD' && $moedaDestino === 'EUR') return $valor / $taxa; return $valor; } function carregarPrecosAtuais(): ?array { global $ROOT; $jsonFile = rtrim($ROOT, "/") . "/dados_csv/precos-atuais.json"; if (!file_exists($jsonFile)) return null; $dados = json_decode(@file_get_contents($jsonFile), true); return is_array($dados) ? $dados : null; } function encontrarEntryPrecoPorTicker(array $precos, string $ticker): ?array { $tickerNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper(trim($ticker))); if ($tickerNorm === '') return null; if (isset($precos[$ticker]) && is_array($precos[$ticker])) return $precos[$ticker]; foreach ($precos as $k => $v) { if (!is_array($v)) continue; $kNorm = preg_replace('/[^A-Z0-9]/', '', strtoupper((string)$k)); if ($kNorm === $tickerNorm) return $v; if (strpos($kNorm, $tickerNorm) !== false) return $v; if (strpos($tickerNorm, $kNorm) !== false) return $v; } return null; } function calcularSaldoCaixa(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $csvAcoes = userFilePath('transacoes-acoes.csv'); $stats = [ $moedaDisplay => [ 'depositos' => 0.0, 'levantamentos' => 0.0, 'compras' => 0.0, 'vendas' => 0.0, 'dividendos' => 0.0, 'taxas' => 0.0, ] ]; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $stats[$moedaDisplay]['depositos'] += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $stats[$moedaDisplay]['levantamentos'] += $valorConv; } elseif (strpos($tipo, 'dividendo') !== false) { $stats[$moedaDisplay]['dividendos'] += $valorConv; } else { $stats[$moedaDisplay]['taxas'] += $valorConv; } } } } if (file_exists($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moeda = strtoupper(trim($cols[10] ?? 'EUR')); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $custoInicialConv = converterMoeda($custoInicial, $moeda, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $stats[$moedaDisplay]['compras'] += $custoInicialConv; if ($dataVenda !== '') { $custoFinalConv = converterMoeda($custoFinal, $moeda, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); $stats[$moedaDisplay]['vendas'] += $custoFinalConv; } } } } $saldo = $stats[$moedaDisplay]['depositos'] - $stats[$moedaDisplay]['levantamentos'] - $stats[$moedaDisplay]['compras'] + $stats[$moedaDisplay]['vendas'] + $stats[$moedaDisplay]['dividendos'] - $stats[$moedaDisplay]['taxas']; if (abs($saldo) < 0.005) $saldo = 0.0; return [ 'ok' => true, 'saldo' => round($saldo, 2), 'detalhes' => [ 'depositos' => round($stats[$moedaDisplay]['depositos'], 2), 'levantamentos' => round($stats[$moedaDisplay]['levantamentos'], 2), 'compras' => round($stats[$moedaDisplay]['compras'], 2), 'vendas' => round($stats[$moedaDisplay]['vendas'], 2), 'dividendos' => round($stats[$moedaDisplay]['dividendos'], 2), 'taxas' => round($stats[$moedaDisplay]['taxas'], 2), ], 'moeda' => $moedaDisplay, 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularSaldoCaixaPuro(string $moedaDisplay = "EUR"): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== "EUR" && $moedaDisplay !== "USD") $moedaDisplay = "EUR"; $csvDinheiro = userFilePath("movimentos-caixa.csv"); $csvAcoes = userFilePath("transacoes-acoes.csv"); $stats = [ "depositos" => 0.0, "levantamentos" => 0.0, "compras" => 0.0, "vendas" => 0.0, "dividendos" => 0.0, "taxas" => 0.0 ]; // movimentos-caixa.csv: Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio(opcional) if (file_exists($csvDinheiro)) { $lines = file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $tipo = strtolower(trim(strval($cols[2] ?? ""))); $valor = abs(fnum($cols[3] ?? 0)); $moeda = strtoupper(trim(strval($cols[4] ?? ""))); if ($moeda !== $moedaDisplay) continue; if (strpos($tipo, "depsito") !== false || strpos($tipo, "depósito") !== false || strpos($tipo, "deposito") !== false) { $stats["depositos"] += $valor; } elseif (strpos($tipo, "levantamento") !== false) { $stats["levantamentos"] += $valor; } elseif (strpos($tipo, "dividendo") !== false) { $stats["dividendos"] += $valor; } else { $stats["taxas"] += $valor; // Outros/Taxas } } } } // transacoes-acoes.csv: ... 6 CustoInicial, 7 CustoFinal, ... 10 Moeda if (file_exists($csvAcoes)) { $lines = file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim(strval($cols[1] ?? "")); $dataVenda = trim(strval($cols[2] ?? "")); $custoInicial = fnum($cols[6] ?? 0); $custoFinal = fnum($cols[7] ?? 0); $moeda = strtoupper(trim(strval($cols[10] ?? "EUR"))); if ($moeda !== $moedaDisplay) continue; if ($dataCompra !== "" && $custoInicial != 0) { $stats["compras"] += $custoInicial; } if ($dataVenda !== "" && $custoFinal != 0) { $stats["vendas"] += $custoFinal; } } } } $saldo = $stats["depositos"] - $stats["levantamentos"] - $stats["compras"] + $stats["vendas"] + $stats["dividendos"] - $stats["taxas"]; if (abs($saldo) < 0.005) $saldo = 0.0; return [ "ok" => true, "saldo" => round($saldo, 2), "detalhes" => [ "depositos" => round($stats["depositos"], 2), "levantamentos" => round($stats["levantamentos"], 2), "compras" => round($stats["compras"], 2), "vendas" => round($stats["vendas"], 2), "dividendos" => round($stats["dividendos"], 2), "taxas" => round($stats["taxas"], 2) ], "moeda" => $moedaDisplay, "timestamp" => date("Y-m-d H:i:s") ]; } function calcularCarteiraAtiva(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValorAtual = 0.0; $posicoesAtivas = 0; if (!file_exists($csvAcoes)) { // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), // mantém como está "saldo_caixa" => round($saldoCaixa, 2), // NOVO "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, "timestamp" => date("Y-m-d H:i:s") ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'investido' => 0.0, 'valor_carteira_ativa' => 0.0, 'ganho_ativo' => 0.0, 'posicoes_ativas' => 0, 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV= fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataVenda !== '') continue; if ($dataCompra === '' || $qtd <= 0 || $custoInicialCSV <= 0) continue; $valorInvestidoPosicao = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valorAtualPosicao = 0.0; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; elseif ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valorAtualPosicao = $qtd * $precoConv; } } if ($valorAtualPosicao <= 0 && $custoFinalCSV > 0) { $valorAtualPosicao = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } if ($valorAtualPosicao <= 0) { $valorAtualPosicao = $valorInvestidoPosicao; } $totalInvestido += $valorInvestidoPosicao; $totalValorAtual += $valorAtualPosicao; $posicoesAtivas++; } $ganho = $totalValorAtual - $totalInvestido; // Caixa deve vir do cálculo "puro" (igual à caixa.html / ?acao=caixa&moeda=...) if (function_exists("calcularSaldoCaixaPuro")) { $caixa = calcularSaldoCaixaPuro($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } else { // fallback (não ideal) se ainda não existir a função no teu ficheiro $caixa = calcularSaldoCaixa($moedaDisplay); $saldoCaixa = (is_array($caixa) && isset($caixa["saldo"])) ? floatval($caixa["saldo"]) : 0.0; } $valorCarteiraComCaixa = $totalValorAtual + $saldoCaixa; return [ "ok" => true, "moeda" => $moedaDisplay, "investido" => round($totalInvestido, 2), // Mantém o antigo (compatibilidade) "valorcarteiraativa" => round($valorCarteiraComCaixa, 2), "ganhoativo" => round($ganho, 2), "posicoesativas" => $posicoesAtivas, // NOVOS CAMPOS (para o resumo.html) "saldo_caixa" => round($saldoCaixa, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function calcularInvestimentoInicial(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvDinheiro = userFilePath('movimentos-caixa.csv'); $totalDepositos = 0.0; $totalLevantamentos = 0.0; if (file_exists($csvDinheiro)) { $lines = @file($csvDinheiro, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines && count($lines) > 1) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim($cols[1] ?? ''); $tipo = strtolower(trim($cols[2] ?? '')); $valor = fnum($cols[3] ?? 0); $moeda = strtoupper(trim($cols[4] ?? '')); $taxaLinha = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') $taxaLinha = fnum($cols[6]); if ($moeda !== 'EUR' && $moeda !== 'USD') continue; $valorConv = converterMoeda(abs($valor), $moeda, $moedaDisplay, $data, $taxaLinha); if (strpos($tipo, 'depósito') !== false || strpos($tipo, 'deposito') !== false) { $totalDepositos += $valorConv; } elseif (strpos($tipo, 'levantamento') !== false) { $totalLevantamentos += $valorConv; } } } } $investimento = $totalDepositos - $totalLevantamentos; if ($investimento < 0) $investimento = 0.0; return [ 'ok' => true, 'moeda' => $moedaDisplay, 'depositos' => round($totalDepositos, 2), 'levantamentos' => round($totalLevantamentos, 2), 'investimento' => round($investimento, 2), 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularResumo(string $moedaDisplay = 'EUR'): array { $moedaDisplay = strtoupper(trim($moedaDisplay)); if ($moedaDisplay !== 'EUR' && $moedaDisplay !== 'USD') $moedaDisplay = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $dadosPrecos = carregarPrecosAtuais(); $precos = []; $taxaSpot = null; $precosTimestamp = null; if (is_array($dadosPrecos)) { if (isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) { $precos = $dadosPrecos['precos']; } if (isset($dadosPrecos['cambio']) && is_array($dadosPrecos['cambio'])) { if (isset($dadosPrecos['cambio']['EURUSD']) && is_numeric($dadosPrecos['cambio']['EURUSD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EURUSD']); } elseif (isset($dadosPrecos['cambio']['EUR_USD']) && is_numeric($dadosPrecos['cambio']['EUR_USD'])) { $taxaSpot = floatval($dadosPrecos['cambio']['EUR_USD']); } } $precosTimestamp = $dadosPrecos['ultima_atualizacao'] ?? ($dadosPrecos['cambio']['timestamp'] ?? null); } if ($taxaSpot !== null && $taxaSpot <= 0) $taxaSpot = null; $totalInvestido = 0.0; $totalValor = 0.0; $totalGanho = 0.0; $ativasInvest = 0.0; $ativasValor = 0.0; $ativasGanho = 0.0; $encInvest = 0.0; $encValor = 0.0; $encGanho = 0.0; $porAcaoAtivas = []; $porAcaoEncerradas = []; if (!file_exists($csvAcoes)) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!$lines || count($lines) < 2) { return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'ativas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'encerradas' => ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0], 'porAcaoAtivas' => (object)[], 'porAcaoEncerradas' => (object)[], 'meta' => ['precos_timestamp' => $precosTimestamp], 'timestamp' => date('Y-m-d H:i:s'), ]; } for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim($cols[1] ?? ''); $dataVenda = trim($cols[2] ?? ''); $nomeAcao = trim($cols[3] ?? ''); $qtd = fnum($cols[4] ?? 0); $custoInicialCSV = fnum($cols[6] ?? 0); $custoFinalCSV = fnum($cols[7] ?? 0); $taxaCompra = fnum($cols[8] ?? 0); $taxaVenda = fnum($cols[9] ?? 0); $moedaOrigem = strtoupper(trim($cols[10] ?? 'EUR')); if ($dataCompra === '' || $nomeAcao === '' || $qtd <= 0) continue; if ($custoInicialCSV <= 0) continue; $investido = converterMoeda($custoInicialCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaCompra > 0 ? $taxaCompra : null); $valor = 0.0; if ($dataVenda === '') { $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; $info = null; if ($ticker && is_array($precos)) { $info = encontrarEntryPrecoPorTicker($precos, $ticker); } if (is_array($info)) { $precoAtual = isset($info['preco']) ? floatval($info['preco']) : 0.0; $moedaPreco = strtoupper(trim($info['moeda'] ?? $moedaOrigem)); if ($precoAtual > 0) { $precoConv = $precoAtual; if ($taxaSpot && $moedaPreco !== $moedaDisplay) { if ($moedaPreco === 'USD' && $moedaDisplay === 'EUR') $precoConv = $precoAtual / $taxaSpot; if ($moedaPreco === 'EUR' && $moedaDisplay === 'USD') $precoConv = $precoAtual * $taxaSpot; } $valor = $qtd * $precoConv; } } if ($valor <= 0 && $custoFinalCSV > 0) { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataCompra, $taxaVenda > 0 ? $taxaVenda : null); } } else { $valor = converterMoeda($custoFinalCSV, $moedaOrigem, $moedaDisplay, $dataVenda, $taxaVenda > 0 ? $taxaVenda : null); } $ganho = $valor - $investido; $totalInvestido += $investido; $totalValor += $valor; $totalGanho += $ganho; $isAtiva = ($dataVenda === ''); if ($isAtiva) { $ativasInvest += $investido; $ativasValor += $valor; $ativasGanho += $ganho; if (!isset($porAcaoAtivas[$nomeAcao])) { $porAcaoAtivas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0, 'qtd' => 0.0]; } $porAcaoAtivas[$nomeAcao]['invest'] += $investido; $porAcaoAtivas[$nomeAcao]['valor'] += $valor; $porAcaoAtivas[$nomeAcao]['ganho'] += $ganho; $porAcaoAtivas[$nomeAcao]['qtd'] += $qtd; } else { $encInvest += $investido; $encValor += $valor; $encGanho += $ganho; if (!isset($porAcaoEncerradas[$nomeAcao])) { $porAcaoEncerradas[$nomeAcao] = ['invest' => 0.0, 'valor' => 0.0, 'ganho' => 0.0]; } $porAcaoEncerradas[$nomeAcao]['invest'] += $investido; $porAcaoEncerradas[$nomeAcao]['valor'] += $valor; $porAcaoEncerradas[$nomeAcao]['ganho'] += $ganho; } } $roundMap = function(array $m) { foreach ($m as $k => $v) { if (is_array($v)) { foreach ($v as $kk => $vv) { $m[$k][$kk] = is_numeric($vv) ? round(floatval($vv), 2) : $vv; } } } return $m; }; $porAcaoAtivas = $roundMap($porAcaoAtivas); $porAcaoEncerradas = $roundMap($porAcaoEncerradas); return [ 'ok' => true, 'moeda' => $moedaDisplay, 'global' => [ 'invest' => round($totalInvestido, 2), 'valor' => round($totalValor, 2), 'ganho' => round($totalGanho, 2), ], 'ativas' => [ 'invest' => round($ativasInvest, 2), 'valor' => round($ativasValor, 2), 'ganho' => round($ativasGanho, 2), ], 'encerradas' => [ 'invest' => round($encInvest, 2), 'valor' => round($encValor, 2), 'ganho' => round($encGanho, 2), ], 'porAcaoAtivas' => $porAcaoAtivas, 'porAcaoEncerradas' => $porAcaoEncerradas, 'meta' => [ 'taxa_spot_eurusd' => $taxaSpot ? round($taxaSpot, 4) : null, 'precos_timestamp' => $precosTimestamp, ], 'timestamp' => date('Y-m-d H:i:s'), ]; } function calcularDashboard(string $moedaDisplay = 'EUR'): array { $resumo = calcularResumo($moedaDisplay); $invest = calcularInvestimentoInicial($moedaDisplay); $caixaMoedas = calcularSaldoCaixaPorMoeda(); return [ 'ok' => true, 'moeda' => strtoupper(trim($moedaDisplay)), 'resumo' => $resumo, 'investimento' => $invest, 'caixa_moedas' => $caixaMoedas, 'timestamp' => date('Y-m-d H:i:s'), ]; } /* ========================= ENDPOINTS ========================= */ function endpoint_precos(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $precos = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $precos[$ticker] = [ 'preco' => round(fnum($info['preco'] ?? 0), 6), 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precos' => $precos, 'total_ativos' => count($precos), 'timestamp' => date('Y-m-d H:i:s') ]; } // ENDPOINT ?acao=precosfechoanterior // Retorna apenas o fecho anterior (prevclose) por ativo function endpointPrecosFechoAnterior(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro', 'timestamp' => date('Y-m-d H:i:s') ]; } $saida = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { if (!is_array($info)) $info = []; // Suportar nomes alternativos caso existam em versões anteriores $prevclose = null; if (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } elseif (isset($info['prevclose'])) { $prevclose = fnum($info['prevclose']); } $ok = ($prevclose !== null && $prevclose > 0); $saida[$ticker] = [ 'prevclose' => $ok ? round($prevclose, 6) : null, 'moeda' => $info['moeda'] ?? null, 'fonte' => $info['fonte'] ?? 'desconhecida', 'timestamp' => $info['timestamp'] ?? null, 'status' => $ok ? 'ok' : 'indisponivel' ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'precosfechoanterior' => $saida, 'totalativos' => count($saida), 'timestamp' => date('Y-m-d H:i:s') ]; } /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ /** * ENDPOINT: ?acao=variacaodia * Retorna variação do dia (atual vs abertura) e variação total (atual vs fecho anterior) */ function endpointvariacaodia(): array { $dadosPrecos = carregarPrecosAtuais(); if (!is_array($dadosPrecos) || !isset($dadosPrecos['precos']) || !is_array($dadosPrecos['precos'])) { return [ 'ok' => false, 'erro' => 'Execute ?acao=atualizar primeiro.', 'timestamp' => date('Y-m-d H:i:s') ]; } $variacoes = []; foreach ($dadosPrecos['precos'] as $ticker => $info) { $atual = fnum($info['preco'] ?? 0); $prevclose = fnum($info['prevclose'] ?? 0); $moeda = $info['moeda'] ?? null; if ($atual <= 0) { $variacoes[$ticker] = [ 'atual' => 0, 'prevclose' => null, 'variacaodia' => 0, 'variacaopctdia' => 0, 'status' => 'indisponivel', 'moeda' => $moeda, 'direcao' => 'estavel', ]; continue; } // Variação do dia = atual vs abertura (se existir) if ($prevclose > 0) { $diffDia = $atual - $prevclose; $pctDia = ($prevclose != 0) ? ($diffDia / $prevclose * 100) : 0; $status = 'ok'; } else { $diffDia = 0; $pctDia = 0; $status = 'semfecho'; } $variacoes[$ticker] = [ 'atual' => round($atual, 6), 'prevclose' => ($prevclose > 0) ? round($prevclose, 6) : null, 'variacaodia' => round($diffDia, 6), 'variacaopctdia' => round($pctDia, 2), 'status' => $status, 'moeda' => $moeda, 'direcao' => ($diffDia > 0 ? 'alta' : ($diffDia < 0 ? 'baixa' : 'estavel')), ]; } return [ 'ok' => true, 'data' => date('Y-m-d'), 'hora' => date('H:i:s'), 'variacoes' => $variacoes, 'totalativos' => count($variacoes), 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_caixa(string $moeda): array { // Validação if (!in_array($moeda, ['EUR', 'USD'], true)) { return [ 'ok' => false, 'erro' => 'Moeda inválida. Use EUR ou USD', 'timestamp' => date('Y-m-d H:i:s') ]; } // Reutiliza função existente return calcularSaldoCaixaPuro($moeda); } function endpointcaixatotal(): array { $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa mais correta: tentar "taxa de hoje" via cache/histórico; fallback para 1.10 $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); return [ "ok" => true, "moeda_base" => "EUR", "eur" => $eur, "usd" => $usd, "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), "timestamp" => date("Y-m-d H:i:s") ]; } function endpoint_resumo(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; // Usa função existente return calcularResumo($moeda); } function endpoint_dashboard(string $moeda): array { if (!in_array($moeda, ['EUR', 'USD'], true)) $moeda = 'EUR'; $investimento = calcularInvestimentoInicial($moeda); $carteira = calcularCarteiraAtiva($moeda); $caixa = calcularSaldoCaixa($moeda); $variacoes = endpoint_variacaodia(); $totalPatrimonio = ($carteira['valor_carteira_ativa'] ?? 0) + ($caixa['saldo'] ?? 0); $ganhoTotal = $totalPatrimonio - ($investimento['investimento'] ?? 0); $rentabilidade = ($investimento['investimento'] ?? 0) > 0 ? (($ganhoTotal / $investimento['investimento']) * 100) : 0; // Contador de variações positivas/negativas do dia $varUp = 0; $varDown = 0; if (isset($variacoes['variacoes']) && is_array($variacoes['variacoes'])) { foreach ($variacoes['variacoes'] as $v) { if (!isset($v['variacaopctdia'])) continue; if ($v['variacaopctdia'] > 0) $varUp++; if ($v['variacaopctdia'] < 0) $varDown++; } } } function endpoint_cambio_historico(): array { $historico = cambio_verificarEAtualizar(); if (empty($historico)) { return [ 'ok' => false, 'erro' => 'Cache de câmbio vazio. Execute ?acao=atualizar', 'timestamp' => date('Y-m-d H:i:s') ]; } ksort($historico); // Ordenar por data return [ 'ok' => true, 'moeda_base' => 'EUR', 'moeda_cotacao' => 'USD', 'total_registos' => count($historico), 'data_inicial' => array_key_first($historico), 'data_final' => array_key_last($historico), 'taxa_atual' => end($historico), 'historico' => $historico, 'timestamp' => date('Y-m-d H:i:s') ]; } function endpoint_cambio_atual(): array { $timestamp = date('Y-m-d H:i:s'); $data = date('Y-m-d'); $hora = date('H:i:s'); $eurusd = 0.0; $fonte = 'indisponivel'; // 1) Preferir a função já integrada para taxa live/cache if (function_exists('cambio_obterTaxaHojeInfo')) { $info = cambio_obterTaxaHojeInfo(); if (is_array($info)) { $eurusd = isset($info['taxa']) ? (float)$info['taxa'] : 0.0; $fonte = isset($info['fonte']) ? (string)$info['fonte'] : $fonte; } } // 2) Fallback para histórico/cache local if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = (float) obterTaxaCambio($data); $fonte = 'historico-cambio.json (fallback)'; } // 3) Fallback final fixo if (!is_finite($eurusd) || $eurusd <= 0) { $eurusd = 1.10; $fonte = 'fallback-fixo'; } $eurusd = round($eurusd, 4); $usdeur = round(1 / $eurusd, 4); return [ 'ok' => true, 'par' => 'EURUSD', // nomes que já são usados noutros pontos do projeto 'EURUSD' => $eurusd, 'taxaeurusd' => $eurusd, 'taxaeurparausd' => $eurusd, 'USDEUR' => $usdeur, 'taxausdeur' => $usdeur, 'taxausdparaeur' => $usdeur, 'fonte' => $fonte, 'data' => $data, 'hora' => $hora, 'timestamp' => $timestamp, ]; } function endpoint_atualizar(): array { $inicio = microtime(true); $resultados = []; // 1) Atualizar câmbio histórico + taxa atual try { $historicoCambio = cambio_atualizarCacheCompleto(); $resultados['cambio'] = [ 'ok' => !empty($historicoCambio), 'registos' => count($historicoCambio), 'ultima_taxa' => end($historicoCambio) ?: null ]; } catch (Exception $e) { $resultados['cambio'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } // 2) Atualizar preços atuais try { $atualizacaoPrecos = atualizarPrecosECambio(); $resultados['precos'] = $atualizacaoPrecos; } catch (Exception $e) { $resultados['precos'] = [ 'ok' => false, 'erro' => $e->getMessage() ]; } $duracao = round((microtime(true) - $inicio), 2); return [ 'ok' => ($resultados['cambio']['ok'] ?? false) && ($resultados['precos']['ok'] ?? false), 'detalhes' => $resultados, 'duracao_segundos' => $duracao, 'timestamp' => date('Y-m-d H:i:s') ]; } // ----------------------------------------------------------------------------- // NOVO: Histórico mensal por ativo (fecho do mês) via Stooq + cache + ficheiro por user // Guarda em: userFilePath('historico-precos-mensal.json') // Endpoints: // ?acao=historicoativosmensal -> lê ficheiro // ?acao=atualizarhistoricoativosmensal -> atualiza (fetch) e guarda // Query extras: // &ttl=86400 (cache stooq em segundos, default 30 dias) // &forcar=1 (ignorar cache stooq) // ----------------------------------------------------------------------------- function _hpm_fnum($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([" ", "\t"], "", $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) $s = str_replace(',', '.', $s); $s = str_replace(',', '', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function _hpm_normTicker(string $raw): ?string { $raw = trim($raw); if ($raw === '') return null; if (function_exists('normalizarTickerGlobal')) return normalizarTickerGlobal($raw); $n = strtoupper($raw); $n = preg_replace('/[^A-Z0-9\\.]/', '', $n); $n = str_replace('.', '', $n); return $n ?: null; } function _hpm_monthKey(string $ymd): string { return substr($ymd, 0, 7); } function _hpm_cacheDir(): string { $dir = __DIR__ . '/dados_csv/cache'; if (!is_dir($dir)) @mkdir($dir, 0775, true); return $dir; } function _hpm_cacheFile(string $stooqSymbol): string { return _hpm_cacheDir() . '/stooq-monthclose-' . sha1(strtolower(trim($stooqSymbol))) . '.json'; } /** * Vai buscar série diária do Stooq e reduz para "close mensal" (último close do mês). * Retorna: ['YYYY-MM' => close, ...] */ function _hpm_stooqMonthClose(string $stooqSymbol, int $ttlSeconds = 2592000, bool $forcar = false): array { $stooqSymbol = strtolower(trim($stooqSymbol)); if ($stooqSymbol === '') return []; $cacheFile = _hpm_cacheFile($stooqSymbol); if (!$forcar && is_file($cacheFile) && (time() - filemtime($cacheFile) < $ttlSeconds)) { $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (is_array($j)) return $j; } $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($stooqSymbol) . '&i=d'; $ctx = stream_context_create([ 'http' => [ 'timeout' => 25, 'header' => "User-Agent: Mozilla/5.0\r\n", ] ]); $csv = @file_get_contents($url, false, $ctx); if (!is_string($csv) || trim($csv) === '') return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!$lines || count($lines) < 3) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 5) continue; $date = trim((string)$cols[0]); $close = _hpm_fnum($cols[4]); if ($date === '' || $close <= 0) continue; $ym = _hpm_monthKey($date); // Como o CSV do Stooq vem ordenado por data, isto acaba por ficar com o "último close" do mês. $out[$ym] = $close; } @file_put_contents($cacheFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX); return $out; } function _hpm_obterTickersDaCarteira(): array { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return []; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return []; $set = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); $t = _hpm_normTicker($nomeAcao); if (!$t) continue; $set[$t] = true; } $out = array_keys($set); sort($out); return $out; } function _hpm_obterDataMinCompra(): ?string { $csvAcoes = userFilePath('transacoes-acoes.csv'); if (!is_file($csvAcoes)) return null; $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) return null; $min = null; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if (strlen($dc) < 10) continue; $dc = substr($dc, 0, 10); $min = ($min === null || $dc < $min) ? $dc : $min; } return $min; } /** * Lê/atualiza e guarda o histórico mensal por ativo. * Estrutura do ficheiro: * { * "meta": {...}, * "ativos": { * "AAPL": { "stooq":"aapl.us", "moeda":"USD", "mensal": { "2024-01": 187.12, ... } }, * ... * } * } */ function endpointHistoricoAtivosMensal(bool $atualizar): array { set_time_limit(240); $ts = date('Y-m-d H:i:s'); $getDadosDir = function (): string { $candidatos = [ rtrim(ROOT, '/\\') . '/dados_csv', rtrim(__DIR__, '/\\') . '/dados_csv', __DIR__ . '/dados_csv', ]; foreach ($candidatos as $d) { if (is_dir($d)) return $d; } @mkdir($candidatos[0], 0777, true); return $candidatos[0]; }; $ensureDir = function (string $dir): void { if (!is_dir($dir)) @mkdir($dir, 0777, true); }; $toYm = function (?string $date): ?string { $date = trim((string)$date); if ($date === '') return null; if (strlen($date) >= 7) { $ym = substr($date, 0, 7); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } return null; }; $num = function ($v): ?float { if ($v === null) return null; if (is_float($v) || is_int($v)) return is_finite((float)$v) ? (float)$v : null; $s = trim((string)$v); if ($s === '') return null; $s = str_replace(["\xC2\xA0", ' '], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') >= 1) { $s = str_replace('.', '', $s); $s = str_replace(',', '.', $s); } elseif (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : null; }; $httpGet = function (string $url, int $timeout = 25): ?string { $ctx = stream_context_create([ 'http' => [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\nAccept: */*\r\n", ], 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); $raw = @file_get_contents($url, false, $ctx); if (!is_string($raw) || trim($raw) === '') return null; return $raw; }; $normalizarMensal = function (array $mensal): array { $out = []; foreach ($mensal as $ym => $close) { $ym = trim((string)$ym); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $v = is_numeric($close) ? (float)$close : null; if ($v === null || !is_finite($v) || $v <= 0) continue; $out[$ym] = $v; } ksort($out); return $out; }; $cacheFileFonte = function (string $cacheDir, string $provider, string $symbol): string { $provider = strtolower(trim($provider)); $symbol = strtolower(trim($symbol)); return rtrim($cacheDir, '/\\') . '/hpm-' . preg_replace('/[^a-z0-9_-]+/i', '-', $provider) . '-' . sha1($symbol) . '.json'; }; $readCache = function (string $cacheFile, int $ttl, bool $forcar): ?array { if ($forcar || !is_file($cacheFile)) return null; $age = time() - (int)@filemtime($cacheFile); if ($age < 0 || $age > $ttl) return null; $raw = @file_get_contents($cacheFile); $j = json_decode((string)$raw, true); if (!is_array($j) || !isset($j['data']) || !is_array($j['data'])) return null; return $j['data']; }; $writeCache = function (string $cacheFile, string $provider, string $symbol, array $data) use ($ts): void { @file_put_contents( $cacheFile, json_encode([ 'timestamp' => $ts, 'provider' => $provider, 'symbol' => $symbol, 'data' => $data, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); }; $obterDataMinCompra = function (array $usersScope): ?string { if (!function_exists('userFilePath')) return null; $min = null; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $dc = trim((string)($cols[1] ?? '')); if ($dc === '') continue; if ($min === null || $dc < $min) $min = $dc; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; return $min; }; $obterTickersAtivos = function (bool $todos, bool $encerradas, array $usersScope): array { if (!$encerradas) { if ($todos && function_exists('obterAcoesAtivasDeTodosOsUtilizadores')) { $t = obterAcoesAtivasDeTodosOsUtilizadores(); return is_array($t) ? $t : []; } if (!$todos && function_exists('obterAcoesAtivasDoUtilizador')) { $t = obterAcoesAtivasDoUtilizador(); return is_array($t) ? $t : []; } } if (!function_exists('userFilePath')) return []; $set = []; $userOriginal = function_exists('getUserId') ? getUserId() : null; foreach ($usersScope as $u) { if ($u !== null) $_GET['user'] = $u; $f = userFilePath('transacoes-acoes.csv'); if (!is_file($f)) continue; $lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($lines) || count($lines) < 2) continue; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 11) continue; $nomeAcao = trim((string)($cols[3] ?? '')); if ($nomeAcao === '') continue; $t = null; if (function_exists('normalizarTickerGlobal')) { $t = normalizarTickerGlobal($nomeAcao); } if (!is_string($t) || trim($t) === '') { $t = strtoupper($nomeAcao); $t = preg_replace('/[^A-Z0-9.]/', '', $t); $t = str_replace('.', '-', $t); $t = trim((string)$t); } if ($t !== '') $set[$t] = true; } } if ($userOriginal !== null) $_GET['user'] = $userOriginal; $out = array_keys($set); sort($out); return $out; }; $fetchManual = function (array $cfg) use ($normalizarMensal): array { $manual = $cfg['manual'] ?? null; if (is_array($manual)) return $normalizarMensal($manual); $manualPath = trim((string)($cfg['manual_path'] ?? '')); if ($manualPath !== '' && is_file($manualPath)) { $raw = @file_get_contents($manualPath); $j = json_decode((string)$raw, true); if (is_array($j)) return $normalizarMensal($j); } return []; }; $fetchStooq = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $cacheFile = $cacheDir . '/' . basename(str_replace('.json', '', basename(($GLOBALS['__tmp'] ?? 'x')))); // noop seguro $cacheFile = $cacheDir . '/hpm-stooq-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $sym = strtolower(trim($symbol)); if ($sym === '') return []; $url = 'https://stooq.com/q/d/l/?s=' . rawurlencode($sym) . '&i=d'; $csv = $httpGet($url, 25); if (!is_string($csv)) return []; $lines = preg_split("/\r\n|\n|\r/", trim($csv)); if (!is_array($lines) || count($lines) < 2) return []; $out = []; for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!is_array($cols) || count($cols) < 5) continue; $date = trim((string)($cols[0] ?? '')); $close = $cols[4] ?? null; if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) continue; if (!is_numeric($close)) continue; $ym = substr($date, 0, 7); $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'stooq', $symbol, $out); return $out; }; $fetchTwelveData = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['twelvedata_apikey'] ?? '') ?: ($_ENV['TWELVEDATA_API_KEY'] ?? '') ?: (defined('TWELVEDATA_API_KEY') ? TWELVEDATA_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-twelvedata-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://api.twelvedata.com/time_series?symbol=' . rawurlencode($symbol) . '&interval=1month&outputsize=5000&apikey=' . rawurlencode($apiKey); $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j) || empty($j['values']) || !is_array($j['values'])) return []; $out = []; foreach ($j['values'] as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['datetime'] ?? '')); $close = $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'twelvedata', $symbol, $out); return $out; }; $fetchEodhd = function (string $symbol, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $apiKey = trim((string)( ($_GET['eodhd_apikey'] ?? '') ?: ($_ENV['EODHD_API_KEY'] ?? '') ?: (defined('EODHD_API_KEY') ? EODHD_API_KEY : '') )); if ($apiKey === '') return []; $cacheFile = $cacheDir . '/hpm-eodhd-' . sha1(strtolower(trim($symbol))) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = 'https://eodhd.com/api/eod/' . rawurlencode($symbol) . '?api_token=' . rawurlencode($apiKey) . '&fmt=json&period=m'; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $out = []; foreach ($j as $row) { if (!is_array($row)) continue; $dt = trim((string)($row['date'] ?? '')); $close = $row['adjusted_close'] ?? $row['close'] ?? null; if ($dt === '' || !is_numeric($close)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$close; } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'eodhd', $symbol, $out); return $out; }; $fetchPerplexity = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ($httpGet, $readCache, $writeCache, $normalizarMensal): array { $symbol = trim((string)($cfg['perplexity_symbol'] ?? $cfg['json'] ?? $cfg['ticker'] ?? '')); if ($symbol === '') return []; $cacheFile = $cacheDir . '/hpm-perplexity-' . sha1(strtolower($symbol)) . '.json'; $hit = $readCache($cacheFile, $ttl, $forcar); if (is_array($hit)) return $normalizarMensal($hit); $url = trim((string)($cfg['perplexity_url'] ?? '')); if ($url === '') return []; $raw = $httpGet($url, 30); if (!is_string($raw)) return []; $j = json_decode($raw, true); if (!is_array($j)) return []; $cand = []; if (isset($j['mensal']) && is_array($j['mensal'])) $cand = $j['mensal']; elseif (isset($j['data']) && is_array($j['data'])) $cand = $j['data']; else $cand = $j; $out = []; foreach ($cand as $k => $v) { if (is_array($v)) { $dt = trim((string)($v['date'] ?? $v['datetime'] ?? $v['mes'] ?? '')); $cl = $v['close'] ?? $v['price'] ?? $v['valor'] ?? null; if ($dt === '' || !is_numeric($cl)) continue; $ym = substr($dt, 0, 7); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; $out[$ym] = (float)$cl; } else { $ym = trim((string)$k); if (!preg_match('/^\d{4}-\d{2}$/', $ym)) continue; if (!is_numeric($v)) continue; $out[$ym] = (float)$v; } } $out = $normalizarMensal($out); if (!empty($out)) $writeCache($cacheFile, 'perplexity', $symbol, $out); return $out; }; $resolverMensalPorFonte = function (array $cfg, int $ttl, bool $forcar, string $cacheDir) use ( $fetchManual, $fetchStooq, $fetchTwelveData, $fetchEodhd, $fetchPerplexity ): array { $ordem = $cfg['fontes_historico_mensal'] ?? $cfg['fontes'] ?? ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; if (!is_array($ordem) || empty($ordem)) { $ordem = ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual']; } $fontesTentadas = []; foreach ($ordem as $fonteRaw) { $fonte = strtolower(trim((string)$fonteRaw)); if ($fonte === '') continue; $fontesTentadas[] = $fonte; $mensal = []; if ($fonte === 'manual') { $mensal = $fetchManual($cfg); } elseif ($fonte === 'stooq') { $sym = $cfg['stooq'] ?? null; if (is_array($sym)) $sym = $sym[0] ?? null; if (is_string($sym) && trim($sym) !== '') { $mensal = $fetchStooq($sym, $ttl, $forcar, $cacheDir); } } elseif ($fonte === 'twelvedata') { $sym = trim((string)($cfg['twelvedata'] ?? $cfg['twelve'] ?? $cfg['ticker'] ?? '')); if ($sym !== '') $mensal = $fetchTwelveData($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'eodhd') { $sym = trim((string)($cfg['eodhd'] ?? '')); if ($sym !== '') $mensal = $fetchEodhd($sym, $ttl, $forcar, $cacheDir); } elseif ($fonte === 'perplexity') { $mensal = $fetchPerplexity($cfg, $ttl, $forcar, $cacheDir); } if (!empty($mensal)) { return [ 'fonte' => $fonte, 'mensal' => $mensal, 'fontes_tentadas' => $fontesTentadas, ]; } } return [ 'fonte' => null, 'mensal' => [], 'fontes_tentadas' => $fontesTentadas, ]; }; $dadosDir = $getDadosDir(); $ensureDir($dadosDir); $cacheDir = rtrim($dadosDir, '/\\') . '/cache-hpm'; $ensureDir($cacheDir); $outFile = rtrim($dadosDir, '/\\') . '/historico-precos-mensal.json'; $existente = null; if (is_file($outFile)) { $raw = @file_get_contents($outFile); $j = json_decode((string)$raw, true); if (is_array($j)) $existente = $j; } if (!$atualizar) { return [ 'ok' => true, 'modo' => 'ler', 'path' => $outFile, 'ficheiro' => basename($outFile), 'dados' => (is_array($existente) ? $existente : [ 'meta' => [], 'ativos' => (object)[] ]), 'timestamp' => $ts, ]; } $ttl = isset($_GET['ttl']) ? (int)$_GET['ttl'] : 2592000; if ($ttl < 60) $ttl = 60; $forcar = isset($_GET['forcar']) && (string)$_GET['forcar'] === '1'; $todos = isset($_GET['todos']) && (string)$_GET['todos'] === '1'; $encerradas = isset($_GET['encerradas']) && (string)$_GET['encerradas'] === '1'; $scopeUsers = $todos ? ['tiago', 'filipe', 'maria', 'agostinha'] : [null]; $tickers = $obterTickersAtivos($todos, $encerradas, $scopeUsers); $dataMin = $obterDataMinCompra($scopeUsers); $minYm = $dataMin ? $toYm($dataMin) : null; $ativosOut = (is_array($existente) && isset($existente['ativos']) && is_array($existente['ativos'])) ? $existente['ativos'] : []; $stats = [ 'totaltickers' => is_array($tickers) ? count($tickers) : 0, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ]; $debugTickers = []; foreach ($tickers as $tRaw) { if (count($debugTickers) < 20) $debugTickers[] = (string)$tRaw; $t = strtoupper(trim((string)$tRaw)); if ($t === '') continue; if (function_exists('normalizarTickerGlobal')) { $tn = normalizarTickerGlobal($t); if (is_string($tn) && trim($tn) !== '') $t = trim($tn); } else { $t = preg_replace('/[^A-Z0-9.-]/', '', $t); } $mapa = null; if (defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS)) { $mapa = MAPA_SIMBOLOS; } if (!is_array($mapa) || !isset($mapa[$t]) || !is_array($mapa[$t])) { $stats['ignoradossemmapa']++; continue; } $cfg = $mapa[$t]; try { $res = $resolverMensalPorFonte($cfg, $ttl, $forcar, $cacheDir); $mensal = is_array($res['mensal'] ?? null) ? $res['mensal'] : []; $fonteUsada = $res['fonte'] ?? null; $fontesTentadas = is_array($res['fontes_tentadas'] ?? null) ? $res['fontes_tentadas'] : []; if (empty($mensal)) { $stats['semdados']++; continue; } if ($minYm !== null) { $filtrado = []; foreach ($mensal as $ym => $close) { if ($ym < $minYm) continue; $filtrado[$ym] = $close; } $mensal = $filtrado; } if (empty($mensal)) { $stats['semdados']++; continue; } $moeda = strtoupper(trim((string)($cfg['moeda'] ?? 'EUR'))); $mensalExtra = []; $dadosPrecosAtuais = carregarPrecosAtuais(); $precosAtuais = ( is_array($dadosPrecosAtuais) && isset($dadosPrecosAtuais['precos']) && is_array($dadosPrecosAtuais['precos']) ) ? $dadosPrecosAtuais['precos'] : []; $infoPrecoAtual = encontrarEntryPrecoPorTicker($precosAtuais, $t); $mesAtual = date('Y-m'); if (is_array($infoPrecoAtual)) { $precoAtual = fnum($infoPrecoAtual['preco'] ?? 0); if ($precoAtual > 0) { $mensalExtra[] = [ 'mes' => $mesAtual, 'meslabel' => $mesAtual . ' - preço atual', 'tipo' => 'preco_atual', 'preco' => round($precoAtual, 6), 'precoatual' => round($precoAtual, 6), 'moeda' => strtoupper(trim((string)($infoPrecoAtual['moeda'] ?? $moeda))), 'fonte' => $infoPrecoAtual['fonte'] ?? 'precos', 'timestamp' => $infoPrecoAtual['timestamp'] ?? ($dadosPrecosAtuais['ultima_atualizacao'] ?? null), 'isatual' => true, ]; } } $ativosOut[$t] = [ 'moeda' => $moeda, 'fonte' => $fonteUsada, 'fontestentadas' => $fontesTentadas, 'stooq' => $cfg['stooq'] ?? null, 'twelvedata' => $cfg['twelvedata'] ?? ($cfg['twelve'] ?? null), 'eodhd' => $cfg['eodhd'] ?? null, 'perplexityurl' => $cfg['perplexityurl'] ?? null, 'mensal' => $mensal, 'mensal_extra' => $mensalExtra, ]; $stats['atualizados']++; if (is_string($fonteUsada) && isset($stats['porfonte'][$fonteUsada])) { $stats['porfonte'][$fonteUsada]++; } } catch (\Throwable $e) { $stats['erros']++; } } ksort($ativosOut); $out = [ 'meta' => [ 'user' => function_exists('getUserId') ? getUserId() : null, 'todos' => $todos, 'encerradas' => $encerradas, 'mindatacompra' => $dataMin, 'minmesguardado' => $minYm, 'debugtickersamostra' => $debugTickers, 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => $ttl, 'forcar' => $forcar, 'stats' => $stats, 'timestamp' => $ts, ], 'ativos' => $ativosOut, ]; @file_put_contents( $outFile, json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX ); return [ 'ok' => true, 'modo' => 'atualizar', 'ficheiro' => basename($outFile), 'path' => $outFile, 'meta' => $out['meta'], 'totalativosnoficheiro' => is_array($ativosOut) ? count($ativosOut) : 0, 'timestamp' => $ts, ]; } function lmToNum($v): float { if ($v === null) return 0.0; if (is_int($v) || is_float($v)) { $n = (float)$v; return is_finite($n) ? $n : 0.0; } $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace(['€', '$', ' ', "\t"], '', $s); if (substr_count($s, ',') === 1 && substr_count($s, '.') === 0) { $s = str_replace(',', '.', $s); } else { $s = str_replace(',', '', $s); } $n = (float)$s; return is_finite($n) ? $n : 0.0; } function lmMonthKey(string $date): string { return substr($date, 0, 7); } function lmMonthEndDate(string $ym): string { $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) return $ym . '-28'; $dt->modify('last day of this month'); return $dt->format('Y-m-d'); } function lmMonthRange(string $startYm, string $endYm): array { $out = []; $dt = DateTime::createFromFormat('Y-m-d', $startYm . '-01'); $end = DateTime::createFromFormat('Y-m-d', $endYm . '-01'); if (!$dt || !$end) return $out; while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function lmClassificarMovimento(string $tipo, string $descricao): string { $k = mb_strtolower(trim($tipo . ' ' . $descricao), 'UTF-8'); if ( strpos($k, 'depósito') !== false || strpos($k, 'deposito') !== false || strpos($k, 'deposit') !== false || strpos($k, 'top up') !== false || strpos($k, 'topup') !== false ) { return 'deposito'; } if ( strpos($k, 'levantamento') !== false || strpos($k, 'withdraw') !== false ) { return 'levantamento'; } if ( strpos($k, 'dividendo') !== false || strpos($k, 'dividend') !== false ) { return 'dividendo'; } return 'taxa'; } function lmObterAtivosMensaisGuardados(): array { $resp = endpointHistoricoAtivosMensal(false); if (isset($resp['dados']['ativos']) && is_array($resp['dados']['ativos'])) { return $resp['dados']['ativos']; } if (isset($resp['ativos']) && is_array($resp['ativos'])) { return $resp['ativos']; } return []; } function lmPrecoMensalDoAtivo(array $ativosMensais, array $precosAtuais, string $ticker, string $ym, bool $isCurrentMonth): array { $price = 0.0; $moeda = null; $fonte = null; if ($isCurrentMonth && isset($precosAtuais[$ticker]) && is_array($precosAtuais[$ticker])) { $price = lmToNum($precosAtuais[$ticker]['preco'] ?? 0); if ($price > 0) { $moeda = strtoupper(trim((string)($precosAtuais[$ticker]['moeda'] ?? ''))); $fonte = 'precosatuais'; } } if ($price <= 0 && isset($ativosMensais[$ticker]) && is_array($ativosMensais[$ticker])) { $mensal = $ativosMensais[$ticker]['mensal'] ?? null; if (is_array($mensal) && isset($mensal[$ym])) { $price = lmToNum($mensal[$ym]); if ($price > 0) { $moeda = strtoupper(trim((string)($ativosMensais[$ticker]['moeda'] ?? ''))); $fonte = 'historicoativosmensal'; } } } if (($moeda === null || $moeda === '') && defined('MAPA_SIMBOLOS') && is_array(MAPA_SIMBOLOS) && isset(MAPA_SIMBOLOS[$ticker])) { $moeda = strtoupper(trim((string)(MAPA_SIMBOLOS[$ticker]['moeda'] ?? ''))); } return [ 'preco' => $price > 0 ? $price : 0.0, 'moeda' => ($moeda === 'EUR' || $moeda === 'USD') ? $moeda : null, 'fonte' => $fonte, ]; } function endpointLucroMensal(string $moeda = 'EUR'): array { $ts = date('Y-m-d H:i:s'); $today = date('Y-m-d'); $currYm = date('Y-m'); $moeda = strtoupper(trim($moeda)); if ($moeda !== 'EUR' && $moeda !== 'USD') $moeda = 'EUR'; $csvAcoes = userFilePath('transacoes-acoes.csv'); $csvCaixa = userFilePath('movimentos-caixa.csv'); $ativosMensais = lmObterAtivosMensaisGuardados(); if (empty($ativosMensais)) { return [ 'ok' => false, 'erro' => 'Sem histórico mensal por ativo. Execute ?acao=atualizarhistoricoativosmensal primeiro.', 'fonte' => 'historicoativosmensal', 'timestamp' => $ts, ]; } $dadosPrecos = carregarPrecosAtuais(); $precosAtuais = (is_array($dadosPrecos) && isset($dadosPrecos['precos']) && is_array($dadosPrecos['precos'])) ? $dadosPrecos['precos'] : []; $txs = []; $cashRows = []; $minDate = null; if (is_file($csvAcoes)) { $lines = @file($csvAcoes, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 11) continue; $dataCompra = trim((string)($cols[1] ?? '')); $dataVenda = trim((string)($cols[2] ?? '')); $nomeAcao = trim((string)($cols[3] ?? '')); $qtd = lmToNum($cols[4] ?? 0); $custoIni = abs(lmToNum($cols[6] ?? 0)); $custoFin = abs(lmToNum($cols[7] ?? 0)); $taxaCompra = lmToNum($cols[8] ?? 0); $taxaVenda = lmToNum($cols[9] ?? 0); $moedaTrans = strtoupper(trim((string)($cols[10] ?? 'EUR'))); if ($dataCompra === '' || strlen($dataCompra) < 10 || $qtd <= 0 || $custoIni <= 0) continue; $dc = substr($dataCompra, 0, 10); $dv = ($dataVenda !== '' && strlen($dataVenda) >= 10) ? substr($dataVenda, 0, 10) : ''; $ticker = function_exists('normalizarTickerGlobal') ? normalizarTickerGlobal($nomeAcao) : null; if (!$ticker) continue; $txs[] = [ 'ticker' => $ticker, 'qtd' => $qtd, 'dataCompra' => $dc, 'dataVenda' => $dv, 'custoIni' => $custoIni, 'custoFin' => $custoFin, 'taxaCompra' => ($taxaCompra > 0 ? $taxaCompra : null), 'taxaVenda' => ($taxaVenda > 0 ? $taxaVenda : null), 'moedaTrans' => ($moedaTrans === 'USD' ? 'USD' : 'EUR'), ]; if ($minDate === null || $dc < $minDate) $minDate = $dc; if ($dv !== '' && ($minDate === null || $dv < $minDate)) $minDate = $dv; } } } if (is_file($csvCaixa)) { $lines = @file($csvCaixa, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (is_array($lines) && count($lines) >= 2) { for ($i = 1; $i < count($lines); $i++) { $cols = str_getcsv($lines[$i]); if (!$cols || count($cols) < 6) continue; $data = trim((string)($cols[1] ?? '')); if ($data === '' || strlen($data) < 10) continue; $d = substr($data, 0, 10); $tipo = trim((string)($cols[2] ?? '')); $valor = abs(lmToNum($cols[3] ?? 0)); $moedaRow = strtoupper(trim((string)($cols[4] ?? ''))); $descricao = trim((string)($cols[5] ?? '')); $fxLine = null; if (isset($cols[6]) && trim((string)$cols[6]) !== '') { $tmpFx = lmToNum($cols[6]); $fxLine = $tmpFx > 0 ? $tmpFx : null; } if (($moedaRow !== 'EUR' && $moedaRow !== 'USD') || $valor <= 0) continue; $cashRows[] = [ 'data' => $d, 'tipo' => $tipo, 'descricao' => $descricao, 'valor' => $valor, 'moeda' => $moedaRow, 'fx' => $fxLine, ]; if ($minDate === null || $d < $minDate) $minDate = $d; } } } if ($minDate === null) { return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => 0, 'investimentoinicial' => 0, 'series' => [], 'timestamp' => $ts, ]; } $startYm = substr($minDate, 0, 7); $months = lmMonthRange($startYm, $currYm); $series = []; $prevR = 0.0; $prevU = 0.0; $depAcc = 0.0; $levAcc = 0.0; $divAcc = 0.0; $taxAcc = 0.0; $buyAcc = 0.0; $sellAcc = 0.0; $depAccP = 0.0; $levAccP = 0.0; $divAccP = 0.0; $taxAccP = 0.0; $buyAccP = 0.0; $sellAccP = 0.0; foreach ($months as $ym) { $isCurrentMonth = ($ym === $currYm); $endDate = $isCurrentMonth ? $today : lmMonthEndDate($ym); $eurusdEnd = obterTaxaCambio($endDate); if (!is_finite($eurusdEnd) || $eurusdEnd <= 0) $eurusdEnd = 1.10; $divMes = 0.0; $taxMes = 0.0; $depMes = 0.0; $levMes = 0.0; $divMesP = 0.0; $taxMesP = 0.0; $depMesP = 0.0; $levMesP = 0.0; foreach ($cashRows as $r) { if (lmMonthKey($r['data']) !== $ym) continue; $cls = lmClassificarMovimento((string)$r['tipo'], (string)$r['descricao']); $vConv = converterMoeda((float)$r['valor'], (string)$r['moeda'], $moeda, (string)$r['data'], $r['fx']); $vPuro = ((string)$r['moeda'] === $moeda) ? (float)$r['valor'] : 0.0; if ($cls === 'deposito') { $depMes += $vConv; $depMesP += $vPuro; } elseif ($cls === 'levantamento') { $levMes += $vConv; $levMesP += $vPuro; } elseif ($cls === 'dividendo') { $divMes += $vConv; $divMesP += $vPuro; } else { $taxMes += $vConv; $taxMesP += $vPuro; } } $depAcc += $depMes; $levAcc += $levMes; $divAcc += $divMes; $taxAcc += $taxMes; $depAccP += $depMesP; $levAccP += $levMesP; $divAccP += $divMesP; $taxAccP += $taxMesP; $buyMes = 0.0; $sellMes = 0.0; $buyMesP = 0.0; $sellMesP = 0.0; foreach ($txs as $t) { if (lmMonthKey($t['dataCompra']) === $ym && $t['dataCompra'] <= $endDate) { $buyMes += converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); if ((string)$t['moedaTrans'] === $moeda) $buyMesP += (float)$t['custoIni']; } if ($t['dataVenda'] !== '' && lmMonthKey($t['dataVenda']) === $ym && $t['dataVenda'] <= $endDate) { $sellMes += converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); if ((string)$t['moedaTrans'] === $moeda) $sellMesP += (float)$t['custoFin']; } } $buyAcc += $buyMes; $sellAcc += $sellMes; $buyAccP += $buyMesP; $sellAccP += $sellMesP; $R = 0.0; foreach ($txs as $t) { if ($t['dataVenda'] === '' || $t['dataVenda'] > $endDate) continue; $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $sell = converterMoeda((float)$t['custoFin'], (string)$t['moedaTrans'], $moeda, (string)$t['dataVenda'], $t['taxaVenda']); $R += ($sell - $buy); } $U = 0.0; $MV = 0.0; $fontesMes = []; foreach ($txs as $t) { if ($t['dataCompra'] > $endDate) continue; if ($t['dataVenda'] !== '' && $t['dataVenda'] <= $endDate) continue; $ticker = (string)$t['ticker']; $assetInfo = lmPrecoMensalDoAtivo($ativosMensais, $precosAtuais, $ticker, $ym, $isCurrentMonth); $price = (float)($assetInfo['preco'] ?? 0); if ($price <= 0) continue; $assetMoeda = strtoupper(trim((string)($assetInfo['moeda'] ?? $t['moedaTrans']))); if ($assetMoeda !== 'EUR' && $assetMoeda !== 'USD') $assetMoeda = (string)$t['moedaTrans']; $valLocal = (float)$t['qtd'] * $price; if ($assetMoeda === $moeda) { $valDisplay = $valLocal; } elseif ($assetMoeda === 'USD' && $moeda === 'EUR') { $valDisplay = $eurusdEnd > 0 ? ($valLocal / $eurusdEnd) : 0.0; } elseif ($assetMoeda === 'EUR' && $moeda === 'USD') { $valDisplay = $valLocal * $eurusdEnd; } else { $valDisplay = 0.0; } $buy = converterMoeda((float)$t['custoIni'], (string)$t['moedaTrans'], $moeda, (string)$t['dataCompra'], $t['taxaCompra']); $U += ($valDisplay - $buy); $MV += $valDisplay; if (!empty($assetInfo['fonte'])) { $fontesMes[$assetInfo['fonte']] = true; } } $deltaR = $R - $prevR; $deltaU = $U - $prevU; $outrosMes = $divMes - $taxMes; $net = $deltaR + $deltaU + $outrosMes; $investimentoInicialFimMes = $depAcc - $levAcc; $saldoCaixaFimMes = $depAccP - $levAccP - $buyAccP + $sellAccP + $divAccP - $taxAccP; $valorCarteiraFimMes = $MV + $saldoCaixaFimMes; $lucroTotal = $R + $U; $series[] = [ 'mes' => $ym, 'net' => round($net, 2), 'ganhos' => round($net, 2), 'deltarealizado' => round($deltaR, 2), 'deltanaorealizado' => round($deltaU, 2), 'dividendos' => round($divMes, 2), 'taxas' => round($taxMes, 2), 'realizadoacumulado' => round($R, 2), 'naorealizadofimmes' => round($U, 2), 'lucrototal' => round($lucroTotal, 2), 'valorcarteira' => round($valorCarteiraFimMes, 2), 'carteiravalor' => round($MV, 2), 'saldocaixafimmes' => round($saldoCaixaFimMes, 2), 'investimentoinicial' => round($investimentoInicialFimMes, 2), 'investimentoacumulado' => round($investimentoInicialFimMes, 2), 'fimmesusado' => $endDate, 'fxeurusdfimmes' => round($eurusdEnd, 6), 'precofonte' => empty($fontesMes) ? null : implode('+', array_keys($fontesMes)), ]; $prevR = $R; $prevU = $U; } $investimentoInicialGlobal = 0.0; if (!empty($series)) { $investimentoInicialGlobal = (float)($series[count($series) - 1]['investimentoinicial'] ?? 0); } return [ 'ok' => true, 'user' => function_exists('getUserId') ? getUserId() : null, 'moeda' => $moeda, 'compatibilidade' => true, 'metodo' => 'net = ΔRealizado + ΔNãoRealizado + dividendos - taxas', 'precosmensaisfonte' => 'historicoativosmensal', 'totalmeses' => count($series), 'investimentoinicial' => round($investimentoInicialGlobal, 2), 'series' => $series, 'timestamp' => $ts, ]; } // ========================= ROUTING ========================= $acao = $_GET['acao'] ?? ''; $moeda = strtoupper($_GET['moeda'] ?? 'EUR'); switch ($acao) { // 1ï¸âƒ£ PREÇOS ATUAIS (sem câmbio) case 'precos': echo json_encode(endpoint_precos(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'precosfechoanterior': echo json_encode(endpointPrecosFechoAnterior(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'variacaodia': echo json_encode(endpointvariacaodia(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 3ï¸âƒ£ SALDO CAIXA (moeda única) case "caixa": // ?acao=caixa&moeda=EUR|USD -> saldo puro nessa moeda (sem conversões) // ?acao=caixa -> devolve total convertido para EUR + detalhe EUR/USD $moedaParam = isset($_GET["moeda"]) ? strtoupper(trim(strval($_GET["moeda"]))) : ""; if ($moedaParam === "EUR" || $moedaParam === "USD") { // NOTA: esta função tem de existir (ver abaixo). Se preferires outro nome, troca aqui. echo json_encode(calcularSaldoCaixaPuro($moedaParam), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } $eur = calcularSaldoCaixaPuro("EUR"); $usd = calcularSaldoCaixaPuro("USD"); // Taxa EURUSD "mais correta": usar taxa de hoje do cache/histórico (com fallback 7 dias) $taxa = obterTaxaCambio(date("Y-m-d")); if (!is_finite($taxa) || $taxa <= 0) $taxa = 1.10; $saldoEUR = floatval($eur["saldo"] ?? 0); $saldoUSD = floatval($usd["saldo"] ?? 0); $totalEUR = $saldoEUR + ($saldoUSD / $taxa); echo json_encode([ "ok" => true, "moeda_base" => "EUR", "taxaeurusd" => round($taxa, 4), "total_eur_convertido" => round($totalEUR, 2), // manter detalhe (útil para a caixa.html e debug) "eur" => $eur, "usd" => $usd, "timestamp" => date("Y-m-d H:i:s") ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 5ï¸âƒ£ CARTEIRA ATIVA case 'carteira': echo json_encode(calcularCarteiraAtiva($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 6ï¸âƒ£ INVESTIMENTO INICIAL case 'investimento': echo json_encode(calcularInvestimentoInicial($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 7ï¸âƒ£ RESUMO COMPLETO case 'resumo': echo json_encode(endpoint_resumo($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 8ï¸âƒ£ DASHBOARD (resumo + extras) case 'dashboard': echo json_encode(endpoint_dashboard($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 9ï¸âƒ£ CÂMBIO - Histórico case 'cambio_historico': echo json_encode(endpoint_cambio_historico(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 🔟 CÂMBIO - Atual via Perplexity case 'cambio_atual': echo json_encode(endpoint_cambio_atual(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'lucromensal': echo json_encode(endpointLucroMensal($moeda), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'historicoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(false), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'atualizarhistoricoativosmensal': echo json_encode(endpointHistoricoAtivosMensal(true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; // 1ï¸âƒ£1ï¸âƒ£ ATUALIZAR TUDO case 'atualizar': echo json_encode(endpoint_atualizar(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; case 'info': default: echo json_encode([ 'api' => 'calculos.php', 'versao' => '1.0', 'endpoints' => [ 'precos' => '?acao=precos', 'precosfechoanterior' => '?acao=precosfechoanterior', 'variacaodia' => '?acao=variacaodia', 'caixa' => '?acao=caixa&moeda=EUR', 'carteira' => '?acao=carteira&moeda=EUR', 'investimento' => '?acao=investimento&moeda=EUR', 'resumo' => '?acao=resumo&moeda=EUR', 'dashboard' => '?acao=dashboard&moeda=EUR', 'cambio_historico' => '?acao=cambio_historico', 'cambio_atual' => '?acao=cambio_atual', 'historicoativosmensal' => '?acao=historicoativosmensal', 'atualizarhistoricoativosmensal' => '?acao=atualizarhistoricoativosmensal', 'lucromensal' => '?acao=lucromensal', 'atualizar' => '?acao=atualizar', ], ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); break; } ======================================================================================== FICHEIRO: backup_20260611_153533/api/downloadacoes.php Tamanho: 560 bytes ======================================================================================== false, 'error' => 'Nenhuma ação pedida. Use atualizar_caixa=1 e/ou atualizar_acoes=1' ]); exit; } // Ficheiro de extrato por utilizador $ficheiroExtrato = userFilePath('extrato-revolut.csv'); if (!file_exists($ficheiroExtrato)) { echo json_encode([ 'ok' => false, 'error' => "Extrato Revolut não encontrado para utilizador '$user'. Carregue primeiro via Importar Revolut." ]); exit; } // Helpers function extrairValor($texto) { if (preg_match('/(USD|EUR)\s*([+-]?[0-9.,]+)/', $texto, $m)) { return (float) str_replace(',', '', $m[2]); } return 0.0; } function extrairMoeda($texto) { if (preg_match('/(USD|EUR)/', $texto, $m)) { return $m[1]; } return 'USD'; } function mapearTipoCaixa($tipoRevolut) { $tipo = strtoupper(trim($tipoRevolut)); if (strpos($tipo, 'CASH TOP-UP') !== false) return 'Depósito'; if (strpos($tipo, 'CASH WITHDRAWAL') !== false) return 'Levantamento'; if (strpos($tipo, 'DIVIDEND') !== false) return 'Dividendo'; if (strpos($tipo, 'CUSTODY FEE') !== false) return 'Outros'; if (strpos($tipo, 'TRANSFER') !== false) return 'Outros'; return 'Outros'; } function eLinhaCaixa($ticker, $tipoRevolut) { $tipo = strtoupper(trim($tipoRevolut)); // Mesma lógica do JS: só caixa se NÃO tiver ticker // ou se for CASH/DIVIDEND/CUSTODY FEE/TRANSFER e não MARKET. $incluir = (empty($ticker) || strpos($tipo, 'CASH') !== false || strpos($tipo, 'DIVIDEND') !== false || strpos($tipo, 'CUSTODY FEE') !== false || strpos($tipo, 'TRANSFER') !== false); return $incluir && (strpos($tipo, 'MARKET') === false); } function eLinhaAcao($ticker, $tipoRevolut) { if (empty($ticker)) return false; $tipo = strtoupper(trim($tipoRevolut)); return (strpos($tipo, 'BUY') !== false || strpos($tipo, 'SELL') !== false); } function converterDataISO($dataISO) { // "2020-09-17T12:27:15.160488Z" -> "2020-09-17" return substr(trim($dataISO), 0, 10); } // Ler extrato $fh = fopen($ficheiroExtrato, 'r'); if (!$fh) { echo json_encode([ 'ok' => false, 'error' => 'Não foi possível abrir o extrato Revolut.' ]); exit; } // Cabeçalho (esperado): Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate $header = fgetcsv($fh); $map = array_flip($header ?: []); $idxDate = $map['Date'] ?? 0; $idxTicker = $map['Ticker'] ?? 1; $idxType = $map['Type'] ?? 2; $idxQty = $map['Quantity'] ?? 3; $idxTotal = $map['Total Amount'] ?? 5; $idxCurTxt = $map['Currency'] ?? 6; $idxFx = $map['FX Rate'] ?? 7; // Acumuladores $movimentosCaixa = []; $transacoesAcoes = []; $ordemCaixa = 1; $ordemAcoes = 1; while (($cols = fgetcsv($fh)) !== false) { if (count($cols) < 8) continue; $dataISO = $cols[$idxDate] ?? ''; $ticker = trim($cols[$idxTicker] ?? ''); $tipoRevolut = $cols[$idxType] ?? ''; $qtyTxt = $cols[$idxQty] ?? ''; $totalTxt = $cols[$idxTotal] ?? ''; $moedaTxt = $cols[$idxCurTxt] ?? ''; $fxRate = trim($cols[$idxFx] ?? ''); if (trim($dataISO) === '') continue; $data = converterDataISO($dataISO); // Valor e moeda vindos de "Total Amount" (ex: "USD 371.31") $valorBruto = extrairValor($totalTxt); if ($valorBruto == 0.0) { // ainda assim tentar moeda só pelo campo Currency $moeda = extrairMoeda($moedaTxt); } else { $moeda = extrairMoeda($totalTxt); } // 1) Movimentos de CAIXA if ($doCaixa && eLinhaCaixa($ticker, $tipoRevolut) && $valorBruto != 0.0) { $descricao = $ticker ? ($ticker . ' ' . $tipoRevolut) : strtoupper(trim($tipoRevolut)); $movimentosCaixa[] = [ 'ordem' => $ordemCaixa++, 'data' => $data, 'tipo' => mapearTipoCaixa($tipoRevolut), 'valor' => $valorBruto, 'moeda' => $moeda, 'descricao' => $descricao, 'taxa' => $fxRate, ]; } // 2) Transações de AÇÕES if ($doAcoes && eLinhaAcao($ticker, $tipoRevolut) && $valorBruto != 0.0) { $tipoUpper = strtoupper(trim($tipoRevolut)); $qtd = (float) str_replace(',', '.', $qtyTxt); // Normalizar sinal: consideramos valor positivo para custo/receita $valorAbs = abs($valorBruto); $dataCompra = ''; $dataVenda = ''; $custoInicial = 0.0; $custoFinal = 0.0; $taxaCompra = ''; $taxaVenda = ''; if (strpos($tipoUpper, 'BUY') !== false) { // COMPRA $dataCompra = $data; $custoInicial = $valorAbs; $taxaCompra = $fxRate; } elseif (strpos($tipoUpper, 'SELL') !== false) { // VENDA $dataVenda = $data; $custoFinal = $valorAbs; $taxaVenda = $fxRate; } else { // Não reconhecido como BUY/SELL continue; } $transacoesAcoes[] = [ 'ordem' => $ordemAcoes++, 'dataCompra' => $dataCompra, 'dataVenda' => $dataVenda, 'nomeAcao' => $ticker, 'numAcoes' => $qtd, 'comissoes' => 0.0, 'custoInicial' => $custoInicial, 'custoFinal' => $custoFinal, 'taxaCompra' => $taxaCompra, 'taxaVenda' => $taxaVenda, 'moeda' => $moeda, ]; } } fclose($fh); // Gravar ficheiros $result = [ 'ok' => true, 'user' => $user, 'movimentos_caixa'=> 0, 'transacoes_acoes'=> 0, 'ficheiros' => [], ]; if ($doCaixa) { $csv = "Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio\n"; foreach ($movimentosCaixa as $mov) { $valor = number_format($mov['valor'], 2, '.', ''); $taxa = $mov['taxa'] !== '' ? $mov['taxa'] : ''; $desc = str_replace('"', '""', $mov['descricao']); $csv .= "{$mov['ordem']},{$mov['data']},{$mov['tipo']},{$valor},{$mov['moeda']},\"{$desc}\",{$taxa}\n"; } $ficheiroCaixa = userFilePath('movimentos-caixa.csv'); file_put_contents($ficheiroCaixa, $csv); $result['movimentos_caixa'] = count($movimentosCaixa); $result['ficheiros'][] = basename($ficheiroCaixa); } if ($doAcoes) { // 1) Agrupar COMPRA/VENDA com o mesmo NomeAcao e NumAcoes $agrupadas = []; foreach ($transacoesAcoes as $t) { // chave: mesmo nome de ação e mesma quantidade $chave = $t['nomeAcao'] . '|' . number_format($t['numAcoes'], 6, '.', ''); if (!isset($agrupadas[$chave])) { $agrupadas[$chave] = $t; continue; } // Já existe uma linha para esta ação+quantidade → juntar dados $exist = &$agrupadas[$chave]; if ($exist['dataCompra'] === '' && $t['dataCompra'] !== '') { $exist['dataCompra'] = $t['dataCompra']; } if ($exist['dataVenda'] === '' && $t['dataVenda'] !== '') { $exist['dataVenda'] = $t['dataVenda']; } if ((float)$exist['custoInicial'] == 0.0 && (float)$t['custoInicial'] != 0.0) { $exist['custoInicial'] = $t['custoInicial']; } if ((float)$exist['custoFinal'] == 0.0 && (float)$t['custoFinal'] != 0.0) { $exist['custoFinal'] = $t['custoFinal']; } if ($exist['taxaCompra'] === '' && $t['taxaCompra'] !== '') { $exist['taxaCompra'] = $t['taxaCompra']; } if ($exist['taxaVenda'] === '' && $t['taxaVenda'] !== '') { $exist['taxaVenda'] = $t['taxaVenda']; } unset($exist); // limpar referência } // 2) Recriar lista final com novas ordens $transacoesCombinadas = []; $ordem = 1; foreach ($agrupadas as $t) { $t['ordem'] = $ordem++; $transacoesCombinadas[] = $t; } // 3) Gerar CSV $csv = "Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda\n"; foreach ($transacoesCombinadas as $t) { $numAcoes = number_format($t['numAcoes'], 6, '.', ''); $comissoes = number_format($t['comissoes'], 2, '.', ''); $custoInicial = number_format($t['custoInicial'], 2, '.', ''); $custoFinal = number_format($t['custoFinal'], 2, '.', ''); $taxaCompra = $t['taxaCompra'] !== '' ? $t['taxaCompra'] : ''; $taxaVenda = $t['taxaVenda'] !== '' ? $t['taxaVenda'] : ''; $nomeEscapado = str_replace(',', ' ', $t['nomeAcao']); $csv .= $t['ordem'] . ',' . $t['dataCompra'] . ',' . $t['dataVenda'] . ',' . $nomeEscapado . ',' . $numAcoes . ',' . $comissoes . ',' . $custoInicial . ',' . $custoFinal . ',' . $taxaCompra . ',' . $taxaVenda . ',' . $t['moeda'] . "\n"; } $ficheiroAcoes = userFilePath('transacoes-acoes.csv'); file_put_contents($ficheiroAcoes, $csv); $result['transacoes_acoes'] = count($transacoesCombinadas); $result['ficheiros'][] = basename($ficheiroAcoes); } echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); ?> ======================================================================================== FICHEIRO: backup_20260611_153533/api/listar_ficheiros.php Tamanho: 1310 bytes ======================================================================================== true, 'ficheiros' => $ficheiros, 'total' => count($ficheiros), 'timestamp' => date('Y-m-d H:i:s') )); ?> ======================================================================================== FICHEIRO: backup_20260611_153533/api/obterprecosatuais.php Tamanho: 2674 bytes ======================================================================================== $jsonKey, 'info' => MAPA_SIMBOLOS[$jsonKey], ]; } // Match por campo 'json' foreach (MAPA_SIMBOLOS as $interno => $info) { $k = $info['json'] ?? $interno; if ($k === $jsonKey) { return [ 'interno' => $interno, 'info' => $info, ]; } } return null; } $precosTabela = []; // 1) DEVOLVER TUDO o que estiver no JSON foreach ($dados['precos'] as $jsonKey => $entry) { if (!is_array($entry)) continue; $hit = encontrarInfoPorJsonKey((string)$jsonKey); $interno = $hit ? ($hit['interno'] ?? (string)$jsonKey) : (string)$jsonKey; $info = $hit ? ($hit['info'] ?? []) : []; $tabelaKey = $info['tabela'] ?? $interno; $preco = isset($entry['preco']) ? (float)$entry['preco'] : null; $moeda = $entry['moeda'] ?? ($info['moeda'] ?? 'EUR'); $ts = $entry['timestamp'] ?? null; $fonte = $entry['fonte'] ?? null; $precosTabela[$tabelaKey] = [ 'ticker_interno' => $interno, 'json_key' => (string)$jsonKey, 'nome' => $info['nome'] ?? $interno, 'preco' => $preco, 'moeda' => $moeda, 'timestamp' => $ts, 'fonte' => $fonte, ]; } // 2) ADICIONAR CÂMBIO (se existir no JSON) if (isset($dados['cambio']) && is_array($dados['cambio'])) { $precosTabela['cambio'] = $dados['cambio']; } echo json_encode($precosTabela, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); ======================================================================================== FICHEIRO: backup_20260611_153533/api/obtervariacaodia.php Tamanho: 11452 bytes ======================================================================================== [ 'timeout' => $timeout, 'header' => "User-Agent: Mozilla/5.0\r\n" ] ]); $resp = @file_get_contents($url, false, $ctx); if ($resp === false || $resp === null) return null; $data = json_decode($resp, true); return is_array($data) ? $data : null; } function numOrNull($v): ?float { if ($v === null) return null; if (!is_numeric($v)) return null; $n = floatval($v); if (!is_finite($n)) return null; return $n; } function lastKnownPct(array $cache, string $ticker): ?float { // cache esperado: { ok, timestamp, variacao: { TICKER: { pct_dia: x, ... } } } if (!isset($cache['variacao']) || !is_array($cache['variacao'])) return null; if (!isset($cache['variacao'][$ticker]) || !is_array($cache['variacao'][$ticker])) return null; $v = $cache['variacao'][$ticker]['pct_dia'] ?? null; return numOrNull($v); } /* ------------------------- CACHE DIÃRIO PREVCLOSE ------------------------- */ function prevCacheLoad(string $file): array { $data = readJson($file); return is_array($data) ? $data : []; } function prevCacheSave(string $file, array $cache): void { writeJson($file, $cache); } function prevCacheGet(string $file, string $ticker): ?array { $cache = prevCacheLoad($file); $hoje = date('Y-m-d'); if (isset($cache[$hoje]) && is_array($cache[$hoje]) && isset($cache[$hoje][$ticker]) && is_array($cache[$hoje][$ticker])) { return $cache[$hoje][$ticker]; } return null; } function prevCacheSet(string $file, string $ticker, array $val): void { $cache = prevCacheLoad($file); $hoje = date('Y-m-d'); if (!isset($cache[$hoje]) || !is_array($cache[$hoje])) $cache[$hoje] = []; $cache[$hoje][$ticker] = $val + ['cached_at' => date('Y-m-d H:i:s')]; // manter só últimos 7 dias $dias = array_keys($cache); sort($dias); while (count($dias) > 7) { $d = array_shift($dias); unset($cache[$d]); } prevCacheSave($file, $cache); } /* ------------------------- PREVCLOSE PROVIDERS ------------------------- */ function obterPrevCloseTwelveData(string $symbol, string $apikey): ?array { $url = 'https://api.twelvedata.com/quote?symbol=' . urlencode($symbol) . '&apikey=' . urlencode($apikey); $data = httpGetJson($url, 12); if (!is_array($data)) return null; if (isset($data['status']) && $data['status'] === 'error') return null; if (!isset($data['previous_close']) || !is_numeric($data['previous_close'])) return null; return [ 'prev_close' => floatval($data['previous_close']), 'moeda' => isset($data['currency']) ? (string)$data['currency'] : null, 'fonte' => 'twelve' . $symbol ]; } function obterPrevCloseTwelveDataMulti(array $symbols, string $apikey): ?array { foreach ($symbols as $s) { $s = strtoupper(trim((string)$s)); if ($s === '') continue; $r = obterPrevCloseTwelveData($s, $apikey); if (is_array($r) && !empty($r['prev_close']) && floatval($r['prev_close']) > 0) return $r; } return null; } function obterPrevCloseEODHD(string $code, string $apikey): ?array { // busca 2 candles EOD e usa o anterior como prev_close $code = strtoupper(trim($code)); if ($code === '') return null; $url = 'https://eodhd.com/api/eod/' . urlencode($code) . '?api_token=' . urlencode($apikey) . '&fmt=json&order=d&limit=2'; $data = httpGetJson($url, 12); if (!is_array($data) || count($data) < 2) return null; $prev = $data[1] ?? null; // [0]=mais recente, [1]=anterior if (!is_array($prev) || !isset($prev['close']) || !is_numeric($prev['close'])) return null; return [ 'prev_close' => floatval($prev['close']), 'moeda' => null, 'fonte' => 'eodhd:' . $code ]; } function obterPrevCloseEODHDMulti(array $codes, string $apikey): ?array { foreach ($codes as $c) { $c = strtoupper(trim((string)$c)); if ($c === '') continue; $r = obterPrevCloseEODHD($c, $apikey); if (is_array($r) && !empty($r['prev_close']) && floatval($r['prev_close']) > 0) return $r; } return null; } function obterPrevCloseStooq(string $symbol): ?array { // CSV diário: Date,Open,High,Low,Close,Volume $symbol = strtolower(trim($symbol)); if ($symbol === '') return null; $url = 'https://stooq.com/q/d/l/?s=' . urlencode($symbol) . '&i=d'; $csv = @file_get_contents($url); if ($csv === false || trim($csv) === '') return null; $linhas = explode("\n", trim($csv)); if (count($linhas) < 3) return null; // header + pelo menos 2 dias $penultima = str_getcsv(trim($linhas[count($linhas) - 2])); if (count($penultima) < 5 || !is_numeric($penultima[4])) return null; return [ 'prev_close' => floatval($penultima[4]), 'moeda' => null, 'fonte' => 'stooq:' . $symbol ]; } function obterPrevCloseStooqMulti(array $symbols): ?array { foreach ($symbols as $s) { $s = strtolower(trim((string)$s)); if ($s === '') continue; $r = obterPrevCloseStooq($s); if (is_array($r) && !empty($r['prev_close']) && floatval($r['prev_close']) > 0) return $r; } return null; } /* ------------------------- 0) CACHE CURTO FINAL ------------------------- */ if (!$force && $OUT_TTL > 0 && file_exists($outCacheFile)) { $cache = readJson($outCacheFile); if (is_array($cache) && isset($cache['timestamp'])) { $ts = strtotime((string)$cache['timestamp']); if ($ts !== false && (time() - $ts) >= 0 && (time() - $ts) < $OUT_TTL) { responder($cache); } } } /* ------------------------- 1) LER PREÇOS ATUAIS ------------------------- */ $dados = readJson($precosFile); if (!is_array($dados)) { responder(['ok' => false, 'error' => 'precos-atuais.json não encontrado ou inválido'], 404); } $precos = (isset($dados['precos']) && is_array($dados['precos'])) ? $dados['precos'] : []; $cacheAnterior = readJson($outCacheFile); if (!is_array($cacheAnterior)) $cacheAnterior = []; $timestamp = date('Y-m-d H:i:s'); /* Mapa: ações -> TwelveData | ETFs -> Stooq (principal) + EODHD (fallback) Nota: Stooq symbols confirmados (exemplos): eunl.de, exxt.de, vusa.de [web sources fora deste ficheiro] */ $map = [ // AÇÕES 'AAPL' => ['tipo' => 'acao', 'twelvedata' => ['AAPL']], 'NVDA' => ['tipo' => 'acao', 'twelvedata' => ['NVDA']], 'GOOGL' => ['tipo' => 'acao', 'twelvedata' => ['GOOGL']], // METALS (EUR) – Ouro // Nota: o ticker interno do projeto é "XAUEUR" (key no precos-atuais.json), // mas o símbolo no TwelveData é "XAU/EUR". 'XAUEUR' => ['tipo' => 'acao', 'twelvedata' => ['XAU/EUR']], // ETFs (EUR) 'IWDA' => [ 'tipo' => 'etf', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'] ], 'NDXEX' => [ 'tipo' => 'etf', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'] ], 'VUSA' => [ 'tipo' => 'etf', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'] ], ]; $out = [ 'ok' => true, 'timestamp' => $timestamp, 'variacao' => [] ]; foreach ($precos as $ticker => $info) { if (!is_array($info)) continue; $preco = numOrNull($info['preco'] ?? null); $moeda = isset($info['moeda']) ? (string)$info['moeda'] : null; if ($preco === null || $preco <= 0) continue; // 1) Preferir % já vinda do preço (se existir) $pctDia = numOrNull($info['pct_dia'] ?? ($info['pct'] ?? null)); $prevClose = null; $fontePrev = null; // 2) Se não houver, tentar prev_close no próprio JSON if ($pctDia === null) { $prevCloseLocal = numOrNull($info['prev_close'] ?? ($info['prevclose'] ?? null)); if ($prevCloseLocal !== null && $prevCloseLocal > 0) { $prevClose = $prevCloseLocal; $fontePrev = 'precos-atuais.json'; } } // 3) Se ainda não houver, ir buscar prevclose (com cache diário) if ($pctDia === null && ($prevClose === null || $prevClose <= 0)) { $cached = prevCacheGet($prevCacheFile, $ticker); if (!$force && is_array($cached) && !empty($cached['prev_close']) && floatval($cached['prev_close']) > 0) { $prevClose = floatval($cached['prev_close']); $fontePrev = $cached['fonte'] ?? 'cache'; } else { $conf = $map[$ticker] ?? null; $prevInfo = null; // Ações: Twelve Data if ($conf && ($conf['tipo'] ?? '') === 'acao') { $prevInfo = obterPrevCloseTwelveDataMulti($conf['twelvedata'] ?? [$ticker], $APIKEY_TWELVEDATA); } // ETFs: Stooq principal if (!$prevInfo && $conf && ($conf['tipo'] ?? '') === 'etf') { $prevInfo = obterPrevCloseStooqMulti($conf['stooq'] ?? []); } // ETFs: fallback EODHD if (!$prevInfo && $conf && ($conf['tipo'] ?? '') === 'etf') { $prevInfo = obterPrevCloseEODHDMulti($conf['eodhd'] ?? [], $APIKEY_EODHD); } if ($prevInfo && !empty($prevInfo['prev_close']) && floatval($prevInfo['prev_close']) > 0) { $prevClose = floatval($prevInfo['prev_close']); $fontePrev = $prevInfo['fonte'] ?? null; prevCacheSet($prevCacheFile, $ticker, [ 'prev_close' => $prevClose, 'fonte' => $fontePrev, 'moeda' => $prevInfo['moeda'] ?? null ]); } } } // 4) Calcular % dia se já tiver prevclose if ($pctDia === null && $prevClose !== null && $prevClose > 0) { $pctDia = (($preco - $prevClose) / $prevClose) * 100.0; } // 5) Se ainda não houver, usar último valor válido para evitar '-' / null if ($pctDia === null) { $pctDia = lastKnownPct($cacheAnterior, $ticker); } // 6) Último fallback: 0 if ($pctDia === null) $pctDia = 0.0; $out['variacao'][$ticker] = [ 'ticker' => $ticker, 'moeda' => $moeda, 'preco' => $preco, 'pct_dia' => round($pctDia, 4), 'prev_close' => ($prevClose !== null ? round($prevClose, 6) : null), 'fonte_preco' => $info['fonte'] ?? null, 'fonte_prevclose' => $fontePrev, 'ts_preco' => $info['timestamp'] ?? null ]; } writeJson($outCacheFile, $out); responder($out); ======================================================================================== FICHEIRO: backup_20260611_153533/api/perplexity.php Tamanho: 7835 bytes ======================================================================================== false, 'http_code' => null, 'curl_error' => null, 'api_key_set' => ($apiKey !== ''), 'raw' => null, 'parsed_content' => null, ]; if ($apiKey === '' || $query === '') return null; $url = 'https://api.perplexity.ai/chat/completions'; // Prompt ultra restritivo para facilitar parsing $prompt = "Given this asset description: \"{$query}\", " . "return ONLY ONE number: the latest market price in {$moeda}. " . "Use dot as decimal separator. No symbols, no text, no explanation."; $payload = [ 'model' => 'sonar-pro', 'messages' => [ ['role' => 'system', 'content' => 'Return only the requested numeric value.'], ['role' => 'user', 'content' => $prompt], ], 'max_tokens' => 30, 'temperature' => 0.0, ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 25, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey, ], CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), ]); $resp = curl_exec($ch); $err = curl_error($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $debugOut['http_code'] = $code; $debugOut['curl_error'] = $err ?: null; $debugOut['raw'] = is_string($resp) ? $resp : null; if ($err) return null; if ($code < 200 || $code >= 300) return null; if (!is_string($resp) || trim($resp) === '') return null; $data = json_decode($resp, true); if (!is_array($data)) return null; $content = $data['choices'][0]['message']['content'] ?? null; if (!is_string($content) || trim($content) === '') return null; $debugOut['parsed_content'] = $content; $debugOut['ok_http'] = true; // Extrair primeiro número $clean = trim(str_replace(',', '.', $content)); if (preg_match('/[-+]?[0-9]*\\.?[0-9]+/', $clean, $m)) { $v = (float)$m[0]; if (is_finite($v) && $v > 0) return $v; } return null; } /** * Obter taxa de câmbio EUR/USD via Perplexity API * Usa a constante PPLX_API_KEY definida no início do ficheiro */ function obterTaxaCambioPerplexity(string $query, &$debug = null): ?float { // Usar a constante já definida $apiKey = pplx_api_key(); if ($apiKey === '') { $debug = ['erro' => 'PPLXAPIKEY em falta (env do PHP-FPM)']; return null; } $prompt = "Given this forex description: \"{$query}\", " . "return ONLY ONE number: the current EUR/USD exchange rate with 4 decimals " . "(for example: 1.0534). Use dot as decimal separator. " . "No symbols, no text, no explanation."; $postData = [ 'model' => 'sonar', 'messages' => [ [ 'role' => 'system', 'content' => 'Return only the requested numeric value.' ], [ 'role' => 'user', 'content' => $prompt ] ], 'temperature' => 0.1, 'max_tokens' => 20 ]; $ch = curl_init('https://api.perplexity.ai/chat/completions'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey ], CURLOPT_POSTFIELDS => json_encode($postData), CURLOPT_TIMEOUT => 15, CURLOPT_SSL_VERIFYPEER => true ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); curl_close($ch); if ($httpCode !== 200) { $debug = [ 'erro' => 'HTTP ' . $httpCode, 'curl_error' => $curlError, 'api_key_prefix' => substr($apiKey, 0, 15) . '...' ]; return null; } if (!$response) { $debug = ['erro' => 'Resposta vazia', 'curl_error' => $curlError]; return null; } $data = json_decode($response, true); if (!isset($data['choices'][0]['message']['content'])) { $debug = ['erro' => 'Resposta inválida da API', 'response' => $data]; return null; } $content = trim($data['choices'][0]['message']['content']); // Extrair número (suporta formatos: 1.0534, "1.0534", "The rate is 1.0534") if (preg_match('/(\d+\.\d{2,4})/', $content, $matches)) { $taxa = floatval($matches[1]); // Validação EUR/USD razoável (entre 0.85 e 1.30) if ($taxa >= 0.85 && $taxa <= 1.30) { $debug = [ 'success' => true, 'content' => $content, 'taxa' => $taxa, 'model' => 'sonar' ]; return round($taxa, 4); } else { $debug = [ 'erro' => 'Taxa fora do intervalo válido (0.85-1.30)', 'taxa_recebida' => $taxa, 'content' => $content ]; return null; } } $debug = [ 'erro' => 'Não foi possível extrair número da resposta', 'content' => $content ]; return null; } /** * Obter previous close de ativo via Perplexity * * @param string $query Query (ex: "AAPL previous close price") * @param string $moeda Moeda esperada (EUR ou USD) * @return float|null Previous close ou null */ function obterPrevClosePerplexity(string $query, string $moeda = ''): ?float { $apiKey = pplx_api_key(); if (!$apiKey) return null; $prompt = "Given this asset description: \"{$query}\", " . "return ONLY ONE number: the previous day closing price in {$moeda}. " . "Use dot as decimal separator. No symbols, no text, no explanation."; $postData = [ 'model' => 'sonar', 'messages' => [ [ 'role' => 'system', 'content' => 'Return only the requested numeric value.' ], [ 'role' => 'user', 'content' => $prompt ] ], 'temperature' => 0.1, 'max_tokens' => 50 ]; $ch = curl_init('https://api.perplexity.ai/chat/completions'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey ], CURLOPT_POSTFIELDS => json_encode($postData), CURLOPT_TIMEOUT => 15 ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200 || !$response) { return null; } $data = json_decode($response, true); if (!isset($data['choices'][0]['message']['content'])) { return null; } $content = trim($data['choices'][0]['message']['content']); // Extrair número if (preg_match('/(\d+[\.,]\d+)/', $content, $matches)) { $price = floatval(str_replace(',', '.', $matches[1])); if ($price > 0) { return round($price, 6); } } return null; } ======================================================================================== FICHEIRO: backup_20260611_153533/api/simbolos.php Tamanho: 13712 bytes ======================================================================================== metadados // - "interno": usado em cálculos, JSON de preços e normalizações // - "json": chave dentro de dadoscsvprecos-atuais.json (normalmente igual ao interno) // - "tabela": símbolo com prefixo de bolsa usado nas tabelas (frontend / histórico) // - "aliases": maneiras alternativas de escrever o mesmo ativo (Revolut, CSV, etc.) // - "nome": nome mais usado / amigável para mostrar na UI const MAPA_SIMBOLOS = [ // ------------- CORE / AÇÕES US ------------- 'AAPL' => [ 'nome' => 'Apple', 'json' => 'AAPL', 'tabela' => 'Apple', 'aliases' => ['AAPL', 'NASDAQ:AAPL', 'Apple'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['aapl.us'], 'twelve' => ['AAPL'], 'manual' => 0, ], 'NVDA' => [ 'nome' => 'NVIDIA', 'json' => 'NVDA', 'tabela' => 'NVIDIA', 'aliases' => ['NVDA', 'NASDAQ:NVDA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nvda.us'], 'twelve' => ['NVDA'], 'manual' => 0, ], 'GOOGL' => [ 'nome' => 'Google', 'json' => 'GOOGL', 'tabela' => 'Google', 'aliases' => ['GOOGL', 'NASDAQ:GOOGL', 'GOOG', 'NASDAQ:GOOG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['googl.us'], 'twelve' => ['GOOGL'], 'manual' => 0, ], 'AMZN' => [ 'nome' => 'Amazon', 'json' => 'AMZN', 'tabela' => 'Amazon', 'aliases' => ['AMZN', 'NASDAQ:AMZN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amzn.us'], 'twelve' => ['AMZN'], 'manual' => 0, ], 'ADBE' => [ 'nome' => 'Adobe', 'json' => 'ADBE', 'tabela' => 'Adobe', 'aliases' => ['ADBE', 'NASDAQ:ADBE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['adbe.us'], 'twelve' => ['ADBE'], 'manual' => 0, ], 'TSLA' => [ 'nome' => 'Tesla', 'json' => 'TSLA', 'tabela' => 'Tesla', 'aliases' => ['TSLA', 'NASDAQ:TSLA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsla.us'], 'twelve' => ['TSLA'], 'manual' => 0, ], 'MSFT' => [ 'nome' => 'Microsoft', 'json' => 'MSFT', 'tabela' => 'Microsoft', 'aliases' => ['MSFT', 'NASDAQ:MSFT'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['msft.us'], 'twelve' => ['MSFT'], 'manual' => 0, ], 'NFLX' => [ 'nome' => 'Netflix', 'json' => 'NFLX', 'tabela' => 'Netflix', 'aliases' => ['NFLX', 'NASDAQ:NFLX'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nflx.us'], 'twelve' => ['NFLX'], 'manual' => 0, ], 'AMD' => [ 'nome' => 'Advanced Micro Devices', 'json' => 'AMD', 'tabela' => 'Advanced Micro Devices', 'aliases' => ['AMD', 'NASDAQ:AMD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['amd.us'], 'twelve' => ['AMD'], 'manual' => 0, ], 'ZM' => [ 'nome' => 'Zoom Video', 'json' => 'ZM', 'tabela' => 'Zoom Video', 'aliases' => ['ZM', 'NASDAQ:ZM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['zm.us'], 'twelve' => ['ZM'], 'manual' => 0, ], 'Z' => [ 'nome' => 'Zillow', 'json' => 'Z', 'tabela' => 'Zillow', 'aliases' => ['Z', 'NASDAQ:Z'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['z.us'], 'twelve' => ['Z'], 'manual' => 0, ], 'MRNA' => [ 'nome' => 'Moderna', 'json' => 'MRNA', 'tabela' => 'Moderna', 'aliases' => ['MRNA', 'NASDAQ:MRNA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mrna.us'], 'twelve' => ['MRNA'], 'manual' => 0, ], 'PLUG' => [ 'nome' => 'Plug Power', 'json' => 'PLUG', 'tabela' => 'Plug Power', 'aliases' => ['PLUG', 'NASDAQ:PLUG'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['plug.us'], 'twelve' => ['PLUG'], 'manual' => 0, ], 'PYPL' => [ 'nome' => 'PayPal', 'json' => 'PYPL', 'tabela' => 'PayPal', 'aliases' => ['PYPL', 'NASDAQ:PYPL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['pypl.us'], 'twelve' => ['PYPL'], 'manual' => 0, ], 'ANSS' => [ 'nome' => 'ANSYS', 'json' => 'ANSS', 'tabela' => 'ANSYS', 'aliases' => ['ANSS', 'NASDAQ:ANSS'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['anss.us'], 'twelve' => ['ANSS'], 'manual' => 0, ], 'QCOM' => [ 'nome' => 'Qualcomm', 'json' => 'QCOM', 'tabela' => 'Qualcomm', 'aliases' => ['QCOM', 'NASDAQ:QCOM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['qcom.us'], 'twelve' => ['QCOM'], 'manual' => 0, ], 'UAL' => [ 'nome' => 'United Airlines', 'json' => 'UAL', 'tabela' => 'United Airlines', 'aliases' => ['UAL', 'NASDAQ:UAL'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ual.us'], 'twelve' => ['UAL'], 'manual' => 0, ], // ------------- FINANCE / PAYMENT ------------- 'MA' => [ 'nome' => 'Mastercard', 'json' => 'MA', 'tabela' => 'Mastercard', 'aliases' => ['MA', 'NYSE:MA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ma.us'], 'twelve' => ['MA'], 'manual' => 0, ], 'SQ' => [ 'nome' => 'Square', 'json' => 'SQ', 'tabela' => 'Square', 'aliases' => ['SQ', 'NYSE:SQ'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['sq.us'], 'twelve' => ['SQ'], 'manual' => 0, ], 'BAC' => [ 'nome' => 'Bank of America', 'json' => 'BAC', 'tabela' => 'Bank of America', 'aliases' => ['BAC', 'NYSE:BAC'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['bac.us'], 'twelve' => ['BAC'], 'manual' => 0, ], 'TSM' => [ 'nome' => 'Taiwan Semiconductor', 'json' => 'TSM', 'tabela' => 'Taiwan Semiconductor', 'aliases' => ['TSM', 'NYSE:TSM'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['tsm.us'], 'twelve' => ['TSM'], 'manual' => 0, ], 'BABA' => [ 'nome' => 'Alibaba Group', 'json' => 'BABA', 'tabela' => 'Alibaba Group', 'aliases' => ['BABA', 'NYSE:BABA'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['baba.us'], 'twelve' => ['BABA'], 'manual' => 0, ], 'BRKB' => [ 'nome' => 'Berkshire Hathaway', 'json' => 'BRKB', 'tabela' => 'Berkshire Hathaway', 'aliases' => ['BRKB', 'BRK.B', 'NYSE:BRK.B'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['brk-b.us'], 'twelve' => ['BRK.B', 'BRKB'], 'manual' => 0, ], // ------------- CONSUMO / OUTROS ------------- 'MCD' => [ 'nome' => 'McDonald\'s', 'json' => 'MCD', 'tabela' => 'McDonald\'s', 'aliases' => ['MCD', 'NYSE:MCD'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['mcd.us'], 'twelve' => ['MCD'], 'manual' => 0, ], 'KO' => [ 'nome' => 'Coca-Cola', 'json' => 'KO', 'tabela' => 'Coca-Cola', 'aliases' => ['KO', 'NYSE:KO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['ko.us'], 'twelve' => ['KO'], 'manual' => 0, ], 'SPCE' => [ 'nome' => 'Virgin Galactic', 'json' => 'SPCE', 'tabela' => 'Virgin Galactic', 'aliases' => ['SPCE', 'NYSE:SPCE'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['spce.us'], 'twelve' => ['SPCE'], 'manual' => 0, ], 'O' => [ 'nome' => 'Realty Income', 'json' => 'O', 'tabela' => 'Realty Income', 'aliases' => ['O', 'NYSE:O'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['o.us'], 'twelve' => ['O'], 'manual' => 0, ], 'TWTR' => [ 'nome' => 'Twitter', 'json' => 'TWTR', 'tabela' => 'Twitter', 'aliases' => ['TWTR', 'NYSE:TWTR'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['twtr.us'], 'twelve' => ['TWTR'], 'manual' => 0, ], 'NIO' => [ 'nome' => 'NIO', 'json' => 'NIO', 'tabela' => 'NIO', 'aliases' => ['NIO', 'NYSE:NIO'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['nio.us'], 'twelve' => ['NIO'], 'manual' => 0, ], 'RIVN' => [ 'nome' => 'Rivian', 'json' => 'RIVN', 'tabela' => 'Rivian', 'aliases' => ['RIVN', 'NASDAQ:RIVN'], 'tipo' => 'acao', 'moeda' => 'USD', 'stooq' => ['rivn.us'], 'twelve' => ['RIVN'], 'manual' => 0, ], 'XYZ' => [ 'nome' => 'XYZ', 'json' => 'XYZ', 'tabela' => 'XYZ', 'aliases' => ['XYZ'], // placeholder sem providers ], // ------------- ETFs / RIVN / VUSA / XYZ e OURO ------------- 'VUSA' => [ 'nome' => 'VUSA - Vanguard S&P 500 Dist ETF (Revolut)', 'json' => 'VUSA', 'tabela' => 'VUSA S&P 500', 'aliases' => ['VUSA', 'LSE:VUSA', 'AMS:VUSA', 'VUSA.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['vusa.de'], 'eodhd' => ['VUSA.DE'], 'perplexityquery' => 'Current price Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'perplexityclosequery' => 'Previous close Vanguard S&P 500 UCITS ETF (VUSA.DE) (yahoo)', 'manual' => 0, ], 'IWDA' => [ 'nome' => 'IWDA - iShares Core MSCI World Acc ETF (Revolut)', 'json' => 'IWDA', 'tabela' => 'EUNL MSCI World', 'aliases' => ['IWDA', 'EUNL', 'AMS:IWDA', 'EUNL.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['eunl.de'], 'eodhd' => ['EUNL.DE'], 'perplexityquery' => 'Current price EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'perplexityclosequery' => 'Previous close EUNL.DE – iShares Core MSCI World UCITS ETF (Acc, EUR) (tradingview)', 'manual' => 0, ], 'NDXEX' => [ 'nome' => 'NDXEX - iShares Nasdaq 100 UCITS ETF (Dist) (Revolut)', 'json' => 'NDXEX', 'tabela' => 'EXXT Nasdaq-100', 'aliases' => ['NDXEX', 'NDX', 'INDEXNASDAQ:NDX', 'EXXT', 'EQQQ', 'EXXT.DE'], 'tipo' => 'etf', 'moeda' => 'EUR', 'stooq' => ['exxt.de'], 'eodhd' => ['EXXT.DE'], 'perplexityquery' => 'Current price iShares NASDAQ-100 UCITS ETF (DE) (EXXT.DE) (yahoo)', 'perplexityclosequery' => 'Previous close EXXT.DE iShares NASDAQ-100 UCITS ETF (DE) EUR (yahoo)', 'manual' => 0, ], 'XAUEUR' => [ 'nome' => 'Ouro (XAU/EUR)', 'json' => 'XAUEUR', 'tabela' => 'Ouro', 'moeda' => 'EUR', 'aliases' => ['XAUEUR', 'XAU/EUR', 'XAU EUR', 'OURO', 'GOLD','XAUEUR','XAU'], 'tipo' => 'ouro', 'stooq' => ['xaueur'], 'twelve' => ['XAU/EUR'], 'perplexityquery' => 'Current price, GOLD XAU/EUR', 'perplexityclosequery' => 'Previous close price for GOLD XAU/EUR', 'manual' => 0, ], ]; // Função genérica: dado um ticker qualquer (Revolut, CSV, etc.), devolve o ticker interno function normalizarTickerGlobal(string $raw): ?string { $n = strtoupper(trim($raw)); if ($n === '') { return null; } // 1) Remover prefixos de bolsa mais comuns $n = preg_replace('/^(NASDAQ|NYSE|AMS|INDEXNASDAQ|XETRA|LSE):?/', '', $n); // 2) BRK.B -> BRKB (remover pontos) $n = str_replace('.', '', $n); // 3) Remover qualquer coisa que não seja A–Z ou 0–9 $n = preg_replace('/[^A-Z0-9]/', '', $n); // 4) Procurar primeiro por match direto de interno if (isset(MAPA_SIMBOLOS[$n])) { return $n; } // 5) Procurar nos aliases foreach (MAPA_SIMBOLOS as $interno => $info) { if (!empty($info['aliases']) && in_array($n, $info['aliases'], true)) { return $interno; } } // 6) Fallback: devolve o limpo (permite lidar com ativos novos ainda não registados) return $n; } $simbolos = MAPA_SIMBOLOS; // Se este ficheiro foi chamado diretamente (não via include), enviar JSON if (realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME'] ?? '')) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(MAPA_SIMBOLOS, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } ======================================================================================== FICHEIRO: backup_20260611_153533/api/transacoesvistos.php Tamanho: 4202 bytes ======================================================================================== devolve transacoes-vistos.json do utilizador * POST -> marca/desmarca um visto por (tipo, id) * * Estrutura esperada (compatível com vistoCheck no verificador): * { * "versao": "1.0", * "ultimaAtualizacao": "YYYY-MM-DD HH:MM:SS", * "vistos": { * "alterarlinha": { "L:12": true }, * "adicionartransacao": {}, * "removertransacao": {} * } * } */ // Se este ficheiro estiver em /api/, o apiutilizador.php está 1 nível acima. $bootstrap = __DIR__ . '/../api/utilizador.php'; // Fallback: caso este ficheiro esteja na raiz (sem pasta api) if (!is_file($bootstrap)) $bootstrap = __DIR__ . '/api/utilizador.php'; require_once $bootstrap; function readJsonFile(string $path): array { if (!is_file($path)) return []; $raw = @file_get_contents($path); if (!is_string($raw) || trim($raw) === '') return []; $j = json_decode($raw, true); return is_array($j) ? $j : []; } function writeJsonFile(string $path, array $data): bool { $dir = dirname($path); if (!is_dir($dir)) @mkdir($dir, 0775, true); $raw = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); if (!is_string($raw)) return false; return @file_put_contents($path, $raw, LOCK_EX) !== false; } function ensureSchema(array $j): array { if (!isset($j['versao'])) $j['versao'] = '1.0'; if (!isset($j['vistos']) || !is_array($j['vistos'])) $j['vistos'] = []; foreach (['alterarlinha', 'adicionartransacao', 'removertransacao'] as $t) { if (!isset($j['vistos'][$t]) || !is_array($j['vistos'][$t])) { $j['vistos'][$t] = []; } } if (!isset($j['ultimaAtualizacao'])) $j['ultimaAtualizacao'] = date('Y-m-d H:i:s'); return $j; } $ficheiro = userFilePath('transacoes-vistos.json'); if ($_SERVER['REQUEST_METHOD'] === 'GET') { $j = ensureSchema(readJsonFile($ficheiro)); echo json_encode($j, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $raw = file_get_contents('php://input'); $input = json_decode((string)$raw, true); if (!is_array($input)) { echo json_encode(['ok' => false, 'error' => 'JSON inválido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // Novo formato: tipo + id $tipo = isset($input['tipo']) ? trim((string)$input['tipo']) : ''; $id = isset($input['id']) ? trim((string)$input['id']) : ''; // Compatibilidade mínima com chamadas antigas: {linha:"L:12"} ou {linha:"12"} if (($tipo === '' || $id === '') && isset($input['linha'])) { $tipo = $tipo !== '' ? $tipo : 'alterarlinha'; $linha = trim((string)$input['linha']); if ($linha !== '') { $id = (strpos($linha, 'L:') === 0) ? $linha : ('L:' . $linha); } } if (!in_array($tipo, ['alterarlinha', 'adicionartransacao', 'removertransacao'], true)) { echo json_encode(['ok' => false, 'error' => 'Tipo inválido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if ($id === '') { echo json_encode(['ok' => false, 'error' => 'ID não fornecido'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } $marcar = true; if (isset($input['ok'])) $marcar = (bool)$input['ok']; if (isset($input['marcar'])) $marcar = (bool)$input['marcar']; // alias $j = ensureSchema(readJsonFile($ficheiro)); if ($marcar) { $j['vistos'][$tipo][$id] = true; } else { if (isset($j['vistos'][$tipo][$id])) unset($j['vistos'][$tipo][$id]); } $j['ultimaAtualizacao'] = date('Y-m-d H:i:s'); $ok = writeJsonFile($ficheiro, $j); echo json_encode([ 'ok' => $ok, 'tipo' => $tipo, 'id' => $id, 'marcar' => $marcar, 'user' => getUserId(), 'ficheiro' => basename($ficheiro) ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } echo json_encode(['ok' => false, 'error' => 'Método não suportado'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; ======================================================================================== FICHEIRO: backup_20260611_153533/api/uploadacoes.php Tamanho: 1600 bytes ======================================================================================== false, 'error' => 'CSV vazio.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } // Validação leve: garantir que parece um CSV de transações if (stripos($csv, 'Ordem,') !== 0) { echo json_encode(['ok' => false, 'error' => 'Cabeçalho CSV inválido (esperado começar por "Ordem,").'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $ficheiro = userFilePath('transacoes-acoes.csv'); $dir = dirname($ficheiro); if (!is_dir($dir) && !@mkdir($dir, 0775, true)) { echo json_encode(['ok' => false, 'error' => 'Falha ao criar diretório do utilizador.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0775, true); } // Backup do ficheiro anterior (se existir) if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/transacoes-acoes-' . date('YmdHis') . '.csv'); } $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { echo json_encode(['ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode(['ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId()], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: backup_20260611_153533/api/uploadcaixa.php Tamanho: 2578 bytes ======================================================================================== false, 'error' => 'CSV vazio.']); } // Validação leve: cabeçalho esperado para movimentos-caixa if (stripos($csv, "Ordem,Data,Tipo,Valor,Moeda,Descricao") !== 0) { responder([ 'ok' => false, 'error' => 'Cabeçalho CSV inválido (caixa). Esperado: Ordem,Data,Tipo,Valor,Moeda,Descricao,...' ]); } $user = function_exists('getUserId') ? getUserId() : null; // ✅ ficheiro correto $ficheiro = userFilePath('movimentos-caixa.csv'); $dir = dirname($ficheiro); // Garantir pasta do utilizador if (!is_dir($dir)) { if (!@mkdir($dir, 0775, true)) { $e = error_get_last(); responder([ 'ok' => false, 'error' => 'Falha ao criar diretório do utilizador.', 'dir' => $dir, 'detalhe' => $e['message'] ?? null, 'user' => $user ]); } } // Backups $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0777, true); } // Diagnóstico de permissões clearstatcache(true, $dir); clearstatcache(true, $ficheiro); $diag = [ 'dir' => $dir, 'dir_existe' => is_dir($dir), 'dir_writable' => is_writable($dir), 'ficheiro' => $ficheiro, 'ficheiro_existe' => is_file($ficheiro), 'ficheiro_writable' => is_file($ficheiro) ? is_writable($ficheiro) : null, 'php_user' => function_exists('get_current_user') ? get_current_user() : null, ]; // Backup do ficheiro anterior se existir (não deve bloquear a gravação) if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/movimentos-caixa-' . date('YmdHis') . '.csv'); } // Gravar $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { $e = error_get_last(); responder([ 'ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.', 'detalhe' => $e['message'] ?? null, 'diag' => $diag, 'user' => $user ]); } @chmod($ficheiro, 0777); responder([ 'ok' => true, 'ficheiro' => basename($ficheiro), 'bytes' => $ok, 'diag' => $diag, 'user' => $user ]); ======================================================================================== FICHEIRO: backup_20260611_153533/api/uploadextratorevolut.php Tamanho: 1143 bytes ======================================================================================== false, 'error' => 'Nenhum conteúdo recebido (CSV vazio).', ]); exit; } // Caminho do ficheiro por utilizador: dados_csv//extrato-revolut.csv $ficheiro = userFilePath('extrato-revolut.csv'); $dir = dirname($ficheiro); // Garantir diretório do utilizador if (!is_dir($dir)) { mkdir($dir, 0775, true); } // Pasta de backups $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { mkdir($backupDir, 0775, true); } // Backup do ficheiro anterior (se existir) if (file_exists($ficheiro)) { @copy($ficheiro, $backupDir . '/extrato-revolut-' . date('YmdHis') . '.csv'); } // Gravar extrato atual file_put_contents($ficheiro, $csv); echo json_encode([ 'ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId(), ]); ?> ======================================================================================== FICHEIRO: backup_20260611_153533/api/uploadhistoricoativos.php Tamanho: 1289 bytes ======================================================================================== false, 'error' => 'CSV vazio.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $ficheiro = userFilePath('historico-ativos.csv'); $dir = dirname($ficheiro); if (!is_dir($dir) && !@mkdir($dir, 0775, true)) { echo json_encode(['ok' => false, 'error' => 'Falha ao criar diretório do utilizador.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } $backupDir = $dir . '/backups'; if (!is_dir($backupDir)) { @mkdir($backupDir, 0775, true); } if (is_file($ficheiro)) { @copy($ficheiro, $backupDir . '/historico-ativos-' . date('YmdHis') . '.csv'); } $ok = @file_put_contents($ficheiro, $csv, LOCK_EX); if ($ok === false) { echo json_encode(['ok' => false, 'error' => 'Falha ao gravar o ficheiro no servidor.'], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit; } echo json_encode(['ok' => true, 'ficheiro' => basename($ficheiro), 'user' => getUserId()], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); ======================================================================================== FICHEIRO: backup_20260611_153533/api/utilizador.php Tamanho: 1042 bytes ======================================================================================== / // Ex.: dados_csv/tiago/transacoes-acoes.csv, dados_csv/maria/movimentos-caixa.csv function getUserId(): string { // Aceita ?user=tiago ou ?user=maria na query string ou no corpo POST $user = $_GET['user'] ?? ($_POST['user'] ?? 'tiago'); $user = strtolower($user); // Sanitizar: apenas letras, números, _ e - $user = preg_replace('/[^a-z0-9_\-]/', '', $user); if ($user === '' || $user === null) { $user = 'tiago'; } return $user; } function getUserDataDir(): string { // Este ficheiro está em /api, por isso dirname(__DIR__) = raiz do projeto $root = dirname(__DIR__); $user = getUserId(); $dir = $root . '/dados_csv/' . $user; if (!is_dir($dir)) { @mkdir($dir, 0755, true); } return $dir; } function userFilePath(string $fileName): string { return getUserDataDir() . '/' . $fileName; } ?> ======================================================================================== FICHEIRO: backup_20260611_153533/api_atualizar.php Tamanho: 8597 bytes ======================================================================================== false, 'error' => $e->getMessage())); } exit; function listarFicheiros($dir) { $ficheiros = array(); $ignorar = array('atualizar.html', 'index.html', 'api_atualizar.php', 'icon.png', 'nginx.conf'); $scan = scandir($dir); foreach ($scan as $item) { if ($item === '.' || $item === '..') continue; if (is_dir($dir . '/' . $item)) continue; if (in_array($item, $ignorar)) continue; $ficheiros[] = $item; } sort($ficheiros); return json_encode(array('ok' => true, 'ficheiros' => $ficheiros, 'total' => count($ficheiros))); } function analisar($dir, $input) { if (!isset($input['descricao']) || empty($input['descricao'])) { throw new Exception('Descricao nao fornecida'); } $ficheiros = isset($input['ficheiros']) ? $input['ficheiros'] : array(); if (empty($ficheiros)) { throw new Exception('Nenhum ficheiro selecionado'); } $log = array('ANALISE DO SITE', '', 'PROBLEMA:', $input['descricao'], '', 'FICHEIROS (' . count($ficheiros) . '):'); $conteudos = array(); $encontrados = 0; foreach ($ficheiros as $ficheiro) { $caminho = $dir . '/' . $ficheiro; if (!file_exists($caminho)) { $log[] = '- ' . $ficheiro . ' NAO ENCONTRADO'; continue; } $tamanho = filesize($caminho); $log[] = '- ' . $ficheiro . ' (' . number_format($tamanho) . ' bytes)'; $conteudos[$ficheiro] = file_get_contents($caminho, false, null, 0, 51200); $encontrados++; } if ($encontrados === 0) { throw new Exception('Nenhum ficheiro encontrado'); } $log[] = ''; $log[] = 'Analise concluida - ' . $encontrados . ' ficheiros processados'; return json_encode(array('ok' => true, 'analise' => implode("\n", $log), 'ficheiros_analisados' => $ficheiros, 'conteudos' => $conteudos)); } function gerarPrompt($input) { if (!isset($input['analise'])) { throw new Exception('Analise nao fornecida'); } $analise = $input['analise']; $ficheiros = isset($analise['ficheiros_analisados']) ? $analise['ficheiros_analisados'] : array(); $conteudos = isset($analise['conteudos']) ? $analise['conteudos'] : array(); $prompt = array(); $prompt[] = '# CORRECAO AUTOMATICA'; $prompt[] = ''; $prompt[] = '## PROBLEMA:'; $prompt[] = $analise['analise']; $prompt[] = ''; $prompt[] = '## FICHEIROS:'; foreach ($ficheiros as $ficheiro) { if (isset($conteudos[$ficheiro])) { $prompt[] = ''; $prompt[] = '### ' . $ficheiro; $prompt[] = '--- INICIO DO CODIGO ---'; $prompt[] = $conteudos[$ficheiro]; $prompt[] = '--- FIM DO CODIGO ---'; } } $prompt[] = ''; $prompt[] = '## TAREFA:'; $prompt[] = 'Criar um script unico PHP que corrija o problema descrito acima. Para colar e executar'; return json_encode(array('ok' => true, 'prompt' => implode("\n", $prompt))); } function gerarCodigoPerplexity($input) { // Reaproveitar a lógica de gerarPrompt para construir o texto do prompt if (!isset($input['analise'])) { throw new Exception('Analise nao fornecida'); } // 1) Obter o prompt de texto já montado $jsonPrompt = json_decode(gerarPrompt($input), true); if (!$jsonPrompt || !isset($jsonPrompt['prompt'])) { throw new Exception('Falha ao gerar prompt de base'); } $promptTexto = $jsonPrompt['prompt']; // 2) CHAMAR A API DA PERPLEXITY // Troque "SUA_API_KEY_AQUI" pela sua chave real $apiKey = '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'; $url = 'https://api.perplexity.ai/chat/completions'; $payload = [ 'model' => 'sonar-reasoning-pro', 'messages' => [ [ 'role' => 'system', 'content' => 'És um assistente especializado em gerar scripts PHP de correção automática. Responde SEM explicações, apenas com o código PHP completo, pronto a ser colado e executado.' ], [ 'role' => 'user', 'content' => $promptTexto ] ], 'max_tokens' => 2000, 'temperature' => 0.2, ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey, ], CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_TIMEOUT => 60, ]); $resposta = curl_exec($ch); $erroCurl = curl_error($ch); curl_close($ch); if ($erroCurl) { throw new Exception('Erro na chamada à API Perplexity: ' . $erroCurl); } $data = json_decode($resposta, true); if (!is_array($data) || empty($data['choices'][0]['message']['content'])) { return json_encode([ 'ok' => false, 'error' => 'Resposta inesperada da API Perplexity', 'raw' => $resposta, 'prompt' => $promptTexto, ]); } $codigoGerado = $data['choices'][0]['message']['content']; return json_encode([ 'ok' => true, 'codigo' => $codigoGerado, 'prompt' => $promptTexto, 'raw' => $resposta, ]); } function executar($dir, $backupDir, $input) { if (!isset($input['codigo']) || empty($input['codigo'])) { throw new Exception('Codigo nao fornecido'); } $timestamp = date('Ymd_His'); if (!file_exists($backupDir)) { mkdir($backupDir, 0755, true); } $backupFile = $backupDir . 'backup_' . $timestamp . '.tar.gz'; $cmd = 'cd ' . escapeshellarg($dir) . ' && tar -czf ' . escapeshellarg($backupFile) . ' *.html *.php *.csv *.json 2>&1'; @shell_exec($cmd); $tempFile = $dir . '/temp_' . $timestamp . '.php'; file_put_contents($tempFile, $input['codigo']); ob_start(); try { include $tempFile; $output = ob_get_clean(); } catch (Exception $e) { ob_end_clean(); $output = 'ERRO: ' . $e->getMessage(); } @unlink($tempFile); return json_encode(array('ok' => true, 'log' => $output ? $output : 'Executado com sucesso', 'backup' => basename($backupFile))); } function verificar($dir) { $log = array('VERIFICACAO DE INTEGRIDADE', ''); $ok = 0; $ficheirosEssenciais = array('resumo.html', 'transacoes.html', 'base-dados-dinheiro.html'); foreach ($ficheirosEssenciais as $ficheiro) { $caminho = $dir . '/' . $ficheiro; if (file_exists($caminho)) { $log[] = 'OK: ' . $ficheiro . ' (' . filesize($caminho) . ' bytes)'; $ok++; } else { $log[] = 'ERRO: ' . $ficheiro . ' - NAO ENCONTRADO'; } } $log[] = ''; $log[] = 'Total OK: ' . $ok . '/' . count($ficheirosEssenciais); return json_encode(array('ok' => true, 'relatorio' => implode("\n", $log), 'total_ok' => $ok)); } ?> ======================================================================================== FICHEIRO: backup_20260611_153533/auth.php Tamanho: 162 bytes ======================================================================================== false, "error"=>"Unauthorized"]); exit; } ?> ======================================================================================== FICHEIRO: backup_20260611_153533/converter.php Tamanho: 1791 bytes ======================================================================================== ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/agostinha/lucro-mensal.json Tamanho: 8128 bytes ======================================================================================== { "ok": true, "user": "agostinha", "moeda": "EUR", "compatibilidade": true, "totalmeses": 13, "investimentoinicial": 10000, "series": [ { "mes": "2024-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 580.31, "dividendos": 0, "taxas": 0, "net": 580.31, "deltarealizado": 0, "deltanaorealizado": 580.31, "realizadoacumulado": 0, "naorealizadofimmes": 580.31, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 10469.39, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 10469.39, "investimentoinicial": 10000, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 15:58:45", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/agostinha/movimentos-caixa.csv Tamanho: 231 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2024-12-19,Depósito,10000,EUR,Deposito Inicial,1 2,2024-12-19,Levantamento,-2000,EUR,Transferencia para Dolar,1 3,2024-12-19,Depósito,2077.98,USD,Transferencia para Dolar,1.03899 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/agostinha/transacoes-acoes.csv Tamanho: 338 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2024-12-19","","INDEXNASDAQ:NDX","20.08062405","9.98","4000","","1","","EUR" "2","2024-12-19","","AMS:IWDA","38.58620157","0","4000","","1","","EUR" "3","2024-12-19","","NASDAQ:AAPL","8.27211292","4.99","2077.98","","","","USD" ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/converter.php Tamanho: 10888 bytes ======================================================================================== = 70 ? '19' : '20') . $year; } return sprintf('%04d-%02d', (int)$year, (int)$m[2]); } function parseDecimal(?string $value): ?float { if ($value === null) { return null; } $value = trim($value); if ($value === '' || $value === '-' || strtoupper($value) === 'NULL') { return null; } $value = str_replace(' ', '', $value); $value = str_replace('.', '', $value); $value = str_replace(',', '.', $value); if (!is_numeric($value)) { return null; } return (float)$value; } function normalizeTicker(string $raw): array { $raw = strtoupper(trim($raw)); $manualMap = [ 'AAPL' => ['ticker' => 'AAPL', 'stooq' => 'aapl.us', 'moeda' => 'USD'], 'TSLA' => ['ticker' => 'TSLA', 'stooq' => 'tsla.us', 'moeda' => 'USD'], 'PYPL' => ['ticker' => 'PYPL', 'stooq' => 'pypl.us', 'moeda' => 'USD'], 'GOOGL' => ['ticker' => 'GOOGL', 'stooq' => 'googl.us', 'moeda' => 'USD'], 'AMZN' => ['ticker' => 'AMZN', 'stooq' => 'amzn.us', 'moeda' => 'USD'], 'KO' => ['ticker' => 'KO', 'stooq' => 'ko.us', 'moeda' => 'USD'], 'BAC' => ['ticker' => 'BAC', 'stooq' => 'bac.us', 'moeda' => 'USD'], 'ANSS' => ['ticker' => 'ANSS', 'stooq' => 'anss.us', 'moeda' => 'USD'], 'AMD' => ['ticker' => 'AMD', 'stooq' => 'amd.us', 'moeda' => 'USD'], 'NVDA' => ['ticker' => 'NVDA', 'stooq' => 'nvda.us', 'moeda' => 'USD'], 'ADBE' => ['ticker' => 'ADBE', 'stooq' => 'adbe.us', 'moeda' => 'USD'], 'MSFT' => ['ticker' => 'MSFT', 'stooq' => 'msft.us', 'moeda' => 'USD'], 'SPCE' => ['ticker' => 'SPCE', 'stooq' => 'spce.us', 'moeda' => 'USD'], 'MRNA' => ['ticker' => 'MRNA', 'stooq' => 'mrna.us', 'moeda' => 'USD'], 'SQ' => ['ticker' => 'SQ', 'stooq' => 'sq.us', 'moeda' => 'USD'], 'NFLX' => ['ticker' => 'NFLX', 'stooq' => 'nflx.us', 'moeda' => 'USD'], 'NIO' => ['ticker' => 'NIO', 'stooq' => 'nio.us', 'moeda' => 'USD'], 'BRKB' => ['ticker' => 'BRKB', 'stooq' => 'brk-b.us', 'moeda' => 'USD'], 'PLUG' => ['ticker' => 'PLUG', 'stooq' => 'plug.us', 'moeda' => 'USD'], 'MA' => ['ticker' => 'MA', 'stooq' => 'ma.us', 'moeda' => 'USD'], 'MCD' => ['ticker' => 'MCD', 'stooq' => 'mcd.us', 'moeda' => 'USD'], 'UAL' => ['ticker' => 'UAL', 'stooq' => 'ual.us', 'moeda' => 'USD'], 'ZM' => ['ticker' => 'ZM', 'stooq' => 'zm.us', 'moeda' => 'USD'], 'BABA' => ['ticker' => 'BABA', 'stooq' => 'baba.us', 'moeda' => 'USD'], 'Z' => ['ticker' => 'Z', 'stooq' => 'z.us', 'moeda' => 'USD'], 'O' => ['ticker' => 'O', 'stooq' => 'o.us', 'moeda' => 'USD'], 'TWTR' => ['ticker' => 'TWTR', 'stooq' => 'twtr.us', 'moeda' => 'USD'], 'IWDA' => ['ticker' => 'IWDA', 'stooq' => 'eunl.de', 'moeda' => 'EUR'], 'QCOM' => ['ticker' => 'QCOM', 'stooq' => 'qcom.us', 'moeda' => 'USD'], 'TSM' => ['ticker' => 'TSM', 'stooq' => 'tsm.us', 'moeda' => 'USD'], 'NDXEX' => ['ticker' => 'NDXEX', 'stooq' => 'exxt.de', 'moeda' => 'EUR'], 'VUSA' => ['ticker' => 'VUSA', 'stooq' => 'vusa.de', 'moeda' => 'EUR'], 'XAUEUR' => ['ticker' => 'XAUEUR', 'stooq' => 'xaueur', 'moeda' => 'EUR'], ]; $aliasMap = [ 'NASDAQ:AAP' => 'AAPL', 'NASDAQ:PYP' => 'PYPL', 'NASDAQ:GOO' => 'GOOGL', 'NASDAQ:AMZ' => 'AMZN', 'NASDAQ:ANS' => 'ANSS', 'NASDAQ:NVD' => 'NVDA', 'NASDAQ:ADB' => 'ADBE', 'NASDAQ:MSF' => 'MSFT', 'NASDAQ:MRN' => 'MRNA', 'NASDAQ:NFL' => 'NFLX', 'NASDAQ:PLU' => 'PLUG', 'NASDAQ:QCO' => 'QCOM', 'NYSE:BRK.B' => 'BRKB', 'AMS:IWDA' => 'IWDA', 'AMS:VUSA' => 'VUSA', 'INDEXNASDAQ:NDX' => 'NDXEX', 'CURRENCY:XAUEUR' => 'XAUEUR', ]; if (isset($aliasMap[$raw])) { return $manualMap[$aliasMap[$raw]]; } $parts = strpos($raw, ':') !== false ? explode(':', $raw, 2) : ['', $raw]; $market = strtoupper(trim($parts[0] ?? '')); $ticker = strtoupper(trim($parts[1] ?? $raw)); $ticker = preg_replace('/[^A-Z0-9.\-]/', '', $ticker) ?: $ticker; if ($ticker === 'BRK.B') { $ticker = 'BRKB'; } $shortAliases = [ 'AAP' => 'AAPL', 'PYP' => 'PYPL', 'GOO' => 'GOOGL', 'AMZ' => 'AMZN', 'ANS' => 'ANSS', 'NVD' => 'NVDA', 'ADB' => 'ADBE', 'MSF' => 'MSFT', 'MRN' => 'MRNA', 'NFL' => 'NFLX', 'PLU' => 'PLUG', 'QCO' => 'QCOM', 'XAU' => 'XAUEUR', 'GOLD' => 'XAUEUR', 'OURO' => 'XAUEUR', 'XAUEUR' => 'XAUEUR', ]; if (isset($shortAliases[$ticker])) { $ticker = $shortAliases[$ticker]; } if (isset($manualMap[$ticker])) { return $manualMap[$ticker]; } $suffixByMarket = [ 'NASDAQ' => '.us', 'NYSE' => '.us', 'AMEX' => '.us', 'ARCA' => '.us', 'BATS' => '.us', 'AMS' => '.de', 'XETR' => '.de', 'ETR' => '.de', 'FWB' => '.de', 'DE' => '.de', 'EURONEXT' => '.eu', 'CURRENCY' => '', 'INDEX' => '', ]; $moedaByMarket = [ 'AMS' => 'EUR', 'XETR' => 'EUR', 'ETR' => 'EUR', 'FWB' => 'EUR', 'DE' => 'EUR', 'CURRENCY' => 'EUR', 'INDEX' => 'EUR', ]; $moeda = $moedaByMarket[$market] ?? 'USD'; $suffix = $suffixByMarket[$market] ?? '.us'; $tickerClean = str_replace('.', '', $ticker); $stooqTicker = strtolower($tickerClean . $suffix); return [ 'ticker' => $tickerClean, 'stooq' => $stooqTicker, 'moeda' => $moeda, ]; } function buildDateColumnMap(array $header): array { $map = []; foreach ($header as $index => $cell) { $monthKey = parseMonthKey((string)$cell); if ($monthKey !== null) { $map[$index] = $monthKey; } } return $map; } function createMeta(int $totalTickers): array { return [ 'user' => 'tiago', 'todos' => false, 'encerradas' => false, 'mindatacompra' => '2019-10-15', 'minmesguardado' => '2019-10', 'debugtickersamostra' => ['AAPL', 'NVDA'], 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => 2592000, 'forcar' => false, 'stats' => [ 'totaltickers' => $totalTickers, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ], 'timestamp' => date('Y-m-d H:i:s'), ]; } try { header('Content-Type: application/json; charset=utf-8'); $csvPath = __DIR__ . '/dadosacoes.csv'; $outputDir = __DIR__ ; $jsonPath = $outputDir . '/historico-precos-mensal.json'; if (!is_file($csvPath)) { throw new RuntimeException("Ficheiro CSV não encontrado em: {$csvPath}"); } if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) { throw new RuntimeException("Não foi possível criar a pasta: {$outputDir}"); } $content = readFileUtf8($csvPath); $lines = preg_split('/\R/', trim($content)); if (!$lines || count($lines) < 5) { throw new RuntimeException('O CSV não tem linhas suficientes para ser processado.'); } $header = parseCsvLine($lines[0]); $dateColumnMap = buildDateColumnMap($header); if (!$dateColumnMap) { throw new RuntimeException('Não foi possível detetar colunas de datas no CSV.'); } $ativos = []; foreach ($lines as $lineNumber => $line) { if ($lineNumber < 4) { continue; } $line = trim($line); if ($line === '') { continue; } $cols = parseCsvLine($line); $symbolRaw = strtoupper(trim((string)($cols[1] ?? ''))); if ($symbolRaw === '') { continue; } $looksLikeSymbol = strpos($symbolRaw, ':') !== false || in_array($symbolRaw, ['XAU', 'XAUEUR', 'GOLD', 'OURO'], true) || str_starts_with($symbolRaw, 'INDEX') || str_starts_with($symbolRaw, 'CURRENCY'); if (!$looksLikeSymbol) { continue; } $mapped = normalizeTicker($symbolRaw); $mensal = []; foreach ($dateColumnMap as $index => $monthKey) { $value = parseDecimal($cols[$index] ?? null); if ($value !== null) { $mensal[$monthKey] = $value; } } if (!$mensal) { continue; } ksort($mensal); $ativos[$mapped['ticker']] = [ 'stooq' => $mapped['stooq'], 'moeda' => $mapped['moeda'], 'mensal' => $mensal, ]; } ksort($ativos); $result = [ 'meta' => createMeta(count($ativos)), 'ativos' => $ativos, ]; $json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); if ($json === false) { throw new RuntimeException('Falha ao gerar JSON.'); } if (file_put_contents($jsonPath, $json . PHP_EOL) === false) { throw new RuntimeException("Não foi possível gravar o ficheiro JSON em: {$jsonPath}"); } echo $json; } catch (Throwable $e) { http_response_code(500); echo json_encode([ 'erro' => $e->getMessage(), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/dadosacoes.csv Tamanho: 20258 bytes ======================================================================================== ;;;;;;31/12/18;31/01/19;28/02/19;31/03/19;30/04/19;31/05/19;30/06/19;31/07/19;31/08/19;30/09/19;31/10/19;30/11/19;31/12/19;31/01/20;29/02/20;31/03/20;30/04/20;31/05/20;30/06/20;31/07/20;31/08/20;30/09/20;31/10/20;30/11/20;31/12/20;31/01/21;28/02/21;31/03/21;30/04/21;31/05/21;30/06/21;31/07/21;31/08/21;30/09/21;31/10/21;30/11/21;31/12/21;31/01/22;28/02/22;31/03/22;30/04/22;31/05/22;30/06/22;31/07/22;31/08/22;30/09/22;31/10/22;30/11/22;30/12/22;31/01/23;28/02/23;31/03/23;30/04/23;31/05/23;30/06/23;31/07/23;31/08/23;30/09/23;31/10/23;30/11/23;31/12/23;31/01/24;29/02/24;31/03/24;30/04/24;31/05/24;27/06/24;30/07/24;31/08/24;30/09/24;31/10/24;30/11/24;31/12/24;31/01/25;28/02/25;31/03/25;30/04/25;31/05/25;30/06/25;31/07/25;31/08/25;30/09/25;31/10/25;30/11/25;31/12/25;31/01/26;28/02/26;31/03/26;30/04/26;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026 ;;;;;;2Ê018;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê026;2Ê026;2Ê026;2Ê026;5;6;7;8;9;10;11;12 ;;;;;;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;31;30;31;31;30;31;30;31 N¼;Tipo A›es;;;;;31;31;28;31;30;31;30;31;31;30;31;30;31;31;29;31;30;31;30;31;31;30;31;30;31;31;28;31;30;31;30;31;31;30;31;30;31;31;28;31;30;31;30;31;31;30;31;30;30;31;28;31;30;31;30;31;31;30;31;30;31;31;29;29;30;31;27;30;31;30;31;30;31;31;28;31;30;31;30;31;31;30;31;30;31;31;28;31;30;;;;;;;; 1;NASDAQ:AAPL;;;;;39,44;41,61;43,29;47,81;50,17;43,77;50,39;53,26;51,43;55,99;62,19;66,04;73,41;77,38;74,7;63,57;73,45;80,46;91,2;106,26;129,04;115,81;108,77;119,05;132,69;134,14;127,79;122,15;131,46;124,28;136,96;145,52;151,83;141,5;148,96;165,3;177,57;174,78;165,12;174,61;157,96;148,84;136,72;161,51;157,22;138,2;153,34;148,03;129,93;144,29;147,41;164,9;169,59;177,25;193,97;196,45;187,87;173,75;170,77;189,95;192,53;184,4;180,75;170,03;170,33;192,25;210,62;222,08;222,77;233;225,91;239,59;250,42;236;241,84;222,13;212,5;201,7;205,17;207,57;229,72;254,63;270,37;283,1;271,86;270,01;264,72;253,79;271,35;;;;;;;; 2;NASDAQ:TSLA;;;;;22,19;20,47;21,33;19,28;15,91;12,34;15,14;16,11;15;16,06;20,99;22,32;27,89;43,37;49,57;34,93;52,13;59,87;71,99;95,38;166,11;143;133,5;189,2;235,22;279,94;239,48;222,64;236,48;207,97;226,57;236,56;245,24;258,49;402,86;381,59;352,26;312,24;290,14;359,2;300,98;252,75;224,47;297,28;275,61;265,25;227,54;194,7;123,18;173,22;205,71;207,46;161,83;203,93;261,77;267,43;258,08;251,6;200,84;240,08;248,48;187,29;201,88;175,22;183,28;178,08;197,88;232,07;210,6;261,63;249,85;357,09;403,84;404,6;292,98;259,16;282,16;342,69;317,66;308,27;329,36;444,72;456,56;430,14;449,72;421,81;403,32;371,75;381,63;;;;;;;; 3;NASDAQ:PYPL;;;;;84,09;88,76;98,07;105,55;112,77;109,75;115,03;110,4;106,75;103,59;104,1;106,21;108,17;113,89;112,86;95,74;123;154,53;174,23;196,07;204,14;197,03;187,76;214,12;234,2;241,85;273,63;242,84;262,29;259,27;291,48;270,99;288,66;260,21;231,28;184,89;188,58;171,94;111,93;115,65;91,53;85,21;69,84;88,57;93,44;86,07;83,58;78,41;71,22;81,49;73,6;75,94;75,11;61,99;66,73;75,82;62,51;58,56;51,8;57,61;61,41;61,35;60,34;65,03;67,92;62,99;58,03;65,78;72;78,03;79,3;86,53;85,35;88,58;71,05;65,25;65,84;70,93;74,32;68,76;69,25;67,06;69,27;62,58;58,38;52,33;45,63;45,23;50,14;;;;;;;; 4;NASDAQ:GOOGL;;;;;52,25;56,29;56,33;59,95;59,95;55,33;55;60,91;58,48;61,06;62,94;64,44;66,97;71,64;69,32;58,1;67,34;71,74;70,9;74,4;81,48;73,28;81,22;87,72;87,63;94,65;103,48;103,13;117,68;119,06;122,09;134,85;144,7;133,68;143,5;141,9;144,85;135,3;135,06;139,07;116,58;113,76;108,96;114,86;108,22;95,65;94,51;100,99;88,23;98,84;90,06;103,73;107,2;122,87;119,7;132,72;136,17;134,17;124,08;132,53;139,69;140,1;138,46;155,49;162,78;172,5;182,15;171,54;157,36;165,85;171,11;171,49;189,3;204,02;170,28;154,64;158,8;169,03;176,23;191,9;211,35;243,1;281,19;314,89;313;343,69;306,52;287,56;384,8;;;;;;;; 5;NASDAQ:AMZN;;;;;75,1;85,94;81,99;90,71;96,33;88,75;96,11;93,34;89,49;86,8;88,83;89,08;92,39;100,44;97,7;97,49;123,7;123,55;137,94;158,23;172,55;157,44;150,22;158,4;162,85;167,14;157,31;154,7;173,37;160,93;172,01;166,57;173,54;164,25;165,91;175,35;166,72;135,3;153,56;163;124,5;120,21;106,21;135,39;126,77;113;102,44;96,54;84;103,13;94,23;103,29;102,05;120,58;130,36;133,68;138,01;129,46;133,09;146,09;151,94;155,2;176,76;180,97;175;176,44;193,25;186,98;176,25;186,33;186,4;210,71;219,39;237,68;212,28;190,26;184,42;206,65;219,39;234,11;225,34;219,57;244,22;233,88;230,82;242,96;208,39;208,27;265,06;;;;;;;; 6;NYSE:KO;;;;;47,35;48,13;45,34;46,72;49,06;49,13;51,6;52,63;55,3;54,44;54,43;53,75;55,35;58,4;55,92;44,25;45,89;46,99;44,68;47,24;49,53;49,37;48,62;51,6;54,84;48,48;49,9;52,71;53,98;55,28;54,11;56,88;56,31;52,47;56,17;52,45;59,21;61,01;62,24;62;63,44;63,38;62,91;64,52;61,71;56,02;59,85;63,61;63,61;61,32;59,51;62,03;64,3;59,66;60,22;61,93;59,83;55,48;56,49;58,44;58,93;59,49;60,02;60,68;61,77;62,93;63,65;66,74;73,01;71,86;65,31;63,65;62,26;63,48;71,21;71,62;72,55;72;70,75;68,75;69,06;66,32;68,9;71,95;69,91;75,33;80,22;76,05;78,76;;;;;;;; 7;NYSE:BAC;;;;;24,64;28,47;29,08;28,54;30,58;26,6;29,42;30,68;27,05;29,17;31,27;33,43;35,22;32,83;29,37;21,23;24,05;24,61;23,75;24,88;25,74;24,09;24,08;28,16;30,31;29,96;35,79;38,69;40,53;42,92;41,23;37,96;41,75;42,45;47,85;44,47;44,49;46,14;44,2;41,22;36,14;37,2;31,13;33,71;33,61;30,2;36,04;37,85;33,12;35,48;34,3;28,6;29,04;27,79;28,69;32;28,67;26,7;26,34;30,49;33,67;34,01;34,52;37,52;37,01;39,99;39,77;40,31;40,7;39,68;41,82;47,04;43,95;46,3;46,1;41,73;39,88;44,08;47,32;47,27;50,42;51,59;53,45;53,24;55;54,03;49,81;48,75;53,46;;0;0;0;0;0;0;0 8;NASDAQ:ANSS;;;;;142,94;164,35;177,26;187,45;195,8;179,5;208,11;203,12;206,01;221,36;220,15;250,7;257,41;274,33;258,81;232,47;261,83;286,7;291,73;310,6;339,01;327,23;311,23;338,06;363,8;367,94;346,11;339,56;365,66;335,99;347,06;369,63;365,36;340,45;376,44;391,48;401,12;340,01;324,19;317,65;279,93;260,36;239,29;279,21;248,3;221,7;221,16;254,3;241,59;266,36;303,61;332,8;314,17;323,59;330,27;342,1;318,87;297,4;278,26;293,36;362,88;327,83;334,17;347,48;324,88;317,45;321,5;313,63;309,02;318,63;320,41;350,51;337,33;350,5;333,25;316,56;321,88;332,61;351,22;351,22;351,22;351,22;351,22;0;0;0;0;0;0;;;;;;;; 9;NASDAQ:AMD;;;;;18,46;24,41;23,53;26,36;27,63;27,41;31,2;30,45;30,9;28,99;33,93;38,73;45,86;47;47,46;45,48;52,39;53,63;52,61;77,43;90,82;81,99;74,7;92,66;91,71;87,66;86,39;78,5;81,62;80,81;93,93;108,63;110,72;102,9;125,23;158,37;143,9;114,25;123,34;109,34;89,84;101,86;76,47;96,78;84,87;63,36;60,06;77,63;64,77;75,15;78,58;98,01;89,69;118,21;113,91;114,4;105,72;103,27;98,5;121,16;147,41;167,69;192,53;183,34;158,38;166,9;162,21;144,48;136,94;164,08;144,07;142,06;120,79;115,95;99,86;102,74;97,35;114,63;141,9;176,31;162,32;161,79;256,12;219,76;214,16;246,27;198,62;203,43;354,49;;;;;;;; 10;NASDAQ:NVDA;;;;;33,38;35,94;38,57;45,57;45,25;33,87;41,54;42,18;41,04;43,52;50,26;52,31;58,83;59,11;69,11;65,9;73,07;88,06;94,98;106,15;133,75;135,31;125,81;134,01;130,55;132,37;138,42;133,48;150,1;162,65;200,03;197,5;223,85;207,16;258,27;326,76;294,11;244,86;243,85;272,86;195,33;186,72;151,59;184,41;150,94;121,39;134,97;169,23;146,14;195,37;232,16;277,77;289,1;378,34;423,02;467,29;493,55;447,82;407,8;467,7;495,22;61,53;79,11;90,36;86,4;109,63;123,54;117,02;108;121,44;132,76;138,63;134,29;120,07;124,92;108,38;108,92;137,38;157,99;177,87;170,78;186,58;202,49;179,92;186,5;185,61;182,48;174,4;199,57;;;;;;;; 11;NASDAQ:ADBE;;;;;226,24;247,82;262,5;272,17;289,25;270,9;300,97;298,86;282,45;276,25;277,93;302,75;329,81;351,14;360,28;318,24;353,64;389,68;435,31;444,32;513,39;490,43;444,94;478,47;500,12;470;469,57;475,37;508,34;495,91;585,64;618,75;663,7;575,72;640,2;669,85;567,06;534,3;467,68;455,62;407,29;416,48;366,06;411,09;373,44;275,2;318,5;344,93;336,53;370,34;323,95;385,37;374,15;417,79;488,99;546,17;559,34;521,13;532,06;611,01;596,6;617,78;560,28;502,09;462,83;444,76;555,54;551,65;571,04;517,78;478,08;516,2;444,68;437,45;438,56;383,53;374,98;403,4;386,88;357,69;345,63;352,75;340,31;322,85;349,99;293,38;260,88;243,08;246,1;;;;;;;; 12;NASDAQ:MSFT;;;;;101,57;104,43;112,03;119,02;130,6;123,68;135,68;136,27;136,04;139,03;143,37;149,55;157,7;170,23;172,79;157,71;179,21;182,83;203,51;205,01;225,53;210,33;202,33;214,07;222,42;239,65;236,94;235,77;252,18;247,4;270,9;284,82;301,88;281,92;329,37;330,59;336,32;310,98;298,79;308,31;284,47;271,87;256,83;278,01;261,47;232,9;232,13;255,14;239,82;247,81;249,42;288,3;305,56;328,39;340,54;335,92;327,76;321,8;338,11;378,91;376,04;397,58;413,64;424,57;389,33;415,13;446,95;418,35;409,44;430,3;406,35;430,98;421,5;415,06;396,99;375,39;395,26;461,97;497,41;533,5;505,12;517,95;517,81;486,74;483,62;423,37;398,55;370,17;407,78;;;;;;;; 13;NYSE:SPCE;;;;;10;10,05;10,12;10,19;10,23;10,34;10,4;10,47;10,34;10,7;9,41;7,44;11,55;17,15;25,98;14,78;17,62;17,52;16,34;22,45;17,9;19,23;17,66;26,61;23,73;53,79;38,14;30,63;22,15;28,88;46;31,87;27,11;25,3;19,55;16;13,38;9,2;9,68;9,88;7,89;7,01;6,02;7,4;5,91;4,71;4,62;5,09;3,48;5,52;5,74;4,05;3,57;3,46;3,88;4,28;2,52;1,77;1,48;2,23;2,45;1,78;1,74;1,43;0,87;0,86;8,43;7,11;6,16;6,1;6,57;7,02;5,88;4,76;3,8;3,03;2,89;3,12;2,73;3,8;3,09;3,86;3,94;3,79;3,21;2,68;2,6;2,43;2,38;;;;;;;; 14;NASDAQ:MRNA;;;;;15,27;16,6;22,6;20,59;26,03;20,78;14,73;13,1;14,88;15,92;16,75;19,76;19,56;20,51;29,88;29,95;45,99;62,18;64,21;74,1;64,89;70,75;67,11;152,74;104,47;157,48;157,4;130,95;175,67;184,66;234,98;346,61;376,69;384,86;337,17;352,43;253,98;169,33;153,6;172,26;142,08;145,33;142,85;161,51;132,27;118,25;150,33;175,91;179,62;176,06;138,81;153,58;133,4;127,71;121,5;117,66;113,07;103,31;75,96;77,7;99,45;101,05;92,24;105,6;110,31;142,55;118,75;119,22;72,94;66,83;54,36;44,26;41,58;39,42;30,96;28,35;28,54;27,05;27,59;29,56;24,19;25,83;27,16;24,16;29,49;42,55;52,85;50,8;45,94;;0;0;0;0;0;0;0 15;NYSE:SQ;;;;;56,09;71,35;81,24;76,32;72,82;61,95;73,2;80,41;61,13;61,95;61,43;66,88;62,56;74,69;80,67;52,38;65,14;82,72;104,94;129,85;159,56;162,55;155,23;210,96;217,64;221,94;241;227,05;244,82;221,95;243,8;272,38;268,07;239,84;255,04;208,33;161,51;122,29;127,5;135,6;105,86;87,51;61,46;77,81;68,91;54,99;60,07;67,77;62,84;81,72;76,73;68,65;60,22;60,39;66,57;80,53;57,65;43,19;40,25;63,43;77,35;65,01;79,47;81,46;73;64,08;64,49;61,88;64,17;67,13;72,32;92,78;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;;;;;;;; 16;NASDAQ:NFLX;;;;;267,66;339,5;358,1;366,96;370,54;343,28;374,6;322,99;289,29;267,62;287,41;309,99;323,57;345,09;381,05;375,5;419,85;425,92;455,04;488,88;529,56;500,03;484,12;490,7;540,73;539,04;550,64;521,66;513,47;499,08;528,21;515,15;569,19;610,34;681,17;641,9;602,44;427,14;394,52;374,59;199,46;197,44;174,87;226,21;223,56;235,44;291,88;305,53;294,88;353,86;322,13;345,48;324,12;395,23;440,49;438,97;433,68;380,33;411,69;473,97;486,88;564,11;602,92;614,31;550,64;641,62;674,88;628,35;675,32;709,27;756,03;897,74;250,42;976,76;980,56;932,53;1Ê131,72;1Ê218,98;1Ê339,13;1Ê159,40;1Ê214,11;1Ê198,92;1Ê118,86;109,13;93,76;82,76;97,09;96,15;93,61;;;;;;;; 17;NYSE:NIO;;;;;6,37;7,88;9,57;5,21;4,85;3,05;2,6;3,47;2,6;1,56;1,45;2,44;4,02;3,78;4,11;2,78;3,41;4,26;7,72;11,94;19,03;21,22;33,32;50,53;48,74;56,99;49,76;38,98;39,84;42,34;53,2;45,85;39,31;35,63;40,84;39,13;31,68;24,51;22,84;21,05;17,5;17,39;21,72;20,18;19,91;15,77;9,67;12,78;9,75;12,07;9,39;10,51;7,81;7,53;9,69;15,3;10,27;8,79;7,3;7,27;9,07;5,62;5,75;4,64;4,72;5,39;4,16;4,44;4,15;6,68;5,1;4,4;403,84;4,32;4,63;3,81;4,05;3,52;3,43;4,87;6,58;7,62;7,25;5,18;5,1;4,52;4,72;6,03;6,39;;;;;;;; 18;NYSE:BRK.B;;;;;204,18;205,54;201,3;205;216,71;197,42;214,62;205,43;200,9;208,02;212,58;220,33;226,5;224,43;217,63;182,83;187,36;183,84;178,51;195,78;218,04;212,94;204,31;228,91;231,87;229,32;249,21;255,47;274,95;289,84;277,92;278,14;285,77;272,94;286,24;276,69;299;313,02;321,45;352,91;318,19;315,98;273,02;295,86;280,8;267,02;295,09;318,6;308,9;311,52;305,18;308,77;330,17;321,08;341;351,96;360,2;348,08;341,33;360;356,66;383,74;409,4;420,2;396,73;414,4;406,8;438,5;476,83;460,26;450,92;477,33;85,35;468,67;513,83;532,58;533,25;502,81;485,77;471,88;501,14;502,74;477,54;508,55;502,65;487,29;480,17;479,2;473,6;;;;;;;; 19;NASDAQ:PLUG;;;;;1,24;1,37;1,79;2,35;2,49;2,56;2,24;2,21;2,14;2,63;2,65;3,8;3,16;3,87;4,36;3,54;4,18;4,28;8,21;7,71;12,98;13,41;15,47;26,39;33,91;63,85;52,46;35,84;28,51;30,89;34,19;26,62;26,06;25,54;41,65;39,85;28,23;21,87;25,29;28,61;21,7;18,48;16,57;21,24;28,04;21,01;15,98;15,96;12,37;17,02;14,87;11,72;8,83;8,32;10,39;13,12;8,46;6,83;5,89;4,04;4,5;4,45;3,53;3,44;2,31;3,33;2,33;2,47;1,75;2,26;1,96;2,3;2,13;1,86;1,61;1,35;0,87;0,82;1,49;1,5;1,48;2,33;2,69;1,92;1,97;2,08;1,81;2,26;3,13;;;;;;;; 20;NYSE:MA;;;;;188,65;211,13;224,77;239,05;254,24;251,49;266,77;272,27;280,11;271,57;276,81;286,47;298,59;315,94;306,74;241,56;274,97;301,4;295,7;308,53;358,19;338,17;289,97;336,51;356,94;321,56;362,9;356,05;382,06;359,79;365,09;375,26;346,23;347,68;334,05;314,92;359,32;386,38;360,82;357,38;359,04;357,87;315,48;350,54;329,35;286,77;328,18;356,4;347,73;370,6;355,29;363,41;379,86;365,02;393,3;394,28;412,64;395,85;376,35;413,83;426,51;449,23;474,76;478,4;451,2;447,07;441,16;463,71;482,12;493,8;499,59;531,36;219,39;555,43;576,31;548,12;548,06;581,22;561,94;566,47;591,87;568,81;551,99;543,97;570,88;555,37;521;499,66;502,92;;;;;;;; 21;NYSE:MCD;;;;;177,57;178,78;183,84;188,39;197,57;198,27;206,3;210,72;217,13;214,71;196,7;195,18;197,61;213,97;202,55;165,35;187,56;187,41;184,47;194,28;213,52;219,49;212,56;217,44;214,58;207,93;208,25;224,14;236,08;233,24;230,99;240,1;237,46;241,11;250,58;244,6;268,07;259,45;244,77;247,28;246,64;252,21;246,88;264,23;252,28;230,74;272,66;272,79;263,53;267,4;263,91;279,61;297,58;285,11;298,41;293,2;281,15;257,75;262,17;281,84;296,51;292,72;292,28;280,22;273,04;258,89;254,84;265,4;285,52;304,51;292,11;292,44;62,26;288,7;308,33;312,37;319,65;312,68;292,17;300,07;315,76;303,89;298,43;303,57;305,63;318,53;334,82;310,79;293,59;;;;;;;; 22;NASDAQ:UAL;;;;;83,73;87,27;87,81;80,87;88,86;77,65;88,45;91,91;83,15;88,41;90,84;91,63;88,09;74,8;61,26;31,55;29,58;29,46;34,61;31,38;36;34,75;33,78;45,05;43,25;39,94;53,31;57,54;54,4;59,67;52,29;46,07;46,51;47,57;48,05;42,26;43,78;42,88;44,4;46,36;50,19;47,63;35,42;37,69;35,01;32,53;43,08;44,17;37,7;48,96;51,96;44,25;44,41;47,47;54,87;54,31;49,81;41,62;35,01;39,4;41,26;41,38;45,49;47,35;51,46;52,99;48,66;45,42;43,87;57,06;78,26;97,44;43,95;105,84;93,81;69,05;68,82;81,23;79,63;88,31;104,68;96,5;94,04;101,12;111,82;107,35;103,21;92,07;90;;;;;;;; 23;NASDAQ:ZM;;;;;;;;;72,47;79,73;86,86;95,51;92,46;76,2;69,89;68,93;68,04;76,3;113,11;146,12;135,17;204,15;253,54;253,91;325,1;470,11;453;478,36;337,32;381,93;409,66;321,29;319,57;327,72;387,03;378,96;289,5;261,5;278,94;211,41;183,91;182,08;132,6;117,23;104,79;107,45;107,97;105,39;80,4;73,59;83,44;75,43;67,74;75;74,59;73,84;61,68;67,13;67,88;73,35;71,03;70,11;59,98;67,83;71,91;64,61;70,73;64,73;61,1;61,34;59,19;60,4;68,83;69,74;74,74;83,11;337,33;86,94;73,7;73,77;77,54;81,27;77,98;74,05;81,94;82,5;87,23;84,94;86,29;92,87;72,72;80,39;97,15;;;;;;;; 24;NYSE:BABA;;;;;137,07;168,49;183,03;180,89;185,57;149,26;175,05;173,11;172,41;167,23;176,67;196,31;212,1;206,59;210,98;194,48;202,67;206,57;215,7;251,02;287,03;293,98;310,84;263,36;232,73;264,69;241,69;226,73;230,95;219,48;226,78;200,09;166,99;148,05;170,17;127,53;118,79;125,79;105,19;108,8;101,21;96,05;113,68;90,34;95,41;79,99;63,58;87,56;88,09;110,2;87,79;102,18;84,16;79,55;83,35;102,16;92,9;86,53;82,54;74,88;77,51;72,17;74,03;73,37;74,85;78,34;72;78,85;82,27;106,12;97,98;85,95;120,79;98,84;132,51;132,23;119,43;114,75;113,41;120,63;138,55;178,73;170,43;164,26;146,58;168,39;142,56;125,46;131,88;;;;;;;; 25;NASDAQ:Z;;;;;31,58;35,09;41,8;35,31;33,4;43,02;47,58;49,96;32,99;29,82;32,57;39,86;45,94;46,21;54,4;36,02;43,96;58,22;57,61;68,39;85,76;101,59;89,16;107,81;129,8;137,05;167;129,64;130,12;113,56;122,22;107,52;95,77;88,14;97,15;54,27;63,85;50,48;57,52;49,29;40,96;39,9;31,75;35,28;33,46;28,61;30,86;37,98;32,21;44,21;42;44,47;43,92;45,61;50,26;54,16;52,16;45,64;36,25;40,94;57,86;56,84;56,15;48,22;42,57;40,95;46,39;48,7;54,01;63,85;60,09;83,7;134,29;82,22;76,66;68,56;67,33;68,36;70,05;79,55;81,81;77,05;74,98;73,53;68,22;62,52;43,54;41,38;44,4;;;;;;;; 26;NYSE:O;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66,09;69,3;67,38;68,22;68,26;73,67;68,28;58,2;62,27;63,07;63,43;67,83;63,95;63,32;61,49;59,69;59,3;61,03;56,26;49,06;47,39;53,84;57,6;54,8;52,14;53,46;53,54;53,06;52,82;57,43;62,28;63,42;59,37;56,69;444,68;54,64;57,03;58,01;57,86;56,58;57,61;56,13;57,74;60,79;57,98;57,43;56,37;60,53;67,56;61,18;64,24;;0;0;0;0;0;0;0 27;NYSE:TWTR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38,69;49,14;39,6;37,39;40,89;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;;;;;;;; 28;AMS:IWDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78,97;81,87;85,02;88,18;90,69;89,58;90,67;95,19;95,39;95,67;96,37;97,55;105,7;5,88;108,18;105,45;97,13;93,33;98,8;100,15;104,94;104,83;107,22;111,79;110,97;111,53;113,44;113,83;108,06;117,06;;;;;;;; 29;NASDAQ:QCOM;;;;;;49,52;53,39;57,81;86,13;66,82;77,52;73,16;75,12;76,28;80,44;82,45;88,23;85,31;80,56;67,65;78,67;79,73;91,21;105,61;119,1;117,68;123,97;147,17;152,34;161,58;139,49;132,59;138,8;133,94;142,93;148,86;146,69;128,98;134,81;180,56;182,87;175,76;171,99;152,82;145,27;143,22;127,74;147,43;137,08;114,84;117,66;126,49;109,94;133,21;123,53;127,58;115,84;113,41;119,04;132,17;114,53;111,1;108,99;129,05;144,63;148,51;157,79;171,72;165,85;204,05;199,18;180,95;163,24;170,05;162,77;163,03;41,58;172,93;157,17;153,61;148,46;146,63;159,26;146,76;158,78;166,36;180,9;168,04;171,05;152,62;141,03;128,78;179,58;;;;;;;; 30;NYSE:TSM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;172,33;165,8;160,49;173,67;190,54;194,4;197,49;209,32;180,53;166;166,69;194,84;226,49;241,62;228,39;279,29;300,43;287,68;303,89;341,36;369,11;337,95;396,06;;;;;;;; 31;INDEXNASDAQ:NDX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;182,06;172,93;171,39;180,14;182,75;200,06;203,04;207,27;201,23;178,2;172,83;189,34;192,41;203,25;198,7;203,66;222,92;218,45;215,21;217,11;211,46;200,38;227,52;;;;;;;; 32;AMS:VUSA;;;;;;44,75;46,63;48,32;49,67;47,2;49,71;51,41;50,55;51,82;51,55;53,4;54,41;55,51;51,43;45,5;50,49;52,1;51,84;52,1;55,66;54,5;54;57,23;57,66;59,07;61,42;64,31;65,96;65,19;68,67;70,48;72,91;71,18;75,44;77,22;79,99;75,58;74,06;78,41;74,42;73;68,54;76,33;75,14;70,83;74,34;72,83;67,72;70,6;71,27;71,19;70,68;74,2;77,11;78,79;79,22;77,47;74,88;79,21;82,04;85,4;89,17;91,45;90,19;91,16;96,89;95,41;96,93;97,52;100,1;109,43;108,03;111,45;107,33;97,32;92,25;97,84;99,78;105,84;104,94;107,45;112,42;111,42;111,06;112,04;111,26;105,86;115,85;;;;;;;; 33;CURRENCY:XAUEUR;;;;;;1154,29;1154,23;1152,01;1144,42;1168,96;1240,94;1276,17;1386,45;1351,13;1356,9;1328,81;1353,15;1430,87;1428,82;1427,49;1539,87;1559,63;1585,08;1675,56;1648,28;1608,99;1612,81;1489,35;1554,28;1518,47;1431,73;1455,77;1470,42;1559,47;1492,99;1529,29;1535,71;1517,31;1542,29;1565,28;1608,2;1599,65;1701,19;1750,71;1797,74;1711,91;1723,83;1722,97;1702,05;1695,66;1652,48;1699,28;1703,4;1774,86;1727,07;1817,14;1805,17;1836,93;1759,5;1787,55;1789,34;1748,36;1875,78;1870,47;1868,7;1885,9;1892,3;2070,6;2142,49;2145,24;2170,81;2260,99;2264,02;2366,64;2521,93;2504,58;2535,07;2700,15;2752,12;2886,94;2902,84;2901,27;2803,54;2881,8;2951,1;3288,04;3469,48;3665,33;3676,67;4089,85;4454,86;4039,4;3940,1;;;;;;;; 34;CURRENCY:USDEUR;;;;;;0,87;0,88;0,89;0,89;0,89;0,88;0,9;0,91;0,92;0,9;0,91;0,89;0,9;0,91;0,91;0,91;0,9;0,89;0,85;0,84;0,85;0,86;0,84;0,82;0,82;0,83;0,85;0,83;0,82;0,84;0,84;0,85;0,86;0,87;0,88;0,88;0,89;0,89;0,9;0,95;0,93;0,95;0,98;1;1,02;1,01;0,96;0,93;0,92;0,95;0,92;0,91;0,94;0,92;0,91;0,92;0,94;0,95;0,92;0,9;0,93;0,93;0,93;0,94;0,92;0,93;0,92;0,9;0,9;0,92;0,95;0,97;0,96;0,96;0,92;0,88;0,88;0,85;0,88;0,86;0,85;0,86;0,86;0,85;0,84;0,85;0,86;0,85;;;;;;;; ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/extrato-revolut.csv Tamanho: 59378 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2019-10-13T20:45:52.089581Z,,CASH TOP-UP,,,USD 10,USD,1.1090 2019-10-15T15:04:56.402300Z,GOOGL,BUY - MARKET,0.00808315,USD 1237.14,USD 10,USD,1.1041 2019-10-16T16:40:49.118522Z,GOOGL,SELL - MARKET,0.00808315,USD 1244.56,USD 10.05,USD,1.1083 2019-10-16T16:42:15.845933Z,AMZN,BUY - MARKET,0.0056605,USD 1775.46,USD 10.05,USD,1.1083 2020-01-22T06:14:35.117802Z,,CASH TOP-UP,,,USD 150,USD,1.1087 2020-01-22T14:35:09.489834Z,AAPL,BUY - MARKET,0.47175745,USD 317.96,USD 150,USD,1.1087 2020-01-27T19:03:34.378166Z,,CASH TOP-UP,,,USD 100,USD,1.1016 2020-01-27T19:03:59.925033Z,AAPL,BUY - MARKET,0.32237266,USD 310.20,USD 100,USD,1.1017 2020-01-27T19:06:24.636699Z,,CASH TOP-UP,,,USD 100,USD,1.1017 2020-01-27T19:06:44.350393Z,AAPL,BUY - MARKET,0.32203007,USD 310.53,USD 100,USD,1.1016 2020-02-04T18:52:14.721865Z,,CASH TOP-UP,,,USD 100,USD,1.1043 2020-02-04T18:53:01.732348Z,ADBE,BUY - MARKET,0.27270991,USD 366.69,USD 100,USD,1.1044 2020-02-06T16:55:04.812084Z,,CASH TOP-UP,,,USD 100,USD,1.0977 2020-02-06T16:55:36.979717Z,TSLA,BUY - MARKET,0.12870012,USD 777,USD 100,USD,1.0977 2020-02-10T17:27:50.154414Z,AMZN,SELL - MARKET,0.0056605,USD 2121.72,USD 12,USD,1.0918 2020-02-12T17:19:39.458866Z,,CASH WITHDRAWAL,,,USD -12,USD,1.0883 2020-02-14T06:27:43.976551Z,AAPL,DIVIDEND,,,USD 0.73,USD,1.0841 2020-02-14T16:15:09.890489Z,,CASH TOP-UP,,,USD 23.44,USD,1.0844 2020-02-19T15:25:37.972712Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:27:08.446046Z,TSLA,BUY - MARKET,0.13183279,USD 933,USD 124.07,USD,1.0788 2020-02-19T15:31:20.268338Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:32:09.673339Z,MA,BUY - MARKET,0.28609409,USD 346.04,USD 100.07,USD,1.0787 2020-02-25T15:34:40.463966Z,,CASH TOP-UP,,,USD 100,USD,1.0852 2020-02-25T15:35:27.862543Z,MA,BUY - MARKET,0.31256977,USD 313.53,USD 99.08,USD,1.0854 2020-02-27T15:58:29.203288Z,,CASH TOP-UP,,,USD 100,USD,1.0989 2020-02-27T15:59:44.008442Z,AMZN,BUY - MARKET,0.05144915,USD 1924.23,USD 100.09,USD,1.0988 2020-02-29T23:14:40.446417Z,,CUSTODY FEE,,,USD -0.01,USD,1.1085 2020-03-10T08:36:25.622472Z,,CASH TOP-UP,,,USD 100,USD,1.1392 2020-03-10T08:43:28.760520Z,,CASH TOP-UP,,,USD 100,USD,1.1385 2020-03-16T15:06:33.044184Z,AAPL,BUY - MARKET,0.39257252,USD 254.73,USD 100,USD,1.1116 2020-03-19T14:18:51.824712Z,AMZN,BUY - MARKET,0.05281643,USD 1893.35,USD 100,USD,1.0791 2020-03-25T19:00:13.188887Z,,CASH TOP-UP,,,USD 100,USD,1.0870 2020-03-25T19:00:56.745398Z,TSLA,BUY - MARKET,0.18182479,USD 549.98,USD 100,USD,1.0875 2020-03-31T23:13:57.154290Z,,CUSTODY FEE,,,USD -0.01,USD,1.1030 2020-04-13T13:44:26.856924Z,AMZN,SELL - MARKET,0.0581643,USD 2068.97,USD 120.33,USD,1.0908 2020-04-14T13:46:27.827041Z,AMZN,SELL - MARKET,0.04610128,USD 2222.06,USD 102.43,USD,1.0963 2020-04-14T13:49:54.123864Z,TSLA,SELL - MARKET,0.18182479,USD 734.50,USD 133.54,USD,1.0962 2020-04-14T13:57:12.990070Z,NFLX,BUY - MARKET,0.25100401,USD 398.40,USD 101.09,USD,1.0962 2020-04-15T13:35:34.237135Z,TSLA,BUY - MARKET,0.13523381,USD 739.46,USD 101.08,USD,1.0879 2020-04-16T13:50:19.111529Z,NFLX,BUY - MARKET,0.22745365,USD 439.65,USD 101.08,USD,1.0879 2020-04-16T15:14:00.808432Z,,CASH TOP-UP,,,USD 150,USD,1.0846 2020-04-16T15:14:35.050777Z,AMZN,BUY - MARKET,0.08295313,USD 2411,USD 201.08,USD,1.0845 2020-04-23T14:28:19.106924Z,,CASH TOP-UP,,,USD 65,USD,1.0835 2020-04-27T13:48:51.812918Z,,CASH TOP-UP,,,USD 150,USD,1.0849 2020-04-27T13:49:44.983233Z,GOOGL,BUY - MARKET,0.15638072,USD 1278.93,USD 201.08,USD,1.0850 2020-04-29T13:25:29.598577Z,,CASH TOP-UP,,,USD 60,USD,1.0862 2020-04-30T15:20:09.164358Z,TSLA,SELL - MARKET,0.13523381,USD 841.36,USD 112.69,USD,1.0945 2020-04-30T23:18:53.565423Z,,CUSTODY FEE,,,USD -0.01,USD,1.0945 2020-05-01T15:48:15.829872Z,TSLA,BUY - MARKET,0.21263626,USD 705.43,USD 151.09,USD,1.1000 2020-05-01T15:48:47.039832Z,,CASH TOP-UP,,,USD 70,USD,1.1000 2020-05-01T15:49:20.695234Z,AMZN,BUY - MARKET,0.04362354,USD 2292.34,USD 101.09,USD,1.1002 2020-05-05T15:31:50.521509Z,AAPL,SELL - MARKET,0.39257252,USD 298.65,USD 117.23,USD,1.0845 2020-05-06T19:08:08.304224Z,TSLA,SELL - MARKET,0.21263626,USD 785.52,USD 167.02,USD,1.0807 2020-05-07T13:31:53.906481Z,MCD,BUY - MARKET,1.11594688,USD 179.22,USD 200,USD,1.0787 2020-05-11T04:29:40.915073Z,MA,DIVIDEND,,,USD 0.20,USD,1.0849 2020-05-11T15:45:23.256201Z,GOOGL,SELL - MARKET,0.15638072,USD 1397.42,USD 217.44,USD,1.0812 2020-05-11T15:57:35.550473Z,AMD,BUY - MARKET,1.80733779,USD 55.33,USD 101.08,USD,1.0815 2020-05-12T16:07:48.403062Z,NFLX,SELL - MARKET,0.25100401,USD 443.18,USD 110.15,USD,1.0866 2020-05-12T19:51:54.916962Z,MA,BUY - MARKET,0.36659579,USD 272.78,USD 101.08,USD,1.0852 2020-05-14T13:39:16.072650Z,GOOGL,BUY - MARKET,0.14908017,USD 1341.56,USD 201.07,USD,1.0794 2020-05-15T06:45:31.771097Z,AAPL,DIVIDEND,,,USD 0.78,USD,1.0803 2020-05-15T14:21:14.417945Z,,CASH TOP-UP,,,USD 200,USD,1.0834 2020-05-15T14:21:43.642288Z,XYZ,BUY - MARKET,2.54097319,USD 78.71,USD 201.08,USD,1.0834 2020-05-20T15:35:46.301014Z,MA,SELL - MARKET,0.36659579,USD 300.47,USD 109.05,USD,1.0994 2020-05-20T15:42:40.689961Z,NVDA,BUY - MARKET,0.34223706,USD 359.40,USD 124.09,USD,1.0989 2020-05-21T11:09:05.866676Z,,CASH TOP-UP,,,USD 200,USD,1.0991 2020-05-21T13:33:35.686825Z,KO,BUY - MARKET,4.34023991,USD 45.85,USD 200.09,USD,1.0984 2020-05-27T15:15:48.029062Z,,CASH TOP-UP,,,USD 101,USD,1.0978 2020-05-27T15:15:56.832046Z,ANSS,BUY - MARKET,0.38406882,USD 260.37,USD 101.09,USD,1.0979 2020-05-28T14:46:13.432873Z,MCD,SELL - MARKET,1.11594688,USD 188.74,USD 209.51,USD,1.1054 2020-05-28T14:46:46.563846Z,QCOM,BUY - MARKET,2.4789291,USD 80.68,USD 201.10,USD,1.1055 2020-05-29T16:04:45.366029Z,XYZ,SELL - MARKET,2.54097319,USD 81.15,USD 205.08,USD,1.1105 2020-05-29T16:07:02.985866Z,MSFT,BUY - MARKET,1.15486141,USD 181.84,USD 211.11,USD,1.1104 2020-05-29T19:26:29.477576Z,ADBE,SELL - MARKET,0.27270991,USD 385.61,USD 104.05,USD,1.1095 2020-05-31T23:19:05.143061Z,,CUSTODY FEE,,,USD -0.02,USD,1.1117 2020-06-01T13:02:55.670900Z,,CASH TOP-UP,,,USD 100,USD,1.1111 2020-06-01T13:42:34.671146Z,UAL,BUY - MARKET,6.8212824,USD 29.32,USD 201.11,USD,1.1117 2020-06-01T16:16:43.298913Z,TSLA,SELL - MARKET,0.12870012,USD 879.56,USD 112.08,USD,1.1131 2020-06-03T14:08:52.405659Z,ANSS,SELL - MARKET,0.38406882,USD 290.47,USD 111.55,USD,1.1224 2020-06-03T14:09:18.216215Z,UAL,BUY - MARKET,7.12250712,USD 31.59,USD 225,USD,1.1218 2020-06-03T15:40:53.775341Z,GOOGL,SELL - MARKET,0.14908017,USD 1435.47,USD 213.99,USD,1.1248 2020-06-03T15:41:39.067184Z,UAL,BUY - MARKET,6.44484412,USD 33.36,USD 216.12,USD,1.1248 2020-06-03T22:53:07.567360Z,,CASH TOP-UP,,,USD 96.40,USD,1.1233 2020-06-04T13:38:22.083446Z,UAL,BUY - MARKET,2.69444444,USD 36,USD 98.12,USD,1.1261 2020-06-04T14:52:37.932806Z,,CASH TOP-UP,,,USD 105.53,USD,1.1334 2020-06-04T14:53:08.914462Z,UAL,BUY - MARKET,2.78884462,USD 37.65,USD 106.13,USD,1.1334 2020-06-04T15:23:45.056331Z,,CASH TOP-UP,,,USD 200,USD,1.1330 2020-06-04T15:24:10.360661Z,UAL,BUY - MARKET,5.20231213,USD 38.06,USD 199.13,USD,1.1330 2020-06-05T13:04:26.828036Z,,CASH TOP-UP,,,USD 113.81,USD,1.1302 2020-06-05T14:18:00.799519Z,UAL,BUY - MARKET,2.4672489,USD 45.80,USD 114.12,USD,1.1297 2020-06-05T17:28:26.976376Z,QCOM,SELL - MARKET,2.4789291,USD 89.12,USD 220.91,USD,1.1289 2020-06-05T17:31:09.772451Z,UAL,BUY - MARKET,4.8456164,USD 44.37,USD 215,USD,1.1287 2020-06-08T14:15:52.005116Z,,CASH TOP-UP,,,USD 102.63,USD,1.1304 2020-06-08T14:16:33.413999Z,ANSS,BUY - MARKET,0.35145678,USD 284.53,USD 100,USD,1.1303 2020-06-08T14:17:24.882389Z,KO,SELL - MARKET,4.34023991,USD 49.70,USD 215.70,USD,1.1304 2020-06-08T14:23:38.760448Z,UAL,BUY - MARKET,4.86896252,USD 46.17,USD 224.80,USD,1.1309 2020-06-09T07:06:15.520922Z,,CASH TOP-UP,,,USD 100,USD,1.1277 2020-06-09T13:51:25.021186Z,UAL,BUY - MARKET,2.22121486,USD 44.12,USD 99.13,USD,1.1346 2020-06-09T14:17:33.110755Z,AMZN,SELL - MARKET,0.04362354,USD 2545.19,USD 109.89,USD,1.1345 2020-06-10T13:37:56.248650Z,UAL,BUY - MARKET,2.43486729,USD 41.07,USD 101.13,USD,1.1373 2020-06-10T13:43:11.542460Z,AAPL,SELL - MARKET,1.11616018,USD 350.18,USD 389.71,USD,1.1369 2020-06-10T13:48:41.773677Z,ANSS,BUY - MARKET,1.03831377,USD 288.93,USD 301.13,USD,1.1366 2020-06-10T14:04:33.156206Z,AMZN,SELL - MARKET,0.08295313,USD 2663.79,USD 219.83,USD,1.1366 2020-06-11T13:37:59.512320Z,TSLA,BUY - MARKET,0.30035742,USD 998.81,USD 301.13,USD,1.1367 2020-06-15T09:43:07.163997Z,,CASH TOP-UP,,,USD 150,USD,1.1250 2020-06-15T14:01:51.523075Z,AAPL,BUY - MARKET,0.44628246,USD 336.11,USD 151.12,USD,1.1280 2020-06-16T21:53:42.937926Z,,CASH TOP-UP,,,USD 97.58,USD,1.1262 2020-06-18T14:35:42.938104Z,UAL,SELL - MARKET,6.8212824,USD 40.04,USD 271.98,USD,1.1212 2020-06-18T14:37:42.274505Z,,CASH TOP-UP,,,USD 192.53,USD,1.1217 2020-06-19T13:52:12.947282Z,MSFT,SELL - MARKET,1.15486141,USD 199.15,USD 228.85,USD,1.1231 2020-06-19T13:53:37.856769Z,GOOGL,BUY - MARKET,0.20775767,USD 1443.99,USD 301.12,USD,1.1231 2020-06-19T14:05:29.762422Z,QCOM,BUY - MARKET,3.3463469,USD 89.65,USD 301.12,USD,1.1226 2020-06-22T13:37:24.868355Z,AAPL,BUY - MARKET,0.56580287,USD 353.48,USD 201.12,USD,1.1228 2020-06-26T06:44:11.028578Z,QCOM,DIVIDEND,,,USD 1.37,USD,1.1215 2020-06-29T04:54:02.365153Z,NVDA,DIVIDEND,,,USD 0.04,USD,1.1243 2020-06-30T18:19:47.514819Z,TSLA,SELL - MARKET,0.13183279,USD 1075.23,USD 141.74,USD,1.1236 2020-06-30T23:13:30.727834Z,,CUSTODY FEE,,,USD -0.03,USD,1.1237 2020-07-01T14:14:41.076966Z,UAL,SELL - MARKET,7.12250712,USD 37.39,USD 266.29,USD,1.1263 2020-07-01T14:24:40.305583Z,TSLA,SELL - MARKET,0.30035742,USD 1118.93,USD 336.06,USD,1.1266 2020-07-01T14:32:04.179320Z,NVDA,SELL - MARKET,0.34223706,USD 382.40,USD 130.86,USD,1.1275 2020-07-01T14:36:38.192960Z,NFLX,SELL - MARKET,0.22745365,USD 464.23,USD 105.58,USD,1.1268 2020-07-01T14:45:25.307546Z,KO,BUY - MARKET,6.61229887,USD 45.37,USD 300,USD,1.1269 2020-07-06T14:03:06.514648Z,AAPL,SELL - MARKET,0.44628246,USD 373.62,USD 166.73,USD,1.1327 2020-07-07T15:08:56.815724Z,UAL,BUY - MARKET,6.00781015,USD 33.29,USD 200,USD,1.1289 2020-07-07T15:09:28.099732Z,TSLA,BUY - MARKET,0.35837412,USD 1395.19,USD 500,USD,1.1289 2020-07-09T13:55:29.714774Z,ZM,BUY - MARKET,0.55248618,USD 271.50,USD 150,USD,1.1329 2020-07-09T17:10:13.780489Z,AMD,SELL - MARKET,1.80733779,USD 56.31,USD 101.76,USD,1.1295 2020-07-10T14:52:58.381420Z,AMZN,BUY - MARKET,0.03145999,USD 3178.64,USD 100,USD,1.1327 2020-07-10T19:29:46.857555Z,TSLA,SELL - MARKET,0.35837412,USD 1534.51,USD 549.91,USD,1.1304 2020-07-13T13:35:28.048770Z,AAPL,SELL - MARKET,0.56580287,USD 390.38,USD 220.87,USD,1.1352 2020-07-13T13:35:47.111924Z,TSLA,BUY - MARKET,0.17648096,USD 1699.90,USD 300,USD,1.1351 2020-07-13T13:35:52.230844Z,AMZN,BUY - MARKET,0.09185548,USD 3266,USD 300,USD,1.1350 2020-07-13T14:51:54.087827Z,MA,SELL - MARKET,0.31256977,USD 296.73,USD 92.74,USD,1.1368 2020-07-14T13:31:59.854077Z,AAPL,BUY - MARKET,0.65824117,USD 379.80,USD 250,USD,1.1369 2020-07-15T13:34:09.322645Z,UAL,SELL - MARKET,6.44484412,USD 34.06,USD 219.50,USD,1.1453 2020-07-15T13:35:04.961261Z,UAL,SELL - MARKET,6.00781015,USD 34.21,USD 205.52,USD,1.1450 2020-07-15T13:36:54.903151Z,AAPL,BUY - MARKET,0.5079494,USD 393.74,USD 200,USD,1.1450 2020-07-15T13:37:08.648684Z,TSLA,BUY - MARKET,0.13297872,USD 1504,USD 200,USD,1.1447 2020-07-17T10:21:42.253727Z,,CASH WITHDRAWAL,,,USD -16,USD,1.1414 2020-07-20T15:28:03.617896Z,GOOGL,SELL - MARKET,0.20775767,USD 1553.01,USD 322.63,USD,1.1444 2020-07-20T15:28:23.429522Z,UAL,BUY - MARKET,9.17150718,USD 32.71,USD 300,USD,1.1443 2020-07-21T13:52:52.140017Z,KO,SELL - MARKET,6.61229887,USD 47.62,USD 314.86,USD,1.1450 2020-07-21T14:53:45.843776Z,AAPL,BUY - MARKET,0.76413652,USD 392.60,USD 300,USD,1.1482 2020-07-23T16:16:56.135853Z,UAL,SELL - MARKET,9.17150718,USD 33.58,USD 307.96,USD,1.1618 2020-07-23T16:17:12.192300Z,AMZN,BUY - MARKET,0.09914274,USD 3025.94,USD 300,USD,1.1619 2020-07-24T13:37:52.361330Z,AMD,BUY - MARKET,1.05263157,USD 66.50,USD 70,USD,1.1611 2020-07-24T15:46:13.810803Z,AMD,SELL - MARKET,1.05263157,USD 68.80,USD 72.41,USD,1.1637 2020-07-24T15:50:14.518607Z,ZM,BUY - MARKET,0.28389503,USD 246.57,USD 70,USD,1.1635 2020-07-25T21:25:27.926085Z,,CASH TOP-UP,,,USD 150,USD,1.1714 2020-07-27T13:40:19.675494Z,TSLA,BUY - MARKET,0.10470034,USD 1432.66,USD 150,USD,1.1746 2020-07-30T13:37:41.742329Z,QCOM,SELL - MARKET,3.3463469,USD 102.67,USD 343.55,USD,1.1800 2020-07-30T13:44:03.123846Z,GOOGL,BUY - MARKET,0.19926934,USD 1505.50,USD 300,USD,1.1804 2020-07-30T16:32:20.847339Z,ANSS,SELL - MARKET,0.35145678,USD 309.60,USD 108.80,USD,1.1801 2020-07-30T16:35:39.859799Z,MSFT,BUY - MARKET,0.73800738,USD 203.25,USD 150,USD,1.1802 2020-07-31T15:21:05.501725Z,AAPL,SELL - MARKET,0.65824117,USD 411.70,USD 270.98,USD,1.1839 2020-07-31T15:23:47.598730Z,GOOGL,BUY - MARKET,0.16989812,USD 1471.47,USD 250,USD,1.1840 2020-07-31T23:43:53.566513Z,,CUSTODY FEE,,,USD -0.03,USD,1.1837 2020-08-03T13:46:32.153897Z,AAPL,SELL - MARKET,1.27208592,USD 444.06,USD 564.86,USD,1.1709 2020-08-03T14:00:31.581377Z,TSLA,BUY - MARKET,0.2030663,USD 1477.35,USD 300,USD,1.1731 2020-08-03T18:28:17.331649Z,ANSS,SELL - MARKET,1.03831377,USD 315.57,USD 327.64,USD,1.1755 2020-08-04T20:41:16.072701Z,,CASH WITHDRAWAL,,,USD -16.50,USD,1.1799 2020-08-05T13:32:48.539437Z,ANSS,BUY - MARKET,0.95910994,USD 312.79,USD 300,USD,1.1881 2020-08-05T13:36:03.481722Z,AMD,BUY - MARKET,1.18990956,USD 84.04,USD 100,USD,1.1891 2020-08-06T09:23:31.359439Z,,CASH TOP-UP,,,USD 300,USD,1.1850 2020-08-06T14:00:31.092775Z,AAPL,BUY - MARKET,0.22504782,USD 444.35,USD 100,USD,1.1859 2020-08-10T04:51:32.749766Z,MA,DIVIDEND,,,USD 0.20,USD,1.1794 2020-08-10T14:52:42.356948Z,UAL,SELL - MARKET,2.6944444,USD 36.55,USD 98.47,USD,1.1769 2020-08-10T14:54:34.374914Z,AMD,BUY - MARKET,1.23701138,USD 80.84,USD 100,USD,1.1768 2020-08-10T14:57:30.636414Z,ANSS,BUY - MARKET,0.32998944,USD 303.04,USD 100,USD,1.1767 2020-08-13T13:31:33.235267Z,TSLA,SELL - MARKET,0.10470034,USD 1607.54,USD 168.30,USD,1.1839 2020-08-13T14:32:36.305371Z,TSLA,SELL - MARKET,0.2030663,USD 1632.37,USD 331.46,USD,1.1859 2020-08-13T14:36:28.249846Z,ZM,BUY - MARKET,0.40695071,USD 245.73,USD 100,USD,1.1851 2020-08-14T06:42:26.713153Z,AAPL,DIVIDEND,,,USD 0.15,USD,1.1819 2020-08-14T13:33:39.022612Z,TSLA,SELL - MARKET,0.1397872,USD 1661.02,USD 232.17,USD,1.1826 2020-08-14T14:12:17.671752Z,XYZ,BUY - MARKET,0.7033338,USD 142.18,USD 100,USD,1.1830 2020-08-17T13:33:39.120706Z,TSLA,BUY - MARKET,0.05902769,USD 1694.12,USD 100,USD,1.1863 2020-08-17T14:36:39.947800Z,TSLA,BUY - MARKET,0.0561394,USD 1781.28,USD 100,USD,1.1883 2020-08-17T16:28:45.503089Z,XYZ,BUY - MARKET,0.66613375,USD 150.12,USD 100,USD,1.1860 2020-08-18T13:40:16.844239Z,TSLA,SELL - MARKET,0.05902769,USD 1883.01,USD 111.14,USD,1.1962 2020-08-18T13:46:26.654Z,ZM,SELL - MARKET,0.40695071,USD 270.87,USD 110.22,USD,1.1962 2020-08-18T14:20:31.458481Z,TSLA,SELL - MARKET,0.17599953,USD 1878.58,USD 330.61,USD,1.1934 2020-08-18T16:27:49.232388Z,UAL,BUY - MARKET,2.9620853,USD 33.76,USD 100,USD,1.1937 2020-08-19T16:01:34.832909Z,AMZN,SELL - MARKET,0.09914274,USD 3306.04,USD 327.75,USD,1.1899 2020-08-19T16:19:13.539922Z,NVDA,BUY - MARKET,0.10171698,USD 491.56,USD 50,USD,1.1872 2020-08-19T16:27:25.319575Z,MA,SELL - MARKET,0.28609409,USD 331.39,USD 94.80,USD,1.1877 2020-08-20T15:13:31.608194Z,TSLA,SELL - MARKET,0.04981235,USD 1966.58,USD 97.95,USD,1.1848 2020-08-20T15:17:03.912150Z,XYZ,SELL - MARKET,0.7033338,USD 156.27,USD 109.90,USD,1.1847 2020-08-20T15:35:58.284968Z,TSLA,BUY - MARKET,0.05034207,USD 1986.41,USD 100,USD,1.1856 2020-08-20T19:11:21.856894Z,TSLA,BUY - MARKET,0.04959308,USD 2016.41,USD 100,USD,1.1860 2020-08-21T13:46:22.168804Z,AAPL,BUY - MARKET,0.41413869,USD 482.93,USD 200,USD,1.1767 2020-08-21T13:46:40.645696Z,TSLA,BUY - MARKET,0.09623805,USD 2078.18,USD 200,USD,1.1765 2020-08-21T16:26:59.511866Z,ZM,SELL - MARKET,0.83638121,USD 290.27,USD 242.76,USD,1.1768 2020-08-21T16:30:38.287214Z,TSLA,BUY - MARKET,0.09596054,USD 2084.19,USD 200,USD,1.1770 2020-08-24T16:07:10.297884Z,UAL,SELL - MARKET,2.9620853,USD 36.19,USD 107.19,USD,1.1805 2020-08-24T16:08:07.511680Z,TSLA,BUY - MARKET,0.09782821,USD 2044.40,USD 200,USD,1.1805 2020-08-25T14:44:00.531640Z,BABA,BUY - MARKET,0.17636684,USD 283.50,USD 50,USD,1.1826 2020-08-25T15:15:44.630812Z,GOOGL,SELL - MARKET,0.16989812,USD 1605.20,USD 272.70,USD,1.1828 2020-08-26T15:07:42.730768Z,ZM,BUY - MARKET,0.1661792,USD 300.88,USD 50,USD,1.1821 2020-08-26T15:42:29.143351Z,BABA,BUY - MARKET,0.17246731,USD 289.91,USD 50,USD,1.1825 2020-08-27T13:56:12.492183Z,MSFT,SELL - MARKET,0.73800738,USD 229.08,USD 169.05,USD,1.1807 2020-08-27T13:57:57.647626Z,UAL,SELL - MARKET,2.78884462,USD 37.49,USD 104.54,USD,1.1803 2020-08-27T14:08:52.657497Z,UAL,SELL - MARKET,5.20231213,USD 36.73,USD 191.07,USD,1.1782 2020-08-27T14:47:04.731766Z,ANSS,SELL - MARKET,0.32998944,USD 331.65,USD 109.43,USD,1.1786 2020-08-27T15:52:39.194814Z,TSLA,BUY - MARKET,0.08780286,USD 2277.83,USD 200,USD,1.1825 2020-08-27T15:59:47.914287Z,TSLA,SELL - MARKET,0.09782821,USD 2272.96,USD 222.35,USD,1.1826 2020-08-27T16:02:06.770299Z,TSLA,BUY - MARKET,0.21983819,USD 2274.40,USD 500,USD,1.1822 2020-08-27T16:40:42.718746Z,TSLA,BUY - MARKET,0.22686231,USD 2203.98,USD 500,USD,1.1825 2020-08-27T17:15:43.206363Z,AAPL,BUY - MARKET,0.40120361,USD 498.50,USD 200,USD,1.1814 2020-08-28T14:57:20.303825Z,TSLA,SELL - MARKET,0.05034207,USD 2272.06,USD 114.37,USD,1.1911 2020-08-28T15:25:39.775903Z,UAL,SELL - MARKET,2.43486729,USD 37.02,USD 90.13,USD,1.1899 2020-08-28T15:30:21.083145Z,NVDA,BUY - MARKET,0.09644131,USD 518.45,USD 50,USD,1.1902 2020-08-31T00:22:15.681429Z,,CASH WITHDRAWAL,,,USD -16.66,USD,1.1915 2020-08-31T08:24:29.814099Z,AAPL,STOCK SPLIT,3.12117036,,USD 0,USD,1.1899 2020-08-31T08:27:18.193687Z,TSLA,STOCK SPLIT,3.10518012,,USD 0,USD,1.1898 2020-08-31T14:23:19.225150Z,TSLA,SELL - MARKET,0.48119025,USD 463.12,USD 222.84,USD,1.1941 2020-08-31T14:25:12.090849Z,TSLA,BUY - MARKET,1.07529194,USD 464.99,USD 500,USD,1.1939 2020-08-31T14:34:07.507538Z,AAPL,SELL - MARKET,0.90019128,USD 128.26,USD 115.45,USD,1.1945 2020-08-31T14:36:41.781166Z,TSLA,SELL - MARKET,0.4798027,USD 465.17,USD 223.18,USD,1.1950 2020-08-31T14:58:49.683011Z,AMD,SELL - MARKET,1.23701138,USD 89.87,USD 111.16,USD,1.1965 2020-08-31T15:00:12.913839Z,AMZN,SELL - MARKET,0.03145999,USD 3492.37,USD 109.86,USD,1.1961 2020-08-31T15:10:00.501852Z,TSLA,BUY - MARKET,0.41160732,USD 485.90,USD 200,USD,1.1951 2020-08-31T15:56:12.322382Z,TSLA,SELL - MARKET,1.13431155,USD 483.77,USD 548.73,USD,1.1955 2020-08-31T19:02:14.692076Z,TSLA,SELL - MARKET,0.2479654,USD 495.19,USD 122.78,USD,1.1935 2020-08-31T19:06:47.005425Z,TSLA,BUY - MARKET,1.00952996,USD 495.28,USD 500,USD,1.1938 2020-08-31T23:54:32.172792Z,,CUSTODY FEE,,,USD -0.02,USD,1.1940 2020-09-01T13:31:35.939299Z,ZM,BUY - MARKET,0.23466466,USD 426.14,USD 100,USD,1.1988 2020-09-01T13:31:46.997999Z,TSLA,BUY - MARKET,1.0119409,USD 494.10,USD 500,USD,1.1988 2020-09-01T13:47:37.140689Z,XYZ,SELL - MARKET,0.66613375,USD 166.08,USD 110.62,USD,1.1977 2020-09-01T13:53:42.126313Z,ZM,BUY - MARKET,0.44881288,USD 445.62,USD 200,USD,1.1969 2020-09-01T13:59:53.248673Z,ZM,SELL - MARKET,0.1661792,USD 453.67,USD 75.38,USD,1.1977 2020-09-01T14:07:15.473203Z,ZM,BUY - MARKET,0.42154073,USD 474.45,USD 200,USD,1.1952 2020-09-01T18:05:30.665718Z,GOOGL,SELL - MARKET,0.19926934,USD 1655.45,USD 329.86,USD,1.1917 2020-09-01T18:07:04.483988Z,ANSS,SELL - MARKET,0.95910994,USD 344.33,USD 330.23,USD,1.1919 2020-09-01T18:13:20.177621Z,NIO,BUY - MARKET,10.07556675,USD 19.85,USD 200,USD,1.1921 2020-09-02T13:33:53.638044Z,NIO,BUY - MARKET,10,USD 20.74,USD 207.40,USD,1.1832 2020-09-02T13:45:31.065500Z,NVDA,SELL - MARKET,0.19815829,USD 577.22,USD 114.37,USD,1.1839 2020-09-02T14:00:41.420342Z,TSLA,BUY - MARKET,0.84973166,USD 447.20,USD 380,USD,1.1834 2020-09-02T14:58:26.424459Z,,CASH TOP-UP,,,USD 200,USD,1.1844 2020-09-04T06:57:55.602815Z,,CASH WITHDRAWAL,,,USD -200,USD,1.1841 2020-09-04T07:21:47.180268Z,,CASH TOP-UP,,,USD 250,USD,1.1845 2020-09-04T07:22:00.765905Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1846 2020-09-10T06:43:18.012788Z,,CASH TOP-UP,,,USD 250,USD,1.1832 2020-09-10T06:43:39.697815Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1832 2020-09-11T07:08:09.301110Z,MSFT,DIVIDEND,,,USD 0.32,USD,1.1840 2020-09-15T14:37:48.200676Z,TSLA,SELL - MARKET,0.65498179,USD 438.20,USD 286.99,USD,1.1850 2020-09-15T14:54:20.817595Z,UAL,SELL - MARKET,2.22121486,USD 37.07,USD 82.33,USD,1.1857 2020-09-17T12:25:07.952921Z,,CASH WITHDRAWAL,,,USD -370.20,USD,1.1805 2020-09-22T13:33:29.786892Z,ZM,SELL - MARKET,0.23466466,USD 469.01,USD 110.05,USD,1.1759 2020-09-22T15:55:51.449872Z,ZM,SELL - MARKET,0.44881288,USD 488.20,USD 219.10,USD,1.1706 2020-09-23T14:38:22.109173Z,ZM,SELL - MARKET,0.42154073,USD 520,USD 219.19,USD,1.1668 2020-09-24T07:30:01.867812Z,,CASH WITHDRAWAL,,,USD -329.15,USD,1.1653 2020-09-25T05:34:43.533083Z,NVDA,DIVIDEND,,,USD 0.03,USD,1.1674 2020-09-25T07:08:24.483137Z,,CASH WITHDRAWAL,,,USD -219.22,USD,1.1668 2020-09-28T15:41:23.188756Z,BABA,SELL - MARKET,0.34883415,USD 275.69,USD 96.16,USD,1.1662 2020-09-29T15:58:04.990015Z,AMD,SELL - MARKET,1.18990956,USD 81.35,USD 96.79,USD,1.1721 2020-09-30T13:41:16.788426Z,NIO,SELL - MARKET,10.07556675,USD 22.13,USD 222.96,USD,1.1695 2020-09-30T23:05:22.729899Z,,CUSTODY FEE,,,USD -0.03,USD,1.1730 2020-10-01T08:39:07.068215Z,,CASH WITHDRAWAL,,,USD -16.40,USD,1.1728 2020-10-01T19:43:49.909598Z,TSLA,SELL - MARKET,0.60709082,USD 448.45,USD 272.23,USD,1.1745 2020-10-02T18:46:35.354198Z,,CASH WITHDRAWAL,,,USD -399.48,USD,1.1719 2020-10-06T13:45:20.572814Z,UAL,SELL - MARKET,2.4672489,USD 36.78,USD 90.74,USD,1.1797 2020-10-06T19:05:39.180375Z,,CASH WITHDRAWAL,,,USD -272.23,USD,1.1754 2020-10-08T14:41:22.813140Z,UAL,SELL - MARKET,4.8456164,USD 37.49,USD 181.65,USD,1.1744 2020-10-08T14:45:00.269291Z,UAL,SELL - MARKET,4.86896256,USD 37.41,USD 182.14,USD,1.1743 2020-10-09T18:26:13.289084Z,AAPL,SELL - MARKET,2.02064706,USD 116.32,USD 235.02,USD,1.1828 2020-10-12T17:56:05.845122Z,AAPL,SELL - MARKET,1.24072214,USD 124.33,USD 154.25,USD,1.1810 2020-10-14T13:30:16.262543Z,NIO,SELL - LIMIT,10,USD 24,USD 239.98,USD,1.1762 2020-10-14T15:26:47.927855Z,TSLA,SELL - MARKET,0.98969047,USD 462.20,USD 457.41,USD,1.1763 2020-10-15T12:02:19.535807Z,,CASH WITHDRAWAL,,,USD -400,USD,1.1708 2020-10-22T09:23:25.613263Z,,CASH WITHDRAWAL,,,USD -680,USD,1.1842 2020-10-22T19:06:30.184890Z,,CASH WITHDRAWAL,,,USD -461.19,USD,1.1819 2020-10-30T16:49:56.657758Z,,CASH TOP-UP,,,USD 230,USD,1.1655 2020-10-30T18:55:13.772909Z,,CASH WITHDRAWAL,,,USD -230,USD,1.1650 2020-11-01T00:12:15.461073Z,,CUSTODY FEE,,,USD -0.01,USD,1.1764 2020-11-02T23:50:23.731454Z,,CASH TOP-UP,,,USD 0.01,USD,1.1643 2020-11-13T17:32:40.396936Z,TSLA,SELL - MARKET,1.09919095,USD 404.95,USD 445.10,USD,1.1829 2020-11-13T17:33:09.255036Z,AMZN,SELL - MARKET,0.09185548,USD 3115.11,USD 286.12,USD,1.1829 2020-11-17T08:14:31.505714Z,,CASH WITHDRAWAL,,,USD -731.22,USD,1.1861 2020-11-26T10:29:43.997425Z,,CASH TOP-UP,,,USD 64.15,USD,1.1908 2020-11-30T14:07:20.231291Z,,CASH TOP-UP,,,USD 600,USD,1.1997 2020-11-30T14:13:04.510383Z,,CASH WITHDRAWAL,,,USD -664.15,USD,1.1995 2020-11-30T23:42:00.247197Z,,CUSTODY FEE,,,USD -0.01,USD,1.1938 2020-12-01T23:01:04.658915Z,,CASH TOP-UP,,,USD 0.01,USD,1.2075 2020-12-03T16:01:52.681026Z,TSLA,SELL - MARKET,1.51430624,USD 587.30,USD 889.32,USD,1.2162 2020-12-03T20:02:02.615104Z,,CASH TOP-UP,,,USD 283.13,USD,1.2146 2020-12-07T09:33:26.482581Z,,CASH TOP-UP,,,USD 245.04,USD,1.2091 2020-12-07T10:19:04.708279Z,,CASH WITHDRAWAL,,,USD -1417.49,USD,1.2098 2020-12-08T20:25:49.896141Z,,CASH TOP-UP,,,USD 600,USD,1.2104 2020-12-08T20:26:38.575792Z,MRNA,BUY - MARKET,3,USD 167.84,USD 503.52,USD,1.2104 2020-12-10T08:24:28.915801Z,,CASH TOP-UP,,,USD 1045.98,USD,1.2095 2020-12-10T14:30:02.653115Z,AMD,BUY - LIMIT,4,USD 89.55,USD 358.20,USD,1.2110 2020-12-10T14:30:13.150135Z,TSLA,BUY - LIMIT,1,USD 573.85,USD 573.85,USD,1.2112 2020-12-10T14:47:14.048156Z,MRNA,BUY - MARKET,1,USD 155.44,USD 155.44,USD,1.2139 2020-12-14T08:42:02.044895Z,,CASH TOP-UP,,,USD 873.84,USD,1.2148 2020-12-14T14:48:21.225847Z,TSLA,BUY - MARKET,1.39009052,USD 617.42,USD 858.27,USD,1.2161 2020-12-14T14:56:33.643638Z,NIO,BUY - MARKET,1,USD 39.90,USD 39.90,USD,1.2163 2020-12-15T14:33:22.241704Z,TSLA,SELL - MARKET,1.42113728,USD 640.27,USD 909.88,USD,1.2156 2020-12-15T14:50:30.838195Z,ANSS,BUY - MARKET,1,USD 345.66,USD 345.66,USD,1.2159 2020-12-15T18:04:07.650518Z,MRNA,BUY - LIMIT,4,USD 145,USD 580,USD,1.2161 2020-12-17T08:40:21.201412Z,,CASH TOP-UP,,,USD 1011.96,USD,1.2241 2020-12-17T14:30:06.433198Z,AAPL,BUY - LIMIT,3,USD 128.98,USD 386.94,USD,1.2249 2020-12-17T14:44:55.714193Z,TSLA,BUY - LIMIT,1,USD 620,USD 620,USD,1.2253 2020-12-17T20:44:47.556398Z,TSLA,SELL - LIMIT,1,USD 650,USD 649.98,USD,1.2263 2020-12-17T20:47:30.660341Z,AAPL,BUY - LIMIT,5,USD 128.63,USD 643.15,USD,1.2263 2020-12-21T13:26:44.115395Z,,CASH TOP-UP,,,USD 934.75,USD,1.2192 2020-12-21T15:25:16.971865Z,AMD,BUY - LIMIT,3,USD 92,USD 276,USD,1.2219 2020-12-22T14:30:05.457349Z,TSLA,BUY - LIMIT,1,USD 647.31,USD 647.31,USD,1.2225 2020-12-23T08:20:49.417315Z,,CASH TOP-UP,,,USD 440.80,USD,1.2179 2020-12-23T10:08:57.914132Z,,CASH TOP-UP,,,USD 1218.96,USD,1.2194 2020-12-23T14:30:12.260390Z,AAPL,BUY - LIMIT,4,USD 132.17,USD 528.68,USD,1.2199 2020-12-23T14:32:40.448977Z,TSLA,BUY - LIMIT,1,USD 630,USD 630,USD,1.2217 2020-12-23T15:56:56.184999Z,AMZN,BUY - MARKET,0.15645779,USD 3195.75,USD 500,USD,1.2185 2020-12-24T15:56:44.818105Z,,CASH TOP-UP,,,USD 14.23,USD,1.2184 2020-12-30T19:41:15.069854Z,TSLA,SELL - LIMIT,2,USD 695,USD 1389.96,USD,1.2289 2020-12-31T12:20:23.184470Z,,CASH TOP-UP,,,USD 500,USD,1.2276 2020-12-31T12:24:43.742Z,,CASH WITHDRAWAL,,,USD -64.98,USD,1.2273 2020-12-31T14:31:39.601626Z,NIO,BUY - LIMIT,10,USD 48.50,USD 485,USD,1.2279 2020-12-31T17:17:42.145519Z,TSLA,BUY - MARKET,1,USD 716.49,USD 716.49,USD,1.2232 2021-01-01T01:29:50.870336Z,,CUSTODY FEE,,,USD -0.04,USD,1.2219 2021-01-04T16:07:56.289208Z,AAPL,BUY - LIMIT,1,USD 130,USD 130,USD,1.2275 2021-01-06T16:21:50.650163Z,TSLA,BUY - MARKET,0.71085433,USD 769.37,USD 546.91,USD,1.2280 2021-01-07T15:55:24.088592Z,TSLA,SELL - LIMIT,2,USD 800,USD 1599.95,USD,1.2262 2021-01-07T16:23:46.257213Z,TSLA,BUY - MARKET,1,USD 805.56,USD 805.56,USD,1.2275 2021-01-08T01:26:54.692376Z,,CASH TOP-UP,,,USD 549.96,USD,1.2246 2021-01-08T09:16:01.965750Z,,CASH WITHDRAWAL,,,USD -71.85,USD,1.2234 2021-01-08T14:34:59.679144Z,TSLA,BUY - MARKET,0.28914567,USD 845.97,USD 244.61,USD,1.2280 2021-01-08T15:22:16.713016Z,TSLA,BUY - MARKET,1,USD 869.32,USD 869.32,USD,1.2229 2021-01-11T15:11:20.833428Z,NIO,BUY - MARKET,2,USD 64.89,USD 129.78,USD,1.2147 2021-01-13T08:40:39.001823Z,,CASH TOP-UP,,,USD 576.16,USD,1.2198 2021-01-13T14:36:16.142906Z,PLUG,BUY - MARKET,8,USD 69.31,USD 554.48,USD,1.2167 2021-01-14T15:14:44.924095Z,TSLA,SELL - LIMIT,1,USD 860,USD 859.97,USD,1.2118 2021-01-14T18:07:30.816970Z,PLUG,SELL - MARKET,8,USD 64.35,USD 514.78,USD,1.2167 2021-01-14T18:07:52.552385Z,MRNA,BUY - MARKET,4,USD 129.08,USD 516.32,USD,1.2168 2021-01-15T15:13:10.226921Z,NIO,BUY - MARKET,15,USD 57.38,USD 860.70,USD,1.2094 2021-01-20T14:30:56.453166Z,NIO,SELL - LIMIT,11,USD 60,USD 659.98,USD,1.2101 2021-01-22T16:33:20.961547Z,TSLA,BUY - MARKET,0.84141694,USD 831.93,USD 700,USD,1.2179 2021-01-25T15:03:48.621618Z,TSLA,SELL - LIMIT,1,USD 900,USD 899.97,USD,1.2129 2021-01-25T15:46:48.750569Z,AAPL,SELL - MARKET,5,USD 144.30,USD 721.47,USD,1.2129 2021-01-25T15:58:40.136461Z,TSLA,BUY - LIMIT,1,USD 870,USD 870,USD,1.2130 2021-01-25T16:04:44.895297Z,AAPL,BUY - LIMIT,5,USD 140,USD 700,USD,1.2129 2021-01-25T18:05:09.838791Z,NIO,BUY - LIMIT,1,USD 59.62,USD 59.62,USD,1.2148 2021-01-27T15:07:02.285287Z,,CASH TOP-UP,,,USD 136.83,USD,1.2080 2021-01-27T15:20:25.147014Z,,CASH TOP-UP,,,USD 470.71,USD,1.2077 2021-01-27T15:43:15.633441Z,AAPL,BUY - MARKET,2,USD 143.31,USD 286.62,USD,1.2091 2021-01-27T15:48:10.015296Z,MRNA,BUY - LIMIT,2,USD 158.09,USD 316.18,USD,1.2094 2021-01-28T07:27:07.598501Z,,CASH TOP-UP,,,USD 1373.27,USD,1.2089 2021-01-28T17:28:28.927848Z,MRNA,BUY - MARKET,3,USD 165.86,USD 497.58,USD,1.2126 2021-01-29T14:30:47.770020Z,MRNA,SELL - LIMIT,6,USD 174,USD 1043.97,USD,1.2153 2021-01-29T14:51:33.499884Z,TSLA,BUY - MARKET,1,USD 840.99,USD 840.99,USD,1.2148 2021-01-29T15:16:26.525884Z,MRNA,BUY - LIMIT,6,USD 177.35,USD 1064.10,USD,1.2147 2021-02-01T04:30:09.384615Z,,CUSTODY FEE,,,USD -0.09,USD,1.2133 2021-02-01T18:09:50.812968Z,,CASH TOP-UP,,,USD 196.46,USD,1.2067 2021-02-01T18:10:12.917721Z,MRNA,BUY - MARKET,1,USD 156.50,USD 156.50,USD,1.2067 2021-02-02T15:02:02.882495Z,ANSS,SELL - MARKET,1,USD 375.59,USD 375.57,USD,1.2033 2021-02-02T15:37:15.304627Z,TSLA,SELL - MARKET,0.71085433,USD 872.04,USD 619.87,USD,1.2029 2021-02-02T15:56:12.366798Z,AAPL,BUY - MARKET,4,USD 135.67,USD 542.68,USD,1.2029 2021-02-03T17:43:36.485615Z,AMZN,SELL - MARKET,0.15645779,USD 3399.26,USD 531.82,USD,1.2031 2021-02-04T17:57:10.745295Z,MRNA,SELL - MARKET,6,USD 172,USD 1031.97,USD,1.1965 2021-02-04T18:01:38.009039Z,,CASH WITHDRAWAL,,,USD -32.26,USD,1.1962 2021-02-05T17:10:07.082216Z,PYPL,BUY - MARKET,3,USD 267.18,USD 801.54,USD,1.2040 2021-02-08T14:56:37.080784Z,MRNA,SELL - LIMIT,6,USD 185,USD 1109.97,USD,1.2061 2021-02-08T15:09:42.308233Z,PYPL,BUY - MARKET,3,USD 280.95,USD 842.85,USD,1.2061 2021-02-08T15:15:57.131010Z,AMZN,BUY - MARKET,0.25,USD 3323.72,USD 830.93,USD,1.2060 2021-02-09T19:58:40.343296Z,NIO,SELL - MARKET,15,USD 62.66,USD 939.87,USD,1.2121 2021-02-09T20:00:27.291440Z,MRNA,BUY - MARKET,3,USD 178.82,USD 536.46,USD,1.2121 2021-02-09T21:20:29.683577Z,,CASH WITHDRAWAL,,,USD -500,USD,1.2121 2021-02-10T14:43:53.048254Z,TSLA,BUY - MARKET,0.69581812,USD 835.75,USD 581.53,USD,1.2135 2021-02-11T15:53:16.248489Z,PYPL,SELL - LIMIT,3,USD 300.01,USD 900,USD,1.2140 2021-02-11T19:21:16.355706Z,PYPL,BUY - LIMIT,3,USD 285,USD 855,USD,1.2133 2021-02-12T07:09:53.382539Z,AAPL,DIVIDEND,,,USD 3.31,USD,1.2126 2021-02-12T15:12:50.744899Z,AMZN,SELL - MARKET,0.25,USD 3250.16,USD 812.51,USD,1.2097 2021-02-12T15:13:55.508641Z,PYPL,BUY - MARKET,2.8,USD 292.47,USD 818.92,USD,1.2098 2021-02-19T18:01:22.470148Z,,CASH WITHDRAWAL,,,USD -41.90,USD,1.2129 2021-03-01T02:07:33.445438Z,,CUSTODY FEE,,,USD -0.08,USD,1.2090 2021-03-02T21:51:18.062393Z,,CASH TOP-UP,,,USD 0.08,USD,1.2091 2021-03-12T14:45:17.576033Z,,CASH TOP-UP,,,USD 178.93,USD,1.1937 2021-03-12T14:45:57.397742Z,NIO,BUY - LIMIT,4,USD 44.30,USD 177.20,USD,1.1933 2021-04-01T07:49:55.154005Z,,CUSTODY FEE,,,USD -0.97,USD,1.1737 2021-04-15T16:45:21.353857Z,AMD,SELL - MARKET,7,USD 83.06,USD 581.42,USD,1.1976 2021-04-19T14:24:42.527100Z,TSLA,BUY - MARKET,0.78607363,USD 699.68,USD 550,USD,1.2032 2021-05-01T08:17:07.806729Z,,CUSTODY FEE,,,USD -1.07,USD,1.2142 2021-05-03T19:47:37.874160Z,MRNA,SELL - MARKET,9,USD 186.87,USD 1681.81,USD,1.2067 2021-05-04T14:18:13.245358Z,GOOGL,BUY - MARKET,0.09823182,USD 2290.50,USD 225,USD,1.2027 2021-05-04T17:03:55.276186Z,MRNA,BUY - MARKET,4,USD 175.47,USD 701.88,USD,1.2021 2021-05-04T17:06:43.250543Z,ANSS,BUY - MARKET,2,USD 350.09,USD 700.18,USD,1.2023 2021-05-04T17:07:18.273114Z,AMZN,BUY - MARKET,0.02585158,USD 3288,USD 85,USD,1.2023 2021-05-14T04:54:27.999346Z,AAPL,DIVIDEND,,,USD 3.55,USD,1.2089 2021-05-24T15:55:44.146809Z,,CASH TOP-UP,,,USD 50,USD,1.2213 2021-05-24T15:56:03.617327Z,SPCE,BUY - MARKET,2,USD 24.93,USD 49.86,USD,1.2212 2021-05-27T15:57:09.986850Z,SPCE,SELL - MARKET,2,USD 28.02,USD 56.03,USD,1.2198 2021-05-27T16:51:08.235670Z,,CASH TOP-UP,,,USD 50,USD,1.2193 2021-05-27T16:52:28.014919Z,,CASH TOP-UP,,,USD 10,USD,1.2195 2021-05-27T16:52:47.221525Z,SPCE,BUY - MARKET,4,USD 28.53,USD 114.12,USD,1.2194 2021-05-27T19:11:54.661834Z,MRNA,SELL - MARKET,4,USD 177.05,USD 708.19,USD,1.2200 2021-05-27T19:12:45.582300Z,SPCE,BUY - LIMIT,23,USD 30.62,USD 704.26,USD,1.2199 2021-06-01T04:34:31.145849Z,,CUSTODY FEE,,,USD -1.03,USD,1.2229 2021-06-07T15:22:20.528310Z,SPCE,SELL - MARKET,27,USD 33.85,USD 913.97,USD,1.2198 2021-06-07T19:32:00.085384Z,NIO,BUY - MARKET,10,USD 43.72,USD 437.20,USD,1.2198 2021-06-08T14:19:53.290150Z,SPCE,BUY - MARKET,12,USD 37.36,USD 448.31,USD,1.2188 2021-06-25T13:30:46.699710Z,SPCE,SELL - LIMIT,12,USD 47.73,USD 572.75,USD,1.1969 2021-06-28T15:36:38.638872Z,NIO,SELL - LIMIT,14,USD 49,USD 685.99,USD,1.1932 2021-07-01T07:07:29.237955Z,,CUSTODY FEE,,,USD -1.02,USD,1.1855 2021-07-01T15:10:49.364022Z,NIO,BUY - LIMIT,10,USD 52,USD 520,USD,1.1869 2021-07-06T14:13:29.561384Z,AMZN,SELL - MARKET,0.02585158,USD 3621.44,USD 93.61,USD,1.1841 2021-07-06T14:13:42.195388Z,GOOGL,SELL - MARKET,0.09823182,USD 2521.08,USD 247.64,USD,1.1841 2021-07-06T15:42:06.615634Z,GOOGL,BUY - MARKET,0.21915668,USD 2509.62,USD 550,USD,1.1830 2021-07-07T13:40:07.363142Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1807 2021-07-08T15:28:51.781770Z,SPCE,SELL - LIMIT,12,USD 50,USD 599.99,USD,1.1848 2021-07-09T14:51:56.656892Z,AAPL,SELL - LIMIT,4,USD 145.04,USD 580.17,USD,1.1875 2021-07-12T13:40:10.104714Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1858 2021-07-14T19:19:12.332908Z,AAPL,SELL - MARKET,4,USD 149.16,USD 596.63,USD,1.1838 2021-07-14T20:06:27.095455Z,,CASH WITHDRAWAL,,,USD -63.73,USD,1.1839 2021-07-15T14:52:57.411248Z,MRNA,BUY - MARKET,1,USD 255.80,USD 255.80,USD,1.1817 2021-07-16T13:30:15.150905Z,SPCE,BUY - LIMIT,24,USD 32.56,USD 781.44,USD,1.1811 2021-07-16T14:00:06.695873Z,MRNA,SELL - LIMIT,1,USD 285,USD 284.99,USD,1.1804 2021-07-16T15:51:31.477893Z,AAPL,BUY - LIMIT,3,USD 147.31,USD 441.92,USD,1.1813 2021-07-23T16:05:00.019087Z,PYPL,SELL - MARKET,3,USD 308.81,USD 926.42,USD,1.1764 2021-07-23T16:05:29.193871Z,MRNA,BUY - MARKET,2,USD 335.27,USD 670.54,USD,1.1765 2021-07-27T06:51:45.976639Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1793 2021-08-01T05:41:21.067616Z,,CUSTODY FEE,,,USD -1.12,USD,1.1999 2021-08-03T18:07:55.781076Z,MRNA,SELL - LIMIT,2,USD 370,USD 739.99,USD,1.1866 2021-08-03T18:10:06.118513Z,AMZN,BUY - MARKET,0.22221761,USD 3375.07,USD 750,USD,1.1866 2021-08-09T14:53:34.032557Z,GOOGL,SELL - MARKET,0.21915668,USD 2716.87,USD 595.41,USD,1.1751 2021-08-09T14:54:08.334621Z,MRNA,BUY - MARKET,1,USD 450.93,USD 450.93,USD,1.1752 2021-08-13T04:42:24.271612Z,AAPL,DIVIDEND,,,USD 2.62,USD,1.1742 2021-08-16T13:39:48.653719Z,AAPL,SELL - LIMIT,4,USD 150,USD 599.99,USD,1.1785 2021-08-19T13:30:23.348630Z,AAPL,BUY - LIMIT,5,USD 144.93,USD 724.65,USD,1.1697 2021-09-01T07:40:38.748966Z,,CUSTODY FEE,,,USD -1.15,USD,1.1800 2021-09-07T13:41:12.356305Z,AAPL,SELL - LIMIT,5,USD 155.05,USD 775.24,USD,1.1862 2021-09-10T16:13:16.888876Z,AAPL,BUY - MARKET,5,USD 149.97,USD 749.85,USD,1.1823 2021-09-17T14:05:43.934832Z,TSLA,SELL - MARKET,0.78607363,USD 758.73,USD 596.41,USD,1.1758 2021-09-17T14:06:29.208538Z,AAPL,BUY - MARKET,4,USD 146.83,USD 587.32,USD,1.1758 2021-10-01T03:10:46.826293Z,,CUSTODY FEE,,,USD -1.11,USD,1.1580 2021-10-01T08:38:11.538983Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1582 2021-10-19T15:35:49.113762Z,ANSS,SELL - MARKET,2,USD 364.67,USD 729.33,USD,1.1638 2021-10-19T15:36:40.367755Z,GOOGL,BUY - MARKET,0.25686385,USD 2859.18,USD 734.42,USD,1.1640 2021-10-21T14:37:31.105249Z,TSLA,SELL - MARKET,0.84141694,USD 895.48,USD 753.46,USD,1.1640 2021-10-25T13:30:27.810820Z,TSLA,SELL - LIMIT,1,USD 951.50,USD 951.49,USD,1.1614 2021-10-25T14:12:51.623985Z,TSLA,SELL - MARKET,0.98496385,USD 956.01,USD 941.63,USD,1.1613 2021-10-25T14:30:51.121969Z,TSLA,SELL - MARKET,0.99999994,USD 974.91,USD 974.90,USD,1.1615 2021-10-25T14:35:27.184763Z,,CASH WITHDRAWAL,,,USD -78.27,USD,1.1616 2021-10-25T16:30:55.577488Z,TSLA,SELL - MARKET,1,USD 992.83,USD 992.81,USD,1.1610 2021-10-26T13:33:01.736631Z,TSLA,BUY - MARKET,1,USD 1044.49,USD 1044.49,USD,1.1609 2021-10-26T13:45:33.604150Z,AAPL,BUY - MARKET,4,USD 150.48,USD 601.92,USD,1.1611 2021-10-27T16:17:31.917375Z,AAPL,BUY - MARKET,10,USD 149.25,USD 1492.49,USD,1.1603 2021-10-29T10:53:14.177467Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1652 2021-11-01T14:50:45.336203Z,TSLA,SELL - LIMIT,1,USD 1150,USD 1149.98,USD,1.1583 2021-11-01T20:36:56.194415Z,,CASH WITHDRAWAL,,,USD -100,USD,1.1609 2021-11-04T01:13:01.959445Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.1613 2021-11-04T03:17:16.783359Z,,CUSTODY FEE,,,USD -1.07,USD,1.1603 2021-11-04T06:29:23.316411Z,,CASH TOP-UP,,,USD 2000,USD,1.1586 2021-11-04T14:10:12.273414Z,NIO,SELL - MARKET,13,USD 43.54,USD 566.02,USD,1.1553 2021-11-04T14:22:38.394300Z,KO,BUY - MARKET,10,USD 56.29,USD 562.89,USD,1.1552 2021-11-04T14:23:41.524349Z,BAC,BUY - MARKET,10,USD 47.49,USD 474.89,USD,1.1551 2021-11-09T16:46:11.784013Z,TSLA,BUY - MARKET,1,USD 1065.78,USD 1065.78,USD,1.1586 2021-11-09T16:52:01.682293Z,SPCE,SELL - LIMIT,24,USD 20.99,USD 503.77,USD,1.1588 2021-11-10T15:33:05.030639Z,TSLA,BUY - MARKET,1,USD 1073.50,USD 1073.50,USD,1.1521 2021-11-17T07:09:11.457335Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1305 2021-11-18T19:06:58.592793Z,AAPL,SELL - LIMIT,2,USD 158,USD 315.99,USD,1.1372 2021-11-19T14:33:40.386692Z,AMZN,SELL - MARKET,0.22221761,USD 3734.13,USD 829.78,USD,1.1315 2021-11-19T16:55:21.098116Z,AAPL,SELL - LIMIT,5,USD 160,USD 799.99,USD,1.1318 2021-11-19T19:20:55.700535Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1292 2021-11-22T10:38:55.919887Z,,CASH WITHDRAWAL,,,USD -153.20,USD,1.1287 2021-11-22T14:38:56.905968Z,PYPL,SELL - MARKET,3,USD 191.85,USD 575.54,USD,1.1242 2021-11-22T14:40:07.462187Z,AAPL,BUY - MARKET,10,USD 163.08,USD 1630.79,USD,1.1243 2021-11-22T14:40:36.826246Z,TSLA,BUY - MARKET,0.5,USD 1181.76,USD 590.88,USD,1.1244 2021-11-22T17:28:58.134841Z,MRNA,BUY - LIMIT,1,USD 287.97,USD 287.97,USD,1.1255 2021-11-26T14:30:44.164387Z,MRNA,SELL - LIMIT,1,USD 320,USD 319.99,USD,1.1289 2021-11-26T15:11:21.748088Z,AAPL,BUY - LIMIT,2,USD 158.17,USD 316.34,USD,1.1300 2021-11-26T17:15:02.710330Z,MRNA,SELL - MARKET,1,USD 327.96,USD 327.95,USD,1.1300 2021-11-26T17:19:19.840447Z,AMZN,BUY - MARKET,0.09497631,USD 3527.09,USD 334.99,USD,1.1297 2021-11-30T20:55:44.227431Z,AAPL,SELL - LIMIT,7,USD 165,USD 1154.98,USD,1.1337 2021-12-01T16:17:49.426751Z,AAPL,SELL - LIMIT,15,USD 170,USD 2549.98,USD,1.1331 2021-12-02T06:08:45.125392Z,,CUSTODY FEE,,,USD -1.07,USD,1.1325 2021-12-02T09:09:32.353819Z,,CASH WITHDRAWAL,,,USD -300,USD,1.1325 2021-12-02T09:09:59.218758Z,,CASH TOP-UP,,,USD 100,USD,1.1324 2021-12-02T14:30:31.195638Z,AAPL,BUY - LIMIT,7,USD 158.72,USD 1111.04,USD,1.1345 2021-12-02T14:48:54.578317Z,AAPL,BUY - MARKET,3,USD 160.89,USD 482.67,USD,1.1349 2021-12-02T17:17:29.448590Z,AMZN,BUY - MARKET,0.08667514,USD 3461.20,USD 300,USD,1.1310 2021-12-02T17:22:47.526948Z,AAPL,BUY - MARKET,9,USD 163.26,USD 1469.33,USD,1.1307 2021-12-03T15:52:09.743899Z,SPCE,SELL - MARKET,12,USD 14.32,USD 171.84,USD,1.1280 2021-12-06T15:14:43.715974Z,AAPL,SELL - MARKET,4,USD 167.09,USD 668.35,USD,1.1290 2021-12-06T15:23:37.271485Z,,CASH TOP-UP,,,USD 50,USD,1.1293 2021-12-06T15:24:23.771651Z,TSLA,BUY - LIMIT,1,USD 992.90,USD 992.90,USD,1.1291 2021-12-10T20:40:03.360809Z,AAPL,SELL - MARKET,5,USD 178.17,USD 890.85,USD,1.1316 2021-12-10T20:46:05.031639Z,,CASH WITHDRAWAL,,,USD -26.65,USD,1.1319 2021-12-13T14:31:24.268753Z,AAPL,SELL - LIMIT,7,USD 181,USD 1266.98,USD,1.1294 2021-12-13T17:18:39.928392Z,AAPL,BUY - MARKET,4,USD 178.20,USD 712.80,USD,1.1302 2021-12-14T07:45:33.061233Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1279 2021-12-14T19:27:37.943686Z,TSLA,BUY - MARKET,0.5,USD 943.68,USD 471.84,USD,1.1264 2021-12-14T19:27:59.893606Z,AAPL,BUY - MARKET,4,USD 174.17,USD 696.68,USD,1.1264 2021-12-17T08:05:11.817525Z,KO,DIVIDEND,,,USD 3.57,USD,1.1323 2021-12-21T22:24:23.051009Z,,CASH TOP-UP,,,USD 550,USD,1.1288 2021-12-25T17:04:42.634707Z,,CASH TOP-UP,,,USD 100,USD,1.1315 2021-12-27T16:07:19.048883Z,TSLA,SELL - MARKET,0.5,USD 1102.70,USD 551.34,USD,1.1327 2021-12-28T15:52:44.354571Z,AMZN,BUY - MARKET,0.05822687,USD 3434.84,USD 200,USD,1.1295 2022-01-03T15:04:47.514435Z,TSLA,SELL - MARKET,1,USD 1153.59,USD 1153.57,USD,1.1309 2022-01-03T17:21:55.035249Z,ANSS,BUY - MARKET,2,USD 393.43,USD 786.86,USD,1.1288 2022-01-03T20:22:20.865769Z,TSLA,SELL - MARKET,0.5,USD 1194.86,USD 597.42,USD,1.1302 2022-01-04T05:38:05.560396Z,BAC,DIVIDEND,,,USD 1.78,USD,1.1307 2022-01-04T10:52:06.498921Z,,CUSTODY FEE,,,USD -1.16,USD,1.1303 2022-01-06T14:54:57.808284Z,TSLA,BUY - LIMIT,1,USD 1050,USD 1050,USD,1.1330 2022-01-11T14:44:35.020133Z,AAPL,BUY - LIMIT,6,USD 171,USD 1026,USD,1.1324 2022-02-02T13:11:56.907881Z,,CUSTODY FEE,,,USD -1.22,USD,1.1324 2022-02-02T14:35:03.638282Z,PYPL,SELL - MARKET,2.8,USD 136.33,USD 381.71,USD,1.1317 2022-02-02T14:38:16.310927Z,GOOGL,BUY - MARKET,0.1370781,USD 3006.68,USD 412.15,USD,1.1318 2022-02-15T05:59:54.545870Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1320 2022-02-17T19:14:51.499522Z,KO,SELL - LIMIT,10,USD 62,USD 619.99,USD,1.1365 2022-02-18T14:43:59.084299Z,TSLA,BUY - MARKET,0.5,USD 863.86,USD 431.93,USD,1.1344 2022-02-18T16:23:53.036317Z,O,BUY - MARKET,2,USD 67.03,USD 134.06,USD,1.1336 2022-02-28T12:59:53.335490Z,,CASH TOP-UP,,,USD 250,USD,1.1198 2022-02-28T14:38:21.778362Z,KO,BUY - MARKET,2,USD 61.93,USD 123.86,USD,1.1225 2022-03-02T06:56:23.623381Z,,CUSTODY FEE,,,USD -1.16,USD,1.1104 2022-03-02T16:10:30.245886Z,MSFT,BUY - MARKET,0.62199751,USD 297.67,USD 185.15,USD,1.1092 2022-03-16T05:35:16.177499Z,O,DIVIDEND,,,USD 0.42,USD,1.0978 2022-03-22T15:06:09.673524Z,TSLA,SELL - MARKET,0.5,USD 942.18,USD 471.08,USD,1.1033 2022-03-25T09:15:31.379423Z,,CASH WITHDRAWAL,,,USD -257.83,USD,1.1004 2022-03-28T04:32:31.012802Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0955 2022-04-02T04:06:59.837476Z,,CUSTODY FEE,,,USD -1.24,USD,1.1051 2022-04-04T04:35:23.159499Z,KO,DIVIDEND,,,USD 0.75,USD,1.1051 2022-04-13T19:27:21.376535Z,AAPL,BUY - MARKET,1,USD 170.66,USD 170.66,USD,1.0892 2022-04-14T11:17:15.965883Z,,CASH TOP-UP,,,USD 200,USD,1.0905 2022-04-14T13:30:19.229173Z,TWTR,BUY - LIMIT,4,USD 48.42,USD 193.68,USD,1.0829 2022-04-19T05:08:35.489675Z,O,DIVIDEND,,,USD 0.42,USD,1.0772 2022-04-19T13:30:44.030267Z,TWTR,BUY - LIMIT,1,USD 47.24,USD 47.24,USD,1.0798 2022-04-20T17:05:03.527689Z,O,SELL - LIMIT,2,USD 75,USD 149.99,USD,1.0848 2022-04-22T13:56:13.446949Z,O,BUY - LIMIT,2,USD 74,USD 148,USD,1.0817 2022-05-03T04:22:39.919354Z,,CUSTODY FEE,,,USD -1.11,USD,1.0519 2022-05-16T05:21:24.813176Z,O,DIVIDEND,,,USD 0.42,USD,1.0410 2022-05-16T05:26:42.889192Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0407 2022-05-20T08:17:11.587079Z,,CASH TOP-UP,,,USD 150,USD,1.0562 2022-05-20T13:30:08.229515Z,AAPL,BUY - LIMIT,1,USD 139.02,USD 139.02,USD,1.0564 2022-06-02T05:19:39.349765Z,,CUSTODY FEE,,,USD -1.05,USD,1.0657 2022-06-06T05:21:09.168520Z,AMZN,STOCK SPLIT,4.55768808,,USD 0,USD,1.0738 2022-06-07T15:18:23.292832Z,,CASH TOP-UP,,,USD 10,USD,1.0702 2022-06-07T15:19:02.548830Z,AMZN,BUY - MARKET,0.2024336,USD 122.26,USD 24.75,USD,1.0700 2022-06-10T04:51:36.764084Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0635 2022-06-16T04:24:09.940734Z,O,DIVIDEND,,,USD 0.42,USD,1.0441 2022-06-27T04:21:07.933377Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0571 2022-07-02T10:16:19.663439Z,,CUSTODY FEE,,,USD -0.96,USD,1.0432 2022-07-05T04:30:14.263191Z,KO,DIVIDEND,,,USD 0.75,USD,1.0442 2022-07-18T04:23:43.057183Z,O,DIVIDEND,,,USD 0.42,USD,1.0105 2022-07-18T05:13:29.606545Z,GOOGL,STOCK SPLIT,7.48489705,,USD 0,USD,1.0100 2022-07-21T16:32:01.558198Z,AAPL,SELL - LIMIT,1,USD 155.04,USD 155.02,USD,1.0194 2022-07-29T15:15:54.355733Z,,CASH TOP-UP,,,USD 150,USD,1.0209 2022-08-02T14:00:10.449611Z,,CUSTODY FEE,,,USD -1.13,USD,1.0210 2022-08-16T06:38:59.962142Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0171 2022-08-16T06:48:27.180503Z,O,DIVIDEND,,,USD 0.42,USD,1.0165 2022-08-25T08:29:28.839969Z,TSLA,STOCK SPLIT,6,,USD 0,USD,0.9997 2022-09-03T11:43:40.762285Z,,CUSTODY FEE,,,USD -1.08,USD,0.9961 2022-09-12T05:35:58.495990Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0096 2022-09-14T14:19:49.128161Z,AAPL,BUY - LIMIT,2,USD 155.78,USD 311.56,USD,0.9982 2022-09-16T05:17:20.255485Z,O,DIVIDEND,,,USD 0.42,USD,0.9995 2022-10-03T04:32:31.694830Z,BAC,DIVIDEND,,,USD 1.87,USD,0.9807 2022-10-04T04:31:18.366499Z,,CUSTODY FEE,,,USD -1,USD,0.9841 2022-10-04T06:15:22.053724Z,KO,DIVIDEND,,,USD 0.75,USD,0.9861 2022-10-05T14:17:47.799690Z,TWTR,SELL - MARKET,5,USD 50.93,USD 254.64,USD,0.9852 2022-10-17T04:30:26.662073Z,O,DIVIDEND,,,USD 0.42,USD,0.9748 2022-11-02T09:58:08.362246Z,,CUSTODY FEE,,,USD -1,USD,0.9906 2022-11-11T10:43:43.775454Z,AAPL,DIVIDEND,,,USD 7.04,USD,1.0271 2022-11-16T06:44:25.085056Z,O,DIVIDEND,,,USD 0.42,USD,1.0383 2022-12-02T06:58:53.260720Z,,CUSTODY FEE,,,USD -0.97,USD,1.0532 2022-12-09T07:49:09.937455Z,MSFT,DIVIDEND,,,USD 0.36,USD,1.0582 2022-12-16T06:53:22.378091Z,KO,DIVIDEND,,,USD 0.75,USD,1.0667 2022-12-16T06:58:57.301385Z,O,DIVIDEND,,,USD 0.42,USD,1.0662 2022-12-20T14:35:52.087523Z,AAPL,BUY - LIMIT,2,USD 130,USD 260,USD,1.0620 2023-01-03T05:33:54.622583Z,BAC,DIVIDEND,,,USD 1.87,USD,1.0672 2023-01-04T09:51:33.829102Z,,CUSTODY FEE,,,USD -0.84,USD,1.0625 2023-01-17T05:40:19.551093Z,O,DIVIDEND,,,USD 0.35,USD,1.0831 2023-01-23T16:49:31.990Z,AAPL,SELL - LIMIT,2,USD 143,USD 285.98,USD,1.0868 2023-01-23T16:50:31.944Z,TSLA,BUY - MARKET,2,USD 141.48,USD 282.96,USD,1.0866 2023-01-26T14:30:02.502Z,TSLA,SELL - LIMIT,2,USD 159.99,USD 319.96,USD,1.0901 2023-01-30T15:28:04.951Z,AAPL,BUY - MARKET,2,USD 143.94,USD 287.88,USD,1.0889 2023-02-01T04:47:19.689616Z,,CUSTODY FEE,,,USD -0.95,USD,1.0871 2023-02-16T07:10:29.099680Z,O,DIVIDEND,,,USD 0.35,USD,1.0707 2023-02-17T07:05:43.640146Z,AAPL,DIVIDEND,,,USD 6.12,USD,1.0641 2023-03-01T11:12:23.865134Z,,CASH TOP-UP,,,USD 250,USD,1.0669 2023-03-01T14:45:06.338Z,BRK.B,BUY - LIMIT,1,USD 303.16,USD 303.16,USD,1.0685 2023-03-02T08:37:29.518195Z,,CUSTODY FEE,,,USD -1,USD,1.0636 2023-03-13T05:01:07.362448Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0731 2023-03-16T05:53:51.457497Z,O,DIVIDEND,,,USD 0.36,USD,1.0618 2023-03-22T14:28:40.213Z,AAPL,SELL - LIMIT,2,USD 160,USD 319.98,USD,1.0794 2023-04-03T04:34:36.432266Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0809 2023-04-04T07:43:19.011071Z,KO,DIVIDEND,,,USD 0.64,USD,1.0919 2023-04-04T10:05:57.474134Z,,CUSTODY FEE,,,USD -1.08,USD,1.0941 2023-04-17T05:14:59.411865Z,O,DIVIDEND,,,USD 0.36,USD,1.1000 2023-05-02T16:58:09.717081Z,,CUSTODY FEE,,,USD -1.07,USD,1.1010 2023-05-05T13:33:41.989Z,AAPL,SELL - LIMIT,2,USD 172,USD 343.98,USD,1.0998 2023-05-08T16:49:22.657920Z,,CASH TOP-UP,,,USD 150,USD,1.1037 2023-05-08T16:50:05.075Z,TSLA,BUY - MARKET,1,USD 171.76,USD 171.76,USD,1.1037 2023-05-16T05:28:06.065980Z,O,DIVIDEND,,,USD 0.36,USD,1.0890 2023-05-19T06:32:05.730565Z,AAPL,DIVIDEND,,,USD 5.71,USD,1.0800 2023-05-23T13:45:40.451Z,TSLA,SELL - LIMIT,1,USD 190,USD 189.98,USD,1.0783 2023-05-23T13:53:42.530Z,AAPL,BUY - MARKET,1,USD 172.79,USD 172.79,USD,1.0783 2023-05-25T13:41:55.501Z,MSFT,SELL - MARKET,0.62199751,USD 321.63,USD 200.03,USD,1.0722 2023-05-26T14:28:00.905Z,TSLA,BUY - MARKET,1,USD 190.12,USD 190.12,USD,1.0743 2023-06-02T08:57:47.333209Z,,CUSTODY FEE,,,USD -1.13,USD,1.0788 2023-06-02T13:30:02.757Z,TSLA,SELL - LIMIT,1,USD 210,USD 209.98,USD,1.0779 2023-06-05T11:24:00.663315Z,,CASH TOP-UP,,,USD 100,USD,1.0703 2023-06-06T07:53:30.801799Z,,CASH WITHDRAWAL,,,USD -200,USD,1.0725 2023-06-06T15:58:37.683Z,AAPL,BUY - MARKET,4,USD 178.62,USD 714.50,USD,1.0706 2023-06-09T06:10:29.033529Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0787 2023-06-14T15:52:32.276Z,BRK.B,SELL - LIMIT,1,USD 340,USD 339.98,USD,1.0868 2023-06-14T16:30:12.174Z,TSLA,BUY - MARKET,1,USD 258,USD 258,USD,1.0872 2023-06-15T13:53:37.361Z,AAPL,SELL - LIMIT,19,USD 185.01,USD 3515.15,USD,1.0909 2023-06-15T14:32:54.586Z,BRK.B,BUY - MARKET,4,USD 338.24,USD 1352.95,USD,1.0927 2023-06-16T04:49:46.803865Z,O,DIVIDEND,,,USD 0.36,USD,1.0954 2023-06-20T17:34:39.166Z,TSLA,BUY - MARKET,2,USD 271.03,USD 542.06,USD,1.0929 2023-06-30T15:35:47.990Z,AAPL,BUY - MARKET,4,USD 192.45,USD 769.79,USD,1.0928 2023-07-03T04:42:47.064493Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0929 2023-07-04T06:14:58.867435Z,,CUSTODY FEE,,,USD -1.19,USD,1.0914 2023-07-05T04:38:30.594392Z,KO,DIVIDEND,,,USD 0.64,USD,1.0888 2023-07-17T04:29:28.019975Z,O,DIVIDEND,,,USD 0.36,USD,1.1239 2023-07-19T13:58:34.924Z,TSLA,BUY - MARKET,3,USD 296.58,USD 889.74,USD,1.1228 2023-08-02T09:34:03.883636Z,,CUSTODY FEE,,,USD -1.31,USD,1.0994 2023-08-16T04:35:04.390352Z,O,DIVIDEND,,,USD 0.36,USD,1.0928 2023-08-18T04:57:05.333405Z,AAPL,DIVIDEND,,,USD 4.03,USD,1.0901 2023-09-02T03:13:46.440774Z,,CUSTODY FEE,,,USD -1.27,USD,1.0790 2023-09-09T08:05:14.452584Z,,TRANSFER FROM REVOLUT BANK UAB TO REVOLUT SECURITIES EUROPE UAB,,,USD 117.44,USD,1.0719 2023-09-09T09:34:24.443702Z,GOOGL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,7.878839,,USD 0,USD,1.0719 2023-09-09T09:34:24.561658Z,O,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:24.660297Z,TSLA,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,15,,USD 0,USD,1.0719 2023-09-09T09:34:24.767410Z,BAC,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,10,,USD 0,USD,1.0719 2023-09-09T09:34:24.873457Z,BRK.B,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,4,,USD 0,USD,1.0719 2023-09-09T09:34:24.979123Z,KO,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.079904Z,ANSS,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.189128Z,AMZN,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,5,,USD 0,USD,1.0719 2023-09-09T09:34:25.292873Z,AAPL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,24,,USD 0,USD,1.0719 2023-09-13T15:07:29.260651Z,,CASH TOP-UP,,,USD 11.76,USD,1.0756 2023-09-13T15:08:11.622299Z,,CASH TOP-UP,,,USD 400,USD,1.0757 2023-09-13T15:09:28.691Z,AAPL,BUY - LIMIT,3,USD 175.02,USD 525.05,USD,1.0757 2023-09-18T10:59:47.342077Z,O,DIVIDEND,,,USD 0.36,USD,1.0686 2023-10-01T07:39:16.220080Z,,CUSTODY FEE,,,USD -1.25,USD,1.0595 2023-10-02T11:08:11.013935Z,BAC,DIVIDEND,,,USD 1.68,USD,1.0550 2023-10-03T12:35:09.127138Z,KO,DIVIDEND,,,USD 0.78,USD,1.0488 2023-10-16T13:27:58.306547Z,O,DIVIDEND,,,USD 0.43,USD,1.0557 2023-11-02T07:47:24.136368Z,,CUSTODY FEE,,,USD -1.17,USD,1.0617 2023-11-16T12:42:39.810501Z,O,DIVIDEND,,,USD 0.43,USD,1.0863 2023-11-16T14:31:16.694Z,AAPL,SELL - LIMIT,6,USD 190,USD 1139.98,USD,1.0885 2023-11-17T18:26:36.033179Z,AAPL,DIVIDEND,,,USD 5.51,USD,1.0913 2023-12-01T10:05:46.401211Z,,CUSTODY FEE,,,USD -1.19,USD,1.0922 2023-12-13T13:32:17.638Z,AAPL,SELL - LIMIT,7,USD 196,USD 1371.98,USD,1.0814 2023-12-14T11:33:48.192861Z,,CASH WITHDRAWAL,,,USD -490,USD,1.0942 2023-12-14T11:42:42.236702Z,,CASH WITHDRAWAL,,,USD -540,USD,1.0945 2023-12-14T11:44:57.481825Z,,CASH TOP-UP,,,EUR 493.36,EUR,1.0000 2023-12-14T11:46:14.224594Z,,CASH TOP-UP,,,EUR 22.55,EUR,1.0000 2023-12-14T11:46:28.633Z,EUNL,BUY - MARKET,6,EUR 81.89,EUR 491.33,EUR,1.0000 2023-12-14T11:46:58.960291Z,,CASH WITHDRAWAL,,,EUR -22.55,EUR,1.0000 2023-12-18T14:35:49.692078Z,O,DIVIDEND,,,USD 0.43,USD,1.0945 2023-12-18T14:42:19.088Z,AAPL,BUY - LIMIT,2,USD 195,USD 390,USD,1.0946 2023-12-18T16:03:32.089281Z,KO,DIVIDEND,,,USD 0.78,USD,1.0937 2023-12-22T14:53:30.293Z,ANSS,SELL - MARKET,2,USD 334.81,USD 669.60,USD,1.1060 2023-12-22T14:55:28Z,AAPL,BUY - MARKET,3,USD 195.24,USD 585.73,USD,1.1059 2023-12-29T17:03:07.509Z,AAPL,BUY - MARKET,3,USD 192.32,USD 576.95,USD,1.1082 2024-01-01T07:00:29.342845Z,,CUSTODY FEE,,,USD -1.18,USD,1.1060 2024-01-01T07:00:29.400142Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-01-03T17:20:49.193495Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0927 2024-01-08T09:32:34.413Z,AAPL,BUY - LIMIT,3,USD 180,USD 540,USD,1.0945 2024-01-16T12:06:46.872915Z,O,DIVIDEND,,,USD 0.43,USD,1.0909 2024-01-25T14:32:03.923Z,BRK.B,SELL - LIMIT,4,USD 380,USD 1519.98,USD,1.0876 2024-01-25T14:46:38.746Z,TSLA,SELL - MARKET,3,USD 187.76,USD 563.25,USD,1.0875 2024-01-25T14:53:37.441Z,NVDA,BUY - MARKET,3,USD 621.78,USD 1865.35,USD,1.0876 2024-01-29T15:13:05.633327Z,,CASH WITHDRAWAL,,,USD -288.99,USD,1.0829 2024-01-31T16:53:08.153Z,TSLA,SELL - LIMIT,3,USD 190,USD 569.98,USD,1.0877 2024-01-31T17:17:42.114Z,MSFT,BUY - MARKET,1,USD 402.58,USD 402.58,USD,1.0869 2024-02-01T03:25:42.443177Z,,CUSTODY FEE,,,USD -1.10,USD,1.0837 2024-02-01T03:25:42.504846Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-02-02T18:27:54.549Z,AMZN,SELL - MARKET,5,USD 171.96,USD 859.78,USD,1.0804 2024-02-02T18:28:56.258Z,NVDA,BUY - MARKET,1,USD 659.78,USD 659.78,USD,1.0805 2024-02-02T18:42:33.310Z,AAPL,BUY - MARKET,1,USD 186.01,USD 186.01,USD,1.0809 2024-02-05T19:01:24.403Z,TSLA,SELL - MARKET,3,USD 181.48,USD 544.43,USD,1.0765 2024-02-05T19:13:49.716Z,NVDA,BUY - MARKET,1,USD 688.87,USD 688.87,USD,1.0765 2024-02-09T18:38:36.240Z,NVDA,SELL - LIMIT,3,USD 720,USD 2159.97,USD,1.0809 2024-02-09T19:04:23.041Z,TSLA,SELL - MARKET,4,USD 192.78,USD 771.11,USD,1.0811 2024-02-13T14:35:34.549398Z,,CASH WITHDRAWAL,,,USD -755.30,USD,1.0737 2024-02-16T15:48:11.314342Z,O,DIVIDEND,,,USD 0.43,USD,1.0796 2024-02-16T17:20:34.309565Z,AAPL,DIVIDEND,,,USD 5.30,USD,1.0789 2024-02-21T21:25:57.106Z,NVDA,BUY - LIMIT,3,USD 679,USD 2037,USD,1.0838 2024-03-01T09:08:46.556Z,TSLA,SELL - LIMIT,2,USD 201.22,USD 402.43,USD,1.0834 2024-03-05T17:02:20.128Z,BRK.B,BUY - LIMIT,1,USD 400,USD 400,USD,1.0882 2024-03-11T09:45:10.733671Z,,CASH TOP-UP,,,USD 1091.80,USD,1.0964 2024-03-11T09:45:57.889Z,NVDA,BUY - LIMIT,1,USD 889.33,USD 889.33,USD,1.0964 2024-03-11T14:04:39.233521Z,,CASH TOP-UP,,,USD 126.74,USD,1.0941 2024-03-15T12:28:23.824579Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0914 2024-03-18T13:44:16.977280Z,O,DIVIDEND,,,USD 0.43,USD,1.0912 2024-03-28T12:59:32.090109Z,NVDA,DIVIDEND,,,USD 0.17,USD,1.0831 2024-04-01T14:18:52.459Z,AAPL,BUY - LIMIT,3,USD 170,USD 510,USD,1.0768 2024-04-02T17:32:27.807174Z,KO,DIVIDEND,,,USD 0.82,USD,1.0788 2024-04-02T17:50:08.293837Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0789 2024-04-12T13:53:08.110Z,GOOGL,SELL - LIMIT,5,USD 160,USD 799.98,USD,1.0659 2024-04-16T11:57:48.211880Z,O,DIVIDEND,,,USD 0.43,USD,1.0668 2024-04-22T13:42:17.982936Z,,CASH WITHDRAWAL,,,USD -720,USD,1.0653 2024-04-22T13:43:26.153902Z,,CASH TOP-UP,,,EUR 675.75,EUR,1.0000 2024-04-22T13:44:05.671Z,EUNL,BUY - MARKET,7,EUR 88.42,EUR 618.93,EUR,1.0000 2024-04-26T13:30:00.940Z,GOOGL,SELL - MARKET,2.878839,USD 174.33,USD 501.85,USD,1.0733 2024-04-30T14:37:07.030880Z,,CASH WITHDRAWAL,,,USD -398.79,USD,1.0728 2024-05-16T08:51:27.652167Z,O,DIVIDEND,,,USD 0.43,USD,1.0895 2024-05-17T10:26:14.210180Z,AAPL,DIVIDEND,,,USD 6.16,USD,1.0867 2024-05-20T13:54:41.117Z,NVDA,SELL - LIMIT,1,USD 950,USD 949.98,USD,1.0889 2024-05-22T21:14:39.325Z,NVDA,SELL - LIMIT,5,USD 1000,USD 4999.85,USD,1.0847 2024-05-28T15:44:41.483Z,NVDA,BUY - MARKET,3,USD 1120.59,USD 3361.77,USD,1.0899 2024-06-05T10:11:57.724Z,KO,SELL - LIMIT,2,USD 63.92,USD 127.83,USD,1.0890 2024-06-06T12:20:06.768Z,NVDA,BUY - LIMIT,2,USD 1249.18,USD 2498.35,USD,1.0907 2024-06-10T12:35:45.964651Z,NVDA,STOCK SPLIT,45,,USD 0,USD,1.0778 2024-06-11T14:16:51.891Z,AAPL,SELL - LIMIT,6,USD 200,USD 1199.96,USD,1.0748 2024-06-12T13:53:20.883Z,AAPL,BUY - MARKET,7,USD 213.95,USD 1497.64,USD,1.0856 2024-06-14T10:17:31.111265Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0709 2024-06-17T10:18:03.287961Z,O,DIVIDEND,,,USD 0.44,USD,1.0728 2024-06-17T18:01:31.892Z,MSFT,SELL - LIMIT,1,USD 450,USD 449.98,USD,1.0750 2024-06-20T15:19:16.531Z,AAPL,BUY - LIMIT,2,USD 210,USD 420,USD,1.0741 2024-07-01T11:01:29.101517Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.0772 2024-07-01T12:19:36.098603Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0768 2024-07-02T15:09:31.105Z,AAPL,SELL - LIMIT,9,USD 220,USD 1979.93,USD,1.0762 2024-07-03T14:43:34.756Z,TSLA,BUY - MARKET,2,USD 247.92,USD 495.85,USD,1.0825 2024-07-11T12:30:08.457Z,BAC,SELL - LIMIT,10,USD 42,USD 419.98,USD,1.0899 2024-07-11T13:25:05.444Z,TSM,BUY - LIMIT,10,USD 193.86,USD 1938.61,USD,1.0915 2024-07-16T08:59:29.967862Z,O,DIVIDEND,,,USD 0.44,USD,1.0923 2024-07-17T14:40:33.756Z,O,SELL - MARKET,2,USD 57.17,USD 114.32,USD,1.0957 2024-07-23T14:02:29.334480Z,,CASH TOP-UP,,,EUR 800,EUR,1.0000 2024-07-23T14:03:16.459Z,EXXT,BUY - MARKET,4.84403203,EUR 177.28,EUR 858.75,EUR,1.0000 2024-07-30T13:34:15.782Z,BRK.B,SELL - LIMIT,1,USD 440,USD 439.98,USD,1.0832 2024-08-01T21:50:35.835874Z,,CASH TOP-UP,,,USD 1077.48,USD,1.0809 2024-08-01T21:51:25.637Z,AAPL,BUY - LIMIT,5,USD 218.85,USD 1094.25,USD,1.0809 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,2,USD 204.90,USD 409.80,USD,1.0966 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,1,USD 204.90,USD 204.90,USD,1.0966 2024-08-16T15:20:28.266341Z,AAPL,DIVIDEND,,,USD 6.59,USD,1.1011 2024-08-29T11:33:30.727Z,AAPL,SELL - LIMIT,5,USD 230,USD 1149.96,USD,1.1113 2024-09-05T08:59:30.602Z,TSLA,SELL - LIMIT,2,USD 225.22,USD 450.43,USD,1.1118 2024-10-04T10:47:03.807610Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.1053 2024-10-10T08:38:54.394212Z,TSM,DIVIDEND,,,USD 4.93,USD,1.0958 2024-10-11T14:46:49.313Z,TSM,SELL - MARKET,10,USD 189.81,USD 1898.01,USD,1.0965 2024-10-17T10:50:43.300Z,NVDA,SELL - LIMIT,10,USD 140,USD 1399.95,USD,1.0885 2024-11-06T15:32:35.795880Z,,CASH TOP-UP,,,USD 34.98,USD,1.0750 2024-11-06T15:32:48.038Z,AAPL,BUY - MARKET,21,USD 225.81,USD 4741.95,USD,1.0750 2024-11-06T15:33:20.894832Z,,CASH WITHDRAWAL,,,USD -34.98,USD,1.0748 2024-11-15T10:57:21.547072Z,AAPL,DIVIDEND,,,USD 9.99,USD,1.0596 2024-11-25T15:51:08.045065Z,,CASH TOP-UP,,,USD 1004,USD,1.0525 2024-11-25T15:51:44.437Z,NVDA,BUY - MARKET,8,USD 137.70,USD 1101.58,USD,1.0526 2024-11-26T14:35:15.260Z,AAPL,SELL - LIMIT,9,USD 235,USD 2114.93,USD,1.0517 2024-11-29T12:41:10.527444Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.0574 2024-12-18T15:56:03.404813Z,EXXT,DIVIDEND,,,EUR 0.51,EUR,1.0000 2024-12-18T18:45:05.272532Z,,CASH TOP-UP,,,USD 2006.76,USD,1.0513 2024-12-18T18:45:59.510540Z,,CASH WITHDRAWAL,,,USD -2240.70,USD,1.0514 2024-12-18T18:47:39.084460Z,,CASH TOP-UP,,,EUR 2133.85,EUR,1.0000 2024-12-18T18:49:15.187Z,EXXT,BUY - LIMIT,10,EUR 203.80,EUR 2038,EUR,1.0000 2024-12-19T08:40:07.479915Z,,CASH TOP-UP,,,USD 0.02,USD,1.0415 2024-12-30T10:55:50.865219Z,NVDA,DIVIDEND,,,USD 0.41,USD,1.0464 2025-01-06T14:49:38.005Z,NVDA,SELL - LIMIT,20,USD 150,USD 2999.91,USD,1.0408 2025-01-07T09:50:04.477942Z,,CASH WITHDRAWAL,,,USD -3000,USD,1.0449 2025-01-07T15:54:48.223347Z,,CASH TOP-UP,,,USD 3001.30,USD,1.0396 2025-01-07T15:56:07.411Z,NVDA,BUY - LIMIT,21,USD 142.77,USD 2998.17,USD,1.0396 2025-01-28T08:48:36.329627Z,,CASH TOP-UP,,,USD 245,USD,1.0451 2025-01-28T09:07:04.086Z,NVDA,BUY - LIMIT,2,USD 123.58,USD 247.17,USD,1.0449 2025-02-14T20:37:33.255111Z,AAPL,DIVIDEND,,,USD 8.08,USD,1.0521 2025-03-19T15:56:49.384716Z,EXXT,DIVIDEND,,,EUR 1.67,EUR,1.0000 2025-04-03T15:56:21.046251Z,NVDA,DIVIDEND,,,USD 0.43,USD,1.1083 2025-05-16T18:36:19.943256Z,AAPL,DIVIDEND,,,USD 8.40,USD,1.1172 2025-05-28T20:38:28.721Z,NVDA,SELL - LIMIT,20,USD 140,USD 2799.99,USD,1.1318 2025-05-29T22:34:38.868352Z,,CASH WITHDRAWAL,,,USD -2818.20,USD,1.1398 2025-06-18T14:58:51.657905Z,EXXT,DIVIDEND,,,EUR 3.70,EUR,1.0000 2025-07-02T11:16:20.772081Z,,CASH TOP-UP,,,USD 2000,USD,1.1797 2025-07-03T14:46:34.490Z,NVDA,BUY - LIMIT,12,USD 159.89,USD 1918.68,USD,1.1784 2025-07-10T07:34:53.882147Z,NVDA,DIVIDEND,,,USD 0.26,USD,1.1761 2025-08-08T15:39:25.511Z,AAPL,SELL - LIMIT,3,USD 225,USD 674.99,USD,1.1692 2025-08-14T23:12:20.834326Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1674 2025-08-20T17:26:50.819936Z,,CASH WITHDRAWAL,,,USD -764.31,USD,1.1692 2025-10-02T19:05:09.782319Z,NVDA,DIVIDEND,,,USD 0.37,USD,1.1750 2025-10-16T08:44:53.616001Z,,CASH TOP-UP,,,USD 1502.57,USD,1.1685 2025-10-16T08:47:26.528Z,NVDA,BUY - LIMIT,8,USD 181.79,USD 1454.35,USD,1.1686 2025-11-11T15:34:00.722Z,AAPL,SELL - MARKET,5,USD 273.91,USD 1369.52,USD,1.1626 2025-11-11T16:59:52.307677Z,,CASH TOP-UP,,,USD 500,USD,1.1619 2025-11-11T18:05:47.274Z,NVDA,BUY - LIMIT,9,USD 193.60,USD 1742.36,USD,1.1619 2025-11-11T18:06:31.280523Z,,CASH WITHDRAWAL,,,USD -175,USD,1.1618 2025-11-13T21:09:36.155137Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1658 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/filipe/extrato-revolut.csv Tamanho: 17561 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2020-09-04T06:59:00.729503Z,,CASH TOP-UP,,,USD 250,USD,1.1839 2020-09-04T07:23:21.719355Z,,CASH TOP-UP,,,USD 250,USD,1.1845 2020-09-04T13:30:50.412089Z,AAPL,BUY - MARKET,2.08333333,USD 120,USD 250,USD,1.1811 2020-09-04T13:31:24.844921Z,TSLA,BUY - MARKET,0.60709082,USD 411.80,USD 250,USD,1.1809 2020-09-10T06:45:04.953968Z,,CASH TOP-UP,,,USD 250,USD,1.1834 2020-09-10T13:31:20.802910Z,TSLA,BUY - MARKET,0.65498179,USD 381.69,USD 250,USD,1.1896 2020-09-24T07:34:08.996392Z,,CASH TOP-UP,,,USD 329.15,USD,1.1657 2020-09-24T13:30:43.242667Z,TSLA,BUY - MARKET,0.89772262,USD 366.65,USD 329.15,USD,1.1651 2020-09-24T18:21:14.916812Z,TSLA,SELL - MARKET,0.89772262,USD 391.49,USD 351.43,USD,1.1679 2020-09-24T18:23:04.012520Z,ZM,BUY - MARKET,0.74879082,USD 469.33,USD 351.43,USD,1.1677 2020-09-25T07:24:45.526328Z,,CASH TOP-UP,,,USD 219.22,USD,1.1679 2020-09-25T07:28:29.757600Z,,CASH WITHDRAWAL,,,USD -219.22,USD,1.1687 2020-09-30T23:52:35.122704Z,,CUSTODY FEE,,,USD -0.01,USD,1.1727 2020-10-02T18:47:58.639012Z,,CASH TOP-UP,,,USD 0.01,USD,1.1718 2020-10-02T18:48:18.615660Z,,CASH TOP-UP,,,USD 415.88,USD,1.1718 2020-10-02T18:49:38.635966Z,TSLA,BUY - MARKET,0.98969047,USD 419.03,USD 415.88,USD,1.1717 2020-10-12T17:58:35.238834Z,AAPL,SELL - MARKET,1.17523455,USD 124.41,USD 145.02,USD,1.1811 2020-10-13T16:19:26.919939Z,Z,BUY - LIMIT,1,USD 100,USD 101.17,USD,1.1736 2020-10-13T18:36:26.239154Z,ZM,SELL - MARKET,0.74879082,USD 512.17,USD 382.32,USD,1.1746 2020-10-15T12:03:01.014983Z,,CASH TOP-UP,,,USD 400,USD,1.1708 2020-10-15T18:11:52.039017Z,ANSS,BUY - MARKET,1,USD 350.37,USD 351.53,USD,1.1699 2020-10-15T18:12:50.686186Z,TSLA,BUY - MARKET,1,USD 447.03,USD 448.19,USD,1.1699 2020-10-22T19:08:13.614097Z,,CASH TOP-UP,,,USD 499.59,USD,1.1821 2020-10-22T19:09:34.905452Z,NIO,BUY - MARKET,19.00692924,USD 27.42,USD 521.17,USD,1.1819 2020-10-29T18:55:00.260065Z,NIO,SELL - MARKET,19.00692924,USD 31.80,USD 604.41,USD,1.1676 2020-10-30T18:56:29.039455Z,,CASH TOP-UP,,,USD 230,USD,1.1650 2020-10-30T18:56:51.641601Z,NIO,BUY - MARKET,19,USD 30.59,USD 581.21,USD,1.1650 2020-10-30T18:57:57.787675Z,AAPL,BUY - MARKET,2.37198781,USD 108.31,USD 258.07,USD,1.1650 2020-10-31T23:47:17.741658Z,,CUSTODY FEE,,,USD -0.02,USD,1.1764 2020-11-03T15:53:12.856984Z,NIO,SELL - LIMIT,19,USD 34.50,USD 654.32,USD,1.1732 2020-11-04T18:55:00.333905Z,NIO,BUY - MARKET,17.55848346,USD 37.19,USD 654.17,USD,1.1722 2020-11-05T20:22:09.458491Z,NIO,SELL - MARKET,17.55848346,USD 41.52,USD 727.82,USD,1.1832 2020-11-06T14:34:58.811794Z,Z,SELL - LIMIT,1,USD 116,USD 114.81,USD,1.1881 2020-11-06T18:59:27.241831Z,NIO,BUY - LIMIT,20,USD 41.18,USD 824.77,USD,1.1885 2020-11-12T18:51:45.536988Z,NIO,SELL - MARKET,20,USD 49.06,USD 979.99,USD,1.1811 2020-11-12T20:28:48.899248Z,ZM,BUY - MARKET,1,USD 434.26,USD 435.44,USD,1.1806 2020-11-13T07:29:21.306371Z,AAPL,DIVIDEND,,,USD 0.57,USD,1.1809 2020-11-13T16:00:28.844792Z,NIO,BUY - LIMIT,12,USD 45,USD 541.18,USD,1.1825 2020-11-17T08:15:59.644143Z,,CASH TOP-UP,,,USD 731.22,USD,1.1865 2020-11-17T14:30:26.648440Z,NIO,BUY - LIMIT,15,USD 47.60,USD 715.18,USD,1.1881 2020-11-18T20:12:07.728932Z,TSLA,SELL - MARKET,1.84973166,USD 493.13,USD 910.95,USD,1.1869 2020-11-18T20:19:35.527950Z,AAPL,BUY - MARKET,4,USD 119.46,USD 479.02,USD,1.1869 2020-11-23T18:57:03.219942Z,ZM,SELL - MARKET,1,USD 428.78,USD 428.76,USD,1.1844 2020-11-23T19:06:24.107144Z,MRNA,BUY - MARKET,8,USD 101.20,USD 809.60,USD,1.1846 2020-11-23T19:55:40.733Z,NIO,SELL - LIMIT,27,USD 55,USD 1484.96,USD,1.1844 2020-11-23T20:30:29.564774Z,AAPL,BUY - MARKET,4,USD 114.01,USD 457.22,USD,1.1846 2020-11-24T18:51:56.018454Z,NIO,BUY - MARKET,20,USD 53.06,USD 1062.38,USD,1.1883 2020-11-27T15:27:23.105927Z,MRNA,SELL - LIMIT,8,USD 125,USD 998.78,USD,1.1948 2020-11-30T14:15:54.164131Z,,CASH TOP-UP,,,USD 664.15,USD,1.1995 2020-11-30T14:30:49.626140Z,AAPL,BUY - LIMIT,2,USD 116.83,USD 234.84,USD,1.2000 2020-11-30T14:33:41.605018Z,MRNA,BUY - LIMIT,10,USD 145.90,USD 1460.19,USD,1.1999 2020-12-01T00:30:11.291111Z,,CUSTODY FEE,,,USD -0.03,USD,1.1944 2020-12-07T10:23:47.307513Z,,CASH TOP-UP,,,USD 1426.49,USD,1.2111 2020-12-07T14:30:14.146234Z,MRNA,BUY - LIMIT,3,USD 155,USD 466.21,USD,1.2140 2020-12-07T14:30:16.651365Z,AMD,BUY - LIMIT,4,USD 95,USD 381.21,USD,1.2140 2020-12-07T14:37:45.448906Z,NIO,BUY - MARKET,8,USD 43.88,USD 352.25,USD,1.2151 2020-12-07T14:48:29.177623Z,,CASH TOP-UP,,,USD 11.90,USD,1.2160 2020-12-07T14:52:21.891107Z,AAPL,BUY - LIMIT,2,USD 124.20,USD 249.61,USD,1.2160 2020-12-08T20:31:41.166482Z,ANSS,SELL - MARKET,1,USD 339.69,USD 338.47,USD,1.2103 2020-12-08T20:41:46.607512Z,AMD,SELL - MARKET,4,USD 92.80,USD 369.97,USD,1.2106 2020-12-10T07:20:47.264099Z,,CASH WITHDRAWAL,,,USD -719.84,USD,1.2099 2020-12-10T20:40:18.560804Z,TSLA,SELL - MARKET,1.40203142,USD 624.15,USD 873.84,USD,1.2144 2020-12-14T07:43:28.816492Z,,CASH WITHDRAWAL,,,USD -873.84,USD,1.2154 2020-12-15T18:55:28.066297Z,AAPL,SELL - MARKET,8,USD 126.65,USD 1011.96,USD,1.2156 2020-12-17T07:54:05.445923Z,,CASH WITHDRAWAL,,,USD -1011.96,USD,1.2239 2020-12-17T18:55:02.049985Z,AAPL,SELL - MARKET,7.28008659,USD 128.57,USD 934.75,USD,1.2266 2020-12-21T13:20:36.584594Z,,CASH WITHDRAWAL,,,USD -934.75,USD,1.2181 2020-12-21T19:56:52.327716Z,NIO,SELL - MARKET,9,USD 48.98,USD 440.80,USD,1.2250 2020-12-23T07:28:05.324423Z,,CASH WITHDRAWAL,,,USD -440.80,USD,1.2194 2020-12-31T23:45:30.563583Z,,CUSTODY FEE,,,USD -0.02,USD,1.2219 2021-01-06T14:38:58.419778Z,NIO,SELL - LIMIT,10,USD 55,USD 549.98,USD,1.2310 2021-01-08T01:23:25.271933Z,,CASH WITHDRAWAL,,,USD -549.96,USD,1.2243 2021-01-11T19:10:30.338236Z,NIO,SELL - MARKET,9,USD 64.02,USD 576.16,USD,1.2172 2021-01-13T07:46:17.357323Z,,CASH WITHDRAWAL,,,USD -576.16,USD,1.2219 2021-01-21T19:55:57.688286Z,MRNA,SELL - MARKET,4,USD 134.71,USD 538.82,USD,1.2161 2021-01-25T08:21:04.979177Z,,CASH WITHDRAWAL,,,USD -538.82,USD,1.2174 2021-01-26T19:19:16.914055Z,MRNA,SELL - MARKET,9,USD 152.59,USD 1373.27,USD,1.2165 2021-01-28T07:22:05.590731Z,,CASH WITHDRAWAL,,,USD -1373.27,USD,1.2092 2023-11-24T17:03:57.734783Z,,CASH TOP-UP,,,EUR 504.50,EUR,1.0000 2023-11-24T17:15:33.304Z,EUNL,BUY - MARKET,6.396602,EUR 78.87,EUR 504.50,EUR,1.0000 2023-12-01T08:42:05.534265Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2023-12-14T11:34:52.147494Z,,CASH TOP-UP,,,EUR 0.05,EUR,1.0000 2023-12-14T16:36:50.068587Z,,CASH TOP-UP,,,USD 489.94,USD,1.1019 2023-12-14T16:40:51.905Z,AAPL,BUY - MARKET,2.46591654,USD 198.19,USD 489.94,USD,1.1019 2023-12-22T13:27:28.076800Z,,CASH TOP-UP,,,USD 879,USD,1.1040 2023-12-22T17:20:12.958Z,AAPL,BUY - LIMIT,2,USD 194,USD 388,USD,1.1031 2023-12-26T14:30:08.353Z,AAPL,BUY - MARKET,2.52985537,USD 193.60,USD 491,USD,1.1043 2024-01-01T06:23:42.708819Z,,CUSTODY FEE,,,USD -0.13,USD,1.1060 2024-01-01T06:23:42.760294Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-01-02T19:59:58.107632Z,,CASH TOP-UP,,,USD 0.13,USD,1.0967 2024-01-02T20:01:20.502425Z,,CASH TOP-UP,,,USD 543,USD,1.0968 2024-01-08T09:32:34.413Z,AAPL,BUY - LIMIT,3,USD 180,USD 541.37,USD,1.0945 2024-01-25T15:07:15.293590Z,,CASH TOP-UP,,,EUR 0.05,EUR,1.0000 2024-01-25T20:42:52.086873Z,,CASH TOP-UP,,,EUR 200.69,EUR,1.0000 2024-01-26T07:00:11.166Z,EUNL,BUY - MARKET,2.37003708,EUR 84.68,EUR 200.69,EUR,1.0000 2024-01-31T12:52:00.509845Z,,CASH TOP-UP,,,USD 288.99,USD,1.0857 2024-01-31T14:30:00.714Z,MSFT,BUY - MARKET,0.71112093,USD 407.16,USD 290.63,USD,1.0886 2024-02-01T08:56:45.345127Z,,CUSTODY FEE,,,USD -0.21,USD,1.0810 2024-02-01T08:56:45.413690Z,,CUSTODY FEE,,,EUR -0.07,EUR,1.0000 2024-02-13T14:38:08.488487Z,,CASH TOP-UP,,,USD 0.22,USD,1.0738 2024-02-13T14:40:17.841298Z,,CASH TOP-UP,,,USD 755.08,USD,1.0736 2024-02-13T14:40:38.679Z,NVDA,BUY - MARKET,1.06123369,USD 709.74,USD 755.09,USD,1.0736 2024-02-16T19:52:41.455422Z,AAPL,DIVIDEND,,,USD 2.03,USD,1.0804 2024-03-04T14:22:20.905847Z,,CASH TOP-UP,,,EUR 0.07,EUR,1.0000 2024-03-04T14:23:11.695860Z,,CASH TOP-UP,,,USD 499.93,USD,1.0871 2024-03-04T14:23:32.332134Z,,CASH TOP-UP,,,USD 38.14,USD,1.0872 2024-03-04T14:55:06.012Z,AAPL,BUY - LIMIT,3,USD 175,USD 525,USD,1.0884 2024-03-04T17:52:28.294Z,AAPL,BUY - MARKET,0.0803971,USD 174.26,USD 15.09,USD,1.0881 2024-03-15T13:18:50.186954Z,MSFT,DIVIDEND,,,USD 0.45,USD,1.0916 2024-03-22T09:33:28.387261Z,,CASH TOP-UP,,,EUR 802.91,EUR,1.0000 2024-03-22T09:35:02.359240Z,,CASH WITHDRAWAL,,,EUR -802.91,EUR,1.0000 2024-03-22T09:36:34.905427Z,,CASH TOP-UP,,,USD 866.85,USD,1.0841 2024-03-22T13:30:03.044Z,AAPL,BUY - MARKET,5.05272356,USD 171.65,USD 867.30,USD,1.0844 2024-03-28T13:14:54.322150Z,NVDA,DIVIDEND,,,USD 0.03,USD,1.0832 2024-04-30T18:58:29.511144Z,,CASH TOP-UP,,,USD 398.79,USD,1.0701 2024-04-30T21:53:59.511625Z,,CASH WITHDRAWAL,,,USD -398.80,USD,1.0692 2024-04-30T21:54:43.619956Z,,CASH TOP-UP,,,EUR 373.01,EUR,1.0000 2024-05-02T06:00:16.615Z,EUNL,BUY - MARKET,4.18924079,EUR 89.04,EUR 373.01,EUR,1.0000 2024-05-17T10:53:20.444540Z,AAPL,DIVIDEND,,,USD 3.85,USD,1.0861 2024-05-22T21:14:39.648Z,NVDA,SELL - LIMIT,1,USD 1000,USD 999.96,USD,1.0847 2024-06-06T21:07:57.606092Z,,CASH WITHDRAWAL,,,USD -1000,USD,1.0915 2024-06-10T12:45:20.997537Z,NVDA,STOCK SPLIT,0.55110321,,USD 0,USD,1.0774 2024-06-11T15:45:44.606498Z,,CASH TOP-UP,,,USD 510.70,USD,1.0753 2024-06-11T15:46:11.821Z,AAPL,BUY - MARKET,2.51985895,USD 204.19,USD 514.53,USD,1.0754 2024-06-14T10:33:01.853533Z,MSFT,DIVIDEND,,,USD 0.45,USD,1.0711 2024-06-20T12:29:51.031136Z,,CASH TOP-UP,,,USD 855.76,USD,1.0747 2024-06-20T12:33:04.082900Z,,CASH TOP-UP,,,EUR 0.39,EUR,1.0000 2024-06-20T13:30:18.215Z,NVDA,BUY - MARKET,6.12891911,USD 139.70,USD 856.21,USD,1.0747 2024-06-21T14:34:27.483597Z,,CASH TOP-UP,,,EUR 1300,EUR,1.0000 2024-06-21T14:38:20.081676Z,,CASH WITHDRAWAL,,,EUR -1300.39,EUR,1.0000 2024-06-21T14:38:56.144330Z,,CASH TOP-UP,,,EUR 1300.39,EUR,1.0000 2024-06-21T14:45:00.298869Z,,CASH WITHDRAWAL,,,EUR -1200.39,EUR,1.0000 2024-06-21T15:13:03.410460Z,,CASH WITHDRAWAL,,,EUR -100,EUR,1.0000 2024-06-21T15:14:11.098313Z,,CASH TOP-UP,,,USD 1300.39,USD,1.0709 2024-06-21T15:15:59.315Z,RIVN,BUY - MARKET,4.46376811,USD 10.35,USD 47.27,USD,1.0708 2024-06-24T14:03:36.788Z,NVDA,BUY - MARKET,10.13228499,USD 123.37,USD 1253.12,USD,1.0767 2024-06-25T19:28:23.934655Z,,CASH TOP-UP,,,EUR 70.80,EUR,1.0000 2024-06-26T06:00:38.873Z,EUNL,BUY - MARKET,0.73362482,EUR 95.14,EUR 70.80,EUR,1.0000 2024-07-10T15:23:26.567689Z,,CASH TOP-UP,,,EUR 550,EUR,1.0000 2024-07-10T15:23:28.152Z,EUNL,BUY - MARKET,5.71561028,EUR 95.99,EUR 550,EUR,1.0000 2024-07-15T07:00:47.240466Z,,CASH TOP-UP,,,EUR 4125,EUR,1.0000 2024-07-15T07:04:43.399Z,EUNL,BUY - MARKET,42.71029686,EUR 96.34,EUR 4125,EUR,1.0000 2024-07-15T07:58:13.494235Z,,CASH TOP-UP,,,EUR 5500,EUR,1.0000 2024-07-17T06:48:24.137Z,EXXT,BUY - MARKET,12,EUR 180.60,EUR 2172.62,EUR,1.0000 2024-07-18T23:08:19.546857Z,,CASH WITHDRAWAL,,,EUR -1500,EUR,1.0000 2024-07-18T23:08:45.728004Z,,CASH TOP-UP,,,USD 1500,USD,1.0922 2024-07-19T17:22:56.157Z,EXXT,BUY - LIMIT,5,EUR 174,EUR 872.18,EUR,1.0000 2024-07-22T10:03:28.017672Z,,CASH TOP-UP,,,EUR 117.07,EUR,1.0000 2024-07-22T10:59:38.965Z,EXXT,BUY - MARKET,6.07934523,EUR 175.94,EUR 1072.27,EUR,1.0000 2024-07-22T13:30:01.410Z,RIVN,BUY - MARKET,0.51790957,USD 17.03,USD 9.91,USD,1.0903 2024-07-24T14:01:21.718Z,,CASH TOP-UP,,,USD 750.06,USD,1.0879 2024-07-24T14:44:00.063Z,AAPL,BUY - LIMIT,6,USD 220,USD 1320,USD,1.0882 2024-07-25T13:58:18.968Z,NVDA,BUY - LIMIT,6,USD 110,USD 661.65,USD,1.0856 2024-08-01T18:45:39.482Z,RIVN,BUY - LIMIT,5,USD 15,USD 76.08,USD,1.0803 2024-08-02T10:03:50.184733Z,,CASH TOP-UP,,,USD 1500,USD,1.0840 2024-08-02T11:09:33.988193Z,,CASH TOP-UP,,,USD 97.92,USD,1.0844 2024-08-02T13:30:04.412Z,AAPL,BUY - MARKET,6.88368697,USD 219.15,USD 1512.33,USD,1.0912 2024-08-02T13:30:07.004Z,RIVN,BUY - MARKET,6.65955983,USD 14.54,USD 97.91,USD,1.0911 2024-08-02T19:13:53.883371Z,,CASH TOP-UP,,,USD 6.42,USD,1.0934 2024-08-02T19:14:06.918Z,RIVN,BUY - MARKET,0.36335623,USD 14.67,USD 6.42,USD,1.0934 2024-08-05T13:30:00.026Z,RIVN,BUY - LIMIT,13,USD 12.96,USD 169.57,USD,1.1015 2024-08-16T15:17:34.058952Z,AAPL,DIVIDEND,,,USD 7.12,USD,1.1013 2024-09-12T13:30:01.579Z,AAPL,BUY - MARKET,0.0344176,USD 222.27,USD 7.65,USD,1.1060 2024-09-13T10:09:30.437957Z,MSFT,DIVIDEND,,,USD 0.45,USD,1.1112 2024-10-04T11:06:38.613263Z,NVDA,DIVIDEND,,,USD 0.19,USD,1.1052 2024-10-17T10:50:43.300Z,NVDA,SELL - LIMIT,22,USD 140,USD 3079.90,USD,1.0885 2024-10-28T13:20:19.490825Z,,CASH WITHDRAWAL,,,USD -3080.54,USD,1.0838 2024-10-28T13:22:04.259575Z,,CASH TOP-UP,,,USD 3080.54,USD,1.0837 2024-11-06T11:36:43.272005Z,,CASH WITHDRAWAL,,,USD -3080.54,USD,1.0741 2024-11-15T10:51:18.882155Z,AAPL,DIVIDEND,,,USD 7.13,USD,1.0596 2024-11-19T21:10:34.073573Z,,CASH TOP-UP,,,EUR 1000.93,EUR,1.0000 2024-11-19T21:16:04.015409Z,,CASH WITHDRAWAL,,,USD -7.13,USD,1.0617 2024-11-19T21:22:13.152382Z,,CASH TOP-UP,,,EUR 2913.11,EUR,1.0000 2024-11-20T07:00:23.409Z,VUSA,BUY - MARKET,36.80546152,EUR 106.34,EUR 3914.04,EUR,1.0000 2024-11-22T10:18:57.120815Z,,CASH TOP-UP,,,USD 2076.27,USD,1.0422 2024-11-22T14:30:10.466Z,NVDA,BUY - MARKET,14.19916358,USD 145.86,USD 2076.26,USD,1.0433 2024-12-09T15:22:26.481Z,RIVN,SELL - MARKET,30.00459374,USD 14.63,USD 437.89,USD,1.0597 2024-12-10T15:18:23.058Z,MSFT,SELL - MARKET,0.71112093,USD 449.40,USD 318.51,USD,1.0529 2024-12-13T13:07:55.553427Z,MSFT,DIVIDEND,,,USD 0.50,USD,1.0539 2024-12-13T13:10:24.438650Z,,CASH WITHDRAWAL,,,USD -756.41,USD,1.0540 2024-12-17T13:13:41.278239Z,,CASH TOP-UP,,,USD 756.47,USD,1.0518 2024-12-17T14:30:09.042Z,NVDA,BUY - MARKET,5.8574199,USD 128.91,USD 756.97,USD,1.0526 2024-12-18T15:56:07.657064Z,EXXT,DIVIDEND,,,EUR 2.45,EUR,1.0000 2024-12-20T08:53:47.568825Z,,CASH TOP-UP,,,EUR 1000,EUR,1.0000 2024-12-20T08:55:41.144Z,VUSA,BUY - MARKET,9.41762804,EUR 106.44,EUR 1002.45,EUR,1.0000 2024-12-30T11:13:13.047080Z,NVDA,DIVIDEND,,,USD 0.13,USD,1.0463 2024-12-31T16:37:09.382630Z,VUSA,DIVIDEND,,,EUR 10.77,EUR,1.0000 2025-01-02T08:26:47.227963Z,,CASH WITHDRAWAL,,,USD -0.13,USD,1.0379 2025-01-02T08:27:04.695292Z,,CASH WITHDRAWAL,,,EUR -10.77,EUR,1.0000 2025-01-22T20:26:44.223967Z,,CASH TOP-UP,,,USD 841,USD,1.0442 2025-01-22T20:49:21.147Z,AAPL,BUY - MARKET,3.76830361,USD 223.18,USD 841,USD,1.0436 2025-01-30T18:51:53.611617Z,,CASH TOP-UP,,,USD 510.77,USD,1.0445 2025-01-30T18:52:55.951777Z,,CASH TOP-UP,,,USD 8,USD,1.0446 2025-01-30T18:53:43.860Z,NVDA,BUY - MARKET,4.32358593,USD 119.69,USD 518.77,USD,1.0445 2025-02-14T20:34:14.179261Z,AAPL,DIVIDEND,,,USD 7.93,USD,1.0521 2025-02-24T12:57:16.960888Z,,CASH WITHDRAWAL,,,USD -7.93,USD,1.0488 2025-02-25T07:54:24.798945Z,,CASH TOP-UP,,,EUR 1700,EUR,1.0000 2025-02-25T08:04:16.746Z,EXXT,BUY - MARKET,8.58499141,EUR 198.02,EUR 1700,EUR,1.0000 2025-03-07T21:56:26.746370Z,,CASH TOP-UP,,,EUR 1800,EUR,1.0000 2025-03-10T07:09:05.065Z,EXXT,BUY - MARKET,9.9562493,EUR 180.34,EUR 1800,EUR,1.0000 2025-03-17T14:53:56.276880Z,,CASH TOP-UP,,,EUR 809.79,EUR,1.0000 2025-03-17T14:54:43.632Z,VUSA,BUY - MARKET,8.21071355,EUR 98.38,EUR 809.79,EUR,1.0000 2025-03-19T15:57:20.906797Z,EXXT,DIVIDEND,,,EUR 4.69,EUR,1.0000 2025-03-31T13:35:22.737068Z,,CASH TOP-UP,,,EUR 850.28,EUR,1.0000 2025-03-31T13:35:49.950Z,EXXT,BUY - MARKET,5.03515901,EUR 169.80,EUR 854.97,EUR,1.0000 2025-04-03T16:28:39.241991Z,NVDA,DIVIDEND,,,USD 0.21,USD,1.1066 2025-04-10T16:57:00.357808Z,VUSA,DIVIDEND,,,EUR 15.74,EUR,1.0000 2025-04-11T01:03:23.685545Z,,CASH WITHDRAWAL,,,EUR -15.74,EUR,1.0000 2025-04-11T01:03:38.016522Z,,CASH WITHDRAWAL,,,USD -0.21,USD,1.1326 2025-04-28T11:43:36.485Z,AAPL,SELL - LIMIT,6,USD 210,USD 1256.80,USD,1.1366 2025-05-01T16:19:41.043934Z,,CASH WITHDRAWAL,,,USD -1256.80,USD,1.1305 2025-05-05T21:46:31.246939Z,,CASH TOP-UP,,,USD 1265.50,USD,1.1341 2025-05-16T18:31:25.227508Z,AAPL,DIVIDEND,,,USD 6.92,USD,1.1172 2025-06-16T15:11:22.017Z,NVDA,SELL - LIMIT,9,USD 146,USD 1312.84,USD,1.1614 2025-06-18T14:59:15.822789Z,EXXT,DIVIDEND,,,EUR 11.63,EUR,1.0000 2025-06-19T06:17:45.118728Z,,CASH WITHDRAWAL,,,EUR -11.63,EUR,1.0000 2025-06-19T14:25:19.692788Z,,CASH WITHDRAWAL,,,USD -1474.11,USD,1.1500 2025-07-09T12:24:12.220532Z,VUSA,DIVIDEND,,,EUR 14.42,EUR,1.0000 2025-07-10T08:16:38.327181Z,NVDA,DIVIDEND,,,USD 0.21,USD,1.1755 2025-07-25T16:14:30.658497Z,,CASH WITHDRAWAL,,,USD -0.21,USD,1.1753 2025-07-25T16:15:18.340Z,AAPL,BUY - MARKET,5.17526109,USD 214.48,USD 1111.15,USD,1.1751 2025-07-25T16:18:04.910320Z,,CASH WITHDRAWAL,,,EUR -14.42,EUR,1.0000 2025-07-25T16:19:37.782025Z,,CASH TOP-UP,,,USD 1478.65,USD,1.1750 2025-07-25T16:19:38.539Z,GOOGL,BUY - MARKET,7.64474569,USD 193.27,USD 1478.65,USD,1.1750 2025-07-25T16:20:51.847436Z,,CASH TOP-UP,,,EUR 1032.78,EUR,1.0000 2025-07-25T16:20:54.709Z,EXXT,BUY - MARKET,5.3399234,EUR 193.22,EUR 1032.78,EUR,1.0000 2025-08-14T23:05:38.545180Z,AAPL,DIVIDEND,,,USD 8.07,USD,1.1677 2025-08-29T19:22:45.487940Z,,CASH WITHDRAWAL,,,USD -8.07,USD,1.1726 2025-09-15T14:26:50.602733Z,GOOGL,DIVIDEND,,,USD 1.36,USD,1.1778 2025-10-01T13:37:38.687481Z,,CASH WITHDRAWAL,,,USD -1.36,USD,1.1785 2025-10-02T20:11:01.878991Z,NVDA,DIVIDEND,,,USD 0.14,USD,1.1747 2025-10-03T17:03:55.879717Z,VUSA,DIVIDEND,,,EUR 13.94,EUR,1.0000 2025-10-03T17:05:28.310537Z,,CASH WITHDRAWAL,,,USD -0.14,USD,1.1766 2025-10-06T16:20:24.426444Z,,CASH WITHDRAWAL,,,EUR -13.94,EUR,1.0000 2025-10-24T11:59:42.247101Z,,CASH TOP-UP,,,EUR 937.20,EUR,1.0000 2025-10-24T12:05:53.567199Z,,CASH WITHDRAWAL,,,EUR -937.20,EUR,1.0000 2025-11-09T13:33:45.679788Z,,CASH TOP-UP,,,USD 1011.67,USD,1.1610 2025-11-10T14:30:42.949Z,NVDA,BUY - MARKET,5.18210256,USD 195,USD 1011.66,USD,1.1591 2025-11-13T21:03:12.016246Z,AAPL,DIVIDEND,,,USD 8.07,USD,1.1658 2025-12-04T21:00:36.955089Z,,CASH WITHDRAWAL,,,USD -8.08,USD,1.1670 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/filipe/lucro-mensal.json Tamanho: 43267 bytes ======================================================================================== { "ok": true, "user": "filipe", "moeda": "EUR", "compatibilidade": true, "totalmeses": 71, "investimentoinicial": 33002.77, "series": [ { "mes": "2020-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-02-29", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-09", "ganhos": 18.4, "dividendos": 0, "taxas": 0.01, "net": 18.39, "deltarealizado": 18.4, "deltanaorealizado": 0, "realizadoacumulado": 18.4, "naorealizadofimmes": 0, "fimmesusado": "2020-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 915.97, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 915.97, "precofonte": "stooq" }, { "mes": "2020-10", "ganhos": 104.6, "dividendos": 0, "taxas": 0.02, "net": 104.58, "deltarealizado": 104.6, "deltanaorealizado": 0, "realizadoacumulado": 123, "naorealizadofimmes": 0, "fimmesusado": "2020-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 2232.59, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 2232.59, "precofonte": "stooq" }, { "mes": "2020-11", "ganhos": 804.33, "dividendos": 0.48, "taxas": 0, "net": 804.81, "deltarealizado": 804.33, "deltanaorealizado": 0, "realizadoacumulado": 927.33, "naorealizadofimmes": 0, "fimmesusado": "2020-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3402.56, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3402.56, "precofonte": "stooq" }, { "mes": "2020-12", "ganhos": 211.01, "dividendos": 0, "taxas": 0.04, "net": 210.97, "deltarealizado": 211.01, "deltanaorealizado": 0, "realizadoacumulado": 1138.34, "naorealizadofimmes": 0, "fimmesusado": "2020-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 1320.56, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 1320.56, "precofonte": "stooq" }, { "mes": "2021-01", "ganhos": 41.78, "dividendos": 0, "taxas": 0, "net": 41.78, "deltarealizado": 41.78, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -673.96, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -673.96, "precofonte": "stooq" }, { "mes": "2023-12", "ganhos": 0, "dividendos": 0, "taxas": 0.05, "net": -0.05, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 566.92, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 566.92, "precofonte": "stooq" }, { "mes": "2024-01", "ganhos": 0, "dividendos": 0, "taxas": 0.17, "net": -0.17, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 1529.03, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 1529.03, "precofonte": "stooq" }, { "mes": "2024-02", "ganhos": 0, "dividendos": 1.88, "taxas": 0.26, "net": 1.61, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-02-29", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 2232.55, "saldocaixafimmes": -0.07, "valorcarteira": -0.07, "investimentoinicial": 2232.55, "precofonte": "stooq" }, { "mes": "2024-03", "ganhos": 0, "dividendos": 0.44, "taxas": 0, "net": 0.44, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3527.18, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 3527.18, "precofonte": "stooq" }, { "mes": "2024-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3899.87, "saldocaixafimmes": 373.01, "valorcarteira": 373.01, "investimentoinicial": 3899.87, "precofonte": "stooq" }, { "mes": "2024-05", "ganhos": 259.13, "dividendos": 3.54, "taxas": 0, "net": 262.68, "deltarealizado": 259.13, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3899.87, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 3899.87, "precofonte": "stooq" }, { "mes": "2024-06", "ganhos": 0, "dividendos": 0.42, "taxas": 0, "net": 0.42, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 5540.01, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5540.01, "precofonte": "stooq" }, { "mes": "2024-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 16394.91, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 16394.91, "precofonte": "stooq" }, { "mes": "2024-08", "ganhos": 0, "dividendos": 6.47, "taxas": 0, "net": 6.47, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 17874.85, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 17874.85, "precofonte": "stooq" }, { "mes": "2024-09", "ganhos": 0, "dividendos": 0.4, "taxas": 0, "net": 0.4, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 17874.85, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 17874.85, "precofonte": "stooq" }, { "mes": "2024-10", "ganhos": 291.41, "dividendos": 0.17, "taxas": 0, "net": 291.58, "deltarealizado": 291.41, "deltanaorealizado": 0, "realizadoacumulado": 1730.66, "naorealizadofimmes": 0, "fimmesusado": "2024-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 17875.11, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 17875.11, "precofonte": "stooq" }, { "mes": "2024-11", "ganhos": 0, "dividendos": 6.73, "taxas": 0, "net": 6.73, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1730.66, "naorealizadofimmes": 0, "fimmesusado": "2024-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 20906.61, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 20906.61, "precofonte": "stooq" }, { "mes": "2024-12", "ganhos": 75.54, "dividendos": 13.82, "taxas": 0, "net": 89.36, "deltarealizado": 75.54, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 21908.17, "saldocaixafimmes": 10.77, "valorcarteira": 10.77, "investimentoinicial": 21908.17, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 23199.35, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 23199.35, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 7.54, "taxas": 0, "net": 7.54, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 24891.78, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 24891.78, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 4.69, "taxas": 0, "net": 4.69, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 28351.85, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 28351.85, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": -107.26, "dividendos": 15.93, "taxas": 0, "net": -91.33, "deltarealizado": -107.26, "deltanaorealizado": 0, "realizadoacumulado": 1698.94, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 28335.93, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 28335.93, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 0, "dividendos": 6.19, "taxas": 0, "net": 6.19, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1698.94, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 28340.07, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 28340.07, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 56.26, "dividendos": 11.63, "taxas": 0, "net": 67.89, "deltarealizado": 56.26, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 27046.61, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 27046.61, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 14.6, "taxas": 0, "net": 14.6, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 31223.21, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 31223.21, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 0, "dividendos": 6.91, "taxas": 0, "net": 6.91, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 31216.33, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 31216.33, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 1.15, "taxas": 0, "net": 1.15, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 31216.33, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 31216.33, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 14.06, "taxas": 0, "net": 14.06, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 32138.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 32138.32, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 0, "dividendos": 6.92, "taxas": 0, "net": 6.92, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 33009.7, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 33009.7, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 6647.07, "dividendos": 0, "taxas": 0, "net": 6647.07, "deltarealizado": 0, "deltanaorealizado": 6647.07, "realizadoacumulado": 1755.21, "naorealizadofimmes": 6647.07, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 41529.28, "investimentoacumulado": 33002.77, "saldocaixafimmes": 0, "valorcarteira": 41529.28, "investimentoinicial": 33002.77, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 16:00:50", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/filipe/movimentos-caixa.csv Tamanho: 8615 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2020-09-04,Depósito,250,USD,CASH TOP-UP,1.1839 2,2020-09-04,Depósito,250,USD,CASH TOP-UP,1.1845 3,2020-09-10,Depósito,250,USD,CASH TOP-UP,1.1834 4,2020-09-24,Depósito,329.15,USD,CASH TOP-UP,1.1657 5,2020-09-25,Depósito,219.22,USD,CASH TOP-UP,1.1679 6,2020-09-25,Levantamento,-219.22,USD,CASH WITHDRAWAL,1.1687 7,2020-09-30,Outros,-0.01,USD,CUSTODY FEE,1.1727 8,2020-10-02,Depósito,0.01,USD,CASH TOP-UP,1.1718 9,2020-10-02,Depósito,415.88,USD,CASH TOP-UP,1.1718 10,2020-10-15,Depósito,400,USD,CASH TOP-UP,1.1708 11,2020-10-22,Depósito,499.59,USD,CASH TOP-UP,1.1821 12,2020-10-30,Depósito,230,USD,CASH TOP-UP,1.165 13,2020-10-31,Outros,-0.02,USD,CUSTODY FEE,1.1764 14,2020-11-13,Dividendo,0.57,USD,AAPL DIVIDEND,1.1809 15,2020-11-17,Depósito,731.22,USD,CASH TOP-UP,1.1865 16,2020-11-30,Depósito,664.15,USD,CASH TOP-UP,1.1995 17,2020-12-01,Outros,-0.03,USD,CUSTODY FEE,1.1944 18,2020-12-07,Depósito,1426.49,USD,CASH TOP-UP,1.2111 19,2020-12-07,Depósito,11.9,USD,CASH TOP-UP,1.216 20,2020-12-10,Levantamento,-719.84,USD,CASH WITHDRAWAL,1.2099 21,2020-12-14,Levantamento,-873.84,USD,CASH WITHDRAWAL,1.2154 22,2020-12-17,Levantamento,-1011.96,USD,CASH WITHDRAWAL,1.2239 23,2020-12-21,Levantamento,-934.75,USD,CASH WITHDRAWAL,1.2181 24,2020-12-23,Levantamento,-440.8,USD,CASH WITHDRAWAL,1.2194 25,2020-12-31,Outros,-0.02,USD,CUSTODY FEE,1.2219 26,2021-01-08,Levantamento,-549.96,USD,CASH WITHDRAWAL,1.2243 27,2021-01-13,Levantamento,-576.16,USD,CASH WITHDRAWAL,1.2219 28,2021-01-25,Levantamento,-538.82,USD,CASH WITHDRAWAL,1.2174 29,2021-01-28,Levantamento,-1373.27,USD,CASH WITHDRAWAL,1.2092 30,2023-11-24,Depósito,504.5,EUR,CASH TOP-UP,1 31,2023-12-01,Outros,-0.05,EUR,CUSTODY FEE,1 32,2023-12-14,Depósito,0.05,EUR,CASH TOP-UP,1 33,2023-12-14,Depósito,489.94,USD,CASH TOP-UP,1.1019 34,2023-12-22,Depósito,879,USD,CASH TOP-UP,1.104 35,2024-01-01,Outros,-0.13,USD,CUSTODY FEE,1.106 36,2024-01-01,Outros,-0.05,EUR,CUSTODY FEE,1 37,2024-01-02,Depósito,0.13,USD,CASH TOP-UP,1.0967 38,2024-01-02,Depósito,543,USD,CASH TOP-UP,1.0968 39,2024-01-25,Depósito,0.05,EUR,CASH TOP-UP,1 40,2024-01-25,Depósito,200.69,EUR,CASH TOP-UP,1 41,2024-01-31,Depósito,288.99,USD,CASH TOP-UP,1.0857 42,2024-02-01,Outros,-0.21,USD,CUSTODY FEE,1.081 43,2024-02-01,Outros,-0.07,EUR,CUSTODY FEE,1 44,2024-02-13,Depósito,0.22,USD,CASH TOP-UP,1.0738 45,2024-02-13,Depósito,755.08,USD,CASH TOP-UP,1.0736 46,2024-02-16,Dividendo,2.03,USD,AAPL DIVIDEND,1.0804 47,2024-03-04,Depósito,0.07,EUR,CASH TOP-UP,1 48,2024-03-04,Depósito,499.93,USD,CASH TOP-UP,1.0871 49,2024-03-04,Depósito,38.14,USD,CASH TOP-UP,1.0872 50,2024-03-15,Dividendo,0.45,USD,MSFT DIVIDEND,1.0916 51,2024-03-22,Depósito,802.91,EUR,CASH TOP-UP,1 52,2024-03-22,Levantamento,-802.91,EUR,CASH WITHDRAWAL,1 53,2024-03-22,Depósito,866.85,USD,CASH TOP-UP,1.0841 54,2024-03-28,Dividendo,0.03,USD,NVDA DIVIDEND,1.0832 55,2024-04-30,Depósito,398.79,USD,CASH TOP-UP,1.0701 56,2024-04-30,Levantamento,-398.8,USD,CASH WITHDRAWAL,1.0692 57,2024-04-30,Depósito,373.01,EUR,CASH TOP-UP,1 58,2024-05-17,Dividendo,3.85,USD,AAPL DIVIDEND,1.0861 59,2024-06-06,Levantamento,-1000,USD,CASH WITHDRAWAL,1.0915 60,2024-06-11,Depósito,510.7,USD,CASH TOP-UP,1.0753 61,2024-06-14,Dividendo,0.45,USD,MSFT DIVIDEND,1.0711 62,2024-06-20,Depósito,855.76,USD,CASH TOP-UP,1.0747 63,2024-06-20,Depósito,0.39,EUR,CASH TOP-UP,1 64,2024-06-21,Depósito,1300,EUR,CASH TOP-UP,1 65,2024-06-21,Levantamento,-1300.39,EUR,CASH WITHDRAWAL,1 66,2024-06-21,Depósito,1300.39,EUR,CASH TOP-UP,1 67,2024-06-21,Levantamento,-1200.39,EUR,CASH WITHDRAWAL,1 68,2024-06-21,Levantamento,-100,EUR,CASH WITHDRAWAL,1 69,2024-06-21,Depósito,1300.39,USD,CASH TOP-UP,1.0709 70,2024-06-25,Depósito,70.8,EUR,CASH TOP-UP,1 71,2024-07-10,Depósito,550,EUR,CASH TOP-UP,1 72,2024-07-15,Depósito,4125,EUR,CASH TOP-UP,1 73,2024-07-15,Depósito,5500,EUR,CASH TOP-UP,1 74,2024-07-18,Levantamento,-1500,EUR,CASH WITHDRAWAL,1 75,2024-07-18,Depósito,1500,USD,CASH TOP-UP,1.0922 76,2024-07-22,Depósito,117.07,EUR,CASH TOP-UP,1 77,2024-07-24,Depósito,750.06,USD,CASH TOP-UP,1.0879 78,2024-08-02,Depósito,1500,USD,CASH TOP-UP,1.084 79,2024-08-02,Depósito,97.92,USD,CASH TOP-UP,1.0844 80,2024-08-02,Depósito,6.42,USD,CASH TOP-UP,1.0934 81,2024-08-16,Dividendo,7.12,USD,AAPL DIVIDEND,1.1013 82,2024-09-13,Dividendo,0.45,USD,MSFT DIVIDEND,1.1112 83,2024-10-04,Dividendo,0.19,USD,NVDA DIVIDEND,1.1052 84,2024-10-28,Levantamento,-3080.54,USD,CASH WITHDRAWAL,1.0838 85,2024-10-28,Depósito,3080.54,USD,CASH TOP-UP,1.0837 86,2024-11-06,Levantamento,-3080.54,USD,CASH WITHDRAWAL,1.0741 87,2024-11-15,Dividendo,7.13,USD,AAPL DIVIDEND,1.0596 88,2024-11-19,Depósito,1000.93,EUR,CASH TOP-UP,1 89,2024-11-19,Levantamento,-7.13,USD,CASH WITHDRAWAL,1.0617 90,2024-11-19,Depósito,2913.11,EUR,CASH TOP-UP,1 91,2024-11-22,Depósito,2076.27,USD,CASH TOP-UP,1.0422 92,2024-12-13,Dividendo,0.5,USD,MSFT DIVIDEND,1.0539 93,2024-12-13,Levantamento,-756.41,USD,CASH WITHDRAWAL,1.054 94,2024-12-17,Depósito,756.47,USD,CASH TOP-UP,1.0518 95,2024-12-18,Dividendo,2.45,EUR,EXXT DIVIDEND,1 96,2024-12-20,Depósito,1000,EUR,CASH TOP-UP,1 97,2024-12-30,Dividendo,0.13,USD,NVDA DIVIDEND,1.0463 98,2024-12-31,Dividendo,10.77,EUR,VUSA DIVIDEND,1 99,2025-01-02,Levantamento,-0.13,USD,CASH WITHDRAWAL,1.0379 100,2025-01-02,Levantamento,-10.77,EUR,CASH WITHDRAWAL,1 101,2025-01-22,Depósito,841,USD,CASH TOP-UP,1.0442 102,2025-01-30,Depósito,510.77,USD,CASH TOP-UP,1.0445 103,2025-01-30,Depósito,8,USD,CASH TOP-UP,1.0446 104,2025-02-14,Dividendo,7.93,USD,AAPL DIVIDEND,1.0521 105,2025-02-24,Levantamento,-7.93,USD,CASH WITHDRAWAL,1.0488 106,2025-02-25,Depósito,1700,EUR,CASH TOP-UP,1 107,2025-03-07,Depósito,1800,EUR,CASH TOP-UP,1 108,2025-03-17,Depósito,809.79,EUR,CASH TOP-UP,1 109,2025-03-19,Dividendo,4.69,EUR,EXXT DIVIDEND,1 110,2025-03-31,Depósito,850.28,EUR,CASH TOP-UP,1 111,2025-04-03,Dividendo,0.21,USD,NVDA DIVIDEND,1.1066 112,2025-04-10,Dividendo,15.74,EUR,VUSA DIVIDEND,1 113,2025-04-11,Levantamento,-15.74,EUR,CASH WITHDRAWAL,1 114,2025-04-11,Levantamento,-0.21,USD,CASH WITHDRAWAL,1.1326 115,2025-05-01,Levantamento,-1256.8,USD,CASH WITHDRAWAL,1.1305 116,2025-05-05,Depósito,1265.5,USD,CASH TOP-UP,1.1341 117,2025-05-16,Dividendo,6.92,USD,AAPL DIVIDEND,1.1172 118,2025-06-18,Dividendo,11.63,EUR,EXXT DIVIDEND,1 119,2025-06-19,Levantamento,-11.63,EUR,CASH WITHDRAWAL,1 120,2025-06-19,Levantamento,-1474.11,USD,CASH WITHDRAWAL,1.15 121,2025-07-09,Dividendo,14.42,EUR,VUSA DIVIDEND,1 122,2025-07-10,Dividendo,0.21,USD,NVDA DIVIDEND,1.1755 123,2025-07-25,Levantamento,-0.21,USD,CASH WITHDRAWAL,1.1753 124,2025-07-25,Levantamento,-14.42,EUR,CASH WITHDRAWAL,1 125,2025-07-25,Depósito,1478.65,USD,CASH TOP-UP,1.175 126,2025-07-25,Depósito,1032.78,EUR,CASH TOP-UP,1 127,2025-08-14,Dividendo,8.07,USD,AAPL DIVIDEND,1.1677 128,2025-08-29,Levantamento,-8.07,USD,CASH WITHDRAWAL,1.1726 129,2025-09-15,Dividendo,1.36,USD,GOOGL DIVIDEND,1.1778 130,2025-10-01,Levantamento,-1.36,USD,CASH WITHDRAWAL,1.1785 131,2025-10-02,Dividendo,0.14,USD,NVDA DIVIDEND,1.1747 132,2025-10-03,Dividendo,13.94,EUR,VUSA DIVIDEND,1 133,2025-10-03,Levantamento,-0.14,USD,CASH WITHDRAWAL,1.1766 134,2025-10-06,Levantamento,-13.94,EUR,CASH WITHDRAWAL,1 135,2025-10-24,Depósito,937.2,EUR,CASH TOP-UP,1 136,2025-10-24,Levantamento,-937.2,EUR,CASH WITHDRAWAL,1 137,2025-11-09,Depósito,1011.67,USD,CASH TOP-UP,1.161 138,2025-11-13,Dividendo,8.07,USD,AAPL DIVIDEND,1.1658 139,2025-12-04,Levantamento,-8.08,USD,CASH WITHDRAWAL,1.167 140,2025-07-27,Depósito,1900,EUR,CASH TOP-UP,1 141,2025-10-24,Depósito,937.2,EUR,CASH TOP-UP,1 142,2025-12-15,Dividendo,1.36,USD,GOOGL DIVIDEND, 143,2025-12-17,Dividendo,2.45,EUR,EXXT DIVIDEND,1 144,2025-12-22,Levantamento,-2.45,EUR,CASH WITHDRAWAL,1 145,2025-12-22,Levantamento,-1.36,USD,CASH WITHDRAWAL, 146,2025-12-26,Dividendo,0.18,USD,NVDA DIVIDEND, 147,2025-12-31,Levantamento,-0.18,USD,CASH WITHDRAWAL, 148,2026-01-05,Dividendo,13.87,EUR,VUSA DIVIDEND,1 149,2026-01-13,Levantamento,-13.87,EUR,CASH WITHDRAWAL,1 150,2026-02-12,Dividendo,8.07,USD,AAPL DIVIDEND, 151,2026-02-20,Levantamento,-8.07,USD,CASH WITHDRAWAL, 152,2026-03-16,Dividendo,1.36,USD,GOOGL DIVIDEND, 153,2026-03-19,Dividendo,4.9,EUR,EXXT DIVIDEND,1 154,2026-03-23,Levantamento,-1.36,USD,CASH WITHDRAWAL, 155,2026-03-23,Levantamento,4.9,EUR,CASH WITHDRAWAL,1 156,2026-04-01,Dividendo,0.18,USD,NVDA DIVIDEND, 157,2026-04-07,Dividendo,15.53,EUR,VUSA DIVIDEND,1 158,2026-04-13,Levantamento,-15.53,EUR,CASH WITHDRAWAL,1 159,2026-04-13,Levantamento,-0.18,USD,CASH WITHDRAWAL, 160,2026-05-01,Depósito,2021,USD,CASH TOP-UP, ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/filipe/transacoes-acoes.csv Tamanho: 7194 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2020-09-04","2020-12-17","AAPL","0.908098","0.00","108.97","116.60","1.1811","1.2266","USD" "2","2020-09-04","2020-12-10","TSLA","1.821273","0.00","250.00","250.57","1.1809","1.2144","USD" "3","2020-09-10","2020-11-18","TSLA","1.964946","0.00","250.00","341.61","1.1896","1.1869","USD" "4","2020-09-24","2020-09-24","TSLA","2.693169","0.00","329.15","351.43","1.1651","1.1679","USD" "5","2020-09-24","2020-10-13","ZM","0.748791","0.00","351.43","382.32","1.1677","1.1746","USD" "6","2020-10-02","2020-11-18","TSLA","14.84535","0.00","415.88","569.34","1.1717","1.1869","USD" "7","2020-09-04","2020-10-12","AAPL","1.175235","0.00","141.03","145.02","1.1811","1.1811","USD" "8","2020-10-13","2020-11-06","Z","1.000000","0.00","101.17","114.81","1.1736","1.1881","USD" "9","2020-10-15","2020-12-08","ANSS","1.000000","0.00","351.53","338.47","1.1699","1.2103","USD" "10","2020-10-15","2020-12-10","TSLA","3","0.00","448.19","623.27","1.1699","1.2144","USD" "11","2020-10-22","2020-10-29","NIO","19.006929","0.00","521.17","604.41","1.1819","1.1676","USD" "12","2020-10-30","2020-11-03","NIO","19.000000","0.00","581.21","654.32","1.1650","1.1732","USD" "13","2020-10-30","2020-12-17","AAPL","2.371988","0.00","258.07","304.56","1.1650","1.2266","USD" "14","2020-11-04","2020-11-05","NIO","17.558483","0.00","654.17","727.82","1.1722","1.1832","USD" "15","2020-11-06","2020-11-12","NIO","20.000000","0.00","824.77","979.99","1.1885","1.1811","USD" "16","2020-11-12","2020-11-23","ZM","1.000000","0.00","435.44","428.76","1.1806","1.1844","USD" "17","2020-11-13","2020-11-23","NIO","12.000000","0.00","541.18","659.98","1.1825","1.1844","USD" "18","2020-11-17","2020-11-23","NIO","15.000000","0.00","715.18","824.98","1.1881","1.1844","USD" "20","2020-11-18","2020-12-15","AAPL","4.000000","0.00","479.02","505.98","1.1869","1.2156","USD" "21","2020-11-23","2020-11-27","MRNA","8.000000","0.00","809.60","998.78","1.1846","1.1948","USD" "23","2020-11-30","2020-12-17","AAPL","2.000000","0.00","234.84","256.79","1.2000","1.2266","USD" "24","2020-11-30","2021-01-26","MRNA","10.000000","0.00","1460.19","1373.27","1.1999","1.2165","USD" "25","2020-12-07","2021-01-21","MRNA","3.000000","0.00","466.21","538.82","1.2140","1.2161","USD" "26","2020-12-07","2020-12-08","AMD","4.000000","0.00","381.21","369.97","1.2140","1.2106","USD" "27","2020-12-07","2020-12-21","NIO","8.000000","0.00","352.25","391.82","1.2151","1.2250","USD" "31","2020-11-24","2020-12-21","NIO","1","0.00","53.12","48.98","1.1883","1.2250","USD" "32","2020-11-24","2021-01-06","NIO","10.000000","0.00","531.19","549.98","1.1883","1.2310","USD" "35","2023-11-24","","AMS:IWDA","6.396602","","504.50","","1.0000","","EUR" "36","2023-12-14","","AAPL","2.465917","","489.94","","1.1019","","USD" "37","2023-12-26","","AAPL","2.529855","","491.00","","1.1043","","USD" "38","2024-01-08","","AAPL","3.000000","","541.37","","1.0945","","USD" "39","2024-01-26","","AMS:IWDA","2.370037","","200.69","","1.0000","","EUR" "40","2024-01-31","2024-12-10","MSFT","0.711121","0.00","290.63","318.51","1.0886","1.0529","USD" "41","2024-02-13","","NVDA","0.61234","","43.57","","1.0736","","USD" "42","2024-03-04","","AAPL","0.080397","","15.09","","1.0881","","USD" "43","2024-03-22","","AAPL","5.052724","","867.30","","1.0844","","USD" "44","2024-05-02","","AMS:IWDA","4.189241","","373.01","","1.0000","","EUR" "45","2024-02-13","2024-05-22","NVDA","7","0.00","711.52","999.96","1.0736","1.0847","USD" "46","2024-06-11","","AAPL","2.519859","","514.53","","1.0754","","USD" "47","2024-06-20","2024-10-17","NVDA","6","0.00","838.21","839.97","1.0747","1.0885","USD" "48","2024-06-21","2024-12-09","RIVN","4.463768","0.00","47.27","65.14","1.0708","1.0597","USD" "49","2024-06-24","2024-10-17","NVDA","10","0.00","1236.76","1399.96","1.0767","1.0885","USD" "50","2024-06-26","","AMS:IWDA","0.733625","","70.80","","1.0000","","EUR" "51","2024-07-10","","AMS:IWDA","5.715610","","550.00","","1.0000","","EUR" "52","2024-07-15","","AMS:IWDA","42.710297","","4125.00","","1.0000","","EUR" "53","2024-07-17","","INDEXNASDAQ:NDX","12.000000","","2172.62","","1.0000","","EUR" "54","2024-07-19","","INDEXNASDAQ:NDX","5.000000","","872.18","","1.0000","","EUR" "55","2024-07-22","","INDEXNASDAQ:NDX","6.079345","","1072.27","","1.0000","","EUR" "56","2024-07-22","2024-12-09","RIVN","0.517910","0.00","9.91","7.56","1.0903","1.0597","USD" "57","2024-07-24","2025-04-28","AAPL","6.000000","0.00","1320.00","1256.80","1.0882","1.1366","USD" "58","2024-07-25","2024-10-17","NVDA","6","0.00","661.65","839.97","1.0856","1.0885","USD" "59","2024-08-01","2024-12-09","RIVN","5.000000","0.00","76.08","72.97","1.0803","1.0597","USD" "60","2024-08-02","","AAPL","6.883687","","1512.33","","1.0912","","USD" "61","2024-08-02","2024-12-09","RIVN","6.659560","0.00","97.91","97.19","1.0911","1.0597","USD" "62","2024-08-02","2024-12-09","RIVN","0.363356","0.00","6.42","5.30","1.0934","1.0597","USD" "63","2024-08-05","2024-12-09","RIVN","13.000000","0.00","169.57","189.73","1.1015","1.0597","USD" "64","2024-09-12","","AAPL","0.034418","","7.65","","1.1060","","USD" "66","2024-11-20","","VUSA","36.805462","","3914.04","","1.0000","","EUR" "67","2024-11-22","","NVDA","14.199164","","2076.26","","1.0433","","USD" "69","2024-12-17","2025-06-16","NVDA","5","0.00","646.96","729.36","1.0526","1.1614","USD" "70","2024-12-20","","VUSA","9.417628","","1002.45","","1.0000","","EUR" "71","2025-01-22","","AAPL","3.768304","","841.00","","1.0436","","USD" "72","2025-01-30","2025-06-16","NVDA","4","0.00","479.95","583.48","1.0445","1.1614","USD" "73","2025-02-25","","INDEXNASDAQ:NDX","8.584991","","1700.00","","1.0000","","EUR" "74","2025-03-10","","INDEXNASDAQ:NDX","9.956249","","1800.00","","1.0000","","EUR" "75","2025-03-17","","VUSA","8.210714","","809.79","","1.0000","","EUR" "76","2025-03-31","","INDEXNASDAQ:NDX","5.035159","","854.97","","1.0000","","EUR" "78","2025-07-25","","AAPL","5.175261","","1111.15","","1.1751","","USD" "79","2025-07-25","","GOOGL","7.644746","","1478.65","","1.1750","","USD" "80","2025-07-25","","INDEXNASDAQ:NDX","5.339923","","1032.78","","1.0000","","EUR" "81","2025-11-10","","NVDA","5.182103","","1011.66","","1.1591","","USD" "79","2020-11-24","2021-01-11","NIO","9","0","478.07","576.16","1.1883","1.2172","USD" "79","2024-06-20","","NVDA","0.128919","","18","","1.0767","","USD" "80","2024-06-24","","NVDA","0.132285","","16.36","","1.0747","","USD" "80","2024-12-17","","NVDA","0.857420","","110.01","","1.0526","","USD" "81","2025-01-30","","NVDA","0.323586","","38.82","","1.0445","","USD" "81","2020-11-23","2020-12-15","AAPL","4","0","457.22","505.98","1.1846","1.2156","USD" "82","2020-02-07","2020-12-17","AAPL","2","0","249.61","256.80","1.2160","1.2266","USD" "79","2023-12-22","","AAPL","2","","388","","1.1031","","USD" "80","2024-03-04","","AAPL","3","","525","","1.0884","","USD" "81","2025-07-25","","XAU","0.651188","27.81","1900","","1","","EUR" "82","2025-10-24","","XAU","0.26215","9.28","937.20","","1","","EUR" "83","2026-05-01","","NVDA","10.0358243","1.17","2020.98","","","","USD" ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/historico-ativos.csv Tamanho: 3416 bytes ======================================================================================== Período,EURUSD,AAPL,TSLA,NVDA,GOOGL ,1.1643,280.68,450.20,183.45,317.62 2018/12/31,0.8760,39.44,22.19,33.38, 2019/01/31,0.8850,41.61,20.47,35.94, 2019/02/28,0.8920,43.29,21.33,38.57, 2019/03/31,0.9000,47.81,19.28,45.57, 2019/04/30,0.9200,50.17,15.91,45.25, 2019/05/31,0.9500,43.77,12.34,33.87, 2019/06/30,0.9700,50.39,15.14,41.54, 2019/07/31,0.9750,53.26,16.11,42.18, 2019/08/31,0.9600,51.43,15.00,41.04, 2019/09/30,0.9200,55.99,16.06,43.52, 2019/10/31,0.8800,62.19,20.99,50.26, 2019/11/30,0.8800,66.04,22.32,52.31, 2019/12/31,0.8500,73.41,27.89,58.83, 2020/01/31,0.8800,77.38,43.37,59.11, 2020/02/29,0.8600,74.70,49.57,69.11, 2020/03/31,0.8500,63.57,34.93,65.90, 2020/04/30,0.8600,73.45,52.13,73.07, 2020/05/31,0.8600,80.46,59.87,88.06, 2020/06/30,0.8600,91.20,71.99,94.98, 2020/07/31,0.8600,106.26,95.38,106.15, 2020/08/31,0.8600,129.04,166.11,133.75, 2020/09/30,0.8300,115.81,143.00,135.31, 2020/10/31,0.8300,108.77,133.50,125.81, 2020/11/30,0.8300,119.05,189.20,134.01, 2020/12/31,0.8300,132.69,235.22,130.55, 2021/01/31,0.8200,134.14,279.94,132.37, 2021/02/28,0.8400,127.79,239.48,138.42, 2021/03/31,0.8400,122.15,222.64,133.48, 2021/04/30,0.8300,131.46,236.48,150.10, 2021/05/31,0.8200,124.28,207.97,162.65, 2021/06/30,0.8500,136.96,226.57,200.03, 2021/07/31,0.8600,145.52,236.56,197.50, 2021/08/31,0.8500,151.83,245.24,223.85, 2021/09/30,0.8600,141.50,258.49,207.16, 2021/10/31,0.8800,148.96,402.86,258.27, 2021/11/30,0.8800,165.30,381.59,326.76, 2021/12/31,0.8800,177.57,352.26,294.11, 2022/01/31,0.8800,174.78,312.24,244.86, 2022/02/28,0.8900,165.12,290.14,243.85, 2022/03/31,0.9200,174.61,359.20,272.86, 2022/04/30,0.9400,157.96,300.98,195.33, 2022/05/31,0.9500,148.84,252.75,186.72, 2022/06/30,0.9600,136.72,224.47,151.59, 2022/07/31,0.9700,161.51,297.28,184.41, 2022/08/31,0.9800,157.22,275.61,150.94, 2022/09/30,0.9700,138.20,265.25,121.39, 2022/10/31,0.9700,153.34,227.54,134.97, 2022/11/30,0.9800,148.03,194.70,169.23, 2022/12/30,0.9900,129.93,123.18,146.14, 2023/01/31,1.0000,144.29,173.22,195.37, 2023/02/28,1.0100,147.41,205.71,232.16, 2023/03/31,1.0800,164.90,207.46,277.77, 2023/04/30,1.1000,169.59,161.83,289.10, 2023/05/31,1.0800,177.25,203.93,378.34, 2023/06/30,1.0900,193.97,261.77,423.02, 2023/07/31,1.1100,196.45,267.43,467.29, 2023/08/31,1.0900,187.87,258.08,493.55, 2023/09/30,1.0600,173.75,251.60,447.82, 2023/10/31,1.0600,170.77,200.84,407.80, 2023/11/30,1.0900,189.95,240.08,467.70, 2023/12/31,1.1000,192.53,248.48,495.22, 2024/01/31,1.0800,184.40,187.29,61.53, 2024/02/29,1.0800,180.75,201.88,79.11, 2024/03/31,1.0800,170.03,175.22,90.36, 2024/04/30,1.0700,170.33,183.28,86.40, 2024/05/31,1.0800,192.25,178.08,109.63, 2024/06/27,1.0700,210.62,197.88,123.54, 2024/07/30,1.0900,222.08,232.07,117.02, 2024/08/31,1.1100,222.77,210.60,108.00, 2024/09/30,1.1100,233.00,261.63,121.44, 2024/10/31,1.0900,225.91,249.85,132.76, 2024/11/30,1.0800,239.59,357.09,134.29, 2024/12/31,1.0500,250.42,403.84,120.07, 2025/01/31,1.0800,236.00,292.98,124.92, 2025/02/28,1.0900,241.84,259.16,108.38, 2025/03/31,1.0900,222.13,282.16,108.92, 2025/04/30,1.1000,212.50,342.69,137.38, 2025/05/31,1.1200,201.70,317.66,157.99, 2025/06/30,1.1300,205.17,308.27,177.87, 2025/07/31,1.1400,207.57,329.36,170.78, 2025/08/31,1.1500,229.72,444.72,186.58, 2025/09/30,1.1600,254.63,456.56,202.49, 2025/10/31,1.1600,270.37,430.14,179.92, 2025/11/30,1.1600,283.10,454.48,183.38, 2025/12/31,1.1643,280.68,450.20,183.45,317.62 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/historico-cambio-date.txt Tamanho: 10 bytes ======================================================================================== 2026-06-11 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/historico-cambio.json Tamanho: 44374 bytes ======================================================================================== { "2019-10-01": 1.0898, "2019-10-02": 1.0925, "2019-10-03": 1.0951, "2019-10-04": 1.0979, "2019-10-07": 1.0993, "2019-10-08": 1.0986, "2019-10-09": 1.0981, "2019-10-10": 1.103, "2019-10-11": 1.1043, "2019-10-14": 1.1031, "2019-10-15": 1.1007, "2019-10-16": 1.1025, "2019-10-17": 1.1113, "2019-10-18": 1.1144, "2019-10-21": 1.1173, "2019-10-22": 1.113, "2019-10-23": 1.1123, "2019-10-24": 1.1128, "2019-10-25": 1.1107, "2019-10-28": 1.1087, "2019-10-29": 1.1095, "2019-10-30": 1.1106, "2019-10-31": 1.1154, "2019-11-01": 1.1139, "2019-11-04": 1.1158, "2019-11-05": 1.1109, "2019-11-06": 1.109, "2019-11-07": 1.1077, "2019-11-08": 1.1034, "2019-11-11": 1.1041, "2019-11-12": 1.1015, "2019-11-13": 1.1006, "2019-11-14": 1.0997, "2019-11-15": 1.1034, "2019-11-18": 1.1061, "2019-11-19": 1.1077, "2019-11-20": 1.1059, "2019-11-21": 1.1091, "2019-11-22": 1.1058, "2019-11-25": 1.1008, "2019-11-26": 1.102, "2019-11-27": 1.1009, "2019-11-28": 1.1005, "2019-11-29": 1.0982, "2019-12-02": 1.1023, "2019-12-03": 1.1071, "2019-12-04": 1.1081, "2019-12-05": 1.1094, "2019-12-06": 1.1094, "2019-12-09": 1.1075, "2019-12-10": 1.1077, "2019-12-11": 1.1075, "2019-12-12": 1.1137, "2019-12-13": 1.1174, "2019-12-16": 1.1146, "2019-12-17": 1.1162, "2019-12-18": 1.1115, "2019-12-19": 1.1117, "2019-12-20": 1.1097, "2019-12-23": 1.1075, "2019-12-24": 1.108, "2019-12-27": 1.1153, "2019-12-30": 1.1189, "2019-12-31": 1.1234, "2020-01-02": 1.1193, "2020-01-03": 1.1147, "2020-01-06": 1.1194, "2020-01-07": 1.1172, "2020-01-08": 1.1115, "2020-01-09": 1.111, "2020-01-10": 1.1091, "2020-01-13": 1.1126, "2020-01-14": 1.1115, "2020-01-15": 1.1142, "2020-01-16": 1.1169, "2020-01-17": 1.1108, "2020-01-20": 1.1085, "2020-01-21": 1.1115, "2020-01-22": 1.1088, "2020-01-23": 1.1091, "2020-01-24": 1.1035, "2020-01-27": 1.1025, "2020-01-28": 1.1005, "2020-01-29": 1.1001, "2020-01-30": 1.1029, "2020-01-31": 1.1052, "2020-02-03": 1.1066, "2020-02-04": 1.1048, "2020-02-05": 1.1023, "2020-02-06": 1.1003, "2020-02-07": 1.0969, "2020-02-10": 1.0951, "2020-02-11": 1.0901, "2020-02-12": 1.0914, "2020-02-13": 1.0867, "2020-02-14": 1.0842, "2020-02-17": 1.0835, "2020-02-18": 1.0816, "2020-02-19": 1.08, "2020-02-20": 1.079, "2020-02-21": 1.0801, "2020-02-24": 1.0818, "2020-02-25": 1.084, "2020-02-26": 1.0875, "2020-02-27": 1.0964, "2020-02-28": 1.0977, "2020-03-02": 1.1122, "2020-03-03": 1.1117, "2020-03-04": 1.1125, "2020-03-05": 1.1187, "2020-03-06": 1.1336, "2020-03-09": 1.1456, "2020-03-10": 1.139, "2020-03-11": 1.1336, "2020-03-12": 1.124, "2020-03-13": 1.1104, "2020-03-16": 1.1157, "2020-03-17": 1.0982, "2020-03-18": 1.0934, "2020-03-19": 1.0801, "2020-03-20": 1.0707, "2020-03-23": 1.0783, "2020-03-24": 1.0843, "2020-03-25": 1.0827, "2020-03-26": 1.0981, "2020-03-27": 1.0977, "2020-03-30": 1.1034, "2020-03-31": 1.0956, "2020-04-01": 1.0936, "2020-04-02": 1.0906, "2020-04-03": 1.0785, "2020-04-06": 1.0791, "2020-04-07": 1.0885, "2020-04-08": 1.0871, "2020-04-09": 1.0867, "2020-04-14": 1.0963, "2020-04-15": 1.0903, "2020-04-16": 1.0888, "2020-04-17": 1.086, "2020-04-20": 1.086, "2020-04-21": 1.0837, "2020-04-22": 1.0867, "2020-04-23": 1.0772, "2020-04-24": 1.08, "2020-04-27": 1.0852, "2020-04-28": 1.0877, "2020-04-29": 1.0842, "2020-04-30": 1.0876, "2020-05-04": 1.0942, "2020-05-05": 1.0843, "2020-05-06": 1.0807, "2020-05-07": 1.0783, "2020-05-08": 1.0843, "2020-05-11": 1.0824, "2020-05-12": 1.0858, "2020-05-13": 1.0875, "2020-05-14": 1.0792, "2020-05-15": 1.0798, "2020-05-18": 1.0832, "2020-05-19": 1.095, "2020-05-20": 1.0958, "2020-05-21": 1.1, "2020-05-22": 1.0904, "2020-05-25": 1.091, "2020-05-26": 1.0975, "2020-05-27": 1.0991, "2020-05-28": 1.1016, "2020-05-29": 1.1136, "2020-06-01": 1.1116, "2020-06-02": 1.1174, "2020-06-03": 1.1194, "2020-06-04": 1.125, "2020-06-05": 1.133, "2020-06-08": 1.1285, "2020-06-09": 1.1294, "2020-06-10": 1.1375, "2020-06-11": 1.1348, "2020-06-12": 1.1304, "2020-06-15": 1.1253, "2020-06-16": 1.1308, "2020-06-17": 1.1232, "2020-06-18": 1.1222, "2020-06-19": 1.121, "2020-06-22": 1.1213, "2020-06-23": 1.1318, "2020-06-24": 1.128, "2020-06-25": 1.12, "2020-06-26": 1.1213, "2020-06-29": 1.1284, "2020-06-30": 1.1198, "2020-07-01": 1.12, "2020-07-02": 1.1286, "2020-07-03": 1.1224, "2020-07-06": 1.1325, "2020-07-07": 1.129, "2020-07-08": 1.1286, "2020-07-09": 1.1342, "2020-07-10": 1.1276, "2020-07-13": 1.1329, "2020-07-14": 1.1375, "2020-07-15": 1.1444, "2020-07-16": 1.1414, "2020-07-17": 1.1428, "2020-07-20": 1.1448, "2020-07-21": 1.1443, "2020-07-22": 1.1578, "2020-07-23": 1.1569, "2020-07-24": 1.1608, "2020-07-27": 1.176, "2020-07-28": 1.1717, "2020-07-29": 1.1725, "2020-07-30": 1.1743, "2020-07-31": 1.1848, "2020-08-03": 1.1726, "2020-08-04": 1.1765, "2020-08-05": 1.1854, "2020-08-06": 1.1843, "2020-08-07": 1.1817, "2020-08-10": 1.1763, "2020-08-11": 1.1783, "2020-08-12": 1.1771, "2020-08-13": 1.1833, "2020-08-14": 1.1813, "2020-08-17": 1.1853, "2020-08-18": 1.1906, "2020-08-19": 1.1933, "2020-08-20": 1.185, "2020-08-21": 1.1769, "2020-08-24": 1.1847, "2020-08-25": 1.1814, "2020-08-26": 1.1789, "2020-08-27": 1.1806, "2020-08-28": 1.1915, "2020-08-31": 1.194, "2020-09-01": 1.1987, "2020-09-02": 1.1861, "2020-09-03": 1.1813, "2020-09-04": 1.1842, "2020-09-07": 1.1824, "2020-09-08": 1.1785, "2020-09-09": 1.1773, "2020-09-10": 1.1849, "2020-09-11": 1.1854, "2020-09-14": 1.1876, "2020-09-15": 1.1892, "2020-09-16": 1.1869, "2020-09-17": 1.1797, "2020-09-18": 1.1833, "2020-09-21": 1.1787, "2020-09-22": 1.174, "2020-09-23": 1.1692, "2020-09-24": 1.1645, "2020-09-25": 1.1634, "2020-09-28": 1.167, "2020-09-29": 1.1702, "2020-09-30": 1.1708, "2020-10-01": 1.1752, "2020-10-02": 1.173, "2020-10-05": 1.1768, "2020-10-06": 1.1795, "2020-10-07": 1.177, "2020-10-08": 1.1765, "2020-10-09": 1.1795, "2020-10-12": 1.1799, "2020-10-13": 1.1787, "2020-10-14": 1.175, "2020-10-15": 1.1698, "2020-10-16": 1.1741, "2020-10-19": 1.1785, "2020-10-20": 1.181, "2020-10-21": 1.1852, "2020-10-22": 1.1821, "2020-10-23": 1.1856, "2020-10-26": 1.1819, "2020-10-27": 1.1832, "2020-10-28": 1.1727, "2020-10-29": 1.1704, "2020-10-30": 1.1698, "2020-11-02": 1.1652, "2020-11-03": 1.1702, "2020-11-04": 1.1721, "2020-11-05": 1.1855, "2020-11-06": 1.187, "2020-11-09": 1.1883, "2020-11-10": 1.1808, "2020-11-11": 1.1766, "2020-11-12": 1.1791, "2020-11-13": 1.1815, "2020-11-16": 1.183, "2020-11-17": 1.1882, "2020-11-18": 1.1868, "2020-11-19": 1.1832, "2020-11-20": 1.1863, "2020-11-23": 1.1901, "2020-11-24": 1.1865, "2020-11-25": 1.189, "2020-11-26": 1.19, "2020-11-27": 1.1922, "2020-11-30": 1.198, "2020-12-01": 1.1968, "2020-12-02": 1.2066, "2020-12-03": 1.2151, "2020-12-04": 1.2159, "2020-12-07": 1.2128, "2020-12-08": 1.2114, "2020-12-09": 1.2109, "2020-12-10": 1.2115, "2020-12-11": 1.2127, "2020-12-14": 1.2162, "2020-12-15": 1.214, "2020-12-16": 1.2189, "2020-12-17": 1.2246, "2020-12-18": 1.2259, "2020-12-21": 1.2173, "2020-12-22": 1.2239, "2020-12-23": 1.2166, "2020-12-24": 1.2193, "2020-12-28": 1.2219, "2020-12-29": 1.2259, "2020-12-30": 1.2281, "2020-12-31": 1.2271, "2021-01-04": 1.2296, "2021-01-05": 1.2271, "2021-01-06": 1.2338, "2021-01-07": 1.2276, "2021-01-08": 1.225, "2021-01-11": 1.2163, "2021-01-12": 1.2161, "2021-01-13": 1.2166, "2021-01-14": 1.2124, "2021-01-15": 1.2123, "2021-01-18": 1.2064, "2021-01-19": 1.2132, "2021-01-20": 1.2101, "2021-01-21": 1.2158, "2021-01-22": 1.2158, "2021-01-25": 1.2152, "2021-01-26": 1.2143, "2021-01-27": 1.2114, "2021-01-28": 1.2091, "2021-01-29": 1.2136, "2021-02-01": 1.2084, "2021-02-02": 1.2044, "2021-02-03": 1.2017, "2021-02-04": 1.1996, "2021-02-05": 1.1983, "2021-02-08": 1.2025, "2021-02-09": 1.2104, "2021-02-10": 1.2127, "2021-02-11": 1.2147, "2021-02-12": 1.2108, "2021-02-15": 1.2129, "2021-02-16": 1.2143, "2021-02-17": 1.206, "2021-02-18": 1.2084, "2021-02-19": 1.2139, "2021-02-22": 1.2133, "2021-02-23": 1.2143, "2021-02-24": 1.2146, "2021-02-25": 1.2225, "2021-02-26": 1.2121, "2021-03-01": 1.2053, "2021-03-02": 1.2028, "2021-03-03": 1.2048, "2021-03-04": 1.2034, "2021-03-05": 1.1938, "2021-03-08": 1.1866, "2021-03-09": 1.1894, "2021-03-10": 1.1892, "2021-03-11": 1.1969, "2021-03-12": 1.1933, "2021-03-15": 1.192, "2021-03-16": 1.1926, "2021-03-17": 1.1907, "2021-03-18": 1.1912, "2021-03-19": 1.1891, "2021-03-22": 1.1926, "2021-03-23": 1.1883, "2021-03-24": 1.1825, "2021-03-25": 1.1802, "2021-03-26": 1.1782, "2021-03-29": 1.1784, "2021-03-30": 1.1741, "2021-03-31": 1.1725, "2021-04-01": 1.1746, "2021-04-06": 1.1812, "2021-04-07": 1.1884, "2021-04-08": 1.1873, "2021-04-09": 1.1888, "2021-04-12": 1.1904, "2021-04-13": 1.1896, "2021-04-14": 1.1964, "2021-04-15": 1.197, "2021-04-16": 1.1986, "2021-04-19": 1.2035, "2021-04-20": 1.2051, "2021-04-21": 1.2007, "2021-04-22": 1.2046, "2021-04-23": 1.2066, "2021-04-26": 1.2085, "2021-04-27": 1.2088, "2021-04-28": 1.207, "2021-04-29": 1.2129, "2021-04-30": 1.2082, "2021-05-03": 1.2044, "2021-05-04": 1.2021, "2021-05-05": 1.2005, "2021-05-06": 1.206, "2021-05-07": 1.2059, "2021-05-10": 1.2169, "2021-05-11": 1.217, "2021-05-12": 1.2118, "2021-05-13": 1.2081, "2021-05-14": 1.2123, "2021-05-17": 1.2143, "2021-05-18": 1.2222, "2021-05-19": 1.2212, "2021-05-20": 1.2203, "2021-05-21": 1.2188, "2021-05-24": 1.2212, "2021-05-25": 1.2264, "2021-05-26": 1.2229, "2021-05-27": 1.2198, "2021-05-28": 1.2142, "2021-05-31": 1.2201, "2021-06-01": 1.2225, "2021-06-02": 1.2186, "2021-06-03": 1.2187, "2021-06-04": 1.2117, "2021-06-07": 1.2162, "2021-06-08": 1.2182, "2021-06-09": 1.2195, "2021-06-10": 1.2174, "2021-06-11": 1.2125, "2021-06-14": 1.2112, "2021-06-15": 1.2108, "2021-06-16": 1.2124, "2021-06-17": 1.1937, "2021-06-18": 1.1898, "2021-06-21": 1.1891, "2021-06-22": 1.1894, "2021-06-23": 1.1951, "2021-06-24": 1.1936, "2021-06-25": 1.195, "2021-06-28": 1.191, "2021-06-29": 1.1888, "2021-06-30": 1.1884, "2021-07-01": 1.1884, "2021-07-02": 1.1823, "2021-07-05": 1.1866, "2021-07-06": 1.1838, "2021-07-07": 1.1831, "2021-07-08": 1.1838, "2021-07-09": 1.1858, "2021-07-12": 1.1852, "2021-07-13": 1.1844, "2021-07-14": 1.1812, "2021-07-15": 1.1809, "2021-07-16": 1.1802, "2021-07-19": 1.1766, "2021-07-20": 1.1775, "2021-07-21": 1.1772, "2021-07-22": 1.1775, "2021-07-23": 1.1767, "2021-07-26": 1.1787, "2021-07-27": 1.181, "2021-07-28": 1.1807, "2021-07-29": 1.1873, "2021-07-30": 1.1891, "2021-08-02": 1.1886, "2021-08-03": 1.1885, "2021-08-04": 1.1861, "2021-08-05": 1.185, "2021-08-06": 1.1807, "2021-08-09": 1.1761, "2021-08-10": 1.1722, "2021-08-11": 1.1718, "2021-08-12": 1.1739, "2021-08-13": 1.1765, "2021-08-16": 1.1772, "2021-08-17": 1.1767, "2021-08-18": 1.1723, "2021-08-19": 1.1696, "2021-08-20": 1.1671, "2021-08-23": 1.1718, "2021-08-24": 1.174, "2021-08-25": 1.1736, "2021-08-26": 1.1767, "2021-08-27": 1.1761, "2021-08-30": 1.1801, "2021-08-31": 1.1834, "2021-09-01": 1.1817, "2021-09-02": 1.1846, "2021-09-03": 1.1872, "2021-09-06": 1.1864, "2021-09-07": 1.186, "2021-09-08": 1.1827, "2021-09-09": 1.1838, "2021-09-10": 1.1841, "2021-09-13": 1.178, "2021-09-14": 1.1814, "2021-09-15": 1.1824, "2021-09-16": 1.1763, "2021-09-17": 1.178, "2021-09-20": 1.1711, "2021-09-21": 1.1738, "2021-09-22": 1.1729, "2021-09-23": 1.1715, "2021-09-24": 1.1719, "2021-09-27": 1.1698, "2021-09-28": 1.1678, "2021-09-29": 1.1654, "2021-09-30": 1.1579, "2021-10-01": 1.16, "2021-10-04": 1.1636, "2021-10-05": 1.1602, "2021-10-06": 1.1542, "2021-10-07": 1.1562, "2021-10-08": 1.1569, "2021-10-11": 1.1574, "2021-10-12": 1.1555, "2021-10-13": 1.1562, "2021-10-14": 1.1602, "2021-10-15": 1.1602, "2021-10-18": 1.1604, "2021-10-19": 1.1655, "2021-10-20": 1.1623, "2021-10-21": 1.1637, "2021-10-22": 1.163, "2021-10-25": 1.1603, "2021-10-26": 1.1618, "2021-10-27": 1.1617, "2021-10-28": 1.1593, "2021-10-29": 1.1645, "2021-11-01": 1.1578, "2021-11-02": 1.1603, "2021-11-03": 1.1578, "2021-11-04": 1.1569, "2021-11-05": 1.1519, "2021-11-08": 1.1579, "2021-11-09": 1.1577, "2021-11-10": 1.1558, "2021-11-11": 1.146, "2021-11-12": 1.1448, "2021-11-15": 1.1444, "2021-11-16": 1.1368, "2021-11-17": 1.1316, "2021-11-18": 1.1345, "2021-11-19": 1.1271, "2021-11-22": 1.1278, "2021-11-23": 1.1259, "2021-11-24": 1.1206, "2021-11-25": 1.1223, "2021-11-26": 1.1291, "2021-11-29": 1.1276, "2021-11-30": 1.1363, "2021-12-01": 1.1314, "2021-12-02": 1.1339, "2021-12-03": 1.1291, "2021-12-06": 1.1287, "2021-12-07": 1.1256, "2021-12-08": 1.1299, "2021-12-09": 1.1311, "2021-12-10": 1.1273, "2021-12-13": 1.1278, "2021-12-14": 1.1309, "2021-12-15": 1.1262, "2021-12-16": 1.1336, "2021-12-17": 1.133, "2021-12-20": 1.1273, "2021-12-21": 1.1295, "2021-12-22": 1.1301, "2021-12-23": 1.131, "2021-12-24": 1.1317, "2021-12-27": 1.1312, "2021-12-28": 1.1331, "2021-12-29": 1.1303, "2021-12-30": 1.1334, "2021-12-31": 1.1326, "2022-01-03": 1.1355, "2022-01-04": 1.1279, "2022-01-05": 1.1319, "2022-01-06": 1.1315, "2022-01-07": 1.1298, "2022-01-10": 1.1318, "2022-01-11": 1.1336, "2022-01-12": 1.137, "2022-01-13": 1.1463, "2022-01-14": 1.1447, "2022-01-17": 1.1403, "2022-01-18": 1.1367, "2022-01-19": 1.1345, "2022-01-20": 1.1338, "2022-01-21": 1.1348, "2022-01-24": 1.1304, "2022-01-25": 1.1268, "2022-01-26": 1.1277, "2022-01-27": 1.116, "2022-01-28": 1.1138, "2022-01-31": 1.1156, "2022-02-01": 1.126, "2022-02-02": 1.1323, "2022-02-03": 1.1286, "2022-02-04": 1.1464, "2022-02-07": 1.1447, "2022-02-08": 1.1408, "2022-02-09": 1.1435, "2022-02-10": 1.1439, "2022-02-11": 1.1417, "2022-02-14": 1.1316, "2022-02-15": 1.1345, "2022-02-16": 1.1372, "2022-02-17": 1.137, "2022-02-18": 1.1354, "2022-02-21": 1.1338, "2022-02-22": 1.1342, "2022-02-23": 1.1344, "2022-02-24": 1.1163, "2022-02-25": 1.1216, "2022-02-28": 1.1199, "2022-03-01": 1.1162, "2022-03-02": 1.1106, "2022-03-03": 1.1076, "2022-03-04": 1.0929, "2022-03-07": 1.0895, "2022-03-08": 1.0892, "2022-03-09": 1.0993, "2022-03-10": 1.1084, "2022-03-11": 1.099, "2022-03-14": 1.096, "2022-03-15": 1.0991, "2022-03-16": 1.0994, "2022-03-17": 1.1051, "2022-03-18": 1.1008, "2022-03-21": 1.1038, "2022-03-22": 1.1024, "2022-03-23": 1.0985, "2022-03-24": 1.0978, "2022-03-25": 1.1002, "2022-03-28": 1.0966, "2022-03-29": 1.1085, "2022-03-30": 1.1126, "2022-03-31": 1.1101, "2022-04-01": 1.1052, "2022-04-04": 1.1005, "2022-04-05": 1.0969, "2022-04-06": 1.0923, "2022-04-07": 1.0916, "2022-04-08": 1.0861, "2022-04-11": 1.09, "2022-04-12": 1.0861, "2022-04-13": 1.0826, "2022-04-14": 1.0878, "2022-04-19": 1.0803, "2022-04-20": 1.083, "2022-04-21": 1.0887, "2022-04-22": 1.0817, "2022-04-25": 1.0746, "2022-04-26": 1.0674, "2022-04-27": 1.0583, "2022-04-28": 1.0485, "2022-04-29": 1.054, "2022-05-02": 1.0524, "2022-05-03": 1.0556, "2022-05-04": 1.0531, "2022-05-05": 1.0568, "2022-05-06": 1.057, "2022-05-09": 1.0559, "2022-05-10": 1.0554, "2022-05-11": 1.0553, "2022-05-12": 1.0408, "2022-05-13": 1.0385, "2022-05-16": 1.0422, "2022-05-17": 1.0541, "2022-05-18": 1.0523, "2022-05-19": 1.0525, "2022-05-20": 1.0577, "2022-05-23": 1.0659, "2022-05-24": 1.072, "2022-05-25": 1.0656, "2022-05-26": 1.0697, "2022-05-27": 1.0722, "2022-05-30": 1.0764, "2022-05-31": 1.0713, "2022-06-01": 1.0712, "2022-06-02": 1.0692, "2022-06-03": 1.073, "2022-06-06": 1.0726, "2022-06-07": 1.0662, "2022-06-08": 1.0739, "2022-06-09": 1.0743, "2022-06-10": 1.0578, "2022-06-13": 1.0455, "2022-06-14": 1.0452, "2022-06-15": 1.0431, "2022-06-16": 1.04, "2022-06-17": 1.0486, "2022-06-20": 1.0517, "2022-06-21": 1.055, "2022-06-22": 1.0521, "2022-06-23": 1.0493, "2022-06-24": 1.0524, "2022-06-27": 1.0572, "2022-06-28": 1.0561, "2022-06-29": 1.0517, "2022-06-30": 1.0387, "2022-07-01": 1.0425, "2022-07-04": 1.0455, "2022-07-05": 1.029, "2022-07-06": 1.0177, "2022-07-07": 1.018, "2022-07-08": 1.0163, "2022-07-11": 1.0098, "2022-07-12": 1.0042, "2022-07-13": 1.0067, "2022-07-14": 1.0005, "2022-07-15": 1.0059, "2022-07-18": 1.0131, "2022-07-19": 1.0245, "2022-07-20": 1.0199, "2022-07-21": 1.0199, "2022-07-22": 1.019, "2022-07-25": 1.0236, "2022-07-26": 1.0124, "2022-07-27": 1.0152, "2022-07-28": 1.0122, "2022-07-29": 1.0198, "2022-08-01": 1.0233, "2022-08-02": 1.0224, "2022-08-03": 1.0194, "2022-08-04": 1.0181, "2022-08-05": 1.0233, "2022-08-08": 1.0199, "2022-08-09": 1.0234, "2022-08-10": 1.0252, "2022-08-11": 1.0338, "2022-08-12": 1.0285, "2022-08-15": 1.0195, "2022-08-16": 1.0131, "2022-08-17": 1.0164, "2022-08-18": 1.0178, "2022-08-19": 1.0054, "2022-08-22": 1.0001, "2022-08-23": 0.9927, "2022-08-24": 0.9934, "2022-08-25": 0.997, "2022-08-26": 1.0007, "2022-08-29": 0.9986, "2022-08-30": 1.0034, "2022-08-31": 1, "2022-09-01": 1.0004, "2022-09-02": 0.9993, "2022-09-05": 0.992, "2022-09-06": 0.9928, "2022-09-07": 0.9885, "2022-09-08": 1.0009, "2022-09-09": 1.0049, "2022-09-12": 1.0155, "2022-09-13": 1.0175, "2022-09-14": 0.999, "2022-09-15": 0.9992, "2022-09-16": 0.9954, "2022-09-19": 0.999, "2022-09-20": 0.9986, "2022-09-21": 0.9906, "2022-09-22": 0.9884, "2022-09-23": 0.9754, "2022-09-26": 0.9646, "2022-09-27": 0.9644, "2022-09-28": 0.9565, "2022-09-29": 0.9706, "2022-09-30": 0.9748, "2022-10-03": 0.9764, "2022-10-04": 0.9891, "2022-10-05": 0.9915, "2022-10-06": 0.986, "2022-10-07": 0.9797, "2022-10-10": 0.9697, "2022-10-11": 0.9723, "2022-10-12": 0.9706, "2022-10-13": 0.9739, "2022-10-14": 0.9717, "2022-10-17": 0.9739, "2022-10-18": 0.9835, "2022-10-19": 0.9778, "2022-10-20": 0.9811, "2022-10-21": 0.973, "2022-10-24": 0.9851, "2022-10-25": 0.9861, "2022-10-26": 1.0023, "2022-10-27": 1.0037, "2022-10-28": 0.9951, "2022-10-31": 0.9914, "2022-11-01": 0.9947, "2022-11-02": 0.9908, "2022-11-03": 0.9753, "2022-11-04": 0.9872, "2022-11-07": 0.9993, "2022-11-08": 0.9996, "2022-11-09": 1.0039, "2022-11-10": 0.9954, "2022-11-11": 1.0308, "2022-11-14": 1.0319, "2022-11-15": 1.0404, "2022-11-16": 1.0412, "2022-11-17": 1.0319, "2022-11-18": 1.0366, "2022-11-21": 1.0246, "2022-11-22": 1.0274, "2022-11-23": 1.0325, "2022-11-24": 1.0413, "2022-11-25": 1.0375, "2022-11-28": 1.0463, "2022-11-29": 1.0366, "2022-11-30": 1.0376, "2022-12-01": 1.0454, "2022-12-02": 1.0538, "2022-12-05": 1.0587, "2022-12-06": 1.0516, "2022-12-07": 1.0529, "2022-12-08": 1.0519, "2022-12-09": 1.0559, "2022-12-12": 1.0562, "2022-12-13": 1.0545, "2022-12-14": 1.0649, "2022-12-15": 1.0621, "2022-12-16": 1.0619, "2022-12-19": 1.0598, "2022-12-20": 1.0599, "2022-12-21": 1.0636, "2022-12-22": 1.0633, "2022-12-23": 1.0622, "2022-12-27": 1.0624, "2022-12-28": 1.064, "2022-12-29": 1.0649, "2022-12-30": 1.0666, "2023-01-02": 1.0683, "2023-01-03": 1.0545, "2023-01-04": 1.0599, "2023-01-05": 1.0601, "2023-01-06": 1.05, "2023-01-09": 1.0696, "2023-01-10": 1.0723, "2023-01-11": 1.0747, "2023-01-12": 1.0772, "2023-01-13": 1.0814, "2023-01-16": 1.0812, "2023-01-17": 1.0843, "2023-01-18": 1.0839, "2023-01-19": 1.0815, "2023-01-20": 1.0826, "2023-01-23": 1.0871, "2023-01-24": 1.0858, "2023-01-25": 1.0878, "2023-01-26": 1.0895, "2023-01-27": 1.0865, "2023-01-30": 1.0903, "2023-01-31": 1.0833, "2023-02-01": 1.0894, "2023-02-02": 1.0988, "2023-02-03": 1.0937, "2023-02-06": 1.0776, "2023-02-07": 1.07, "2023-02-08": 1.0735, "2023-02-09": 1.0771, "2023-02-10": 1.069, "2023-02-13": 1.0686, "2023-02-14": 1.0759, "2023-02-15": 1.07, "2023-02-16": 1.07, "2023-02-17": 1.0625, "2023-02-20": 1.0674, "2023-02-21": 1.0664, "2023-02-22": 1.0644, "2023-02-23": 1.0616, "2023-02-24": 1.057, "2023-02-27": 1.0554, "2023-02-28": 1.0619, "2023-03-01": 1.0684, "2023-03-02": 1.0605, "2023-03-03": 1.0615, "2023-03-06": 1.0646, "2023-03-07": 1.0665, "2023-03-08": 1.0545, "2023-03-09": 1.0554, "2023-03-10": 1.0586, "2023-03-13": 1.0706, "2023-03-14": 1.0737, "2023-03-15": 1.0549, "2023-03-16": 1.0595, "2023-03-17": 1.0623, "2023-03-20": 1.0717, "2023-03-21": 1.0776, "2023-03-22": 1.0785, "2023-03-23": 1.0879, "2023-03-24": 1.0745, "2023-03-27": 1.0773, "2023-03-28": 1.0841, "2023-03-29": 1.0847, "2023-03-30": 1.0886, "2023-03-31": 1.0875, "2023-04-03": 1.087, "2023-04-04": 1.0901, "2023-04-05": 1.094, "2023-04-06": 1.0915, "2023-04-11": 1.0905, "2023-04-12": 1.0922, "2023-04-13": 1.1015, "2023-04-14": 1.1057, "2023-04-17": 1.0981, "2023-04-18": 1.0972, "2023-04-19": 1.0933, "2023-04-20": 1.0944, "2023-04-21": 1.0978, "2023-04-24": 1.1002, "2023-04-25": 1.1022, "2023-04-26": 1.1039, "2023-04-27": 1.1042, "2023-04-28": 1.0981, "2023-05-02": 1.0965, "2023-05-03": 1.1043, "2023-05-04": 1.1074, "2023-05-05": 1.1014, "2023-05-08": 1.1037, "2023-05-09": 1.0959, "2023-05-10": 1.095, "2023-05-11": 1.093, "2023-05-12": 1.0892, "2023-05-15": 1.0876, "2023-05-16": 1.0881, "2023-05-17": 1.0829, "2023-05-18": 1.0813, "2023-05-19": 1.0808, "2023-05-22": 1.0822, "2023-05-23": 1.0779, "2023-05-24": 1.0785, "2023-05-25": 1.0735, "2023-05-26": 1.0751, "2023-05-29": 1.0715, "2023-05-30": 1.0744, "2023-05-31": 1.0683, "2023-06-01": 1.0697, "2023-06-02": 1.0763, "2023-06-05": 1.069, "2023-06-06": 1.0683, "2023-06-07": 1.0717, "2023-06-08": 1.0737, "2023-06-09": 1.078, "2023-06-12": 1.0765, "2023-06-13": 1.0793, "2023-06-14": 1.0809, "2023-06-15": 1.0819, "2023-06-16": 1.0966, "2023-06-19": 1.0922, "2023-06-20": 1.0933, "2023-06-21": 1.0923, "2023-06-22": 1.0985, "2023-06-23": 1.0884, "2023-06-26": 1.0918, "2023-06-27": 1.0951, "2023-06-28": 1.0938, "2023-06-29": 1.0938, "2023-06-30": 1.0866, "2023-07-03": 1.0899, "2023-07-04": 1.0895, "2023-07-05": 1.0879, "2023-07-06": 1.0899, "2023-07-07": 1.0888, "2023-07-10": 1.0956, "2023-07-11": 1.0989, "2023-07-12": 1.1022, "2023-07-13": 1.1182, "2023-07-14": 1.1221, "2023-07-17": 1.123, "2023-07-18": 1.1255, "2023-07-19": 1.1222, "2023-07-20": 1.1197, "2023-07-21": 1.1123, "2023-07-24": 1.1096, "2023-07-25": 1.1051, "2023-07-26": 1.1059, "2023-07-27": 1.1125, "2023-07-28": 1.101, "2023-07-31": 1.1023, "2023-08-01": 1.097, "2023-08-02": 1.0985, "2023-08-03": 1.0932, "2023-08-04": 1.0946, "2023-08-07": 1.0984, "2023-08-08": 1.0944, "2023-08-09": 1.0968, "2023-08-10": 1.1019, "2023-08-11": 1.1004, "2023-08-14": 1.093, "2023-08-15": 1.0926, "2023-08-16": 1.0916, "2023-08-17": 1.09, "2023-08-18": 1.0867, "2023-08-21": 1.0908, "2023-08-22": 1.0887, "2023-08-23": 1.0805, "2023-08-24": 1.084, "2023-08-25": 1.0808, "2023-08-28": 1.0808, "2023-08-29": 1.0803, "2023-08-30": 1.0886, "2023-08-31": 1.0868, "2023-09-01": 1.0844, "2023-09-04": 1.0801, "2023-09-05": 1.0731, "2023-09-06": 1.0745, "2023-09-07": 1.071, "2023-09-08": 1.0704, "2023-09-11": 1.0724, "2023-09-12": 1.0713, "2023-09-13": 1.0733, "2023-09-14": 1.073, "2023-09-15": 1.0658, "2023-09-18": 1.0663, "2023-09-19": 1.0713, "2023-09-20": 1.0702, "2023-09-21": 1.0635, "2023-09-22": 1.0647, "2023-09-25": 1.0633, "2023-09-26": 1.0605, "2023-09-27": 1.0536, "2023-09-28": 1.0539, "2023-09-29": 1.0594, "2023-10-02": 1.053, "2023-10-03": 1.0469, "2023-10-04": 1.0497, "2023-10-05": 1.0526, "2023-10-06": 1.0563, "2023-10-09": 1.0531, "2023-10-10": 1.0582, "2023-10-11": 1.0604, "2023-10-12": 1.0619, "2023-10-13": 1.0524, "2023-10-16": 1.0538, "2023-10-17": 1.0569, "2023-10-18": 1.0565, "2023-10-19": 1.0558, "2023-10-20": 1.0591, "2023-10-23": 1.0597, "2023-10-24": 1.0632, "2023-10-25": 1.0576, "2023-10-26": 1.054, "2023-10-27": 1.0541, "2023-10-30": 1.0605, "2023-10-31": 1.0619, "2023-11-01": 1.0537, "2023-11-02": 1.0661, "2023-11-03": 1.0702, "2023-11-06": 1.0741, "2023-11-07": 1.0686, "2023-11-08": 1.0671, "2023-11-09": 1.0691, "2023-11-10": 1.0683, "2023-11-13": 1.067, "2023-11-14": 1.0724, "2023-11-15": 1.0868, "2023-11-16": 1.0849, "2023-11-17": 1.0872, "2023-11-20": 1.0928, "2023-11-21": 1.0955, "2023-11-22": 1.0911, "2023-11-23": 1.09, "2023-11-24": 1.0916, "2023-11-27": 1.0951, "2023-11-28": 1.0949, "2023-11-29": 1.0985, "2023-11-30": 1.0931, "2023-12-01": 1.0875, "2023-12-04": 1.0868, "2023-12-05": 1.0817, "2023-12-06": 1.0778, "2023-12-07": 1.0771, "2023-12-08": 1.0777, "2023-12-11": 1.0757, "2023-12-12": 1.0804, "2023-12-13": 1.0787, "2023-12-14": 1.0919, "2023-12-15": 1.0946, "2023-12-18": 1.0918, "2023-12-19": 1.0962, "2023-12-20": 1.0944, "2023-12-21": 1.0983, "2023-12-22": 1.1023, "2023-12-27": 1.1065, "2023-12-28": 1.1114, "2023-12-29": 1.105, "2024-01-02": 1.0956, "2024-01-03": 1.0919, "2024-01-04": 1.0953, "2024-01-05": 1.0921, "2024-01-08": 1.0946, "2024-01-09": 1.094, "2024-01-10": 1.0946, "2024-01-11": 1.0987, "2024-01-12": 1.0942, "2024-01-15": 1.0945, "2024-01-16": 1.0882, "2024-01-17": 1.0877, "2024-01-18": 1.0875, "2024-01-19": 1.0887, "2024-01-22": 1.089, "2024-01-23": 1.0872, "2024-01-24": 1.0905, "2024-01-25": 1.0893, "2024-01-26": 1.0871, "2024-01-29": 1.0823, "2024-01-30": 1.0846, "2024-01-31": 1.0837, "2024-02-01": 1.0814, "2024-02-02": 1.0883, "2024-02-05": 1.0746, "2024-02-06": 1.0743, "2024-02-07": 1.0776, "2024-02-08": 1.0758, "2024-02-09": 1.0772, "2024-02-12": 1.0773, "2024-02-13": 1.0793, "2024-02-14": 1.0713, "2024-02-15": 1.0743, "2024-02-16": 1.0768, "2024-02-19": 1.0776, "2024-02-20": 1.0802, "2024-02-21": 1.0809, "2024-02-22": 1.0844, "2024-02-23": 1.0834, "2024-02-26": 1.0852, "2024-02-27": 1.0856, "2024-02-28": 1.0808, "2024-02-29": 1.0826, "2024-03-01": 1.0813, "2024-03-04": 1.0846, "2024-03-05": 1.0849, "2024-03-06": 1.0874, "2024-03-07": 1.0895, "2024-03-08": 1.0932, "2024-03-11": 1.0926, "2024-03-12": 1.0916, "2024-03-13": 1.0939, "2024-03-14": 1.0925, "2024-03-15": 1.0892, "2024-03-18": 1.0892, "2024-03-19": 1.0854, "2024-03-20": 1.0844, "2024-03-21": 1.0907, "2024-03-22": 1.0823, "2024-03-25": 1.0835, "2024-03-26": 1.0855, "2024-03-27": 1.0816, "2024-03-28": 1.0811, "2024-04-02": 1.0749, "2024-04-03": 1.0783, "2024-04-04": 1.0852, "2024-04-05": 1.0841, "2024-04-08": 1.0823, "2024-04-09": 1.0867, "2024-04-10": 1.086, "2024-04-11": 1.0729, "2024-04-12": 1.0652, "2024-04-15": 1.0656, "2024-04-16": 1.0637, "2024-04-17": 1.0638, "2024-04-18": 1.0679, "2024-04-19": 1.0653, "2024-04-22": 1.0632, "2024-04-23": 1.0674, "2024-04-24": 1.0686, "2024-04-25": 1.072, "2024-04-26": 1.0714, "2024-04-29": 1.072, "2024-04-30": 1.0718, "2024-05-02": 1.0698, "2024-05-03": 1.0744, "2024-05-06": 1.0776, "2024-05-07": 1.0766, "2024-05-08": 1.0743, "2024-05-09": 1.0732, "2024-05-10": 1.0779, "2024-05-13": 1.0795, "2024-05-14": 1.0796, "2024-05-15": 1.0832, "2024-05-16": 1.0866, "2024-05-17": 1.0844, "2024-05-20": 1.0861, "2024-05-21": 1.0864, "2024-05-22": 1.083, "2024-05-23": 1.0854, "2024-05-24": 1.084, "2024-05-27": 1.0843, "2024-05-28": 1.0882, "2024-05-29": 1.0857, "2024-05-30": 1.0815, "2024-05-31": 1.0852, "2024-06-03": 1.0842, "2024-06-04": 1.0865, "2024-06-05": 1.0872, "2024-06-06": 1.0865, "2024-06-07": 1.0898, "2024-06-10": 1.0756, "2024-06-11": 1.073, "2024-06-12": 1.0765, "2024-06-13": 1.0784, "2024-06-14": 1.0686, "2024-06-17": 1.0712, "2024-06-18": 1.0715, "2024-06-19": 1.0749, "2024-06-20": 1.0719, "2024-06-21": 1.0688, "2024-06-24": 1.073, "2024-06-25": 1.0714, "2024-06-26": 1.0689, "2024-06-27": 1.0696, "2024-06-28": 1.0705, "2024-07-01": 1.0745, "2024-07-02": 1.0729, "2024-07-03": 1.0758, "2024-07-04": 1.08, "2024-07-05": 1.0824, "2024-07-08": 1.0835, "2024-07-09": 1.0814, "2024-07-10": 1.0825, "2024-07-11": 1.0855, "2024-07-12": 1.089, "2024-07-15": 1.0907, "2024-07-16": 1.0902, "2024-07-17": 1.0934, "2024-07-18": 1.093, "2024-07-19": 1.089, "2024-07-22": 1.0888, "2024-07-23": 1.086, "2024-07-24": 1.0848, "2024-07-25": 1.0851, "2024-07-26": 1.086, "2024-07-29": 1.0817, "2024-07-30": 1.0824, "2024-07-31": 1.0828, "2024-08-01": 1.0789, "2024-08-02": 1.0835, "2024-08-05": 1.0966, "2024-08-06": 1.0915, "2024-08-07": 1.0922, "2024-08-08": 1.093, "2024-08-09": 1.0917, "2024-08-12": 1.0925, "2024-08-13": 1.0931, "2024-08-14": 1.1019, "2024-08-15": 1.1011, "2024-08-16": 1.0994, "2024-08-19": 1.1041, "2024-08-20": 1.1084, "2024-08-21": 1.1116, "2024-08-22": 1.1135, "2024-08-23": 1.1121, "2024-08-26": 1.1163, "2024-08-27": 1.1162, "2024-08-28": 1.1117, "2024-08-29": 1.1088, "2024-08-30": 1.1087, "2024-09-02": 1.1061, "2024-09-03": 1.1035, "2024-09-04": 1.105, "2024-09-05": 1.1097, "2024-09-06": 1.1103, "2024-09-09": 1.1043, "2024-09-10": 1.1031, "2024-09-11": 1.1043, "2024-09-12": 1.1016, "2024-09-13": 1.1081, "2024-09-16": 1.1126, "2024-09-17": 1.1139, "2024-09-18": 1.1124, "2024-09-19": 1.1156, "2024-09-20": 1.1166, "2024-09-23": 1.1119, "2024-09-24": 1.1133, "2024-09-25": 1.1194, "2024-09-26": 1.1155, "2024-09-27": 1.1158, "2024-09-30": 1.1196, "2024-10-01": 1.1086, "2024-10-02": 1.1071, "2024-10-03": 1.1039, "2024-10-04": 1.1029, "2024-10-07": 1.0982, "2024-10-08": 1.0982, "2024-10-09": 1.0957, "2024-10-10": 1.0932, "2024-10-11": 1.0938, "2024-10-14": 1.0915, "2024-10-15": 1.0903, "2024-10-16": 1.0897, "2024-10-17": 1.0866, "2024-10-18": 1.0847, "2024-10-21": 1.0853, "2024-10-22": 1.0821, "2024-10-23": 1.0767, "2024-10-24": 1.0801, "2024-10-25": 1.0825, "2024-10-28": 1.0818, "2024-10-29": 1.0774, "2024-10-30": 1.0815, "2024-10-31": 1.0882, "2024-11-01": 1.0885, "2024-11-04": 1.0904, "2024-11-05": 1.0897, "2024-11-06": 1.0695, "2024-11-07": 1.0785, "2024-11-08": 1.0772, "2024-11-11": 1.0651, "2024-11-12": 1.0617, "2024-11-13": 1.0629, "2024-11-14": 1.0533, "2024-11-15": 1.0583, "2024-11-18": 1.0552, "2024-11-19": 1.0578, "2024-11-20": 1.0562, "2024-11-21": 1.0526, "2024-11-22": 1.0412, "2024-11-25": 1.0495, "2024-11-26": 1.0522, "2024-11-27": 1.0531, "2024-11-28": 1.0542, "2024-11-29": 1.0562, "2024-12-02": 1.0507, "2024-12-03": 1.0512, "2024-12-04": 1.0492, "2024-12-05": 1.054, "2024-12-06": 1.0581, "2024-12-09": 1.0568, "2024-12-10": 1.0527, "2024-12-11": 1.0507, "2024-12-12": 1.0491, "2024-12-13": 1.0518, "2024-12-16": 1.0498, "2024-12-17": 1.0497, "2024-12-18": 1.0496, "2024-12-19": 1.0395, "2024-12-20": 1.039, "2024-12-23": 1.0393, "2024-12-24": 1.0395, "2024-12-27": 1.0435, "2024-12-30": 1.0444, "2024-12-31": 1.0389, "2025-01-02": 1.0321, "2025-01-03": 1.0299, "2025-01-06": 1.0426, "2025-01-07": 1.0393, "2025-01-08": 1.0286, "2025-01-09": 1.0305, "2025-01-10": 1.0304, "2025-01-13": 1.0198, "2025-01-14": 1.0245, "2025-01-15": 1.03, "2025-01-16": 1.0272, "2025-01-17": 1.0298, "2025-01-20": 1.0316, "2025-01-21": 1.0357, "2025-01-22": 1.0443, "2025-01-23": 1.0404, "2025-01-24": 1.0472, "2025-01-27": 1.053, "2025-01-28": 1.0421, "2025-01-29": 1.0396, "2025-01-30": 1.0403, "2025-01-31": 1.0393, "2025-02-03": 1.0274, "2025-02-04": 1.0335, "2025-02-05": 1.0422, "2025-02-06": 1.036, "2025-02-07": 1.0377, "2025-02-10": 1.032, "2025-02-11": 1.0324, "2025-02-12": 1.037, "2025-02-13": 1.039, "2025-02-14": 1.0478, "2025-02-17": 1.0473, "2025-02-18": 1.0447, "2025-02-19": 1.0434, "2025-02-20": 1.0443, "2025-02-21": 1.0465, "2025-02-24": 1.0466, "2025-02-25": 1.0497, "2025-02-26": 1.0487, "2025-02-27": 1.0477, "2025-02-28": 1.0411, "2025-03-03": 1.0465, "2025-03-04": 1.0557, "2025-03-05": 1.0694, "2025-03-06": 1.0796, "2025-03-07": 1.0857, "2025-03-10": 1.0845, "2025-03-11": 1.0912, "2025-03-12": 1.0886, "2025-03-13": 1.083, "2025-03-14": 1.0889, "2025-03-17": 1.0903, "2025-03-18": 1.0918, "2025-03-19": 1.0897, "2025-03-20": 1.0833, "2025-03-21": 1.0827, "2025-03-24": 1.0824, "2025-03-25": 1.0825, "2025-03-26": 1.0788, "2025-03-27": 1.0785, "2025-03-28": 1.0797, "2025-03-31": 1.0815, "2025-04-01": 1.0788, "2025-04-02": 1.0803, "2025-04-03": 1.1097, "2025-04-04": 1.1057, "2025-04-07": 1.0967, "2025-04-08": 1.095, "2025-04-09": 1.1045, "2025-04-10": 1.1082, "2025-04-11": 1.1346, "2025-04-14": 1.1377, "2025-04-15": 1.1324, "2025-04-16": 1.1355, "2025-04-17": 1.136, "2025-04-22": 1.1476, "2025-04-23": 1.1415, "2025-04-24": 1.1376, "2025-04-25": 1.1357, "2025-04-28": 1.1358, "2025-04-29": 1.1373, "2025-04-30": 1.1373, "2025-05-02": 1.1343, "2025-05-05": 1.1343, "2025-05-06": 1.1325, "2025-05-07": 1.136, "2025-05-08": 1.1297, "2025-05-09": 1.1252, "2025-05-12": 1.1106, "2025-05-13": 1.1112, "2025-05-14": 1.1214, "2025-05-15": 1.1185, "2025-05-16": 1.1194, "2025-05-19": 1.1262, "2025-05-20": 1.1241, "2025-05-21": 1.1321, "2025-05-22": 1.1309, "2025-05-23": 1.1301, "2025-05-26": 1.1381, "2025-05-27": 1.1356, "2025-05-28": 1.1317, "2025-05-29": 1.1281, "2025-05-30": 1.1339, "2025-06-02": 1.1419, "2025-06-03": 1.1386, "2025-06-04": 1.1384, "2025-06-05": 1.1423, "2025-06-06": 1.1411, "2025-06-09": 1.141, "2025-06-10": 1.1429, "2025-06-11": 1.1433, "2025-06-12": 1.1594, "2025-06-13": 1.1512, "2025-06-16": 1.1574, "2025-06-17": 1.1568, "2025-06-18": 1.1508, "2025-06-19": 1.1478, "2025-06-20": 1.1515, "2025-06-23": 1.1472, "2025-06-24": 1.1607, "2025-06-25": 1.1598, "2025-06-26": 1.1695, "2025-06-27": 1.1704, "2025-06-30": 1.172, "2025-07-01": 1.181, "2025-07-02": 1.1755, "2025-07-03": 1.1782, "2025-07-04": 1.1767, "2025-07-07": 1.1728, "2025-07-08": 1.1718, "2025-07-09": 1.1698, "2025-07-10": 1.1709, "2025-07-11": 1.1683, "2025-07-14": 1.169, "2025-07-15": 1.1665, "2025-07-16": 1.1602, "2025-07-17": 1.1579, "2025-07-18": 1.165, "2025-07-21": 1.1667, "2025-07-22": 1.1699, "2025-07-23": 1.1726, "2025-07-24": 1.1756, "2025-07-25": 1.1724, "2025-07-28": 1.1654, "2025-07-29": 1.1533, "2025-07-30": 1.1527, "2025-07-31": 1.1446, "2025-08-01": 1.1404, "2025-08-04": 1.1565, "2025-08-05": 1.1546, "2025-08-06": 1.1604, "2025-08-07": 1.1643, "2025-08-08": 1.1648, "2025-08-11": 1.1622, "2025-08-12": 1.1606, "2025-08-13": 1.1711, "2025-08-14": 1.169, "2025-08-15": 1.1688, "2025-08-18": 1.1673, "2025-08-19": 1.1682, "2025-08-20": 1.1651, "2025-08-21": 1.1639, "2025-08-22": 1.1608, "2025-08-25": 1.1697, "2025-08-26": 1.1656, "2025-08-27": 1.1593, "2025-08-28": 1.1676, "2025-08-29": 1.1658, "2025-09-01": 1.1715, "2025-09-02": 1.1646, "2025-09-03": 1.1653, "2025-09-04": 1.1647, "2025-09-05": 1.1697, "2025-09-08": 1.1728, "2025-09-09": 1.1744, "2025-09-10": 1.1707, "2025-09-11": 1.1685, "2025-09-12": 1.1718, "2025-09-15": 1.1766, "2025-09-16": 1.1807, "2025-09-17": 1.1837, "2025-09-18": 1.1818, "2025-09-19": 1.1736, "2025-09-22": 1.1781, "2025-09-23": 1.1793, "2025-09-24": 1.1756, "2025-09-25": 1.1739, "2025-09-26": 1.1672, "2025-09-29": 1.1723, "2025-09-30": 1.1741, "2025-10-01": 1.1724, "2025-10-02": 1.1754, "2025-10-03": 1.1734, "2025-10-06": 1.1678, "2025-10-07": 1.1666, "2025-10-08": 1.1627, "2025-10-09": 1.1611, "2025-10-10": 1.1568, "2025-10-13": 1.1569, "2025-10-14": 1.1553, "2025-10-15": 1.1622, "2025-10-16": 1.1649, "2025-10-17": 1.1681, "2025-10-20": 1.1655, "2025-10-21": 1.1607, "2025-10-22": 1.1587, "2025-10-23": 1.1593, "2025-10-24": 1.1612, "2025-10-27": 1.164, "2025-10-28": 1.163, "2025-10-29": 1.1636, "2025-10-30": 1.155, "2025-10-31": 1.1554, "2025-11-03": 1.1514, "2025-11-04": 1.1491, "2025-11-05": 1.1492, "2025-11-06": 1.1533, "2025-11-07": 1.1561, "2025-11-10": 1.1571, "2025-11-11": 1.1575, "2025-11-12": 1.1576, "2025-11-13": 1.1619, "2025-11-14": 1.1648, "2025-11-17": 1.1593, "2025-11-18": 1.159, "2025-11-19": 1.1583, "2025-11-20": 1.1514, "2025-11-21": 1.152, "2025-11-24": 1.1544, "2025-11-25": 1.1551, "2025-11-26": 1.1577, "2025-11-27": 1.1586, "2025-11-28": 1.1566, "2025-12-01": 1.1646, "2025-12-02": 1.1614, "2025-12-03": 1.1668, "2025-12-04": 1.1666, "2025-12-05": 1.1645, "2025-12-08": 1.1655, "2025-12-09": 1.1637, "2025-12-10": 1.1634, "2025-12-11": 1.1714, "2025-12-12": 1.1731, "2025-12-15": 1.1753, "2025-12-16": 1.1776, "2025-12-17": 1.1722, "2025-12-18": 1.1719, "2025-12-19": 1.1712, "2025-12-22": 1.1745, "2025-12-23": 1.1786, "2025-12-24": 1.1787, "2025-12-29": 1.1766, "2025-12-30": 1.1757, "2025-12-31": 1.175, "2026-01-02": 1.1721, "2026-01-05": 1.1664, "2026-01-06": 1.1707, "2026-01-07": 1.1684, "2026-01-08": 1.1675, "2026-01-09": 1.1642, "2026-01-12": 1.1692, "2026-01-13": 1.1654, "2026-01-14": 1.1651, "2026-01-15": 1.1624, "2026-01-16": 1.1617, "2026-01-19": 1.1631, "2026-01-20": 1.1728, "2026-01-21": 1.1739, "2026-01-22": 1.1706, "2026-01-23": 1.1742, "2026-01-26": 1.1836, "2026-01-27": 1.1929, "2026-01-28": 1.1974, "2026-01-29": 1.1968, "2026-01-30": 1.1919, "2026-02-02": 1.184, "2026-02-03": 1.1801, "2026-02-04": 1.182, "2026-02-05": 1.1798, "2026-02-06": 1.1794, "2026-02-09": 1.1886, "2026-02-10": 1.1894, "2026-02-11": 1.19, "2026-02-12": 1.1874, "2026-02-13": 1.1862, "2026-02-16": 1.1855, "2026-02-17": 1.1826, "2026-02-18": 1.1845, "2026-02-19": 1.1753, "2026-02-20": 1.1767, "2026-02-23": 1.1784, "2026-02-24": 1.1777, "2026-02-25": 1.1784, "2026-02-26": 1.1814, "2026-02-27": 1.1805, "2026-03-02": 1.1698, "2026-03-03": 1.1606, "2026-03-04": 1.1649, "2026-03-05": 1.1618, "2026-03-06": 1.1561, "2026-03-09": 1.1555, "2026-03-10": 1.1641, "2026-03-11": 1.1581, "2026-03-12": 1.1547, "2026-03-13": 1.1476, "2026-03-16": 1.1478, "2026-03-17": 1.1531, "2026-03-18": 1.15, "2026-03-19": 1.1489, "2026-03-20": 1.1555, "2026-03-23": 1.1596, "2026-03-24": 1.1572, "2026-03-25": 1.1592, "2026-03-26": 1.1539, "2026-03-27": 1.1517, "2026-03-30": 1.1484, "2026-03-31": 1.1498, "2026-04-01": 1.1605, "2026-04-02": 1.1525, "2026-04-07": 1.1557, "2026-04-08": 1.1706, "2026-04-09": 1.1685, "2026-04-10": 1.1711, "2026-04-13": 1.1684, "2026-04-14": 1.1793, "2026-04-15": 1.178, "2026-04-16": 1.1782, "2026-04-17": 1.1797, "2026-04-20": 1.176, "2026-04-21": 1.1767, "2026-04-22": 1.1733, "2026-04-23": 1.1694, "2026-04-24": 1.1712, "2026-04-27": 1.1749, "2026-04-28": 1.168, "2026-04-29": 1.1706, "2026-04-30": 1.1702, "2026-05-04": 1.17, "2026-05-05": 1.1686, "2026-05-06": 1.1762, "2026-05-07": 1.177, "2026-05-08": 1.1761, "2026-05-11": 1.1765, "2026-05-12": 1.1738, "2026-05-13": 1.1715, "2026-05-14": 1.1702, "2026-05-15": 1.1628, "2026-05-18": 1.1648, "2026-05-19": 1.162, "2026-05-20": 1.16, "2026-05-21": 1.1599, "2026-05-22": 1.1595, "2026-05-25": 1.1643, "2026-05-26": 1.1634, "2026-05-27": 1.1637, "2026-05-28": 1.1617, "2026-05-29": 1.1644, "2026-06-01": 1.1646, "2026-06-02": 1.1649, "2026-06-03": 1.1614, "2026-06-04": 1.164, "2026-06-05": 1.164, "2026-06-08": 1.154, "2026-06-09": 1.1573, "2026-06-10": 1.1539, "2026-06-11": 1.15 } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/historico-precos-mensal.json Tamanho: 99027 bytes ======================================================================================== { "meta": { "user": "tiago", "todos": false, "encerradas": false, "mindatacompra": "2019-10-15", "minmesguardado": "2019-10", "debugtickersamostra": [ "AAPL", "NVDA" ], "fontes_prioridade_default": [ "stooq", "twelvedata", "eodhd", "perplexity", "manual" ], "ttlcachesegundos": 2592000, "forcar": false, "stats": { "totaltickers": 34, "atualizados": 0, "ignoradossemmapa": 0, "semdados": 0, "erros": 0, "porfonte": { "stooq": 0, "twelvedata": 0, "eodhd": 0, "perplexity": 0, "manual": 0 } }, "timestamp": "2026-05-02 21:48:17" }, "ativos": { "AAPL": { "stooq": "aapl.us", "moeda": "USD", "mensal": { "2018-12": 39.44, "2019-01": 41.61, "2019-02": 43.29, "2019-03": 47.81, "2019-04": 50.17, "2019-05": 43.77, "2019-06": 50.39, "2019-07": 53.26, "2019-08": 51.43, "2019-09": 55.99, "2019-10": 62.19, "2019-11": 66.04, "2019-12": 73.41, "2020-01": 77.38, "2020-02": 74.7, "2020-03": 63.57, "2020-04": 73.45, "2020-05": 80.46, "2020-06": 91.2, "2020-07": 106.26, "2020-08": 129.04, "2020-09": 115.81, "2020-10": 108.77, "2020-11": 119.05, "2020-12": 132.69, "2021-01": 134.14, "2021-02": 127.79, "2021-03": 122.15, "2021-04": 131.46, "2021-05": 124.28, "2021-06": 136.96, "2021-07": 145.52, "2021-08": 151.83, "2021-09": 141.5, "2021-10": 148.96, "2021-11": 165.3, "2021-12": 177.57, "2022-01": 174.78, "2022-02": 165.12, "2022-03": 174.61, "2022-04": 157.96, "2022-05": 148.84, "2022-06": 136.72, "2022-07": 161.51, "2022-08": 157.22, "2022-09": 138.2, "2022-10": 153.34, "2022-11": 148.03, "2022-12": 129.93, "2023-01": 144.29, "2023-02": 147.41, "2023-03": 164.9, "2023-04": 169.59, "2023-05": 177.25, "2023-06": 193.97, "2023-07": 196.45, "2023-08": 187.87, "2023-09": 173.75, "2023-10": 170.77, "2023-11": 189.95, "2023-12": 192.53, "2024-01": 184.4, "2024-02": 180.75, "2024-03": 170.03, "2024-04": 170.33, "2024-05": 192.25, "2024-06": 210.62, "2024-07": 222.08, "2024-08": 222.77, "2024-09": 233, "2024-10": 225.91, "2024-11": 239.59, "2024-12": 250.42, "2025-01": 236, "2025-02": 241.84, "2025-03": 222.13, "2025-04": 212.5, "2025-05": 201.7, "2025-06": 205.17, "2025-07": 207.57, "2025-08": 229.72, "2025-09": 254.63, "2025-10": 270.37, "2025-11": 283.1, "2025-12": 271.86, "2026-01": 270.01, "2026-02": 264.72, "2026-03": 253.79, "2026-04": 271.35 } }, "ADBE": { "stooq": "adbe.us", "moeda": "USD", "mensal": { "2018-12": 226.24, "2019-01": 247.82, "2019-02": 262.5, "2019-03": 272.17, "2019-04": 289.25, "2019-05": 270.9, "2019-06": 300.97, "2019-07": 298.86, "2019-08": 282.45, "2019-09": 276.25, "2019-10": 277.93, "2019-11": 302.75, "2019-12": 329.81, "2020-01": 351.14, "2020-02": 360.28, "2020-03": 318.24, "2020-04": 353.64, "2020-05": 389.68, "2020-06": 435.31, "2020-07": 444.32, "2020-08": 513.39, "2020-09": 490.43, "2020-10": 444.94, "2020-11": 478.47, "2020-12": 500.12, "2021-01": 470, "2021-02": 469.57, "2021-03": 475.37, "2021-04": 508.34, "2021-05": 495.91, "2021-06": 585.64, "2021-07": 618.75, "2021-08": 663.7, "2021-09": 575.72, "2021-10": 640.2, "2021-11": 669.85, "2021-12": 567.06, "2022-01": 534.3, "2022-02": 467.68, "2022-03": 455.62, "2022-04": 407.29, "2022-05": 416.48, "2022-06": 366.06, "2022-07": 411.09, "2022-08": 373.44, "2022-09": 275.2, "2022-10": 318.5, "2022-11": 344.93, "2022-12": 336.53, "2023-01": 370.34, "2023-02": 323.95, "2023-03": 385.37, "2023-04": 374.15, "2023-05": 417.79, "2023-06": 488.99, "2023-07": 546.17, "2023-08": 559.34, "2023-09": 521.13, "2023-10": 532.06, "2023-11": 611.01, "2023-12": 596.6, "2024-01": 617.78, "2024-02": 560.28, "2024-03": 502.09, "2024-04": 462.83, "2024-05": 444.76, "2024-06": 555.54, "2024-07": 551.65, "2024-08": 571.04, "2024-09": 517.78, "2024-10": 478.08, "2024-11": 516.2, "2024-12": 444.68, "2025-01": 437.45, "2025-02": 438.56, "2025-03": 383.53, "2025-04": 374.98, "2025-05": 403.4, "2025-06": 386.88, "2025-07": 357.69, "2025-08": 345.63, "2025-09": 352.75, "2025-10": 340.31, "2025-11": 322.85, "2025-12": 349.99, "2026-01": 293.38, "2026-02": 260.88, "2026-03": 243.08, "2026-04": 246.1 } }, "AMD": { "stooq": "amd.us", "moeda": "USD", "mensal": { "2018-12": 18.46, "2019-01": 24.41, "2019-02": 23.53, "2019-03": 26.36, "2019-04": 27.63, "2019-05": 27.41, "2019-06": 31.2, "2019-07": 30.45, "2019-08": 30.9, "2019-09": 28.99, "2019-10": 33.93, "2019-11": 38.73, "2019-12": 45.86, "2020-01": 47, "2020-02": 47.46, "2020-03": 45.48, "2020-04": 52.39, "2020-05": 53.63, "2020-06": 52.61, "2020-07": 77.43, "2020-08": 90.82, "2020-09": 81.99, "2020-10": 74.7, "2020-11": 92.66, "2020-12": 91.71, "2021-01": 87.66, "2021-02": 86.39, "2021-03": 78.5, "2021-04": 81.62, "2021-05": 80.81, "2021-06": 93.93, "2021-07": 108.63, "2021-08": 110.72, "2021-09": 102.9, "2021-10": 125.23, "2021-11": 158.37, "2021-12": 143.9, "2022-01": 114.25, "2022-02": 123.34, "2022-03": 109.34, "2022-04": 89.84, "2022-05": 101.86, "2022-06": 76.47, "2022-07": 96.78, "2022-08": 84.87, "2022-09": 63.36, "2022-10": 60.06, "2022-11": 77.63, "2022-12": 64.77, "2023-01": 75.15, "2023-02": 78.58, "2023-03": 98.01, "2023-04": 89.69, "2023-05": 118.21, "2023-06": 113.91, "2023-07": 114.4, "2023-08": 105.72, "2023-09": 103.27, "2023-10": 98.5, "2023-11": 121.16, "2023-12": 147.41, "2024-01": 167.69, "2024-02": 192.53, "2024-03": 183.34, "2024-04": 158.38, "2024-05": 166.9, "2024-06": 162.21, "2024-07": 144.48, "2024-08": 136.94, "2024-09": 164.08, "2024-10": 144.07, "2024-11": 142.06, "2024-12": 120.79, "2025-01": 115.95, "2025-02": 99.86, "2025-03": 102.74, "2025-04": 97.35, "2025-05": 114.63, "2025-06": 141.9, "2025-07": 176.31, "2025-08": 162.32, "2025-09": 161.79, "2025-10": 256.12, "2025-11": 219.76, "2025-12": 214.16, "2026-01": 246.27, "2026-02": 198.62, "2026-03": 203.43, "2026-04": 354.49 } }, "AMZN": { "stooq": "amzn.us", "moeda": "USD", "mensal": { "2018-12": 75.1, "2019-01": 85.94, "2019-02": 81.99, "2019-03": 90.71, "2019-04": 96.33, "2019-05": 88.75, "2019-06": 96.11, "2019-07": 93.34, "2019-08": 89.49, "2019-09": 86.8, "2019-10": 88.83, "2019-11": 89.08, "2019-12": 92.39, "2020-01": 100.44, "2020-02": 97.7, "2020-03": 97.49, "2020-04": 123.7, "2020-05": 123.55, "2020-06": 137.94, "2020-07": 158.23, "2020-08": 172.55, "2020-09": 157.44, "2020-10": 150.22, "2020-11": 158.4, "2020-12": 162.85, "2021-01": 167.14, "2021-02": 157.31, "2021-03": 154.7, "2021-04": 173.37, "2021-05": 160.93, "2021-06": 172.01, "2021-07": 166.57, "2021-08": 173.54, "2021-09": 164.25, "2021-10": 165.91, "2021-11": 175.35, "2021-12": 166.72, "2022-01": 135.3, "2022-02": 153.56, "2022-03": 163, "2022-04": 124.5, "2022-05": 120.21, "2022-06": 106.21, "2022-07": 135.39, "2022-08": 126.77, "2022-09": 113, "2022-10": 102.44, "2022-11": 96.54, "2022-12": 84, "2023-01": 103.13, "2023-02": 94.23, "2023-03": 103.29, "2023-04": 102.05, "2023-05": 120.58, "2023-06": 130.36, "2023-07": 133.68, "2023-08": 138.01, "2023-09": 129.46, "2023-10": 133.09, "2023-11": 146.09, "2023-12": 151.94, "2024-01": 155.2, "2024-02": 176.76, "2024-03": 180.97, "2024-04": 175, "2024-05": 176.44, "2024-06": 193.25, "2024-07": 186.98, "2024-08": 176.25, "2024-09": 186.33, "2024-10": 186.4, "2024-11": 210.71, "2024-12": 219.39, "2025-01": 237.68, "2025-02": 212.28, "2025-03": 190.26, "2025-04": 184.42, "2025-05": 206.65, "2025-06": 219.39, "2025-07": 234.11, "2025-08": 225.34, "2025-09": 219.57, "2025-10": 244.22, "2025-11": 233.88, "2025-12": 230.82, "2026-01": 242.96, "2026-02": 208.39, "2026-03": 208.27, "2026-04": 265.06 } }, "ANSS": { "stooq": "anss.us", "moeda": "USD", "mensal": { "2018-12": 142.94, "2019-01": 164.35, "2019-02": 177.26, "2019-03": 187.45, "2019-04": 195.8, "2019-05": 179.5, "2019-06": 208.11, "2019-07": 203.12, "2019-08": 206.01, "2019-09": 221.36, "2019-10": 220.15, "2019-11": 250.7, "2019-12": 257.41, "2020-01": 274.33, "2020-02": 258.81, "2020-03": 232.47, "2020-04": 261.83, "2020-05": 286.7, "2020-06": 291.73, "2020-07": 310.6, "2020-08": 339.01, "2020-09": 327.23, "2020-10": 311.23, "2020-11": 338.06, "2020-12": 363.8, "2021-01": 367.94, "2021-02": 346.11, "2021-03": 339.56, "2021-04": 365.66, "2021-05": 335.99, "2021-06": 347.06, "2021-07": 369.63, "2021-08": 365.36, "2021-09": 340.45, "2021-10": 376.44, "2021-11": 391.48, "2021-12": 401.12, "2022-01": 340.01, "2022-02": 324.19, "2022-03": 317.65, "2022-04": 279.93, "2022-05": 260.36, "2022-06": 239.29, "2022-07": 279.21, "2022-08": 248.3, "2022-09": 221.7, "2022-10": 221.16, "2022-11": 254.3, "2022-12": 241.59, "2023-01": 266.36, "2023-02": 303.61, "2023-03": 332.8, "2023-04": 314.17, "2023-05": 323.59, "2023-06": 330.27, "2023-07": 342.1, "2023-08": 318.87, "2023-09": 297.4, "2023-10": 278.26, "2023-11": 293.36, "2023-12": 362.88, "2024-01": 327.83, "2024-02": 334.17, "2024-03": 347.48, "2024-04": 324.88, "2024-05": 317.45, "2024-06": 321.5, "2024-07": 313.63, "2024-08": 309.02, "2024-09": 318.63, "2024-10": 320.41, "2024-11": 350.51, "2024-12": 337.33, "2025-01": 350.5, "2025-02": 333.25, "2025-03": 316.56, "2025-04": 321.88, "2025-05": 332.61, "2025-06": 351.22, "2025-07": 351.22, "2025-08": 351.22, "2025-09": 351.22, "2025-10": 351.22, "2025-11": 0, "2025-12": 0, "2026-01": 0, "2026-02": 0, "2026-03": 0, "2026-04": 0 } }, "BABA": { "stooq": "baba.us", "moeda": "USD", "mensal": { "2018-12": 137.07, "2019-01": 168.49, "2019-02": 183.03, "2019-03": 180.89, "2019-04": 185.57, "2019-05": 149.26, "2019-06": 175.05, "2019-07": 173.11, "2019-08": 172.41, "2019-09": 167.23, "2019-10": 176.67, "2019-11": 196.31, "2019-12": 212.1, "2020-01": 206.59, "2020-02": 210.98, "2020-03": 194.48, "2020-04": 202.67, "2020-05": 206.57, "2020-06": 215.7, "2020-07": 251.02, "2020-08": 287.03, "2020-09": 293.98, "2020-10": 310.84, "2020-11": 263.36, "2020-12": 232.73, "2021-01": 264.69, "2021-02": 241.69, "2021-03": 226.73, "2021-04": 230.95, "2021-05": 219.48, "2021-06": 226.78, "2021-07": 200.09, "2021-08": 166.99, "2021-09": 148.05, "2021-10": 170.17, "2021-11": 127.53, "2021-12": 118.79, "2022-01": 125.79, "2022-02": 105.19, "2022-03": 108.8, "2022-04": 101.21, "2022-05": 96.05, "2022-06": 113.68, "2022-07": 90.34, "2022-08": 95.41, "2022-09": 79.99, "2022-10": 63.58, "2022-11": 87.56, "2022-12": 88.09, "2023-01": 110.2, "2023-02": 87.79, "2023-03": 102.18, "2023-04": 84.16, "2023-05": 79.55, "2023-06": 83.35, "2023-07": 102.16, "2023-08": 92.9, "2023-09": 86.53, "2023-10": 82.54, "2023-11": 74.88, "2023-12": 77.51, "2024-01": 72.17, "2024-02": 74.03, "2024-03": 73.37, "2024-04": 74.85, "2024-05": 78.34, "2024-06": 72, "2024-07": 78.85, "2024-08": 82.27, "2024-09": 106.12, "2024-10": 97.98, "2024-11": 85.95, "2024-12": 120.79, "2025-01": 98.84, "2025-02": 132.51, "2025-03": 132.23, "2025-04": 119.43, "2025-05": 114.75, "2025-06": 113.41, "2025-07": 120.63, "2025-08": 138.55, "2025-09": 178.73, "2025-10": 170.43, "2025-11": 164.26, "2025-12": 146.58, "2026-01": 168.39, "2026-02": 142.56, "2026-03": 125.46, "2026-04": 131.88 } }, "BAC": { "stooq": "bac.us", "moeda": "USD", "mensal": { "2018-12": 24.64, "2019-01": 28.47, "2019-02": 29.08, "2019-03": 28.54, "2019-04": 30.58, "2019-05": 26.6, "2019-06": 29.42, "2019-07": 30.68, "2019-08": 27.05, "2019-09": 29.17, "2019-10": 31.27, "2019-11": 33.43, "2019-12": 35.22, "2020-01": 32.83, "2020-02": 29.37, "2020-03": 21.23, "2020-04": 24.05, "2020-05": 24.61, "2020-06": 23.75, "2020-07": 24.88, "2020-08": 25.74, "2020-09": 24.09, "2020-10": 24.08, "2020-11": 28.16, "2020-12": 30.31, "2021-01": 29.96, "2021-02": 35.79, "2021-03": 38.69, "2021-04": 40.53, "2021-05": 42.92, "2021-06": 41.23, "2021-07": 37.96, "2021-08": 41.75, "2021-09": 42.45, "2021-10": 47.85, "2021-11": 44.47, "2021-12": 44.49, "2022-01": 46.14, "2022-02": 44.2, "2022-03": 41.22, "2022-04": 36.14, "2022-05": 37.2, "2022-06": 31.13, "2022-07": 33.71, "2022-08": 33.61, "2022-09": 30.2, "2022-10": 36.04, "2022-11": 37.85, "2022-12": 33.12, "2023-01": 35.48, "2023-02": 34.3, "2023-03": 28.6, "2023-04": 29.04, "2023-05": 27.79, "2023-06": 28.69, "2023-07": 32, "2023-08": 28.67, "2023-09": 26.7, "2023-10": 26.34, "2023-11": 30.49, "2023-12": 33.67, "2024-01": 34.01, "2024-02": 34.52, "2024-03": 37.52, "2024-04": 37.01, "2024-05": 39.99, "2024-06": 39.77, "2024-07": 40.31, "2024-08": 40.7, "2024-09": 39.68, "2024-10": 41.82, "2024-11": 47.04, "2024-12": 43.95, "2025-01": 46.3, "2025-02": 46.1, "2025-03": 41.73, "2025-04": 39.88, "2025-05": 44.08, "2025-06": 47.32, "2025-07": 47.27, "2025-08": 50.42, "2025-09": 51.59, "2025-10": 53.45, "2025-11": 53.24, "2025-12": 55, "2026-01": 54.03, "2026-02": 49.81, "2026-03": 48.75, "2026-04": 53.46 } }, "BRKB": { "stooq": "brk-b.us", "moeda": "USD", "mensal": { "2018-12": 204.18, "2019-01": 205.54, "2019-02": 201.3, "2019-03": 205, "2019-04": 216.71, "2019-05": 197.42, "2019-06": 214.62, "2019-07": 205.43, "2019-08": 200.9, "2019-09": 208.02, "2019-10": 212.58, "2019-11": 220.33, "2019-12": 226.5, "2020-01": 224.43, "2020-02": 217.63, "2020-03": 182.83, "2020-04": 187.36, "2020-05": 183.84, "2020-06": 178.51, "2020-07": 195.78, "2020-08": 218.04, "2020-09": 212.94, "2020-10": 204.31, "2020-11": 228.91, "2020-12": 231.87, "2021-01": 229.32, "2021-02": 249.21, "2021-03": 255.47, "2021-04": 274.95, "2021-05": 289.84, "2021-06": 277.92, "2021-07": 278.14, "2021-08": 285.77, "2021-09": 272.94, "2021-10": 286.24, "2021-11": 276.69, "2021-12": 299, "2022-01": 313.02, "2022-02": 321.45, "2022-03": 352.91, "2022-04": 318.19, "2022-05": 315.98, "2022-06": 273.02, "2022-07": 295.86, "2022-08": 280.8, "2022-09": 267.02, "2022-10": 295.09, "2022-11": 318.6, "2022-12": 308.9, "2023-01": 311.52, "2023-02": 305.18, "2023-03": 308.77, "2023-04": 330.17, "2023-05": 321.08, "2023-06": 341, "2023-07": 351.96, "2023-08": 360.2, "2023-09": 348.08, "2023-10": 341.33, "2023-11": 360, "2023-12": 356.66, "2024-01": 383.74, "2024-02": 409.4, "2024-03": 420.2, "2024-04": 396.73, "2024-05": 414.4, "2024-06": 406.8, "2024-07": 438.5, "2024-08": 476.83, "2024-09": 460.26, "2024-10": 450.92, "2024-11": 477.33, "2024-12": 85.35, "2025-01": 468.67, "2025-02": 513.83, "2025-03": 532.58, "2025-04": 533.25, "2025-05": 502.81, "2025-06": 485.77, "2025-07": 471.88, "2025-08": 501.14, "2025-09": 502.74, "2025-10": 477.54, "2025-11": 508.55, "2025-12": 502.65, "2026-01": 487.29, "2026-02": 480.17, "2026-03": 479.2, "2026-04": 473.6 } }, "GOOGL": { "stooq": "googl.us", "moeda": "USD", "mensal": { "2018-12": 52.25, "2019-01": 56.29, "2019-02": 56.33, "2019-03": 59.95, "2019-04": 59.95, "2019-05": 55.33, "2019-06": 55, "2019-07": 60.91, "2019-08": 58.48, "2019-09": 61.06, "2019-10": 62.94, "2019-11": 64.44, "2019-12": 66.97, "2020-01": 71.64, "2020-02": 69.32, "2020-03": 58.1, "2020-04": 67.34, "2020-05": 71.74, "2020-06": 70.9, "2020-07": 74.4, "2020-08": 81.48, "2020-09": 73.28, "2020-10": 81.22, "2020-11": 87.72, "2020-12": 87.63, "2021-01": 94.65, "2021-02": 103.48, "2021-03": 103.13, "2021-04": 117.68, "2021-05": 119.06, "2021-06": 122.09, "2021-07": 134.85, "2021-08": 144.7, "2021-09": 133.68, "2021-10": 143.5, "2021-11": 141.9, "2021-12": 144.85, "2022-01": 135.3, "2022-02": 135.06, "2022-03": 139.07, "2022-04": 116.58, "2022-05": 113.76, "2022-06": 108.96, "2022-07": 114.86, "2022-08": 108.22, "2022-09": 95.65, "2022-10": 94.51, "2022-11": 100.99, "2022-12": 88.23, "2023-01": 98.84, "2023-02": 90.06, "2023-03": 103.73, "2023-04": 107.2, "2023-05": 122.87, "2023-06": 119.7, "2023-07": 132.72, "2023-08": 136.17, "2023-09": 134.17, "2023-10": 124.08, "2023-11": 132.53, "2023-12": 139.69, "2024-01": 140.1, "2024-02": 138.46, "2024-03": 155.49, "2024-04": 162.78, "2024-05": 172.5, "2024-06": 182.15, "2024-07": 171.54, "2024-08": 157.36, "2024-09": 165.85, "2024-10": 171.11, "2024-11": 171.49, "2024-12": 189.3, "2025-01": 204.02, "2025-02": 170.28, "2025-03": 154.64, "2025-04": 158.8, "2025-05": 169.03, "2025-06": 176.23, "2025-07": 191.9, "2025-08": 211.35, "2025-09": 243.1, "2025-10": 281.19, "2025-11": 314.89, "2025-12": 313, "2026-01": 343.69, "2026-02": 306.52, "2026-03": 287.56, "2026-04": 384.8 } }, "IWDA": { "stooq": "eunl.de", "moeda": "EUR", "mensal": { "2023-11": 78.97, "2023-12": 81.87, "2024-01": 85.02, "2024-02": 88.18, "2024-03": 90.69, "2024-04": 89.58, "2024-05": 90.67, "2024-06": 95.19, "2024-07": 95.39, "2024-08": 95.67, "2024-09": 96.37, "2024-10": 97.55, "2024-11": 105.7, "2024-12": 5.88, "2025-01": 108.18, "2025-02": 105.45, "2025-03": 97.13, "2025-04": 93.33, "2025-05": 98.8, "2025-06": 100.15, "2025-07": 104.94, "2025-08": 104.83, "2025-09": 107.22, "2025-10": 111.79, "2025-11": 110.97, "2025-12": 111.53, "2026-01": 113.44, "2026-02": 113.83, "2026-03": 108.06, "2026-04": 117.06 } }, "KO": { "stooq": "ko.us", "moeda": "USD", "mensal": { "2018-12": 47.35, "2019-01": 48.13, "2019-02": 45.34, "2019-03": 46.72, "2019-04": 49.06, "2019-05": 49.13, "2019-06": 51.6, "2019-07": 52.63, "2019-08": 55.3, "2019-09": 54.44, "2019-10": 54.43, "2019-11": 53.75, "2019-12": 55.35, "2020-01": 58.4, "2020-02": 55.92, "2020-03": 44.25, "2020-04": 45.89, "2020-05": 46.99, "2020-06": 44.68, "2020-07": 47.24, "2020-08": 49.53, "2020-09": 49.37, "2020-10": 48.62, "2020-11": 51.6, "2020-12": 54.84, "2021-01": 48.48, "2021-02": 49.9, "2021-03": 52.71, "2021-04": 53.98, "2021-05": 55.28, "2021-06": 54.11, "2021-07": 56.88, "2021-08": 56.31, "2021-09": 52.47, "2021-10": 56.17, "2021-11": 52.45, "2021-12": 59.21, "2022-01": 61.01, "2022-02": 62.24, "2022-03": 62, "2022-04": 63.44, "2022-05": 63.38, "2022-06": 62.91, "2022-07": 64.52, "2022-08": 61.71, "2022-09": 56.02, "2022-10": 59.85, "2022-11": 63.61, "2022-12": 63.61, "2023-01": 61.32, "2023-02": 59.51, "2023-03": 62.03, "2023-04": 64.3, "2023-05": 59.66, "2023-06": 60.22, "2023-07": 61.93, "2023-08": 59.83, "2023-09": 55.48, "2023-10": 56.49, "2023-11": 58.44, "2023-12": 58.93, "2024-01": 59.49, "2024-02": 60.02, "2024-03": 60.68, "2024-04": 61.77, "2024-05": 62.93, "2024-06": 63.65, "2024-07": 66.74, "2024-08": 73.01, "2024-09": 71.86, "2024-10": 65.31, "2024-11": 63.65, "2024-12": 62.26, "2025-01": 63.48, "2025-02": 71.21, "2025-03": 71.62, "2025-04": 72.55, "2025-05": 72, "2025-06": 70.75, "2025-07": 68.75, "2025-08": 69.06, "2025-09": 66.32, "2025-10": 68.9, "2025-11": 71.95, "2025-12": 69.91, "2026-01": 75.33, "2026-02": 80.22, "2026-03": 76.05, "2026-04": 78.76 } }, "MA": { "stooq": "ma.us", "moeda": "USD", "mensal": { "2018-12": 188.65, "2019-01": 211.13, "2019-02": 224.77, "2019-03": 239.05, "2019-04": 254.24, "2019-05": 251.49, "2019-06": 266.77, "2019-07": 272.27, "2019-08": 280.11, "2019-09": 271.57, "2019-10": 276.81, "2019-11": 286.47, "2019-12": 298.59, "2020-01": 315.94, "2020-02": 306.74, "2020-03": 241.56, "2020-04": 274.97, "2020-05": 301.4, "2020-06": 295.7, "2020-07": 308.53, "2020-08": 358.19, "2020-09": 338.17, "2020-10": 289.97, "2020-11": 336.51, "2020-12": 356.94, "2021-01": 321.56, "2021-02": 362.9, "2021-03": 356.05, "2021-04": 382.06, "2021-05": 359.79, "2021-06": 365.09, "2021-07": 375.26, "2021-08": 346.23, "2021-09": 347.68, "2021-10": 334.05, "2021-11": 314.92, "2021-12": 359.32, "2022-01": 386.38, "2022-02": 360.82, "2022-03": 357.38, "2022-04": 359.04, "2022-05": 357.87, "2022-06": 315.48, "2022-07": 350.54, "2022-08": 329.35, "2022-09": 286.77, "2022-10": 328.18, "2022-11": 356.4, "2022-12": 347.73, "2023-01": 370.6, "2023-02": 355.29, "2023-03": 363.41, "2023-04": 379.86, "2023-05": 365.02, "2023-06": 393.3, "2023-07": 394.28, "2023-08": 412.64, "2023-09": 395.85, "2023-10": 376.35, "2023-11": 413.83, "2023-12": 426.51, "2024-01": 449.23, "2024-02": 474.76, "2024-03": 478.4, "2024-04": 451.2, "2024-05": 447.07, "2024-06": 441.16, "2024-07": 463.71, "2024-08": 482.12, "2024-09": 493.8, "2024-10": 499.59, "2024-11": 531.36, "2024-12": 219.39, "2025-01": 555.43, "2025-02": 576.31, "2025-03": 548.12, "2025-04": 548.06, "2025-05": 581.22, "2025-06": 561.94, "2025-07": 566.47, "2025-08": 591.87, "2025-09": 568.81, "2025-10": 551.99, "2025-11": 543.97, "2025-12": 570.88, "2026-01": 555.37, "2026-02": 521, "2026-03": 499.66, "2026-04": 502.92 } }, "MCD": { "stooq": "mcd.us", "moeda": "USD", "mensal": { "2018-12": 177.57, "2019-01": 178.78, "2019-02": 183.84, "2019-03": 188.39, "2019-04": 197.57, "2019-05": 198.27, "2019-06": 206.3, "2019-07": 210.72, "2019-08": 217.13, "2019-09": 214.71, "2019-10": 196.7, "2019-11": 195.18, "2019-12": 197.61, "2020-01": 213.97, "2020-02": 202.55, "2020-03": 165.35, "2020-04": 187.56, "2020-05": 187.41, "2020-06": 184.47, "2020-07": 194.28, "2020-08": 213.52, "2020-09": 219.49, "2020-10": 212.56, "2020-11": 217.44, "2020-12": 214.58, "2021-01": 207.93, "2021-02": 208.25, "2021-03": 224.14, "2021-04": 236.08, "2021-05": 233.24, "2021-06": 230.99, "2021-07": 240.1, "2021-08": 237.46, "2021-09": 241.11, "2021-10": 250.58, "2021-11": 244.6, "2021-12": 268.07, "2022-01": 259.45, "2022-02": 244.77, "2022-03": 247.28, "2022-04": 246.64, "2022-05": 252.21, "2022-06": 246.88, "2022-07": 264.23, "2022-08": 252.28, "2022-09": 230.74, "2022-10": 272.66, "2022-11": 272.79, "2022-12": 263.53, "2023-01": 267.4, "2023-02": 263.91, "2023-03": 279.61, "2023-04": 297.58, "2023-05": 285.11, "2023-06": 298.41, "2023-07": 293.2, "2023-08": 281.15, "2023-09": 257.75, "2023-10": 262.17, "2023-11": 281.84, "2023-12": 296.51, "2024-01": 292.72, "2024-02": 292.28, "2024-03": 280.22, "2024-04": 273.04, "2024-05": 258.89, "2024-06": 254.84, "2024-07": 265.4, "2024-08": 285.52, "2024-09": 304.51, "2024-10": 292.11, "2024-11": 292.44, "2024-12": 62.26, "2025-01": 288.7, "2025-02": 308.33, "2025-03": 312.37, "2025-04": 319.65, "2025-05": 312.68, "2025-06": 292.17, "2025-07": 300.07, "2025-08": 315.76, "2025-09": 303.89, "2025-10": 298.43, "2025-11": 303.57, "2025-12": 305.63, "2026-01": 318.53, "2026-02": 334.82, "2026-03": 310.79, "2026-04": 293.59 } }, "MRNA": { "stooq": "mrna.us", "moeda": "USD", "mensal": { "2018-12": 15.27, "2019-01": 16.6, "2019-02": 22.6, "2019-03": 20.59, "2019-04": 26.03, "2019-05": 20.78, "2019-06": 14.73, "2019-07": 13.1, "2019-08": 14.88, "2019-09": 15.92, "2019-10": 16.75, "2019-11": 19.76, "2019-12": 19.56, "2020-01": 20.51, "2020-02": 29.88, "2020-03": 29.95, "2020-04": 45.99, "2020-05": 62.18, "2020-06": 64.21, "2020-07": 74.1, "2020-08": 64.89, "2020-09": 70.75, "2020-10": 67.11, "2020-11": 152.74, "2020-12": 104.47, "2021-01": 157.48, "2021-02": 157.4, "2021-03": 130.95, "2021-04": 175.67, "2021-05": 184.66, "2021-06": 234.98, "2021-07": 346.61, "2021-08": 376.69, "2021-09": 384.86, "2021-10": 337.17, "2021-11": 352.43, "2021-12": 253.98, "2022-01": 169.33, "2022-02": 153.6, "2022-03": 172.26, "2022-04": 142.08, "2022-05": 145.33, "2022-06": 142.85, "2022-07": 161.51, "2022-08": 132.27, "2022-09": 118.25, "2022-10": 150.33, "2022-11": 175.91, "2022-12": 179.62, "2023-01": 176.06, "2023-02": 138.81, "2023-03": 153.58, "2023-04": 133.4, "2023-05": 127.71, "2023-06": 121.5, "2023-07": 117.66, "2023-08": 113.07, "2023-09": 103.31, "2023-10": 75.96, "2023-11": 77.7, "2023-12": 99.45, "2024-01": 101.05, "2024-02": 92.24, "2024-03": 105.6, "2024-04": 110.31, "2024-05": 142.55, "2024-06": 118.75, "2024-07": 119.22, "2024-08": 72.94, "2024-09": 66.83, "2024-10": 54.36, "2024-11": 44.26, "2024-12": 41.58, "2025-01": 39.42, "2025-02": 30.96, "2025-03": 28.35, "2025-04": 28.54, "2025-05": 27.05, "2025-06": 27.59, "2025-07": 29.56, "2025-08": 24.19, "2025-09": 25.83, "2025-10": 27.16, "2025-11": 24.16, "2025-12": 29.49, "2026-01": 42.55, "2026-02": 52.85, "2026-03": 50.8, "2026-04": 45.94 } }, "MSFT": { "stooq": "msft.us", "moeda": "USD", "mensal": { "2018-12": 101.57, "2019-01": 104.43, "2019-02": 112.03, "2019-03": 119.02, "2019-04": 130.6, "2019-05": 123.68, "2019-06": 135.68, "2019-07": 136.27, "2019-08": 136.04, "2019-09": 139.03, "2019-10": 143.37, "2019-11": 149.55, "2019-12": 157.7, "2020-01": 170.23, "2020-02": 172.79, "2020-03": 157.71, "2020-04": 179.21, "2020-05": 182.83, "2020-06": 203.51, "2020-07": 205.01, "2020-08": 225.53, "2020-09": 210.33, "2020-10": 202.33, "2020-11": 214.07, "2020-12": 222.42, "2021-01": 239.65, "2021-02": 236.94, "2021-03": 235.77, "2021-04": 252.18, "2021-05": 247.4, "2021-06": 270.9, "2021-07": 284.82, "2021-08": 301.88, "2021-09": 281.92, "2021-10": 329.37, "2021-11": 330.59, "2021-12": 336.32, "2022-01": 310.98, "2022-02": 298.79, "2022-03": 308.31, "2022-04": 284.47, "2022-05": 271.87, "2022-06": 256.83, "2022-07": 278.01, "2022-08": 261.47, "2022-09": 232.9, "2022-10": 232.13, "2022-11": 255.14, "2022-12": 239.82, "2023-01": 247.81, "2023-02": 249.42, "2023-03": 288.3, "2023-04": 305.56, "2023-05": 328.39, "2023-06": 340.54, "2023-07": 335.92, "2023-08": 327.76, "2023-09": 321.8, "2023-10": 338.11, "2023-11": 378.91, "2023-12": 376.04, "2024-01": 397.58, "2024-02": 413.64, "2024-03": 424.57, "2024-04": 389.33, "2024-05": 415.13, "2024-06": 446.95, "2024-07": 418.35, "2024-08": 409.44, "2024-09": 430.3, "2024-10": 406.35, "2024-11": 430.98, "2024-12": 421.5, "2025-01": 415.06, "2025-02": 396.99, "2025-03": 375.39, "2025-04": 395.26, "2025-05": 461.97, "2025-06": 497.41, "2025-07": 533.5, "2025-08": 505.12, "2025-09": 517.95, "2025-10": 517.81, "2025-11": 486.74, "2025-12": 483.62, "2026-01": 423.37, "2026-02": 398.55, "2026-03": 370.17, "2026-04": 407.78 } }, "NDXEX": { "stooq": "exxt.de", "moeda": "EUR", "mensal": { "2024-06": 182.06, "2024-07": 172.93, "2024-08": 171.39, "2024-09": 180.14, "2024-10": 182.75, "2024-11": 200.06, "2024-12": 203.04, "2025-01": 207.27, "2025-02": 201.23, "2025-03": 178.2, "2025-04": 172.83, "2025-05": 189.34, "2025-06": 192.41, "2025-07": 203.25, "2025-08": 198.7, "2025-09": 203.66, "2025-10": 222.92, "2025-11": 218.45, "2025-12": 215.21, "2026-01": 217.11, "2026-02": 211.46, "2026-03": 200.38, "2026-04": 227.52 } }, "NFLX": { "stooq": "nflx.us", "moeda": "USD", "mensal": { "2018-12": 267.66, "2019-01": 339.5, "2019-02": 358.1, "2019-03": 366.96, "2019-04": 370.54, "2019-05": 343.28, "2019-06": 374.6, "2019-07": 322.99, "2019-08": 289.29, "2019-09": 267.62, "2019-10": 287.41, "2019-11": 309.99, "2019-12": 323.57, "2020-01": 345.09, "2020-02": 381.05, "2020-03": 375.5, "2020-04": 419.85, "2020-05": 425.92, "2020-06": 455.04, "2020-07": 488.88, "2020-08": 529.56, "2020-09": 500.03, "2020-10": 484.12, "2020-11": 490.7, "2020-12": 540.73, "2021-01": 539.04, "2021-02": 550.64, "2021-03": 521.66, "2021-04": 513.47, "2021-05": 499.08, "2021-06": 528.21, "2021-07": 515.15, "2021-08": 569.19, "2021-09": 610.34, "2021-10": 681.17, "2021-11": 641.9, "2021-12": 602.44, "2022-01": 427.14, "2022-02": 394.52, "2022-03": 374.59, "2022-04": 199.46, "2022-05": 197.44, "2022-06": 174.87, "2022-07": 226.21, "2022-08": 223.56, "2022-09": 235.44, "2022-10": 291.88, "2022-11": 305.53, "2022-12": 294.88, "2023-01": 353.86, "2023-02": 322.13, "2023-03": 345.48, "2023-04": 324.12, "2023-05": 395.23, "2023-06": 440.49, "2023-07": 438.97, "2023-08": 433.68, "2023-09": 380.33, "2023-10": 411.69, "2023-11": 473.97, "2023-12": 486.88, "2024-01": 564.11, "2024-02": 602.92, "2024-03": 614.31, "2024-04": 550.64, "2024-05": 641.62, "2024-06": 674.88, "2024-07": 628.35, "2024-08": 675.32, "2024-09": 709.27, "2024-10": 756.03, "2024-11": 897.74, "2024-12": 250.42, "2025-01": 976.76, "2025-02": 980.56, "2025-03": 932.53, "2025-11": 109.13, "2025-12": 93.76, "2026-01": 82.76, "2026-02": 97.09, "2026-03": 96.15, "2026-04": 93.61 } }, "NIO": { "stooq": "nio.us", "moeda": "USD", "mensal": { "2018-12": 6.37, "2019-01": 7.88, "2019-02": 9.57, "2019-03": 5.21, "2019-04": 4.85, "2019-05": 3.05, "2019-06": 2.6, "2019-07": 3.47, "2019-08": 2.6, "2019-09": 1.56, "2019-10": 1.45, "2019-11": 2.44, "2019-12": 4.02, "2020-01": 3.78, "2020-02": 4.11, "2020-03": 2.78, "2020-04": 3.41, "2020-05": 4.26, "2020-06": 7.72, "2020-07": 11.94, "2020-08": 19.03, "2020-09": 21.22, "2020-10": 33.32, "2020-11": 50.53, "2020-12": 48.74, "2021-01": 56.99, "2021-02": 49.76, "2021-03": 38.98, "2021-04": 39.84, "2021-05": 42.34, "2021-06": 53.2, "2021-07": 45.85, "2021-08": 39.31, "2021-09": 35.63, "2021-10": 40.84, "2021-11": 39.13, "2021-12": 31.68, "2022-01": 24.51, "2022-02": 22.84, "2022-03": 21.05, "2022-04": 17.5, "2022-05": 17.39, "2022-06": 21.72, "2022-07": 20.18, "2022-08": 19.91, "2022-09": 15.77, "2022-10": 9.67, "2022-11": 12.78, "2022-12": 9.75, "2023-01": 12.07, "2023-02": 9.39, "2023-03": 10.51, "2023-04": 7.81, "2023-05": 7.53, "2023-06": 9.69, "2023-07": 15.3, "2023-08": 10.27, "2023-09": 8.79, "2023-10": 7.3, "2023-11": 7.27, "2023-12": 9.07, "2024-01": 5.62, "2024-02": 5.75, "2024-03": 4.64, "2024-04": 4.72, "2024-05": 5.39, "2024-06": 4.16, "2024-07": 4.44, "2024-08": 4.15, "2024-09": 6.68, "2024-10": 5.1, "2024-11": 4.4, "2024-12": 403.84, "2025-01": 4.32, "2025-02": 4.63, "2025-03": 3.81, "2025-04": 4.05, "2025-05": 3.52, "2025-06": 3.43, "2025-07": 4.87, "2025-08": 6.58, "2025-09": 7.62, "2025-10": 7.25, "2025-11": 5.18, "2025-12": 5.1, "2026-01": 4.52, "2026-02": 4.72, "2026-03": 6.03, "2026-04": 6.39 } }, "NVDA": { "stooq": "nvda.us", "moeda": "USD", "mensal": { "2018-12": 33.38, "2019-01": 35.94, "2019-02": 38.57, "2019-03": 45.57, "2019-04": 45.25, "2019-05": 33.87, "2019-06": 41.54, "2019-07": 42.18, "2019-08": 41.04, "2019-09": 43.52, "2019-10": 50.26, "2019-11": 52.31, "2019-12": 58.83, "2020-01": 59.11, "2020-02": 69.11, "2020-03": 65.9, "2020-04": 73.07, "2020-05": 88.06, "2020-06": 94.98, "2020-07": 106.15, "2020-08": 133.75, "2020-09": 135.31, "2020-10": 125.81, "2020-11": 134.01, "2020-12": 130.55, "2021-01": 132.37, "2021-02": 138.42, "2021-03": 133.48, "2021-04": 150.1, "2021-05": 162.65, "2021-06": 200.03, "2021-07": 197.5, "2021-08": 223.85, "2021-09": 207.16, "2021-10": 258.27, "2021-11": 326.76, "2021-12": 294.11, "2022-01": 244.86, "2022-02": 243.85, "2022-03": 272.86, "2022-04": 195.33, "2022-05": 186.72, "2022-06": 151.59, "2022-07": 184.41, "2022-08": 150.94, "2022-09": 121.39, "2022-10": 134.97, "2022-11": 169.23, "2022-12": 146.14, "2023-01": 195.37, "2023-02": 232.16, "2023-03": 277.77, "2023-04": 289.1, "2023-05": 378.34, "2023-06": 423.02, "2023-07": 467.29, "2023-08": 493.55, "2023-09": 447.82, "2023-10": 407.8, "2023-11": 467.7, "2023-12": 495.22, "2024-01": 61.53, "2024-02": 79.11, "2024-03": 90.36, "2024-04": 86.4, "2024-05": 109.63, "2024-06": 123.54, "2024-07": 117.02, "2024-08": 108, "2024-09": 121.44, "2024-10": 132.76, "2024-11": 138.63, "2024-12": 134.29, "2025-01": 120.07, "2025-02": 124.92, "2025-03": 108.38, "2025-04": 108.92, "2025-05": 137.38, "2025-06": 157.99, "2025-07": 177.87, "2025-08": 170.78, "2025-09": 186.58, "2025-10": 202.49, "2025-11": 179.92, "2025-12": 186.5, "2026-01": 185.61, "2026-02": 182.48, "2026-03": 174.4, "2026-04": 199.57 } }, "O": { "stooq": "o.us", "moeda": "USD", "mensal": { "2022-02": 66.09, "2022-03": 69.3, "2022-04": 67.38, "2022-05": 68.22, "2022-06": 68.26, "2022-07": 73.67, "2022-08": 68.28, "2022-09": 58.2, "2022-10": 62.27, "2022-11": 63.07, "2022-12": 63.43, "2023-01": 67.83, "2023-02": 63.95, "2023-03": 63.32, "2023-04": 61.49, "2023-05": 59.69, "2023-06": 59.3, "2023-07": 61.03, "2023-08": 56.26, "2023-09": 49.06, "2023-10": 47.39, "2023-11": 53.84, "2023-12": 57.6, "2024-01": 54.8, "2024-02": 52.14, "2024-03": 53.46, "2024-04": 53.54, "2024-05": 53.06, "2024-06": 52.82, "2024-07": 57.43, "2024-08": 62.28, "2024-09": 63.42, "2024-10": 59.37, "2024-11": 56.69, "2024-12": 444.68, "2025-01": 54.64, "2025-02": 57.03, "2025-03": 58.01, "2025-04": 57.86, "2025-05": 56.58, "2025-06": 57.61, "2025-07": 56.13, "2025-08": 57.74, "2025-09": 60.79, "2025-10": 57.98, "2025-11": 57.43, "2025-12": 56.37, "2026-01": 60.53, "2026-02": 67.56, "2026-03": 61.18, "2026-04": 64.24 } }, "PLUG": { "stooq": "plug.us", "moeda": "USD", "mensal": { "2018-12": 1.24, "2019-01": 1.37, "2019-02": 1.79, "2019-03": 2.35, "2019-04": 2.49, "2019-05": 2.56, "2019-06": 2.24, "2019-07": 2.21, "2019-08": 2.14, "2019-09": 2.63, "2019-10": 2.65, "2019-11": 3.8, "2019-12": 3.16, "2020-01": 3.87, "2020-02": 4.36, "2020-03": 3.54, "2020-04": 4.18, "2020-05": 4.28, "2020-06": 8.21, "2020-07": 7.71, "2020-08": 12.98, "2020-09": 13.41, "2020-10": 15.47, "2020-11": 26.39, "2020-12": 33.91, "2021-01": 63.85, "2021-02": 52.46, "2021-03": 35.84, "2021-04": 28.51, "2021-05": 30.89, "2021-06": 34.19, "2021-07": 26.62, "2021-08": 26.06, "2021-09": 25.54, "2021-10": 41.65, "2021-11": 39.85, "2021-12": 28.23, "2022-01": 21.87, "2022-02": 25.29, "2022-03": 28.61, "2022-04": 21.7, "2022-05": 18.48, "2022-06": 16.57, "2022-07": 21.24, "2022-08": 28.04, "2022-09": 21.01, "2022-10": 15.98, "2022-11": 15.96, "2022-12": 12.37, "2023-01": 17.02, "2023-02": 14.87, "2023-03": 11.72, "2023-04": 8.83, "2023-05": 8.32, "2023-06": 10.39, "2023-07": 13.12, "2023-08": 8.46, "2023-09": 6.83, "2023-10": 5.89, "2023-11": 4.04, "2023-12": 4.5, "2024-01": 4.45, "2024-02": 3.53, "2024-03": 3.44, "2024-04": 2.31, "2024-05": 3.33, "2024-06": 2.33, "2024-07": 2.47, "2024-08": 1.75, "2024-09": 2.26, "2024-10": 1.96, "2024-11": 2.3, "2024-12": 2.13, "2025-01": 1.86, "2025-02": 1.61, "2025-03": 1.35, "2025-04": 0.87, "2025-05": 0.82, "2025-06": 1.49, "2025-07": 1.5, "2025-08": 1.48, "2025-09": 2.33, "2025-10": 2.69, "2025-11": 1.92, "2025-12": 1.97, "2026-01": 2.08, "2026-02": 1.81, "2026-03": 2.26, "2026-04": 3.13 } }, "PYPL": { "stooq": "pypl.us", "moeda": "USD", "mensal": { "2018-12": 84.09, "2019-01": 88.76, "2019-02": 98.07, "2019-03": 105.55, "2019-04": 112.77, "2019-05": 109.75, "2019-06": 115.03, "2019-07": 110.4, "2019-08": 106.75, "2019-09": 103.59, "2019-10": 104.1, "2019-11": 106.21, "2019-12": 108.17, "2020-01": 113.89, "2020-02": 112.86, "2020-03": 95.74, "2020-04": 123, "2020-05": 154.53, "2020-06": 174.23, "2020-07": 196.07, "2020-08": 204.14, "2020-09": 197.03, "2020-10": 187.76, "2020-11": 214.12, "2020-12": 234.2, "2021-01": 241.85, "2021-02": 273.63, "2021-03": 242.84, "2021-04": 262.29, "2021-05": 259.27, "2021-06": 291.48, "2021-07": 270.99, "2021-08": 288.66, "2021-09": 260.21, "2021-10": 231.28, "2021-11": 184.89, "2021-12": 188.58, "2022-01": 171.94, "2022-02": 111.93, "2022-03": 115.65, "2022-04": 91.53, "2022-05": 85.21, "2022-06": 69.84, "2022-07": 88.57, "2022-08": 93.44, "2022-09": 86.07, "2022-10": 83.58, "2022-11": 78.41, "2022-12": 71.22, "2023-01": 81.49, "2023-02": 73.6, "2023-03": 75.94, "2023-04": 75.11, "2023-05": 61.99, "2023-06": 66.73, "2023-07": 75.82, "2023-08": 62.51, "2023-09": 58.56, "2023-10": 51.8, "2023-11": 57.61, "2023-12": 61.41, "2024-01": 61.35, "2024-02": 60.34, "2024-03": 65.03, "2024-04": 67.92, "2024-05": 62.99, "2024-06": 58.03, "2024-07": 65.78, "2024-08": 72, "2024-09": 78.03, "2024-10": 79.3, "2024-11": 86.53, "2024-12": 85.35, "2025-01": 88.58, "2025-02": 71.05, "2025-03": 65.25, "2025-04": 65.84, "2025-05": 70.93, "2025-06": 74.32, "2025-07": 68.76, "2025-08": 69.25, "2025-09": 67.06, "2025-10": 69.27, "2025-11": 62.58, "2025-12": 58.38, "2026-01": 52.33, "2026-02": 45.63, "2026-03": 45.23, "2026-04": 50.14 } }, "QCOM": { "stooq": "qcom.us", "moeda": "USD", "mensal": { "2019-01": 49.52, "2019-02": 53.39, "2019-03": 57.81, "2019-04": 86.13, "2019-05": 66.82, "2019-06": 77.52, "2019-07": 73.16, "2019-08": 75.12, "2019-09": 76.28, "2019-10": 80.44, "2019-11": 82.45, "2019-12": 88.23, "2020-01": 85.31, "2020-02": 80.56, "2020-03": 67.65, "2020-04": 78.67, "2020-05": 79.73, "2020-06": 91.21, "2020-07": 105.61, "2020-08": 119.1, "2020-09": 117.68, "2020-10": 123.97, "2020-11": 147.17, "2020-12": 152.34, "2021-01": 161.58, "2021-02": 139.49, "2021-03": 132.59, "2021-04": 138.8, "2021-05": 133.94, "2021-06": 142.93, "2021-07": 148.86, "2021-08": 146.69, "2021-09": 128.98, "2021-10": 134.81, "2021-11": 180.56, "2021-12": 182.87, "2022-01": 175.76, "2022-02": 171.99, "2022-03": 152.82, "2022-04": 145.27, "2022-05": 143.22, "2022-06": 127.74, "2022-07": 147.43, "2022-08": 137.08, "2022-09": 114.84, "2022-10": 117.66, "2022-11": 126.49, "2022-12": 109.94, "2023-01": 133.21, "2023-02": 123.53, "2023-03": 127.58, "2023-04": 115.84, "2023-05": 113.41, "2023-06": 119.04, "2023-07": 132.17, "2023-08": 114.53, "2023-09": 111.1, "2023-10": 108.99, "2023-11": 129.05, "2023-12": 144.63, "2024-01": 148.51, "2024-02": 157.79, "2024-03": 171.72, "2024-04": 165.85, "2024-05": 204.05, "2024-06": 199.18, "2024-07": 180.95, "2024-08": 163.24, "2024-09": 170.05, "2024-10": 162.77, "2024-11": 163.03, "2024-12": 41.58, "2025-01": 172.93, "2025-02": 157.17, "2025-03": 153.61, "2025-04": 148.46, "2025-05": 146.63, "2025-06": 159.26, "2025-07": 146.76, "2025-08": 158.78, "2025-09": 166.36, "2025-10": 180.9, "2025-11": 168.04, "2025-12": 171.05, "2026-01": 152.62, "2026-02": 141.03, "2026-03": 128.78, "2026-04": 179.58 } }, "SPCE": { "stooq": "spce.us", "moeda": "USD", "mensal": { "2018-12": 10, "2019-01": 10.05, "2019-02": 10.12, "2019-03": 10.19, "2019-04": 10.23, "2019-05": 10.34, "2019-06": 10.4, "2019-07": 10.47, "2019-08": 10.34, "2019-09": 10.7, "2019-10": 9.41, "2019-11": 7.44, "2019-12": 11.55, "2020-01": 17.15, "2020-02": 25.98, "2020-03": 14.78, "2020-04": 17.62, "2020-05": 17.52, "2020-06": 16.34, "2020-07": 22.45, "2020-08": 17.9, "2020-09": 19.23, "2020-10": 17.66, "2020-11": 26.61, "2020-12": 23.73, "2021-01": 53.79, "2021-02": 38.14, "2021-03": 30.63, "2021-04": 22.15, "2021-05": 28.88, "2021-06": 46, "2021-07": 31.87, "2021-08": 27.11, "2021-09": 25.3, "2021-10": 19.55, "2021-11": 16, "2021-12": 13.38, "2022-01": 9.2, "2022-02": 9.68, "2022-03": 9.88, "2022-04": 7.89, "2022-05": 7.01, "2022-06": 6.02, "2022-07": 7.4, "2022-08": 5.91, "2022-09": 4.71, "2022-10": 4.62, "2022-11": 5.09, "2022-12": 3.48, "2023-01": 5.52, "2023-02": 5.74, "2023-03": 4.05, "2023-04": 3.57, "2023-05": 3.46, "2023-06": 3.88, "2023-07": 4.28, "2023-08": 2.52, "2023-09": 1.77, "2023-10": 1.48, "2023-11": 2.23, "2023-12": 2.45, "2024-01": 1.78, "2024-02": 1.74, "2024-03": 1.43, "2024-04": 0.87, "2024-05": 0.86, "2024-06": 8.43, "2024-07": 7.11, "2024-08": 6.16, "2024-09": 6.1, "2024-10": 6.57, "2024-11": 7.02, "2024-12": 5.88, "2025-01": 4.76, "2025-02": 3.8, "2025-03": 3.03, "2025-04": 2.89, "2025-05": 3.12, "2025-06": 2.73, "2025-07": 3.8, "2025-08": 3.09, "2025-09": 3.86, "2025-10": 3.94, "2025-11": 3.79, "2025-12": 3.21, "2026-01": 2.68, "2026-02": 2.6, "2026-03": 2.43, "2026-04": 2.38 } }, "SQ": { "stooq": "sq.us", "moeda": "USD", "mensal": { "2018-12": 56.09, "2019-01": 71.35, "2019-02": 81.24, "2019-03": 76.32, "2019-04": 72.82, "2019-05": 61.95, "2019-06": 73.2, "2019-07": 80.41, "2019-08": 61.13, "2019-09": 61.95, "2019-10": 61.43, "2019-11": 66.88, "2019-12": 62.56, "2020-01": 74.69, "2020-02": 80.67, "2020-03": 52.38, "2020-04": 65.14, "2020-05": 82.72, "2020-06": 104.94, "2020-07": 129.85, "2020-08": 159.56, "2020-09": 162.55, "2020-10": 155.23, "2020-11": 210.96, "2020-12": 217.64, "2021-01": 221.94, "2021-02": 241, "2021-03": 227.05, "2021-04": 244.82, "2021-05": 221.95, "2021-06": 243.8, "2021-07": 272.38, "2021-08": 268.07, "2021-09": 239.84, "2021-10": 255.04, "2021-11": 208.33, "2021-12": 161.51, "2022-01": 122.29, "2022-02": 127.5, "2022-03": 135.6, "2022-04": 105.86, "2022-05": 87.51, "2022-06": 61.46, "2022-07": 77.81, "2022-08": 68.91, "2022-09": 54.99, "2022-10": 60.07, "2022-11": 67.77, "2022-12": 62.84, "2023-01": 81.72, "2023-02": 76.73, "2023-03": 68.65, "2023-04": 60.22, "2023-05": 60.39, "2023-06": 66.57, "2023-07": 80.53, "2023-08": 57.65, "2023-09": 43.19, "2023-10": 40.25, "2023-11": 63.43, "2023-12": 77.35, "2024-01": 65.01, "2024-02": 79.47, "2024-03": 81.46, "2024-04": 73, "2024-05": 64.08, "2024-06": 64.49, "2024-07": 61.88, "2024-08": 64.17, "2024-09": 67.13, "2024-10": 72.32, "2024-11": 92.78, "2024-12": 0, "2025-01": 0, "2025-02": 0, "2025-03": 0, "2025-04": 0, "2025-05": 0, "2025-06": 0, "2025-07": 0, "2025-08": 0, "2025-09": 0, "2025-10": 0, "2025-11": 0, "2025-12": 0, "2026-01": 0, "2026-02": 0, "2026-03": 0, "2026-04": 0 } }, "TSLA": { "stooq": "tsla.us", "moeda": "USD", "mensal": { "2018-12": 22.19, "2019-01": 20.47, "2019-02": 21.33, "2019-03": 19.28, "2019-04": 15.91, "2019-05": 12.34, "2019-06": 15.14, "2019-07": 16.11, "2019-08": 15, "2019-09": 16.06, "2019-10": 20.99, "2019-11": 22.32, "2019-12": 27.89, "2020-01": 43.37, "2020-02": 49.57, "2020-03": 34.93, "2020-04": 52.13, "2020-05": 59.87, "2020-06": 71.99, "2020-07": 95.38, "2020-08": 166.11, "2020-09": 143, "2020-10": 133.5, "2020-11": 189.2, "2020-12": 235.22, "2021-01": 279.94, "2021-02": 239.48, "2021-03": 222.64, "2021-04": 236.48, "2021-05": 207.97, "2021-06": 226.57, "2021-07": 236.56, "2021-08": 245.24, "2021-09": 258.49, "2021-10": 402.86, "2021-11": 381.59, "2021-12": 352.26, "2022-01": 312.24, "2022-02": 290.14, "2022-03": 359.2, "2022-04": 300.98, "2022-05": 252.75, "2022-06": 224.47, "2022-07": 297.28, "2022-08": 275.61, "2022-09": 265.25, "2022-10": 227.54, "2022-11": 194.7, "2022-12": 123.18, "2023-01": 173.22, "2023-02": 205.71, "2023-03": 207.46, "2023-04": 161.83, "2023-05": 203.93, "2023-06": 261.77, "2023-07": 267.43, "2023-08": 258.08, "2023-09": 251.6, "2023-10": 200.84, "2023-11": 240.08, "2023-12": 248.48, "2024-01": 187.29, "2024-02": 201.88, "2024-03": 175.22, "2024-04": 183.28, "2024-05": 178.08, "2024-06": 197.88, "2024-07": 232.07, "2024-08": 210.6, "2024-09": 261.63, "2024-10": 249.85, "2024-11": 357.09, "2024-12": 403.84, "2025-01": 404.6, "2025-02": 292.98, "2025-03": 259.16, "2025-04": 282.16, "2025-05": 342.69, "2025-06": 317.66, "2025-07": 308.27, "2025-08": 329.36, "2025-09": 444.72, "2025-10": 456.56, "2025-11": 430.14, "2025-12": 449.72, "2026-01": 421.81, "2026-02": 403.32, "2026-03": 371.75, "2026-04": 381.63 } }, "TSM": { "stooq": "tsm.us", "moeda": "USD", "mensal": { "2024-06": 172.33, "2024-07": 165.8, "2024-08": 160.49, "2024-09": 173.67, "2024-10": 190.54, "2024-11": 194.4, "2024-12": 197.49, "2025-01": 209.32, "2025-02": 180.53, "2025-03": 166, "2025-04": 166.69, "2025-05": 194.84, "2025-06": 226.49, "2025-07": 241.62, "2025-08": 228.39, "2025-09": 279.29, "2025-10": 300.43, "2025-11": 287.68, "2025-12": 303.89, "2026-01": 341.36, "2026-02": 369.11, "2026-03": 337.95, "2026-04": 396.06 } }, "TWTR": { "stooq": "twtr.us", "moeda": "USD", "mensal": { "2022-03": 38.69, "2022-04": 49.14, "2022-05": 39.6, "2022-06": 37.39, "2022-07": 40.89, "2022-08": 0, "2022-09": 0, "2022-10": 0, "2022-11": 0, "2022-12": 0, "2023-01": 0, "2023-02": 0, "2023-03": 0, "2023-04": 0, "2023-05": 0, "2023-06": 0, "2023-07": 0, "2023-08": 0, "2023-09": 0, "2023-10": 0, "2023-11": 0, "2023-12": 0, "2024-01": 0, "2024-02": 0, "2024-03": 0, "2024-04": 0, "2024-05": 0, "2024-06": 0, "2024-07": 0, "2024-08": 0, "2024-09": 0, "2024-10": 0, "2024-11": 0, "2024-12": 0, "2025-01": 0, "2025-02": 0, "2025-03": 0, "2025-04": 0, "2025-05": 0, "2025-06": 0, "2025-07": 0, "2025-08": 0, "2025-09": 0, "2025-10": 0, "2025-11": 0, "2025-12": 0, "2026-01": 0, "2026-02": 0, "2026-03": 0, "2026-04": 0 } }, "UAL": { "stooq": "ual.us", "moeda": "USD", "mensal": { "2018-12": 83.73, "2019-01": 87.27, "2019-02": 87.81, "2019-03": 80.87, "2019-04": 88.86, "2019-05": 77.65, "2019-06": 88.45, "2019-07": 91.91, "2019-08": 83.15, "2019-09": 88.41, "2019-10": 90.84, "2019-11": 91.63, "2019-12": 88.09, "2020-01": 74.8, "2020-02": 61.26, "2020-03": 31.55, "2020-04": 29.58, "2020-05": 29.46, "2020-06": 34.61, "2020-07": 31.38, "2020-08": 36, "2020-09": 34.75, "2020-10": 33.78, "2020-11": 45.05, "2020-12": 43.25, "2021-01": 39.94, "2021-02": 53.31, "2021-03": 57.54, "2021-04": 54.4, "2021-05": 59.67, "2021-06": 52.29, "2021-07": 46.07, "2021-08": 46.51, "2021-09": 47.57, "2021-10": 48.05, "2021-11": 42.26, "2021-12": 43.78, "2022-01": 42.88, "2022-02": 44.4, "2022-03": 46.36, "2022-04": 50.19, "2022-05": 47.63, "2022-06": 35.42, "2022-07": 37.69, "2022-08": 35.01, "2022-09": 32.53, "2022-10": 43.08, "2022-11": 44.17, "2022-12": 37.7, "2023-01": 48.96, "2023-02": 51.96, "2023-03": 44.25, "2023-04": 44.41, "2023-05": 47.47, "2023-06": 54.87, "2023-07": 54.31, "2023-08": 49.81, "2023-09": 41.62, "2023-10": 35.01, "2023-11": 39.4, "2023-12": 41.26, "2024-01": 41.38, "2024-02": 45.49, "2024-03": 47.35, "2024-04": 51.46, "2024-05": 52.99, "2024-06": 48.66, "2024-07": 45.42, "2024-08": 43.87, "2024-09": 57.06, "2024-10": 78.26, "2024-11": 97.44, "2024-12": 43.95, "2025-01": 105.84, "2025-02": 93.81, "2025-03": 69.05, "2025-04": 68.82, "2025-05": 81.23, "2025-06": 79.63, "2025-07": 88.31, "2025-08": 104.68, "2025-09": 96.5, "2025-10": 94.04, "2025-11": 101.12, "2025-12": 111.82, "2026-01": 107.35, "2026-02": 103.21, "2026-03": 92.07, "2026-04": 90 } }, "USDEUR": { "stooq": "usdeur", "moeda": "EUR", "mensal": { "2019-01": 0.87, "2019-02": 0.88, "2019-03": 0.89, "2019-04": 0.89, "2019-05": 0.89, "2019-06": 0.88, "2019-07": 0.9, "2019-08": 0.91, "2019-09": 0.92, "2019-10": 0.9, "2019-11": 0.91, "2019-12": 0.89, "2020-01": 0.9, "2020-02": 0.91, "2020-03": 0.91, "2020-04": 0.91, "2020-05": 0.9, "2020-06": 0.89, "2020-07": 0.85, "2020-08": 0.84, "2020-09": 0.85, "2020-10": 0.86, "2020-11": 0.84, "2020-12": 0.82, "2021-01": 0.82, "2021-02": 0.83, "2021-03": 0.85, "2021-04": 0.83, "2021-05": 0.82, "2021-06": 0.84, "2021-07": 0.84, "2021-08": 0.85, "2021-09": 0.86, "2021-10": 0.87, "2021-11": 0.88, "2021-12": 0.88, "2022-01": 0.89, "2022-02": 0.89, "2022-03": 0.9, "2022-04": 0.95, "2022-05": 0.93, "2022-06": 0.95, "2022-07": 0.98, "2022-08": 1, "2022-09": 1.02, "2022-10": 1.01, "2022-11": 0.96, "2022-12": 0.93, "2023-01": 0.92, "2023-02": 0.95, "2023-03": 0.92, "2023-04": 0.91, "2023-05": 0.94, "2023-06": 0.92, "2023-07": 0.91, "2023-08": 0.92, "2023-09": 0.94, "2023-10": 0.95, "2023-11": 0.92, "2023-12": 0.9, "2024-01": 0.93, "2024-02": 0.93, "2024-03": 0.93, "2024-04": 0.94, "2024-05": 0.92, "2024-06": 0.93, "2024-07": 0.92, "2024-08": 0.9, "2024-09": 0.9, "2024-10": 0.92, "2024-11": 0.95, "2024-12": 0.97, "2025-01": 0.96, "2025-02": 0.96, "2025-03": 0.92, "2025-04": 0.88, "2025-05": 0.88, "2025-06": 0.85, "2025-07": 0.88, "2025-08": 0.86, "2025-09": 0.85, "2025-10": 0.86, "2025-11": 0.86, "2025-12": 0.85, "2026-01": 0.84, "2026-02": 0.85, "2026-03": 0.86, "2026-04": 0.85 } }, "VUSA": { "stooq": "vusa.de", "moeda": "EUR", "mensal": { "2019-01": 44.75, "2019-02": 46.63, "2019-03": 48.32, "2019-04": 49.67, "2019-05": 47.2, "2019-06": 49.71, "2019-07": 51.41, "2019-08": 50.55, "2019-09": 51.82, "2019-10": 51.55, "2019-11": 53.4, "2019-12": 54.41, "2020-01": 55.51, "2020-02": 51.43, "2020-03": 45.5, "2020-04": 50.49, "2020-05": 52.1, "2020-06": 51.84, "2020-07": 52.1, "2020-08": 55.66, "2020-09": 54.5, "2020-10": 54, "2020-11": 57.23, "2020-12": 57.66, "2021-01": 59.07, "2021-02": 61.42, "2021-03": 64.31, "2021-04": 65.96, "2021-05": 65.19, "2021-06": 68.67, "2021-07": 70.48, "2021-08": 72.91, "2021-09": 71.18, "2021-10": 75.44, "2021-11": 77.22, "2021-12": 79.99, "2022-01": 75.58, "2022-02": 74.06, "2022-03": 78.41, "2022-04": 74.42, "2022-05": 73, "2022-06": 68.54, "2022-07": 76.33, "2022-08": 75.14, "2022-09": 70.83, "2022-10": 74.34, "2022-11": 72.83, "2022-12": 67.72, "2023-01": 70.6, "2023-02": 71.27, "2023-03": 71.19, "2023-04": 70.68, "2023-05": 74.2, "2023-06": 77.11, "2023-07": 78.79, "2023-08": 79.22, "2023-09": 77.47, "2023-10": 74.88, "2023-11": 79.21, "2023-12": 82.04, "2024-01": 85.4, "2024-02": 89.17, "2024-03": 91.45, "2024-04": 90.19, "2024-05": 91.16, "2024-06": 96.89, "2024-07": 95.41, "2024-08": 96.93, "2024-09": 97.52, "2024-10": 100.1, "2024-11": 109.43, "2024-12": 108.03, "2025-01": 111.45, "2025-02": 107.33, "2025-03": 97.32, "2025-04": 92.25, "2025-05": 97.84, "2025-06": 99.78, "2025-07": 105.84, "2025-08": 104.94, "2025-09": 107.45, "2025-10": 112.42, "2025-11": 111.42, "2025-12": 111.06, "2026-01": 112.04, "2026-02": 111.26, "2026-03": 105.86, "2026-04": 115.85 } }, "XAUEUR": { "stooq": "xaueur", "moeda": "EUR", "mensal": { "2019-01": 1154.29, "2019-02": 1154.23, "2019-03": 1152.01, "2019-04": 1144.42, "2019-05": 1168.96, "2019-06": 1240.94, "2019-07": 1276.17, "2019-08": 1386.45, "2019-09": 1351.13, "2019-10": 1356.9, "2019-11": 1328.81, "2019-12": 1353.15, "2020-01": 1430.87, "2020-02": 1428.82, "2020-03": 1427.49, "2020-04": 1539.87, "2020-05": 1559.63, "2020-06": 1585.08, "2020-07": 1675.56, "2020-08": 1648.28, "2020-09": 1608.99, "2020-10": 1612.81, "2020-11": 1489.35, "2020-12": 1554.28, "2021-01": 1518.47, "2021-02": 1431.73, "2021-03": 1455.77, "2021-04": 1470.42, "2021-05": 1559.47, "2021-06": 1492.99, "2021-07": 1529.29, "2021-08": 1535.71, "2021-09": 1517.31, "2021-10": 1542.29, "2021-11": 1565.28, "2021-12": 1608.2, "2022-01": 1599.65, "2022-02": 1701.19, "2022-03": 1750.71, "2022-04": 1797.74, "2022-05": 1711.91, "2022-06": 1723.83, "2022-07": 1722.97, "2022-08": 1702.05, "2022-09": 1695.66, "2022-10": 1652.48, "2022-11": 1699.28, "2022-12": 1703.4, "2023-01": 1774.86, "2023-02": 1727.07, "2023-03": 1817.14, "2023-04": 1805.17, "2023-05": 1836.93, "2023-06": 1759.5, "2023-07": 1787.55, "2023-08": 1789.34, "2023-09": 1748.36, "2023-10": 1875.78, "2023-11": 1870.47, "2023-12": 1868.7, "2024-01": 1885.9, "2024-02": 1892.3, "2024-03": 2070.6, "2024-04": 2142.49, "2024-05": 2145.24, "2024-06": 2170.81, "2024-07": 2260.99, "2024-08": 2264.02, "2024-09": 2366.64, "2024-10": 2521.93, "2024-11": 2504.58, "2024-12": 2535.07, "2025-01": 2700.15, "2025-02": 2752.12, "2025-03": 2886.94, "2025-04": 2902.84, "2025-05": 2901.27, "2025-06": 2803.54, "2025-07": 2881.8, "2025-08": 2951.1, "2025-09": 3288.04, "2025-10": 3469.48, "2025-11": 3665.33, "2025-12": 3676.67, "2026-01": 4089.85, "2026-02": 4454.86, "2026-03": 4039.4, "2026-04": 3940.1 } }, "Z": { "stooq": "z.us", "moeda": "USD", "mensal": { "2018-12": 31.58, "2019-01": 35.09, "2019-02": 41.8, "2019-03": 35.31, "2019-04": 33.4, "2019-05": 43.02, "2019-06": 47.58, "2019-07": 49.96, "2019-08": 32.99, "2019-09": 29.82, "2019-10": 32.57, "2019-11": 39.86, "2019-12": 45.94, "2020-01": 46.21, "2020-02": 54.4, "2020-03": 36.02, "2020-04": 43.96, "2020-05": 58.22, "2020-06": 57.61, "2020-07": 68.39, "2020-08": 85.76, "2020-09": 101.59, "2020-10": 89.16, "2020-11": 107.81, "2020-12": 129.8, "2021-01": 137.05, "2021-02": 167, "2021-03": 129.64, "2021-04": 130.12, "2021-05": 113.56, "2021-06": 122.22, "2021-07": 107.52, "2021-08": 95.77, "2021-09": 88.14, "2021-10": 97.15, "2021-11": 54.27, "2021-12": 63.85, "2022-01": 50.48, "2022-02": 57.52, "2022-03": 49.29, "2022-04": 40.96, "2022-05": 39.9, "2022-06": 31.75, "2022-07": 35.28, "2022-08": 33.46, "2022-09": 28.61, "2022-10": 30.86, "2022-11": 37.98, "2022-12": 32.21, "2023-01": 44.21, "2023-02": 42, "2023-03": 44.47, "2023-04": 43.92, "2023-05": 45.61, "2023-06": 50.26, "2023-07": 54.16, "2023-08": 52.16, "2023-09": 45.64, "2023-10": 36.25, "2023-11": 40.94, "2023-12": 57.86, "2024-01": 56.84, "2024-02": 56.15, "2024-03": 48.22, "2024-04": 42.57, "2024-05": 40.95, "2024-06": 46.39, "2024-07": 48.7, "2024-08": 54.01, "2024-09": 63.85, "2024-10": 60.09, "2024-11": 83.7, "2024-12": 134.29, "2025-01": 82.22, "2025-02": 76.66, "2025-03": 68.56, "2025-04": 67.33, "2025-05": 68.36, "2025-06": 70.05, "2025-07": 79.55, "2025-08": 81.81, "2025-09": 77.05, "2025-10": 74.98, "2025-11": 73.53, "2025-12": 68.22, "2026-01": 62.52, "2026-02": 43.54, "2026-03": 41.38, "2026-04": 44.4 } }, "ZM": { "stooq": "zm.us", "moeda": "USD", "mensal": { "2019-04": 72.47, "2019-05": 79.73, "2019-06": 86.86, "2019-07": 95.51, "2019-08": 92.46, "2019-09": 76.2, "2019-10": 69.89, "2019-11": 68.93, "2019-12": 68.04, "2020-01": 76.3, "2020-02": 113.11, "2020-03": 146.12, "2020-04": 135.17, "2020-05": 204.15, "2020-06": 253.54, "2020-07": 253.91, "2020-08": 325.1, "2020-09": 470.11, "2020-10": 453, "2020-11": 478.36, "2020-12": 337.32, "2021-01": 381.93, "2021-02": 409.66, "2021-03": 321.29, "2021-04": 319.57, "2021-05": 327.72, "2021-06": 387.03, "2021-07": 378.96, "2021-08": 289.5, "2021-09": 261.5, "2021-10": 278.94, "2021-11": 211.41, "2021-12": 183.91, "2022-01": 182.08, "2022-02": 132.6, "2022-03": 117.23, "2022-04": 104.79, "2022-05": 107.45, "2022-06": 107.97, "2022-07": 105.39, "2022-08": 80.4, "2022-09": 73.59, "2022-10": 83.44, "2022-11": 75.43, "2022-12": 67.74, "2023-01": 75, "2023-02": 74.59, "2023-03": 73.84, "2023-04": 61.68, "2023-05": 67.13, "2023-06": 67.88, "2023-07": 73.35, "2023-08": 71.03, "2023-09": 70.11, "2023-10": 59.98, "2023-11": 67.83, "2023-12": 71.91, "2024-01": 64.61, "2024-02": 70.73, "2024-03": 64.73, "2024-04": 61.1, "2024-05": 61.34, "2024-06": 59.19, "2024-07": 60.4, "2024-08": 68.83, "2024-09": 69.74, "2024-10": 74.74, "2024-11": 83.11, "2024-12": 337.33, "2025-01": 86.94, "2025-02": 73.7, "2025-03": 73.77, "2025-04": 77.54, "2025-05": 81.27, "2025-06": 77.98, "2025-07": 74.05, "2025-08": 81.94, "2025-09": 82.5, "2025-10": 87.23, "2025-11": 84.94, "2025-12": 86.29, "2026-01": 92.87, "2026-02": 72.72, "2026-03": 80.39, "2026-04": 97.15 } } } } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/maria/extrato-revolut.csv Tamanho: 1636 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2020-09-17T12:27:15.160488Z,,CASH TOP-UP,,,USD 371.31,USD,1.1805 2020-09-17T13:39:22.948143Z,ANSS,BUY - MARKET,1.19565287,USD 310.55,USD 371.31,USD,1.1802 2020-09-25T07:29:38.401058Z,,CASH TOP-UP,,,USD 219.22,USD,1.1685 2020-09-25T13:30:25.062959Z,AAPL,BUY - MARKET,2.02064706,USD 108.49,USD 219.22,USD,1.1637 2020-09-30T23:46:35.132687Z,,CUSTODY FEE,,,USD -0.01,USD,1.1726 2020-10-01T19:31:42.942068Z,ANSS,SELL - MARKET,1.19565287,USD 334.09,USD 399.44,USD,1.1747 2020-10-01T19:32:55.054485Z,GOOGL,BUY - MARKET,0.26943183,USD 1482.49,USD 399.43,USD,1.1747 2020-10-06T19:06:41.107980Z,,CASH TOP-UP,,,USD 272.23,USD,1.1748 2020-10-06T19:08:42.944338Z,AAPL,BUY - MARKET,2.41595669,USD 112.68,USD 272.23,USD,1.1743 2020-10-21T18:37:36.086402Z,GOOGL,SELL - MARKET,0.26943183,USD 1599.25,USD 429.69,USD,1.1870 2020-10-21T18:38:58.188987Z,ZM,BUY - MARKET,0.8230289,USD 520.65,USD 429.69,USD,1.1870 2020-10-31T23:41:36.606251Z,,CUSTODY FEE,,,USD -0.01,USD,1.1764 2020-11-05T19:44:48.031263Z,AAPL,SELL - MARKET,2.37198781,USD 119.23,USD 282.79,USD,1.1839 2020-11-13T07:13:25.304525Z,AAPL,DIVIDEND,,,USD 0.36,USD,1.1804 2020-12-01T00:24:05.293275Z,,CUSTODY FEE,,,USD -0.01,USD,1.1940 2020-12-03T19:58:58.314837Z,,CASH WITHDRAWAL,,,USD -283.13,USD,1.2145 2020-12-03T20:11:17.516495Z,AAPL,SELL - MARKET,2.06461594,USD 123.06,USD 254.05,USD,1.2148 2020-12-07T08:37:25.768991Z,,CASH WITHDRAWAL,,,USD -254.04,USD,1.2099 2020-12-08T20:45:32.828867Z,ZM,SELL - MARKET,0.8230289,USD 410.74,USD 338.03,USD,1.2105 2020-12-10T08:04:34.598480Z,,CASH WITHDRAWAL,,,USD -338.04,USD,1.2091 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/maria/lucro-mensal.json Tamanho: 38309 bytes ======================================================================================== { "ok": true, "user": "maria", "moeda": "EUR", "compatibilidade": true, "totalmeses": 64, "investimentoinicial": 11.2, "series": [ { "mes": "2020-09", "ganhos": 0, "dividendos": 0, "taxas": 0.01, "net": -0.01, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 502.14, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 502.14, "precofonte": "stooq" }, { "mes": "2020-10", "ganhos": 47.39, "dividendos": 0, "taxas": 0.01, "net": 47.38, "deltarealizado": 47.39, "deltanaorealizado": 0, "realizadoacumulado": 47.39, "naorealizadofimmes": 0, "fimmesusado": "2020-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 733.87, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 733.87, "precofonte": "stooq" }, { "mes": "2020-11", "ganhos": 7.04, "dividendos": 0.3, "taxas": 0, "net": 7.34, "deltarealizado": 7.04, "deltanaorealizado": 0, "realizadoacumulado": 54.43, "naorealizadofimmes": 0, "fimmesusado": "2020-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 733.87, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 733.87, "precofonte": "stooq" }, { "mes": "2020-12", "ganhos": -62, "dividendos": 0, "taxas": 0.01, "net": -62.01, "deltarealizado": -62, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2020-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-02-29", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 16:23:59", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/maria/movimentos-caixa.csv Tamanho: 612 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2020-09-17,Depósito,371.31,USD,"CASH TOP-UP",1.1805 2,2020-09-25,Depósito,219.22,USD,"CASH TOP-UP",1.1685 3,2020-09-30,Outros,-0.01,USD,"CUSTODY FEE",1.1726 4,2020-10-06,Depósito,272.23,USD,"CASH TOP-UP",1.1748 5,2020-10-31,Outros,-0.01,USD,"CUSTODY FEE",1.1764 6,2020-11-13,Dividendo,0.36,USD,"AAPL DIVIDEND",1.1804 7,2020-12-01,Outros,-0.01,USD,"CUSTODY FEE",1.1940 8,2020-12-03,Levantamento,-283.13,USD,"CASH WITHDRAWAL",1.2145 9,2020-12-07,Levantamento,-254.04,USD,"CASH WITHDRAWAL",1.2099 10,2020-12-10,Levantamento,-338.04,USD,"CASH WITHDRAWAL",1.2091 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/maria/transacoes-acoes.csv Tamanho: 589 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2020-09-17","2020-10-01","ANSS","1.195653","0.00","371.31","399.44","1.1802","1.1747","USD" "2","2020-09-25","2020-12-03","AAPL","2.020647","0.00","219.22","254.05","1.1637","1.2148","USD" "3","2020-10-01","2020-10-21","GOOGL","0.269432","0.00","399.43","429.69","1.1747","1.1870","USD" "4","2020-10-06","2020-11-05","AAPL","2.415957","0.00","272.23","282.79","1.1743","1.1839","USD" "5","2020-10-21","2020-12-08","ZM","0.823029","0.00","429.69","338.03","1.1870","1.2105","USD" ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/movimentos-caixa.csv Tamanho: 17894 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2019-10-13,Depósito,10.00,USD,CASH TOP-UP,1.1090 2,2020-01-22,Depósito,150.00,USD,CASH TOP-UP,1.1087 3,2020-01-27,Depósito,100.00,USD,CASH TOP-UP,1.1016 4,2020-01-27,Depósito,100.00,USD,CASH TOP-UP,1.1017 5,2020-02-04,Depósito,100.00,USD,CASH TOP-UP,1.1043 6,2020-02-06,Depósito,100.00,USD,CASH TOP-UP,1.0977 7,2020-02-12,Levantamento,-12.00,USD,CASH WITHDRAWAL,1.0883 8,2020-02-14,Dividendo,0.73,USD,AAPL DIVIDEND,1.0841 9,2020-02-14,Depósito,23.44,USD,CASH TOP-UP,1.0844 10,2020-02-19,Depósito,100.00,USD,CASH TOP-UP,1.0786 11,2020-02-19,Depósito,100.00,USD,CASH TOP-UP,1.0786 12,2020-02-25,Depósito,100.00,USD,CASH TOP-UP,1.0852 13,2020-02-27,Depósito,100.00,USD,CASH TOP-UP,1.0989 14,2020-02-29,Outros,-0.01,USD,CUSTODY FEE,1.1085 15,2020-03-10,Depósito,100.00,USD,CASH TOP-UP,1.1392 16,2020-03-10,Depósito,100.00,USD,CASH TOP-UP,1.1385 17,2020-03-25,Depósito,100.00,USD,CASH TOP-UP,1.0870 18,2020-03-31,Outros,-0.01,USD,CUSTODY FEE,1.1030 19,2020-04-16,Depósito,150.00,USD,CASH TOP-UP,1.0846 20,2020-04-23,Depósito,65.00,USD,CASH TOP-UP,1.0835 21,2020-04-27,Depósito,150.00,USD,CASH TOP-UP,1.0849 22,2020-04-29,Depósito,60.00,USD,CASH TOP-UP,1.0862 23,2020-04-30,Outros,-0.01,USD,CUSTODY FEE,1.0945 24,2020-05-01,Depósito,70.00,USD,CASH TOP-UP,1.1000 25,2020-05-11,Dividendo,0.20,USD,MA DIVIDEND,1.0849 26,2020-05-15,Dividendo,0.78,USD,AAPL DIVIDEND,1.0803 27,2020-05-15,Depósito,200.00,USD,CASH TOP-UP,1.0834 28,2020-05-21,Depósito,200.00,USD,CASH TOP-UP,1.0991 29,2020-05-27,Depósito,101.00,USD,CASH TOP-UP,1.0978 30,2020-05-31,Outros,-0.02,USD,CUSTODY FEE,1.1117 31,2020-06-01,Depósito,100.00,USD,CASH TOP-UP,1.1111 32,2020-06-03,Depósito,96.40,USD,CASH TOP-UP,1.1233 33,2020-06-04,Depósito,105.53,USD,CASH TOP-UP,1.1334 34,2020-06-04,Depósito,200.00,USD,CASH TOP-UP,1.1330 35,2020-06-05,Depósito,113.81,USD,CASH TOP-UP,1.1302 36,2020-06-08,Depósito,102.63,USD,CASH TOP-UP,1.1304 37,2020-06-09,Depósito,100.00,USD,CASH TOP-UP,1.1277 38,2020-06-15,Depósito,150.00,USD,CASH TOP-UP,1.1250 39,2020-06-16,Depósito,97.58,USD,CASH TOP-UP,1.1262 40,2020-06-18,Depósito,192.53,USD,CASH TOP-UP,1.1217 41,2020-06-26,Dividendo,1.37,USD,QCOM DIVIDEND,1.1215 42,2020-06-29,Dividendo,0.04,USD,NVDA DIVIDEND,1.1243 43,2020-06-30,Outros,-0.03,USD,CUSTODY FEE,1.1237 44,2020-07-17,Levantamento,-16.00,USD,CASH WITHDRAWAL,1.1414 45,2020-07-25,Depósito,150.00,USD,CASH TOP-UP,1.1714 46,2020-07-31,Outros,-0.03,USD,CUSTODY FEE,1.1837 47,2020-08-04,Levantamento,-16.50,USD,CASH WITHDRAWAL,1.1799 48,2020-08-06,Depósito,300.00,USD,CASH TOP-UP,1.1850 49,2020-08-10,Dividendo,0.20,USD,MA DIVIDEND,1.1794 50,2020-08-14,Dividendo,0.15,USD,AAPL DIVIDEND,1.1819 51,2020-08-31,Levantamento,-16.66,USD,CASH WITHDRAWAL,1.1915 52,2020-08-31,Outros,-0.02,USD,CUSTODY FEE,1.1940 53,2020-09-02,Depósito,200.00,USD,CASH TOP-UP,1.1844 54,2020-09-04,Levantamento,-200.00,USD,CASH WITHDRAWAL,1.1841 55,2020-09-04,Depósito,250.00,USD,CASH TOP-UP,1.1845 56,2020-09-04,Levantamento,-250.00,USD,CASH WITHDRAWAL,1.1846 57,2020-09-10,Depósito,250.00,USD,CASH TOP-UP,1.1832 58,2020-09-10,Levantamento,-250.00,USD,CASH WITHDRAWAL,1.1832 59,2020-09-11,Dividendo,0.32,USD,MSFT DIVIDEND,1.1840 60,2020-09-17,Levantamento,-370.20,USD,CASH WITHDRAWAL,1.1805 61,2020-09-24,Levantamento,-329.15,USD,CASH WITHDRAWAL,1.1653 62,2020-09-25,Dividendo,0.03,USD,NVDA DIVIDEND,1.1674 63,2020-09-25,Levantamento,-219.22,USD,CASH WITHDRAWAL,1.1668 64,2020-09-30,Outros,-0.03,USD,CUSTODY FEE,1.1730 65,2020-10-01,Levantamento,-16.40,USD,CASH WITHDRAWAL,1.1728 66,2020-10-02,Levantamento,-399.48,USD,CASH WITHDRAWAL,1.1719 67,2020-10-06,Levantamento,-272.23,USD,CASH WITHDRAWAL,1.1754 68,2020-10-15,Levantamento,-400.00,USD,CASH WITHDRAWAL,1.1708 69,2020-10-22,Levantamento,-680.00,USD,CASH WITHDRAWAL,1.1842 70,2020-10-22,Levantamento,-461.19,USD,CASH WITHDRAWAL,1.1819 71,2020-10-30,Depósito,230.00,USD,CASH TOP-UP,1.1655 72,2020-10-30,Levantamento,-230.00,USD,CASH WITHDRAWAL,1.1650 73,2020-11-01,Outros,-0.01,USD,CUSTODY FEE,1.1764 74,2020-11-02,Depósito,0.01,USD,CASH TOP-UP,1.1643 75,2020-11-17,Levantamento,-731.22,USD,CASH WITHDRAWAL,1.1861 76,2020-11-26,Depósito,64.15,USD,CASH TOP-UP,1.1908 77,2020-11-30,Depósito,600.00,USD,CASH TOP-UP,1.1997 78,2020-11-30,Levantamento,-664.15,USD,CASH WITHDRAWAL,1.1995 79,2020-11-30,Outros,-0.01,USD,CUSTODY FEE,1.1938 80,2020-12-01,Depósito,0.01,USD,CASH TOP-UP,1.2075 81,2020-12-03,Depósito,283.13,USD,CASH TOP-UP,1.2146 82,2020-12-07,Depósito,245.04,USD,CASH TOP-UP,1.2091 83,2020-12-07,Levantamento,-1417.49,USD,CASH WITHDRAWAL,1.2098 84,2020-12-08,Depósito,600.00,USD,CASH TOP-UP,1.2104 85,2020-12-10,Depósito,1045.98,USD,CASH TOP-UP,1.2095 86,2020-12-14,Depósito,873.84,USD,CASH TOP-UP,1.2148 87,2020-12-17,Depósito,1011.96,USD,CASH TOP-UP,1.2241 88,2020-12-21,Depósito,934.75,USD,CASH TOP-UP,1.2192 89,2020-12-23,Depósito,440.80,USD,CASH TOP-UP,1.2179 90,2020-12-23,Depósito,1218.96,USD,CASH TOP-UP,1.2194 91,2020-12-24,Depósito,14.23,USD,CASH TOP-UP,1.2184 92,2020-12-31,Depósito,500.00,USD,CASH TOP-UP,1.2276 93,2020-12-31,Levantamento,-64.98,USD,CASH WITHDRAWAL,1.2273 94,2021-01-01,Outros,-0.04,USD,CUSTODY FEE,1.2219 95,2021-01-08,Depósito,549.96,USD,CASH TOP-UP,1.2246 96,2021-01-08,Levantamento,-71.85,USD,CASH WITHDRAWAL,1.2234 97,2021-01-13,Depósito,576.16,USD,CASH TOP-UP,1.2198 98,2021-01-27,Depósito,136.83,USD,CASH TOP-UP,1.2080 99,2021-01-27,Depósito,470.71,USD,CASH TOP-UP,1.2077 100,2021-01-28,Depósito,1373.27,USD,CASH TOP-UP,1.2089 101,2021-02-01,Outros,-0.09,USD,CUSTODY FEE,1.2133 102,2021-02-01,Depósito,196.46,USD,CASH TOP-UP,1.2067 103,2021-02-04,Levantamento,-32.26,USD,CASH WITHDRAWAL,1.1962 104,2021-02-09,Levantamento,-500.00,USD,CASH WITHDRAWAL,1.2121 105,2021-02-12,Dividendo,3.31,USD,AAPL DIVIDEND,1.2126 106,2021-02-19,Levantamento,-41.90,USD,CASH WITHDRAWAL,1.2129 107,2021-03-01,Outros,-0.08,USD,CUSTODY FEE,1.2090 108,2021-03-02,Depósito,0.08,USD,CASH TOP-UP,1.2091 109,2021-03-12,Depósito,178.93,USD,CASH TOP-UP,1.1937 110,2021-04-01,Outros,-0.97,USD,CUSTODY FEE,1.1737 111,2021-05-01,Outros,-1.07,USD,CUSTODY FEE,1.2142 112,2021-05-14,Dividendo,3.55,USD,AAPL DIVIDEND,1.2089 113,2021-05-24,Depósito,50.00,USD,CASH TOP-UP,1.2213 114,2021-05-27,Depósito,50.00,USD,CASH TOP-UP,1.2193 115,2021-05-27,Depósito,10.00,USD,CASH TOP-UP,1.2195 116,2021-06-01,Outros,-1.03,USD,CUSTODY FEE,1.2229 117,2021-07-01,Outros,-1.02,USD,CUSTODY FEE,1.1855 118,2021-07-14,Levantamento,-63.73,USD,CASH WITHDRAWAL,1.1839 119,2021-07-27,Levantamento,-250.00,USD,CASH WITHDRAWAL,1.1793 120,2021-08-01,Outros,-1.12,USD,CUSTODY FEE,1.1999 121,2021-08-13,Dividendo,2.62,USD,AAPL DIVIDEND,1.1742 122,2021-09-01,Outros,-1.15,USD,CUSTODY FEE,1.1800 123,2021-10-01,Outros,-1.11,USD,CUSTODY FEE,1.1580 124,2021-10-01,Levantamento,-50.00,USD,CASH WITHDRAWAL,1.1582 125,2021-10-25,Levantamento,-78.27,USD,CASH WITHDRAWAL,1.1616 126,2021-10-29,Levantamento,-50.00,USD,CASH WITHDRAWAL,1.1652 127,2021-11-01,Levantamento,-100.00,USD,CASH WITHDRAWAL,1.1609 128,2021-11-04,Levantamento,-2000.00,USD,CASH WITHDRAWAL,1.1613 129,2021-11-04,Outros,-1.07,USD,CUSTODY FEE,1.1603 130,2021-11-04,Depósito,2000.00,USD,CASH TOP-UP,1.1586 131,2021-11-17,Dividendo,6.17,USD,AAPL DIVIDEND,1.1305 132,2021-11-19,Levantamento,-150.00,USD,CASH WITHDRAWAL,1.1292 133,2021-11-22,Levantamento,-153.20,USD,CASH WITHDRAWAL,1.1287 134,2021-12-02,Outros,-1.07,USD,CUSTODY FEE,1.1325 135,2021-12-02,Levantamento,-300.00,USD,CASH WITHDRAWAL,1.1325 136,2021-12-02,Depósito,100.00,USD,CASH TOP-UP,1.1324 137,2021-12-06,Depósito,50.00,USD,CASH TOP-UP,1.1293 138,2021-12-10,Levantamento,-26.65,USD,CASH WITHDRAWAL,1.1319 139,2021-12-14,Levantamento,-150.00,USD,CASH WITHDRAWAL,1.1279 140,2021-12-17,Dividendo,3.57,USD,KO DIVIDEND,1.1323 141,2021-12-21,Depósito,550.00,USD,CASH TOP-UP,1.1288 142,2021-12-25,Depósito,100.00,USD,CASH TOP-UP,1.1315 143,2022-01-04,Dividendo,1.78,USD,BAC DIVIDEND,1.1307 144,2022-01-04,Outros,-1.16,USD,CUSTODY FEE,1.1303 145,2022-02-02,Outros,-1.22,USD,CUSTODY FEE,1.1324 146,2022-02-15,Dividendo,6.17,USD,AAPL DIVIDEND,1.1320 147,2022-02-28,Depósito,250.00,USD,CASH TOP-UP,1.1198 148,2022-03-02,Outros,-1.16,USD,CUSTODY FEE,1.1104 149,2022-03-16,Dividendo,0.42,USD,O DIVIDEND,1.0978 150,2022-03-25,Levantamento,-257.83,USD,CASH WITHDRAWAL,1.1004 151,2022-03-28,Dividendo,1.78,USD,BAC DIVIDEND,1.0955 152,2022-04-02,Outros,-1.24,USD,CUSTODY FEE,1.1051 153,2022-04-04,Dividendo,0.75,USD,KO DIVIDEND,1.1051 154,2022-04-14,Depósito,200.00,USD,CASH TOP-UP,1.0905 155,2022-04-19,Dividendo,0.42,USD,O DIVIDEND,1.0772 156,2022-05-03,Outros,-1.11,USD,CUSTODY FEE,1.0519 157,2022-05-16,Dividendo,0.42,USD,O DIVIDEND,1.0410 158,2022-05-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0407 159,2022-05-20,Depósito,150.00,USD,CASH TOP-UP,1.0562 160,2022-06-02,Outros,-1.05,USD,CUSTODY FEE,1.0657 161,2022-06-07,Depósito,10.00,USD,CASH TOP-UP,1.0702 162,2022-06-10,Dividendo,0.33,USD,MSFT DIVIDEND,1.0635 163,2022-06-16,Dividendo,0.42,USD,O DIVIDEND,1.0441 164,2022-06-27,Dividendo,1.78,USD,BAC DIVIDEND,1.0571 165,2022-07-02,Outros,-0.96,USD,CUSTODY FEE,1.0432 166,2022-07-05,Dividendo,0.75,USD,KO DIVIDEND,1.0442 167,2022-07-18,Dividendo,0.42,USD,O DIVIDEND,1.0105 168,2022-07-29,Depósito,150.00,USD,CASH TOP-UP,1.0209 169,2022-08-02,Outros,-1.13,USD,CUSTODY FEE,1.0210 170,2022-08-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0171 171,2022-08-16,Dividendo,0.42,USD,O DIVIDEND,1.0165 172,2022-09-03,Outros,-1.08,USD,CUSTODY FEE,0.9961 173,2022-09-12,Dividendo,0.33,USD,MSFT DIVIDEND,1.0096 174,2022-09-16,Dividendo,0.42,USD,O DIVIDEND,0.9995 175,2022-10-03,Dividendo,1.87,USD,BAC DIVIDEND,0.9807 176,2022-10-04,Outros,-1.00,USD,CUSTODY FEE,0.9841 177,2022-10-04,Dividendo,0.75,USD,KO DIVIDEND,0.9861 178,2022-10-17,Dividendo,0.42,USD,O DIVIDEND,0.9748 179,2022-11-02,Outros,-1.00,USD,CUSTODY FEE,0.9906 180,2022-11-11,Dividendo,7.04,USD,AAPL DIVIDEND,1.0271 181,2022-11-16,Dividendo,0.42,USD,O DIVIDEND,1.0383 182,2022-12-02,Outros,-0.97,USD,CUSTODY FEE,1.0532 183,2022-12-09,Dividendo,0.36,USD,MSFT DIVIDEND,1.0582 184,2022-12-16,Dividendo,0.75,USD,KO DIVIDEND,1.0667 185,2022-12-16,Dividendo,0.42,USD,O DIVIDEND,1.0662 186,2023-01-03,Dividendo,1.87,USD,BAC DIVIDEND,1.0672 187,2023-01-04,Outros,-0.84,USD,CUSTODY FEE,1.0625 188,2023-01-17,Dividendo,0.35,USD,O DIVIDEND,1.0831 189,2023-02-01,Outros,-0.95,USD,CUSTODY FEE,1.0871 190,2023-02-16,Dividendo,0.35,USD,O DIVIDEND,1.0707 191,2023-02-17,Dividendo,6.12,USD,AAPL DIVIDEND,1.0641 192,2023-03-01,Depósito,250.00,USD,CASH TOP-UP,1.0669 193,2023-03-02,Outros,-1.00,USD,CUSTODY FEE,1.0636 194,2023-03-13,Dividendo,0.29,USD,MSFT DIVIDEND,1.0731 195,2023-03-16,Dividendo,0.36,USD,O DIVIDEND,1.0618 196,2023-04-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0809 197,2023-04-04,Dividendo,0.64,USD,KO DIVIDEND,1.0919 198,2023-04-04,Outros,-1.08,USD,CUSTODY FEE,1.0941 199,2023-04-17,Dividendo,0.36,USD,O DIVIDEND,1.1000 200,2023-05-02,Outros,-1.07,USD,CUSTODY FEE,1.1010 201,2023-05-08,Depósito,150.00,USD,CASH TOP-UP,1.1037 202,2023-05-16,Dividendo,0.36,USD,O DIVIDEND,1.0890 203,2023-05-19,Dividendo,5.71,USD,AAPL DIVIDEND,1.0800 204,2023-06-02,Outros,-1.13,USD,CUSTODY FEE,1.0788 205,2023-06-05,Depósito,100.00,USD,CASH TOP-UP,1.0703 206,2023-06-06,Levantamento,-200.00,USD,CASH WITHDRAWAL,1.0725 207,2023-06-09,Dividendo,0.29,USD,MSFT DIVIDEND,1.0787 208,2023-06-16,Dividendo,0.36,USD,O DIVIDEND,1.0954 209,2023-07-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0929 210,2023-07-04,Outros,-1.19,USD,CUSTODY FEE,1.0914 211,2023-07-05,Dividendo,0.64,USD,KO DIVIDEND,1.0888 212,2023-07-17,Dividendo,0.36,USD,O DIVIDEND,1.1239 213,2023-08-02,Outros,-1.31,USD,CUSTODY FEE,1.0994 214,2023-08-16,Dividendo,0.36,USD,O DIVIDEND,1.0928 215,2023-08-18,Dividendo,4.03,USD,AAPL DIVIDEND,1.0901 216,2023-09-02,Outros,-1.27,USD,CUSTODY FEE,1.0790 217,2023-09-09,Outros,117.44,USD,TRANSFER FROM REVOLUT BANK UAB TO REVOLUT SECURITIES EUROPE UAB,1.0719 218,2023-09-13,Depósito,11.76,USD,CASH TOP-UP,1.0756 219,2023-09-13,Depósito,400.00,USD,CASH TOP-UP,1.0757 220,2023-09-18,Dividendo,0.36,USD,O DIVIDEND,1.0686 221,2023-10-01,Outros,-1.25,USD,CUSTODY FEE,1.0595 222,2023-10-02,Dividendo,1.68,USD,BAC DIVIDEND,1.0550 223,2023-10-03,Dividendo,0.78,USD,KO DIVIDEND,1.0488 224,2023-10-16,Dividendo,0.43,USD,O DIVIDEND,1.0557 225,2023-11-02,Outros,-1.17,USD,CUSTODY FEE,1.0617 226,2023-11-16,Dividendo,0.43,USD,O DIVIDEND,1.0863 227,2023-11-17,Dividendo,5.51,USD,AAPL DIVIDEND,1.0913 228,2023-12-01,Outros,-1.19,USD,CUSTODY FEE,1.0922 229,2023-12-14,Levantamento,-490.00,USD,CASH WITHDRAWAL,1.0942 230,2023-12-14,Levantamento,-540.00,USD,CASH WITHDRAWAL,1.0945 231,2023-12-14,Depósito,493.36,EUR,CASH TOP-UP,1.0000 232,2023-12-14,Depósito,22.55,EUR,CASH TOP-UP,1.0000 233,2023-12-14,Levantamento,-22.55,EUR,CASH WITHDRAWAL,1.0000 234,2023-12-18,Dividendo,0.43,USD,O DIVIDEND,1.0945 235,2023-12-18,Dividendo,0.78,USD,KO DIVIDEND,1.0937 236,2024-01-01,Outros,-1.18,USD,CUSTODY FEE,1.1060 237,2024-01-01,Outros,-0.05,EUR,CUSTODY FEE,1.0000 238,2024-01-03,Dividendo,2.04,USD,BAC DIVIDEND,1.0927 239,2024-01-16,Dividendo,0.43,USD,O DIVIDEND,1.0909 240,2024-01-29,Levantamento,-288.99,USD,CASH WITHDRAWAL,1.0829 241,2024-02-01,Outros,-1.10,USD,CUSTODY FEE,1.0837 242,2024-02-01,Outros,-0.05,EUR,CUSTODY FEE,1.0000 243,2024-02-13,Levantamento,-755.30,USD,CASH WITHDRAWAL,1.0737 244,2024-02-16,Dividendo,0.43,USD,O DIVIDEND,1.0796 245,2024-02-16,Dividendo,5.30,USD,AAPL DIVIDEND,1.0789 246,2024-03-11,Depósito,1091.80,USD,CASH TOP-UP,1.0964 247,2024-03-11,Depósito,126.74,USD,CASH TOP-UP,1.0941 248,2024-03-15,Dividendo,0.64,USD,MSFT DIVIDEND,1.0914 249,2024-03-18,Dividendo,0.43,USD,O DIVIDEND,1.0912 250,2024-03-28,Dividendo,0.17,USD,NVDA DIVIDEND,1.0831 251,2024-04-02,Dividendo,0.82,USD,KO DIVIDEND,1.0788 252,2024-04-02,Dividendo,2.04,USD,BAC DIVIDEND,1.0789 253,2024-04-16,Dividendo,0.43,USD,O DIVIDEND,1.0668 254,2024-04-22,Levantamento,-720.00,USD,CASH WITHDRAWAL,1.0653 255,2024-04-22,Depósito,675.75,EUR,CASH TOP-UP,1.0000 256,2024-04-30,Levantamento,-398.79,USD,CASH WITHDRAWAL,1.0728 257,2024-05-16,Dividendo,0.43,USD,O DIVIDEND,1.0895 258,2024-05-17,Dividendo,6.16,USD,AAPL DIVIDEND,1.0867 259,2024-06-14,Dividendo,0.64,USD,MSFT DIVIDEND,1.0709 260,2024-06-17,Dividendo,0.44,USD,O DIVIDEND,1.0728 261,2024-07-01,Dividendo,0.42,USD,NVDA DIVIDEND,1.0772 262,2024-07-01,Dividendo,2.04,USD,BAC DIVIDEND,1.0768 263,2024-07-16,Dividendo,0.44,USD,O DIVIDEND,1.0923 264,2024-07-23,Depósito,800.00,EUR,CASH TOP-UP,1.0000 265,2024-08-01,Depósito,1077.48,USD,CASH TOP-UP,1.0809 266,2024-08-16,Dividendo,6.59,USD,AAPL DIVIDEND,1.1011 267,2024-10-04,Dividendo,0.42,USD,NVDA DIVIDEND,1.1053 268,2024-10-10,Dividendo,4.93,USD,TSM DIVIDEND,1.0958 269,2024-11-06,Depósito,34.98,USD,CASH TOP-UP,1.0750 270,2024-11-06,Levantamento,-34.98,USD,CASH WITHDRAWAL,1.0748 271,2024-11-15,Dividendo,9.99,USD,AAPL DIVIDEND,1.0596 272,2024-11-25,Depósito,1004.00,USD,CASH TOP-UP,1.0525 273,2024-11-29,Levantamento,-2000.00,USD,CASH WITHDRAWAL,1.0574 274,2024-12-18,Dividendo,0.51,EUR,EXXT DIVIDEND,1.0000 275,2024-12-18,Depósito,2006.76,USD,CASH TOP-UP,1.0513 276,2024-12-18,Levantamento,-2240.70,USD,CASH WITHDRAWAL,1.0514 277,2024-12-18,Depósito,2133.85,EUR,CASH TOP-UP,1.0000 278,2024-12-19,Depósito,0.02,USD,CASH TOP-UP,1.0415 279,2024-12-30,Dividendo,0.41,USD,NVDA DIVIDEND,1.0464 280,2025-01-07,Levantamento,-3000.00,USD,CASH WITHDRAWAL,1.0449 281,2025-01-07,Depósito,3001.30,USD,CASH TOP-UP,1.0396 282,2025-01-28,Depósito,245.00,USD,CASH TOP-UP,1.0451 283,2025-02-14,Dividendo,8.08,USD,AAPL DIVIDEND,1.0521 284,2025-03-19,Dividendo,1.67,EUR,EXXT DIVIDEND,1.0000 285,2025-04-03,Dividendo,0.43,USD,NVDA DIVIDEND,1.1083 286,2025-05-16,Dividendo,8.40,USD,AAPL DIVIDEND,1.1172 287,2025-05-29,Levantamento,-2818.20,USD,CASH WITHDRAWAL,1.1398 288,2025-06-18,Dividendo,3.70,EUR,EXXT DIVIDEND,1.0000 289,2025-07-02,Depósito,2000.00,USD,CASH TOP-UP,1.1797 290,2025-07-10,Dividendo,0.26,USD,NVDA DIVIDEND,1.1761 291,2025-08-14,Dividendo,7.74,USD,AAPL DIVIDEND,1.1674 292,2025-08-20,Levantamento,-764.31,USD,CASH WITHDRAWAL,1.1692 293,2025-10-02,Dividendo,0.37,USD,NVDA DIVIDEND,1.1750 294,2025-10-16,Depósito,1502.57,USD,CASH TOP-UP,1.1685 295,2025-11-11,Depósito,500.00,USD,CASH TOP-UP,1.1619 296,2025-11-11,Levantamento,-175.00,USD,CASH WITHDRAWAL,1.1618 297,2025-11-13,Dividendo,7.74,USD,AAPL DIVIDEND,1.16584 270,2024-10-10,Dividendo,4.93,USD,TSM DIVIDEND,1.0958 271,2024-11-06,Depósito,34.98,USD,CASH TOP-UP,1.0750 272,2024-11-06,Levantamento,-34.98,USD,CASH WITHDRAWAL,1.0748 273,2024-11-15,Dividendo,9.99,USD,AAPL DIVIDEND,1.0596 274,2024-11-25,Depósito,1004.00,USD,CASH TOP-UP,1.0525 275,2024-11-29,Levantamento,-2000.00,USD,CASH WITHDRAWAL,1.0574 276,2024-12-18,Depósito,2006.76,USD,CASH TOP-UP,1.0513 277,2024-12-18,Levantamento,-2240.70,USD,CASH WITHDRAWAL,1.0514 278,2024-12-19,Depósito,0.02,USD,CASH TOP-UP,1.0415 279,2024-12-30,Dividendo,0.41,USD,NVDA DIVIDEND,1.0464 280,2025-01-07,Levantamento,-3000.00,USD,CASH WITHDRAWAL,1.0449 281,2025-01-07,Depósito,3001.30,USD,CASH TOP-UP,1.0396 282,2025-01-28,Depósito,245.00,USD,CASH TOP-UP,1.0451 283,2025-02-14,Dividendo,8.08,USD,AAPL DIVIDEND,1.0521 284,2025-04-03,Dividendo,0.43,USD,NVDA DIVIDEND,1.1083 285,2025-05-16,Dividendo,8.40,USD,AAPL DIVIDEND,1.1172 286,2025-05-29,Levantamento,-2818.20,USD,CASH WITHDRAWAL,1.1398 287,2025-07-02,Depósito,2000.00,USD,CASH TOP-UP,1.1797 288,2025-07-10,Dividendo,0.26,USD,NVDA DIVIDEND,1.1761 289,2025-08-14,Dividendo,7.74,USD,AAPL DIVIDEND,1.1674 290,2025-08-20,Levantamento,-764.31,USD,CASH WITHDRAWAL,1.1692 291,2025-10-02,Dividendo,0.37,USD,NVDA DIVIDEND,1.1750 292,2025-10-16,Depósito,1502.57,USD,CASH TOP-UP,1.1685 293,2025-11-11,Depósito,500.00,USD,CASH TOP-UP,1.1619 294,2025-11-11,Levantamento,-175.00,USD,CASH WITHDRAWAL,1.1618 295,2025-11-13,Dividendo,7.74,USD,AAPL DIVIDEND,1.1658 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/precos-atuais.json Tamanho: 2088 bytes ======================================================================================== { "precos": { "AAPL": { "preco": 312.51, "moeda": "USD", "timestamp": "2026-05-28 21:35:26", "fonte": "stooq:aapl.us", "prevclose": 310.68, "close": 310.68, "pctdia": 0.589 }, "NVDA": { "preco": 214.26, "moeda": "USD", "timestamp": "2026-05-28 21:35:26", "fonte": "stooq:nvda.us", "prevclose": 211.31, "close": 211.31, "pctdia": 1.3961 }, "GOOGL": { "preco": 390.19, "moeda": "USD", "timestamp": "2026-05-28 21:35:26", "fonte": "stooq:googl.us", "prevclose": 388, "close": 388, "pctdia": 0.5644 }, "VUSA": { "preco": 122.465, "moeda": "EUR", "timestamp": "2026-05-28 21:35:26", "fonte": "stooq:vusa.de", "prevclose": 122.615, "close": 122.615, "pctdia": -0.1223 }, "IWDA": { "preco": 122.815, "moeda": "EUR", "timestamp": "2026-05-28 21:35:26", "fonte": "stooq:eunl.de", "prevclose": 123.055, "close": 123.055, "pctdia": -0.195 }, "NDXEX": { "preco": 249.7, "moeda": "EUR", "timestamp": "2026-05-28 21:35:26", "fonte": "stooq:exxt.de", "prevclose": 250.75, "close": 250.75, "pctdia": -0.4187 }, "XAUEUR": { "preco": 3858.52, "moeda": "EUR", "timestamp": "2026-05-28 21:35:26", "fonte": "stooq:xaueur", "prevclose": 3837.78, "close": 3837.78, "pctdia": 0.5404 } }, "cambio": { "EURUSD": 1.16, "USDEUR": 0.8621, "fonte": "calculos.php?acao=cambio_atual", "timestamp": "2026-05-28 21:35:26" }, "ultima_atualizacao": "2026-05-28 21:35:26" } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/prevclose-cache.json Tamanho: 3242 bytes ======================================================================================== { "2025-12-13": { "eodhd:EUNL.XETRA": { "prevclose": 110.98, "moeda": null, "fonte": "eodhd", "cached_at": "2025-12-13 00:02:27" }, "twelveAAPL": { "prevclose": 278.029999, "moeda": "USD", "fonte": "twelvedata", "cached_at": "2025-12-13 00:02:27" }, "eodhd:EXXT.XETRA": { "prevclose": 214, "moeda": null, "fonte": "eodhd", "cached_at": "2025-12-13 00:02:28" }, "twelveNVDA": { "prevclose": 180.92999, "moeda": "USD", "fonte": "twelvedata", "cached_at": "2025-12-13 00:02:28" }, "twelveGOOGL": { "prevclose": 312.42999, "moeda": "USD", "fonte": "twelvedata", "cached_at": "2025-12-13 00:02:28" }, "eodhd:VUSA.AS": { "prevclose": 110.916, "moeda": null, "fonte": "eodhd", "cached_at": "2025-12-13 00:02:29" }, "IWDA": { "prev_close": 110.98, "fonte": "stooq:eunl.de", "moeda": null, "cached_at": "2025-12-13 23:15:52" }, "AAPL": { "prev_close": 278.029999, "fonte": "twelveAAPL", "moeda": "USD", "cached_at": "2025-12-13 23:15:52" }, "NDXEX": { "prev_close": 210.9, "fonte": "stooq:exxt.de", "moeda": null, "cached_at": "2025-12-13 23:15:53" }, "NVDA": { "prev_close": 180.92999, "fonte": "twelveNVDA", "moeda": "USD", "cached_at": "2025-12-13 23:15:53" }, "GOOGL": { "prev_close": 312.42999, "fonte": "twelveGOOGL", "moeda": "USD", "cached_at": "2025-12-13 23:15:53" }, "VUSA": { "prev_close": 110.915, "fonte": "stooq:vusa.de", "moeda": null, "cached_at": "2025-12-13 23:15:55" } }, "2025-12-14": { "IWDA": { "prev_close": 110.98, "fonte": "stooq:eunl.de", "moeda": null, "cached_at": "2025-12-14 00:02:46" }, "AAPL": { "prev_close": 278.029999, "fonte": "twelveAAPL", "moeda": "USD", "cached_at": "2025-12-14 00:02:46" }, "NDXEX": { "prev_close": 210.9, "fonte": "stooq:exxt.de", "moeda": null, "cached_at": "2025-12-14 00:02:47" }, "NVDA": { "prev_close": 180.92999, "fonte": "twelveNVDA", "moeda": "USD", "cached_at": "2025-12-14 00:02:48" }, "GOOGL": { "prev_close": 312.42999, "fonte": "twelveGOOGL", "moeda": "USD", "cached_at": "2025-12-14 00:02:48" }, "VUSA": { "prev_close": 110.915, "fonte": "stooq:vusa.de", "moeda": null, "cached_at": "2025-12-14 00:02:49" } } } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/extrato-revolut.csv Tamanho: 59378 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2019-10-13T20:45:52.089581Z,,CASH TOP-UP,,,USD 10,USD,1.1090 2019-10-15T15:04:56.402300Z,GOOGL,BUY - MARKET,0.00808315,USD 1237.14,USD 10,USD,1.1041 2019-10-16T16:40:49.118522Z,GOOGL,SELL - MARKET,0.00808315,USD 1244.56,USD 10.05,USD,1.1083 2019-10-16T16:42:15.845933Z,AMZN,BUY - MARKET,0.0056605,USD 1775.46,USD 10.05,USD,1.1083 2020-01-22T06:14:35.117802Z,,CASH TOP-UP,,,USD 150,USD,1.1087 2020-01-22T14:35:09.489834Z,AAPL,BUY - MARKET,0.47175745,USD 317.96,USD 150,USD,1.1087 2020-01-27T19:03:34.378166Z,,CASH TOP-UP,,,USD 100,USD,1.1016 2020-01-27T19:03:59.925033Z,AAPL,BUY - MARKET,0.32237266,USD 310.20,USD 100,USD,1.1017 2020-01-27T19:06:24.636699Z,,CASH TOP-UP,,,USD 100,USD,1.1017 2020-01-27T19:06:44.350393Z,AAPL,BUY - MARKET,0.32203007,USD 310.53,USD 100,USD,1.1016 2020-02-04T18:52:14.721865Z,,CASH TOP-UP,,,USD 100,USD,1.1043 2020-02-04T18:53:01.732348Z,ADBE,BUY - MARKET,0.27270991,USD 366.69,USD 100,USD,1.1044 2020-02-06T16:55:04.812084Z,,CASH TOP-UP,,,USD 100,USD,1.0977 2020-02-06T16:55:36.979717Z,TSLA,BUY - MARKET,0.12870012,USD 777,USD 100,USD,1.0977 2020-02-10T17:27:50.154414Z,AMZN,SELL - MARKET,0.0056605,USD 2121.72,USD 12,USD,1.0918 2020-02-12T17:19:39.458866Z,,CASH WITHDRAWAL,,,USD -12,USD,1.0883 2020-02-14T06:27:43.976551Z,AAPL,DIVIDEND,,,USD 0.73,USD,1.0841 2020-02-14T16:15:09.890489Z,,CASH TOP-UP,,,USD 23.44,USD,1.0844 2020-02-19T15:25:37.972712Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:27:08.446046Z,TSLA,BUY - MARKET,0.13183279,USD 933,USD 124.07,USD,1.0788 2020-02-19T15:31:20.268338Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:32:09.673339Z,MA,BUY - MARKET,0.28609409,USD 346.04,USD 100.07,USD,1.0787 2020-02-25T15:34:40.463966Z,,CASH TOP-UP,,,USD 100,USD,1.0852 2020-02-25T15:35:27.862543Z,MA,BUY - MARKET,0.31256977,USD 313.53,USD 99.08,USD,1.0854 2020-02-27T15:58:29.203288Z,,CASH TOP-UP,,,USD 100,USD,1.0989 2020-02-27T15:59:44.008442Z,AMZN,BUY - MARKET,0.05144915,USD 1924.23,USD 100.09,USD,1.0988 2020-02-29T23:14:40.446417Z,,CUSTODY FEE,,,USD -0.01,USD,1.1085 2020-03-10T08:36:25.622472Z,,CASH TOP-UP,,,USD 100,USD,1.1392 2020-03-10T08:43:28.760520Z,,CASH TOP-UP,,,USD 100,USD,1.1385 2020-03-16T15:06:33.044184Z,AAPL,BUY - MARKET,0.39257252,USD 254.73,USD 100,USD,1.1116 2020-03-19T14:18:51.824712Z,AMZN,BUY - MARKET,0.05281643,USD 1893.35,USD 100,USD,1.0791 2020-03-25T19:00:13.188887Z,,CASH TOP-UP,,,USD 100,USD,1.0870 2020-03-25T19:00:56.745398Z,TSLA,BUY - MARKET,0.18182479,USD 549.98,USD 100,USD,1.0875 2020-03-31T23:13:57.154290Z,,CUSTODY FEE,,,USD -0.01,USD,1.1030 2020-04-13T13:44:26.856924Z,AMZN,SELL - MARKET,0.0581643,USD 2068.97,USD 120.33,USD,1.0908 2020-04-14T13:46:27.827041Z,AMZN,SELL - MARKET,0.04610128,USD 2222.06,USD 102.43,USD,1.0963 2020-04-14T13:49:54.123864Z,TSLA,SELL - MARKET,0.18182479,USD 734.50,USD 133.54,USD,1.0962 2020-04-14T13:57:12.990070Z,NFLX,BUY - MARKET,0.25100401,USD 398.40,USD 101.09,USD,1.0962 2020-04-15T13:35:34.237135Z,TSLA,BUY - MARKET,0.13523381,USD 739.46,USD 101.08,USD,1.0879 2020-04-16T13:50:19.111529Z,NFLX,BUY - MARKET,0.22745365,USD 439.65,USD 101.08,USD,1.0879 2020-04-16T15:14:00.808432Z,,CASH TOP-UP,,,USD 150,USD,1.0846 2020-04-16T15:14:35.050777Z,AMZN,BUY - MARKET,0.08295313,USD 2411,USD 201.08,USD,1.0845 2020-04-23T14:28:19.106924Z,,CASH TOP-UP,,,USD 65,USD,1.0835 2020-04-27T13:48:51.812918Z,,CASH TOP-UP,,,USD 150,USD,1.0849 2020-04-27T13:49:44.983233Z,GOOGL,BUY - MARKET,0.15638072,USD 1278.93,USD 201.08,USD,1.0850 2020-04-29T13:25:29.598577Z,,CASH TOP-UP,,,USD 60,USD,1.0862 2020-04-30T15:20:09.164358Z,TSLA,SELL - MARKET,0.13523381,USD 841.36,USD 112.69,USD,1.0945 2020-04-30T23:18:53.565423Z,,CUSTODY FEE,,,USD -0.01,USD,1.0945 2020-05-01T15:48:15.829872Z,TSLA,BUY - MARKET,0.21263626,USD 705.43,USD 151.09,USD,1.1000 2020-05-01T15:48:47.039832Z,,CASH TOP-UP,,,USD 70,USD,1.1000 2020-05-01T15:49:20.695234Z,AMZN,BUY - MARKET,0.04362354,USD 2292.34,USD 101.09,USD,1.1002 2020-05-05T15:31:50.521509Z,AAPL,SELL - MARKET,0.39257252,USD 298.65,USD 117.23,USD,1.0845 2020-05-06T19:08:08.304224Z,TSLA,SELL - MARKET,0.21263626,USD 785.52,USD 167.02,USD,1.0807 2020-05-07T13:31:53.906481Z,MCD,BUY - MARKET,1.11594688,USD 179.22,USD 200,USD,1.0787 2020-05-11T04:29:40.915073Z,MA,DIVIDEND,,,USD 0.20,USD,1.0849 2020-05-11T15:45:23.256201Z,GOOGL,SELL - MARKET,0.15638072,USD 1397.42,USD 217.44,USD,1.0812 2020-05-11T15:57:35.550473Z,AMD,BUY - MARKET,1.80733779,USD 55.33,USD 101.08,USD,1.0815 2020-05-12T16:07:48.403062Z,NFLX,SELL - MARKET,0.25100401,USD 443.18,USD 110.15,USD,1.0866 2020-05-12T19:51:54.916962Z,MA,BUY - MARKET,0.36659579,USD 272.78,USD 101.08,USD,1.0852 2020-05-14T13:39:16.072650Z,GOOGL,BUY - MARKET,0.14908017,USD 1341.56,USD 201.07,USD,1.0794 2020-05-15T06:45:31.771097Z,AAPL,DIVIDEND,,,USD 0.78,USD,1.0803 2020-05-15T14:21:14.417945Z,,CASH TOP-UP,,,USD 200,USD,1.0834 2020-05-15T14:21:43.642288Z,XYZ,BUY - MARKET,2.54097319,USD 78.71,USD 201.08,USD,1.0834 2020-05-20T15:35:46.301014Z,MA,SELL - MARKET,0.36659579,USD 300.47,USD 109.05,USD,1.0994 2020-05-20T15:42:40.689961Z,NVDA,BUY - MARKET,0.34223706,USD 359.40,USD 124.09,USD,1.0989 2020-05-21T11:09:05.866676Z,,CASH TOP-UP,,,USD 200,USD,1.0991 2020-05-21T13:33:35.686825Z,KO,BUY - MARKET,4.34023991,USD 45.85,USD 200.09,USD,1.0984 2020-05-27T15:15:48.029062Z,,CASH TOP-UP,,,USD 101,USD,1.0978 2020-05-27T15:15:56.832046Z,ANSS,BUY - MARKET,0.38406882,USD 260.37,USD 101.09,USD,1.0979 2020-05-28T14:46:13.432873Z,MCD,SELL - MARKET,1.11594688,USD 188.74,USD 209.51,USD,1.1054 2020-05-28T14:46:46.563846Z,QCOM,BUY - MARKET,2.4789291,USD 80.68,USD 201.10,USD,1.1055 2020-05-29T16:04:45.366029Z,XYZ,SELL - MARKET,2.54097319,USD 81.15,USD 205.08,USD,1.1105 2020-05-29T16:07:02.985866Z,MSFT,BUY - MARKET,1.15486141,USD 181.84,USD 211.11,USD,1.1104 2020-05-29T19:26:29.477576Z,ADBE,SELL - MARKET,0.27270991,USD 385.61,USD 104.05,USD,1.1095 2020-05-31T23:19:05.143061Z,,CUSTODY FEE,,,USD -0.02,USD,1.1117 2020-06-01T13:02:55.670900Z,,CASH TOP-UP,,,USD 100,USD,1.1111 2020-06-01T13:42:34.671146Z,UAL,BUY - MARKET,6.8212824,USD 29.32,USD 201.11,USD,1.1117 2020-06-01T16:16:43.298913Z,TSLA,SELL - MARKET,0.12870012,USD 879.56,USD 112.08,USD,1.1131 2020-06-03T14:08:52.405659Z,ANSS,SELL - MARKET,0.38406882,USD 290.47,USD 111.55,USD,1.1224 2020-06-03T14:09:18.216215Z,UAL,BUY - MARKET,7.12250712,USD 31.59,USD 225,USD,1.1218 2020-06-03T15:40:53.775341Z,GOOGL,SELL - MARKET,0.14908017,USD 1435.47,USD 213.99,USD,1.1248 2020-06-03T15:41:39.067184Z,UAL,BUY - MARKET,6.44484412,USD 33.36,USD 216.12,USD,1.1248 2020-06-03T22:53:07.567360Z,,CASH TOP-UP,,,USD 96.40,USD,1.1233 2020-06-04T13:38:22.083446Z,UAL,BUY - MARKET,2.69444444,USD 36,USD 98.12,USD,1.1261 2020-06-04T14:52:37.932806Z,,CASH TOP-UP,,,USD 105.53,USD,1.1334 2020-06-04T14:53:08.914462Z,UAL,BUY - MARKET,2.78884462,USD 37.65,USD 106.13,USD,1.1334 2020-06-04T15:23:45.056331Z,,CASH TOP-UP,,,USD 200,USD,1.1330 2020-06-04T15:24:10.360661Z,UAL,BUY - MARKET,5.20231213,USD 38.06,USD 199.13,USD,1.1330 2020-06-05T13:04:26.828036Z,,CASH TOP-UP,,,USD 113.81,USD,1.1302 2020-06-05T14:18:00.799519Z,UAL,BUY - MARKET,2.4672489,USD 45.80,USD 114.12,USD,1.1297 2020-06-05T17:28:26.976376Z,QCOM,SELL - MARKET,2.4789291,USD 89.12,USD 220.91,USD,1.1289 2020-06-05T17:31:09.772451Z,UAL,BUY - MARKET,4.8456164,USD 44.37,USD 215,USD,1.1287 2020-06-08T14:15:52.005116Z,,CASH TOP-UP,,,USD 102.63,USD,1.1304 2020-06-08T14:16:33.413999Z,ANSS,BUY - MARKET,0.35145678,USD 284.53,USD 100,USD,1.1303 2020-06-08T14:17:24.882389Z,KO,SELL - MARKET,4.34023991,USD 49.70,USD 215.70,USD,1.1304 2020-06-08T14:23:38.760448Z,UAL,BUY - MARKET,4.86896252,USD 46.17,USD 224.80,USD,1.1309 2020-06-09T07:06:15.520922Z,,CASH TOP-UP,,,USD 100,USD,1.1277 2020-06-09T13:51:25.021186Z,UAL,BUY - MARKET,2.22121486,USD 44.12,USD 99.13,USD,1.1346 2020-06-09T14:17:33.110755Z,AMZN,SELL - MARKET,0.04362354,USD 2545.19,USD 109.89,USD,1.1345 2020-06-10T13:37:56.248650Z,UAL,BUY - MARKET,2.43486729,USD 41.07,USD 101.13,USD,1.1373 2020-06-10T13:43:11.542460Z,AAPL,SELL - MARKET,1.11616018,USD 350.18,USD 389.71,USD,1.1369 2020-06-10T13:48:41.773677Z,ANSS,BUY - MARKET,1.03831377,USD 288.93,USD 301.13,USD,1.1366 2020-06-10T14:04:33.156206Z,AMZN,SELL - MARKET,0.08295313,USD 2663.79,USD 219.83,USD,1.1366 2020-06-11T13:37:59.512320Z,TSLA,BUY - MARKET,0.30035742,USD 998.81,USD 301.13,USD,1.1367 2020-06-15T09:43:07.163997Z,,CASH TOP-UP,,,USD 150,USD,1.1250 2020-06-15T14:01:51.523075Z,AAPL,BUY - MARKET,0.44628246,USD 336.11,USD 151.12,USD,1.1280 2020-06-16T21:53:42.937926Z,,CASH TOP-UP,,,USD 97.58,USD,1.1262 2020-06-18T14:35:42.938104Z,UAL,SELL - MARKET,6.8212824,USD 40.04,USD 271.98,USD,1.1212 2020-06-18T14:37:42.274505Z,,CASH TOP-UP,,,USD 192.53,USD,1.1217 2020-06-19T13:52:12.947282Z,MSFT,SELL - MARKET,1.15486141,USD 199.15,USD 228.85,USD,1.1231 2020-06-19T13:53:37.856769Z,GOOGL,BUY - MARKET,0.20775767,USD 1443.99,USD 301.12,USD,1.1231 2020-06-19T14:05:29.762422Z,QCOM,BUY - MARKET,3.3463469,USD 89.65,USD 301.12,USD,1.1226 2020-06-22T13:37:24.868355Z,AAPL,BUY - MARKET,0.56580287,USD 353.48,USD 201.12,USD,1.1228 2020-06-26T06:44:11.028578Z,QCOM,DIVIDEND,,,USD 1.37,USD,1.1215 2020-06-29T04:54:02.365153Z,NVDA,DIVIDEND,,,USD 0.04,USD,1.1243 2020-06-30T18:19:47.514819Z,TSLA,SELL - MARKET,0.13183279,USD 1075.23,USD 141.74,USD,1.1236 2020-06-30T23:13:30.727834Z,,CUSTODY FEE,,,USD -0.03,USD,1.1237 2020-07-01T14:14:41.076966Z,UAL,SELL - MARKET,7.12250712,USD 37.39,USD 266.29,USD,1.1263 2020-07-01T14:24:40.305583Z,TSLA,SELL - MARKET,0.30035742,USD 1118.93,USD 336.06,USD,1.1266 2020-07-01T14:32:04.179320Z,NVDA,SELL - MARKET,0.34223706,USD 382.40,USD 130.86,USD,1.1275 2020-07-01T14:36:38.192960Z,NFLX,SELL - MARKET,0.22745365,USD 464.23,USD 105.58,USD,1.1268 2020-07-01T14:45:25.307546Z,KO,BUY - MARKET,6.61229887,USD 45.37,USD 300,USD,1.1269 2020-07-06T14:03:06.514648Z,AAPL,SELL - MARKET,0.44628246,USD 373.62,USD 166.73,USD,1.1327 2020-07-07T15:08:56.815724Z,UAL,BUY - MARKET,6.00781015,USD 33.29,USD 200,USD,1.1289 2020-07-07T15:09:28.099732Z,TSLA,BUY - MARKET,0.35837412,USD 1395.19,USD 500,USD,1.1289 2020-07-09T13:55:29.714774Z,ZM,BUY - MARKET,0.55248618,USD 271.50,USD 150,USD,1.1329 2020-07-09T17:10:13.780489Z,AMD,SELL - MARKET,1.80733779,USD 56.31,USD 101.76,USD,1.1295 2020-07-10T14:52:58.381420Z,AMZN,BUY - MARKET,0.03145999,USD 3178.64,USD 100,USD,1.1327 2020-07-10T19:29:46.857555Z,TSLA,SELL - MARKET,0.35837412,USD 1534.51,USD 549.91,USD,1.1304 2020-07-13T13:35:28.048770Z,AAPL,SELL - MARKET,0.56580287,USD 390.38,USD 220.87,USD,1.1352 2020-07-13T13:35:47.111924Z,TSLA,BUY - MARKET,0.17648096,USD 1699.90,USD 300,USD,1.1351 2020-07-13T13:35:52.230844Z,AMZN,BUY - MARKET,0.09185548,USD 3266,USD 300,USD,1.1350 2020-07-13T14:51:54.087827Z,MA,SELL - MARKET,0.31256977,USD 296.73,USD 92.74,USD,1.1368 2020-07-14T13:31:59.854077Z,AAPL,BUY - MARKET,0.65824117,USD 379.80,USD 250,USD,1.1369 2020-07-15T13:34:09.322645Z,UAL,SELL - MARKET,6.44484412,USD 34.06,USD 219.50,USD,1.1453 2020-07-15T13:35:04.961261Z,UAL,SELL - MARKET,6.00781015,USD 34.21,USD 205.52,USD,1.1450 2020-07-15T13:36:54.903151Z,AAPL,BUY - MARKET,0.5079494,USD 393.74,USD 200,USD,1.1450 2020-07-15T13:37:08.648684Z,TSLA,BUY - MARKET,0.13297872,USD 1504,USD 200,USD,1.1447 2020-07-17T10:21:42.253727Z,,CASH WITHDRAWAL,,,USD -16,USD,1.1414 2020-07-20T15:28:03.617896Z,GOOGL,SELL - MARKET,0.20775767,USD 1553.01,USD 322.63,USD,1.1444 2020-07-20T15:28:23.429522Z,UAL,BUY - MARKET,9.17150718,USD 32.71,USD 300,USD,1.1443 2020-07-21T13:52:52.140017Z,KO,SELL - MARKET,6.61229887,USD 47.62,USD 314.86,USD,1.1450 2020-07-21T14:53:45.843776Z,AAPL,BUY - MARKET,0.76413652,USD 392.60,USD 300,USD,1.1482 2020-07-23T16:16:56.135853Z,UAL,SELL - MARKET,9.17150718,USD 33.58,USD 307.96,USD,1.1618 2020-07-23T16:17:12.192300Z,AMZN,BUY - MARKET,0.09914274,USD 3025.94,USD 300,USD,1.1619 2020-07-24T13:37:52.361330Z,AMD,BUY - MARKET,1.05263157,USD 66.50,USD 70,USD,1.1611 2020-07-24T15:46:13.810803Z,AMD,SELL - MARKET,1.05263157,USD 68.80,USD 72.41,USD,1.1637 2020-07-24T15:50:14.518607Z,ZM,BUY - MARKET,0.28389503,USD 246.57,USD 70,USD,1.1635 2020-07-25T21:25:27.926085Z,,CASH TOP-UP,,,USD 150,USD,1.1714 2020-07-27T13:40:19.675494Z,TSLA,BUY - MARKET,0.10470034,USD 1432.66,USD 150,USD,1.1746 2020-07-30T13:37:41.742329Z,QCOM,SELL - MARKET,3.3463469,USD 102.67,USD 343.55,USD,1.1800 2020-07-30T13:44:03.123846Z,GOOGL,BUY - MARKET,0.19926934,USD 1505.50,USD 300,USD,1.1804 2020-07-30T16:32:20.847339Z,ANSS,SELL - MARKET,0.35145678,USD 309.60,USD 108.80,USD,1.1801 2020-07-30T16:35:39.859799Z,MSFT,BUY - MARKET,0.73800738,USD 203.25,USD 150,USD,1.1802 2020-07-31T15:21:05.501725Z,AAPL,SELL - MARKET,0.65824117,USD 411.70,USD 270.98,USD,1.1839 2020-07-31T15:23:47.598730Z,GOOGL,BUY - MARKET,0.16989812,USD 1471.47,USD 250,USD,1.1840 2020-07-31T23:43:53.566513Z,,CUSTODY FEE,,,USD -0.03,USD,1.1837 2020-08-03T13:46:32.153897Z,AAPL,SELL - MARKET,1.27208592,USD 444.06,USD 564.86,USD,1.1709 2020-08-03T14:00:31.581377Z,TSLA,BUY - MARKET,0.2030663,USD 1477.35,USD 300,USD,1.1731 2020-08-03T18:28:17.331649Z,ANSS,SELL - MARKET,1.03831377,USD 315.57,USD 327.64,USD,1.1755 2020-08-04T20:41:16.072701Z,,CASH WITHDRAWAL,,,USD -16.50,USD,1.1799 2020-08-05T13:32:48.539437Z,ANSS,BUY - MARKET,0.95910994,USD 312.79,USD 300,USD,1.1881 2020-08-05T13:36:03.481722Z,AMD,BUY - MARKET,1.18990956,USD 84.04,USD 100,USD,1.1891 2020-08-06T09:23:31.359439Z,,CASH TOP-UP,,,USD 300,USD,1.1850 2020-08-06T14:00:31.092775Z,AAPL,BUY - MARKET,0.22504782,USD 444.35,USD 100,USD,1.1859 2020-08-10T04:51:32.749766Z,MA,DIVIDEND,,,USD 0.20,USD,1.1794 2020-08-10T14:52:42.356948Z,UAL,SELL - MARKET,2.6944444,USD 36.55,USD 98.47,USD,1.1769 2020-08-10T14:54:34.374914Z,AMD,BUY - MARKET,1.23701138,USD 80.84,USD 100,USD,1.1768 2020-08-10T14:57:30.636414Z,ANSS,BUY - MARKET,0.32998944,USD 303.04,USD 100,USD,1.1767 2020-08-13T13:31:33.235267Z,TSLA,SELL - MARKET,0.10470034,USD 1607.54,USD 168.30,USD,1.1839 2020-08-13T14:32:36.305371Z,TSLA,SELL - MARKET,0.2030663,USD 1632.37,USD 331.46,USD,1.1859 2020-08-13T14:36:28.249846Z,ZM,BUY - MARKET,0.40695071,USD 245.73,USD 100,USD,1.1851 2020-08-14T06:42:26.713153Z,AAPL,DIVIDEND,,,USD 0.15,USD,1.1819 2020-08-14T13:33:39.022612Z,TSLA,SELL - MARKET,0.1397872,USD 1661.02,USD 232.17,USD,1.1826 2020-08-14T14:12:17.671752Z,XYZ,BUY - MARKET,0.7033338,USD 142.18,USD 100,USD,1.1830 2020-08-17T13:33:39.120706Z,TSLA,BUY - MARKET,0.05902769,USD 1694.12,USD 100,USD,1.1863 2020-08-17T14:36:39.947800Z,TSLA,BUY - MARKET,0.0561394,USD 1781.28,USD 100,USD,1.1883 2020-08-17T16:28:45.503089Z,XYZ,BUY - MARKET,0.66613375,USD 150.12,USD 100,USD,1.1860 2020-08-18T13:40:16.844239Z,TSLA,SELL - MARKET,0.05902769,USD 1883.01,USD 111.14,USD,1.1962 2020-08-18T13:46:26.654Z,ZM,SELL - MARKET,0.40695071,USD 270.87,USD 110.22,USD,1.1962 2020-08-18T14:20:31.458481Z,TSLA,SELL - MARKET,0.17599953,USD 1878.58,USD 330.61,USD,1.1934 2020-08-18T16:27:49.232388Z,UAL,BUY - MARKET,2.9620853,USD 33.76,USD 100,USD,1.1937 2020-08-19T16:01:34.832909Z,AMZN,SELL - MARKET,0.09914274,USD 3306.04,USD 327.75,USD,1.1899 2020-08-19T16:19:13.539922Z,NVDA,BUY - MARKET,0.10171698,USD 491.56,USD 50,USD,1.1872 2020-08-19T16:27:25.319575Z,MA,SELL - MARKET,0.28609409,USD 331.39,USD 94.80,USD,1.1877 2020-08-20T15:13:31.608194Z,TSLA,SELL - MARKET,0.04981235,USD 1966.58,USD 97.95,USD,1.1848 2020-08-20T15:17:03.912150Z,XYZ,SELL - MARKET,0.7033338,USD 156.27,USD 109.90,USD,1.1847 2020-08-20T15:35:58.284968Z,TSLA,BUY - MARKET,0.05034207,USD 1986.41,USD 100,USD,1.1856 2020-08-20T19:11:21.856894Z,TSLA,BUY - MARKET,0.04959308,USD 2016.41,USD 100,USD,1.1860 2020-08-21T13:46:22.168804Z,AAPL,BUY - MARKET,0.41413869,USD 482.93,USD 200,USD,1.1767 2020-08-21T13:46:40.645696Z,TSLA,BUY - MARKET,0.09623805,USD 2078.18,USD 200,USD,1.1765 2020-08-21T16:26:59.511866Z,ZM,SELL - MARKET,0.83638121,USD 290.27,USD 242.76,USD,1.1768 2020-08-21T16:30:38.287214Z,TSLA,BUY - MARKET,0.09596054,USD 2084.19,USD 200,USD,1.1770 2020-08-24T16:07:10.297884Z,UAL,SELL - MARKET,2.9620853,USD 36.19,USD 107.19,USD,1.1805 2020-08-24T16:08:07.511680Z,TSLA,BUY - MARKET,0.09782821,USD 2044.40,USD 200,USD,1.1805 2020-08-25T14:44:00.531640Z,BABA,BUY - MARKET,0.17636684,USD 283.50,USD 50,USD,1.1826 2020-08-25T15:15:44.630812Z,GOOGL,SELL - MARKET,0.16989812,USD 1605.20,USD 272.70,USD,1.1828 2020-08-26T15:07:42.730768Z,ZM,BUY - MARKET,0.1661792,USD 300.88,USD 50,USD,1.1821 2020-08-26T15:42:29.143351Z,BABA,BUY - MARKET,0.17246731,USD 289.91,USD 50,USD,1.1825 2020-08-27T13:56:12.492183Z,MSFT,SELL - MARKET,0.73800738,USD 229.08,USD 169.05,USD,1.1807 2020-08-27T13:57:57.647626Z,UAL,SELL - MARKET,2.78884462,USD 37.49,USD 104.54,USD,1.1803 2020-08-27T14:08:52.657497Z,UAL,SELL - MARKET,5.20231213,USD 36.73,USD 191.07,USD,1.1782 2020-08-27T14:47:04.731766Z,ANSS,SELL - MARKET,0.32998944,USD 331.65,USD 109.43,USD,1.1786 2020-08-27T15:52:39.194814Z,TSLA,BUY - MARKET,0.08780286,USD 2277.83,USD 200,USD,1.1825 2020-08-27T15:59:47.914287Z,TSLA,SELL - MARKET,0.09782821,USD 2272.96,USD 222.35,USD,1.1826 2020-08-27T16:02:06.770299Z,TSLA,BUY - MARKET,0.21983819,USD 2274.40,USD 500,USD,1.1822 2020-08-27T16:40:42.718746Z,TSLA,BUY - MARKET,0.22686231,USD 2203.98,USD 500,USD,1.1825 2020-08-27T17:15:43.206363Z,AAPL,BUY - MARKET,0.40120361,USD 498.50,USD 200,USD,1.1814 2020-08-28T14:57:20.303825Z,TSLA,SELL - MARKET,0.05034207,USD 2272.06,USD 114.37,USD,1.1911 2020-08-28T15:25:39.775903Z,UAL,SELL - MARKET,2.43486729,USD 37.02,USD 90.13,USD,1.1899 2020-08-28T15:30:21.083145Z,NVDA,BUY - MARKET,0.09644131,USD 518.45,USD 50,USD,1.1902 2020-08-31T00:22:15.681429Z,,CASH WITHDRAWAL,,,USD -16.66,USD,1.1915 2020-08-31T08:24:29.814099Z,AAPL,STOCK SPLIT,3.12117036,,USD 0,USD,1.1899 2020-08-31T08:27:18.193687Z,TSLA,STOCK SPLIT,3.10518012,,USD 0,USD,1.1898 2020-08-31T14:23:19.225150Z,TSLA,SELL - MARKET,0.48119025,USD 463.12,USD 222.84,USD,1.1941 2020-08-31T14:25:12.090849Z,TSLA,BUY - MARKET,1.07529194,USD 464.99,USD 500,USD,1.1939 2020-08-31T14:34:07.507538Z,AAPL,SELL - MARKET,0.90019128,USD 128.26,USD 115.45,USD,1.1945 2020-08-31T14:36:41.781166Z,TSLA,SELL - MARKET,0.4798027,USD 465.17,USD 223.18,USD,1.1950 2020-08-31T14:58:49.683011Z,AMD,SELL - MARKET,1.23701138,USD 89.87,USD 111.16,USD,1.1965 2020-08-31T15:00:12.913839Z,AMZN,SELL - MARKET,0.03145999,USD 3492.37,USD 109.86,USD,1.1961 2020-08-31T15:10:00.501852Z,TSLA,BUY - MARKET,0.41160732,USD 485.90,USD 200,USD,1.1951 2020-08-31T15:56:12.322382Z,TSLA,SELL - MARKET,1.13431155,USD 483.77,USD 548.73,USD,1.1955 2020-08-31T19:02:14.692076Z,TSLA,SELL - MARKET,0.2479654,USD 495.19,USD 122.78,USD,1.1935 2020-08-31T19:06:47.005425Z,TSLA,BUY - MARKET,1.00952996,USD 495.28,USD 500,USD,1.1938 2020-08-31T23:54:32.172792Z,,CUSTODY FEE,,,USD -0.02,USD,1.1940 2020-09-01T13:31:35.939299Z,ZM,BUY - MARKET,0.23466466,USD 426.14,USD 100,USD,1.1988 2020-09-01T13:31:46.997999Z,TSLA,BUY - MARKET,1.0119409,USD 494.10,USD 500,USD,1.1988 2020-09-01T13:47:37.140689Z,XYZ,SELL - MARKET,0.66613375,USD 166.08,USD 110.62,USD,1.1977 2020-09-01T13:53:42.126313Z,ZM,BUY - MARKET,0.44881288,USD 445.62,USD 200,USD,1.1969 2020-09-01T13:59:53.248673Z,ZM,SELL - MARKET,0.1661792,USD 453.67,USD 75.38,USD,1.1977 2020-09-01T14:07:15.473203Z,ZM,BUY - MARKET,0.42154073,USD 474.45,USD 200,USD,1.1952 2020-09-01T18:05:30.665718Z,GOOGL,SELL - MARKET,0.19926934,USD 1655.45,USD 329.86,USD,1.1917 2020-09-01T18:07:04.483988Z,ANSS,SELL - MARKET,0.95910994,USD 344.33,USD 330.23,USD,1.1919 2020-09-01T18:13:20.177621Z,NIO,BUY - MARKET,10.07556675,USD 19.85,USD 200,USD,1.1921 2020-09-02T13:33:53.638044Z,NIO,BUY - MARKET,10,USD 20.74,USD 207.40,USD,1.1832 2020-09-02T13:45:31.065500Z,NVDA,SELL - MARKET,0.19815829,USD 577.22,USD 114.37,USD,1.1839 2020-09-02T14:00:41.420342Z,TSLA,BUY - MARKET,0.84973166,USD 447.20,USD 380,USD,1.1834 2020-09-02T14:58:26.424459Z,,CASH TOP-UP,,,USD 200,USD,1.1844 2020-09-04T06:57:55.602815Z,,CASH WITHDRAWAL,,,USD -200,USD,1.1841 2020-09-04T07:21:47.180268Z,,CASH TOP-UP,,,USD 250,USD,1.1845 2020-09-04T07:22:00.765905Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1846 2020-09-10T06:43:18.012788Z,,CASH TOP-UP,,,USD 250,USD,1.1832 2020-09-10T06:43:39.697815Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1832 2020-09-11T07:08:09.301110Z,MSFT,DIVIDEND,,,USD 0.32,USD,1.1840 2020-09-15T14:37:48.200676Z,TSLA,SELL - MARKET,0.65498179,USD 438.20,USD 286.99,USD,1.1850 2020-09-15T14:54:20.817595Z,UAL,SELL - MARKET,2.22121486,USD 37.07,USD 82.33,USD,1.1857 2020-09-17T12:25:07.952921Z,,CASH WITHDRAWAL,,,USD -370.20,USD,1.1805 2020-09-22T13:33:29.786892Z,ZM,SELL - MARKET,0.23466466,USD 469.01,USD 110.05,USD,1.1759 2020-09-22T15:55:51.449872Z,ZM,SELL - MARKET,0.44881288,USD 488.20,USD 219.10,USD,1.1706 2020-09-23T14:38:22.109173Z,ZM,SELL - MARKET,0.42154073,USD 520,USD 219.19,USD,1.1668 2020-09-24T07:30:01.867812Z,,CASH WITHDRAWAL,,,USD -329.15,USD,1.1653 2020-09-25T05:34:43.533083Z,NVDA,DIVIDEND,,,USD 0.03,USD,1.1674 2020-09-25T07:08:24.483137Z,,CASH WITHDRAWAL,,,USD -219.22,USD,1.1668 2020-09-28T15:41:23.188756Z,BABA,SELL - MARKET,0.34883415,USD 275.69,USD 96.16,USD,1.1662 2020-09-29T15:58:04.990015Z,AMD,SELL - MARKET,1.18990956,USD 81.35,USD 96.79,USD,1.1721 2020-09-30T13:41:16.788426Z,NIO,SELL - MARKET,10.07556675,USD 22.13,USD 222.96,USD,1.1695 2020-09-30T23:05:22.729899Z,,CUSTODY FEE,,,USD -0.03,USD,1.1730 2020-10-01T08:39:07.068215Z,,CASH WITHDRAWAL,,,USD -16.40,USD,1.1728 2020-10-01T19:43:49.909598Z,TSLA,SELL - MARKET,0.60709082,USD 448.45,USD 272.23,USD,1.1745 2020-10-02T18:46:35.354198Z,,CASH WITHDRAWAL,,,USD -399.48,USD,1.1719 2020-10-06T13:45:20.572814Z,UAL,SELL - MARKET,2.4672489,USD 36.78,USD 90.74,USD,1.1797 2020-10-06T19:05:39.180375Z,,CASH WITHDRAWAL,,,USD -272.23,USD,1.1754 2020-10-08T14:41:22.813140Z,UAL,SELL - MARKET,4.8456164,USD 37.49,USD 181.65,USD,1.1744 2020-10-08T14:45:00.269291Z,UAL,SELL - MARKET,4.86896256,USD 37.41,USD 182.14,USD,1.1743 2020-10-09T18:26:13.289084Z,AAPL,SELL - MARKET,2.02064706,USD 116.32,USD 235.02,USD,1.1828 2020-10-12T17:56:05.845122Z,AAPL,SELL - MARKET,1.24072214,USD 124.33,USD 154.25,USD,1.1810 2020-10-14T13:30:16.262543Z,NIO,SELL - LIMIT,10,USD 24,USD 239.98,USD,1.1762 2020-10-14T15:26:47.927855Z,TSLA,SELL - MARKET,0.98969047,USD 462.20,USD 457.41,USD,1.1763 2020-10-15T12:02:19.535807Z,,CASH WITHDRAWAL,,,USD -400,USD,1.1708 2020-10-22T09:23:25.613263Z,,CASH WITHDRAWAL,,,USD -680,USD,1.1842 2020-10-22T19:06:30.184890Z,,CASH WITHDRAWAL,,,USD -461.19,USD,1.1819 2020-10-30T16:49:56.657758Z,,CASH TOP-UP,,,USD 230,USD,1.1655 2020-10-30T18:55:13.772909Z,,CASH WITHDRAWAL,,,USD -230,USD,1.1650 2020-11-01T00:12:15.461073Z,,CUSTODY FEE,,,USD -0.01,USD,1.1764 2020-11-02T23:50:23.731454Z,,CASH TOP-UP,,,USD 0.01,USD,1.1643 2020-11-13T17:32:40.396936Z,TSLA,SELL - MARKET,1.09919095,USD 404.95,USD 445.10,USD,1.1829 2020-11-13T17:33:09.255036Z,AMZN,SELL - MARKET,0.09185548,USD 3115.11,USD 286.12,USD,1.1829 2020-11-17T08:14:31.505714Z,,CASH WITHDRAWAL,,,USD -731.22,USD,1.1861 2020-11-26T10:29:43.997425Z,,CASH TOP-UP,,,USD 64.15,USD,1.1908 2020-11-30T14:07:20.231291Z,,CASH TOP-UP,,,USD 600,USD,1.1997 2020-11-30T14:13:04.510383Z,,CASH WITHDRAWAL,,,USD -664.15,USD,1.1995 2020-11-30T23:42:00.247197Z,,CUSTODY FEE,,,USD -0.01,USD,1.1938 2020-12-01T23:01:04.658915Z,,CASH TOP-UP,,,USD 0.01,USD,1.2075 2020-12-03T16:01:52.681026Z,TSLA,SELL - MARKET,1.51430624,USD 587.30,USD 889.32,USD,1.2162 2020-12-03T20:02:02.615104Z,,CASH TOP-UP,,,USD 283.13,USD,1.2146 2020-12-07T09:33:26.482581Z,,CASH TOP-UP,,,USD 245.04,USD,1.2091 2020-12-07T10:19:04.708279Z,,CASH WITHDRAWAL,,,USD -1417.49,USD,1.2098 2020-12-08T20:25:49.896141Z,,CASH TOP-UP,,,USD 600,USD,1.2104 2020-12-08T20:26:38.575792Z,MRNA,BUY - MARKET,3,USD 167.84,USD 503.52,USD,1.2104 2020-12-10T08:24:28.915801Z,,CASH TOP-UP,,,USD 1045.98,USD,1.2095 2020-12-10T14:30:02.653115Z,AMD,BUY - LIMIT,4,USD 89.55,USD 358.20,USD,1.2110 2020-12-10T14:30:13.150135Z,TSLA,BUY - LIMIT,1,USD 573.85,USD 573.85,USD,1.2112 2020-12-10T14:47:14.048156Z,MRNA,BUY - MARKET,1,USD 155.44,USD 155.44,USD,1.2139 2020-12-14T08:42:02.044895Z,,CASH TOP-UP,,,USD 873.84,USD,1.2148 2020-12-14T14:48:21.225847Z,TSLA,BUY - MARKET,1.39009052,USD 617.42,USD 858.27,USD,1.2161 2020-12-14T14:56:33.643638Z,NIO,BUY - MARKET,1,USD 39.90,USD 39.90,USD,1.2163 2020-12-15T14:33:22.241704Z,TSLA,SELL - MARKET,1.42113728,USD 640.27,USD 909.88,USD,1.2156 2020-12-15T14:50:30.838195Z,ANSS,BUY - MARKET,1,USD 345.66,USD 345.66,USD,1.2159 2020-12-15T18:04:07.650518Z,MRNA,BUY - LIMIT,4,USD 145,USD 580,USD,1.2161 2020-12-17T08:40:21.201412Z,,CASH TOP-UP,,,USD 1011.96,USD,1.2241 2020-12-17T14:30:06.433198Z,AAPL,BUY - LIMIT,3,USD 128.98,USD 386.94,USD,1.2249 2020-12-17T14:44:55.714193Z,TSLA,BUY - LIMIT,1,USD 620,USD 620,USD,1.2253 2020-12-17T20:44:47.556398Z,TSLA,SELL - LIMIT,1,USD 650,USD 649.98,USD,1.2263 2020-12-17T20:47:30.660341Z,AAPL,BUY - LIMIT,5,USD 128.63,USD 643.15,USD,1.2263 2020-12-21T13:26:44.115395Z,,CASH TOP-UP,,,USD 934.75,USD,1.2192 2020-12-21T15:25:16.971865Z,AMD,BUY - LIMIT,3,USD 92,USD 276,USD,1.2219 2020-12-22T14:30:05.457349Z,TSLA,BUY - LIMIT,1,USD 647.31,USD 647.31,USD,1.2225 2020-12-23T08:20:49.417315Z,,CASH TOP-UP,,,USD 440.80,USD,1.2179 2020-12-23T10:08:57.914132Z,,CASH TOP-UP,,,USD 1218.96,USD,1.2194 2020-12-23T14:30:12.260390Z,AAPL,BUY - LIMIT,4,USD 132.17,USD 528.68,USD,1.2199 2020-12-23T14:32:40.448977Z,TSLA,BUY - LIMIT,1,USD 630,USD 630,USD,1.2217 2020-12-23T15:56:56.184999Z,AMZN,BUY - MARKET,0.15645779,USD 3195.75,USD 500,USD,1.2185 2020-12-24T15:56:44.818105Z,,CASH TOP-UP,,,USD 14.23,USD,1.2184 2020-12-30T19:41:15.069854Z,TSLA,SELL - LIMIT,2,USD 695,USD 1389.96,USD,1.2289 2020-12-31T12:20:23.184470Z,,CASH TOP-UP,,,USD 500,USD,1.2276 2020-12-31T12:24:43.742Z,,CASH WITHDRAWAL,,,USD -64.98,USD,1.2273 2020-12-31T14:31:39.601626Z,NIO,BUY - LIMIT,10,USD 48.50,USD 485,USD,1.2279 2020-12-31T17:17:42.145519Z,TSLA,BUY - MARKET,1,USD 716.49,USD 716.49,USD,1.2232 2021-01-01T01:29:50.870336Z,,CUSTODY FEE,,,USD -0.04,USD,1.2219 2021-01-04T16:07:56.289208Z,AAPL,BUY - LIMIT,1,USD 130,USD 130,USD,1.2275 2021-01-06T16:21:50.650163Z,TSLA,BUY - MARKET,0.71085433,USD 769.37,USD 546.91,USD,1.2280 2021-01-07T15:55:24.088592Z,TSLA,SELL - LIMIT,2,USD 800,USD 1599.95,USD,1.2262 2021-01-07T16:23:46.257213Z,TSLA,BUY - MARKET,1,USD 805.56,USD 805.56,USD,1.2275 2021-01-08T01:26:54.692376Z,,CASH TOP-UP,,,USD 549.96,USD,1.2246 2021-01-08T09:16:01.965750Z,,CASH WITHDRAWAL,,,USD -71.85,USD,1.2234 2021-01-08T14:34:59.679144Z,TSLA,BUY - MARKET,0.28914567,USD 845.97,USD 244.61,USD,1.2280 2021-01-08T15:22:16.713016Z,TSLA,BUY - MARKET,1,USD 869.32,USD 869.32,USD,1.2229 2021-01-11T15:11:20.833428Z,NIO,BUY - MARKET,2,USD 64.89,USD 129.78,USD,1.2147 2021-01-13T08:40:39.001823Z,,CASH TOP-UP,,,USD 576.16,USD,1.2198 2021-01-13T14:36:16.142906Z,PLUG,BUY - MARKET,8,USD 69.31,USD 554.48,USD,1.2167 2021-01-14T15:14:44.924095Z,TSLA,SELL - LIMIT,1,USD 860,USD 859.97,USD,1.2118 2021-01-14T18:07:30.816970Z,PLUG,SELL - MARKET,8,USD 64.35,USD 514.78,USD,1.2167 2021-01-14T18:07:52.552385Z,MRNA,BUY - MARKET,4,USD 129.08,USD 516.32,USD,1.2168 2021-01-15T15:13:10.226921Z,NIO,BUY - MARKET,15,USD 57.38,USD 860.70,USD,1.2094 2021-01-20T14:30:56.453166Z,NIO,SELL - LIMIT,11,USD 60,USD 659.98,USD,1.2101 2021-01-22T16:33:20.961547Z,TSLA,BUY - MARKET,0.84141694,USD 831.93,USD 700,USD,1.2179 2021-01-25T15:03:48.621618Z,TSLA,SELL - LIMIT,1,USD 900,USD 899.97,USD,1.2129 2021-01-25T15:46:48.750569Z,AAPL,SELL - MARKET,5,USD 144.30,USD 721.47,USD,1.2129 2021-01-25T15:58:40.136461Z,TSLA,BUY - LIMIT,1,USD 870,USD 870,USD,1.2130 2021-01-25T16:04:44.895297Z,AAPL,BUY - LIMIT,5,USD 140,USD 700,USD,1.2129 2021-01-25T18:05:09.838791Z,NIO,BUY - LIMIT,1,USD 59.62,USD 59.62,USD,1.2148 2021-01-27T15:07:02.285287Z,,CASH TOP-UP,,,USD 136.83,USD,1.2080 2021-01-27T15:20:25.147014Z,,CASH TOP-UP,,,USD 470.71,USD,1.2077 2021-01-27T15:43:15.633441Z,AAPL,BUY - MARKET,2,USD 143.31,USD 286.62,USD,1.2091 2021-01-27T15:48:10.015296Z,MRNA,BUY - LIMIT,2,USD 158.09,USD 316.18,USD,1.2094 2021-01-28T07:27:07.598501Z,,CASH TOP-UP,,,USD 1373.27,USD,1.2089 2021-01-28T17:28:28.927848Z,MRNA,BUY - MARKET,3,USD 165.86,USD 497.58,USD,1.2126 2021-01-29T14:30:47.770020Z,MRNA,SELL - LIMIT,6,USD 174,USD 1043.97,USD,1.2153 2021-01-29T14:51:33.499884Z,TSLA,BUY - MARKET,1,USD 840.99,USD 840.99,USD,1.2148 2021-01-29T15:16:26.525884Z,MRNA,BUY - LIMIT,6,USD 177.35,USD 1064.10,USD,1.2147 2021-02-01T04:30:09.384615Z,,CUSTODY FEE,,,USD -0.09,USD,1.2133 2021-02-01T18:09:50.812968Z,,CASH TOP-UP,,,USD 196.46,USD,1.2067 2021-02-01T18:10:12.917721Z,MRNA,BUY - MARKET,1,USD 156.50,USD 156.50,USD,1.2067 2021-02-02T15:02:02.882495Z,ANSS,SELL - MARKET,1,USD 375.59,USD 375.57,USD,1.2033 2021-02-02T15:37:15.304627Z,TSLA,SELL - MARKET,0.71085433,USD 872.04,USD 619.87,USD,1.2029 2021-02-02T15:56:12.366798Z,AAPL,BUY - MARKET,4,USD 135.67,USD 542.68,USD,1.2029 2021-02-03T17:43:36.485615Z,AMZN,SELL - MARKET,0.15645779,USD 3399.26,USD 531.82,USD,1.2031 2021-02-04T17:57:10.745295Z,MRNA,SELL - MARKET,6,USD 172,USD 1031.97,USD,1.1965 2021-02-04T18:01:38.009039Z,,CASH WITHDRAWAL,,,USD -32.26,USD,1.1962 2021-02-05T17:10:07.082216Z,PYPL,BUY - MARKET,3,USD 267.18,USD 801.54,USD,1.2040 2021-02-08T14:56:37.080784Z,MRNA,SELL - LIMIT,6,USD 185,USD 1109.97,USD,1.2061 2021-02-08T15:09:42.308233Z,PYPL,BUY - MARKET,3,USD 280.95,USD 842.85,USD,1.2061 2021-02-08T15:15:57.131010Z,AMZN,BUY - MARKET,0.25,USD 3323.72,USD 830.93,USD,1.2060 2021-02-09T19:58:40.343296Z,NIO,SELL - MARKET,15,USD 62.66,USD 939.87,USD,1.2121 2021-02-09T20:00:27.291440Z,MRNA,BUY - MARKET,3,USD 178.82,USD 536.46,USD,1.2121 2021-02-09T21:20:29.683577Z,,CASH WITHDRAWAL,,,USD -500,USD,1.2121 2021-02-10T14:43:53.048254Z,TSLA,BUY - MARKET,0.69581812,USD 835.75,USD 581.53,USD,1.2135 2021-02-11T15:53:16.248489Z,PYPL,SELL - LIMIT,3,USD 300.01,USD 900,USD,1.2140 2021-02-11T19:21:16.355706Z,PYPL,BUY - LIMIT,3,USD 285,USD 855,USD,1.2133 2021-02-12T07:09:53.382539Z,AAPL,DIVIDEND,,,USD 3.31,USD,1.2126 2021-02-12T15:12:50.744899Z,AMZN,SELL - MARKET,0.25,USD 3250.16,USD 812.51,USD,1.2097 2021-02-12T15:13:55.508641Z,PYPL,BUY - MARKET,2.8,USD 292.47,USD 818.92,USD,1.2098 2021-02-19T18:01:22.470148Z,,CASH WITHDRAWAL,,,USD -41.90,USD,1.2129 2021-03-01T02:07:33.445438Z,,CUSTODY FEE,,,USD -0.08,USD,1.2090 2021-03-02T21:51:18.062393Z,,CASH TOP-UP,,,USD 0.08,USD,1.2091 2021-03-12T14:45:17.576033Z,,CASH TOP-UP,,,USD 178.93,USD,1.1937 2021-03-12T14:45:57.397742Z,NIO,BUY - LIMIT,4,USD 44.30,USD 177.20,USD,1.1933 2021-04-01T07:49:55.154005Z,,CUSTODY FEE,,,USD -0.97,USD,1.1737 2021-04-15T16:45:21.353857Z,AMD,SELL - MARKET,7,USD 83.06,USD 581.42,USD,1.1976 2021-04-19T14:24:42.527100Z,TSLA,BUY - MARKET,0.78607363,USD 699.68,USD 550,USD,1.2032 2021-05-01T08:17:07.806729Z,,CUSTODY FEE,,,USD -1.07,USD,1.2142 2021-05-03T19:47:37.874160Z,MRNA,SELL - MARKET,9,USD 186.87,USD 1681.81,USD,1.2067 2021-05-04T14:18:13.245358Z,GOOGL,BUY - MARKET,0.09823182,USD 2290.50,USD 225,USD,1.2027 2021-05-04T17:03:55.276186Z,MRNA,BUY - MARKET,4,USD 175.47,USD 701.88,USD,1.2021 2021-05-04T17:06:43.250543Z,ANSS,BUY - MARKET,2,USD 350.09,USD 700.18,USD,1.2023 2021-05-04T17:07:18.273114Z,AMZN,BUY - MARKET,0.02585158,USD 3288,USD 85,USD,1.2023 2021-05-14T04:54:27.999346Z,AAPL,DIVIDEND,,,USD 3.55,USD,1.2089 2021-05-24T15:55:44.146809Z,,CASH TOP-UP,,,USD 50,USD,1.2213 2021-05-24T15:56:03.617327Z,SPCE,BUY - MARKET,2,USD 24.93,USD 49.86,USD,1.2212 2021-05-27T15:57:09.986850Z,SPCE,SELL - MARKET,2,USD 28.02,USD 56.03,USD,1.2198 2021-05-27T16:51:08.235670Z,,CASH TOP-UP,,,USD 50,USD,1.2193 2021-05-27T16:52:28.014919Z,,CASH TOP-UP,,,USD 10,USD,1.2195 2021-05-27T16:52:47.221525Z,SPCE,BUY - MARKET,4,USD 28.53,USD 114.12,USD,1.2194 2021-05-27T19:11:54.661834Z,MRNA,SELL - MARKET,4,USD 177.05,USD 708.19,USD,1.2200 2021-05-27T19:12:45.582300Z,SPCE,BUY - LIMIT,23,USD 30.62,USD 704.26,USD,1.2199 2021-06-01T04:34:31.145849Z,,CUSTODY FEE,,,USD -1.03,USD,1.2229 2021-06-07T15:22:20.528310Z,SPCE,SELL - MARKET,27,USD 33.85,USD 913.97,USD,1.2198 2021-06-07T19:32:00.085384Z,NIO,BUY - MARKET,10,USD 43.72,USD 437.20,USD,1.2198 2021-06-08T14:19:53.290150Z,SPCE,BUY - MARKET,12,USD 37.36,USD 448.31,USD,1.2188 2021-06-25T13:30:46.699710Z,SPCE,SELL - LIMIT,12,USD 47.73,USD 572.75,USD,1.1969 2021-06-28T15:36:38.638872Z,NIO,SELL - LIMIT,14,USD 49,USD 685.99,USD,1.1932 2021-07-01T07:07:29.237955Z,,CUSTODY FEE,,,USD -1.02,USD,1.1855 2021-07-01T15:10:49.364022Z,NIO,BUY - LIMIT,10,USD 52,USD 520,USD,1.1869 2021-07-06T14:13:29.561384Z,AMZN,SELL - MARKET,0.02585158,USD 3621.44,USD 93.61,USD,1.1841 2021-07-06T14:13:42.195388Z,GOOGL,SELL - MARKET,0.09823182,USD 2521.08,USD 247.64,USD,1.1841 2021-07-06T15:42:06.615634Z,GOOGL,BUY - MARKET,0.21915668,USD 2509.62,USD 550,USD,1.1830 2021-07-07T13:40:07.363142Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1807 2021-07-08T15:28:51.781770Z,SPCE,SELL - LIMIT,12,USD 50,USD 599.99,USD,1.1848 2021-07-09T14:51:56.656892Z,AAPL,SELL - LIMIT,4,USD 145.04,USD 580.17,USD,1.1875 2021-07-12T13:40:10.104714Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1858 2021-07-14T19:19:12.332908Z,AAPL,SELL - MARKET,4,USD 149.16,USD 596.63,USD,1.1838 2021-07-14T20:06:27.095455Z,,CASH WITHDRAWAL,,,USD -63.73,USD,1.1839 2021-07-15T14:52:57.411248Z,MRNA,BUY - MARKET,1,USD 255.80,USD 255.80,USD,1.1817 2021-07-16T13:30:15.150905Z,SPCE,BUY - LIMIT,24,USD 32.56,USD 781.44,USD,1.1811 2021-07-16T14:00:06.695873Z,MRNA,SELL - LIMIT,1,USD 285,USD 284.99,USD,1.1804 2021-07-16T15:51:31.477893Z,AAPL,BUY - LIMIT,3,USD 147.31,USD 441.92,USD,1.1813 2021-07-23T16:05:00.019087Z,PYPL,SELL - MARKET,3,USD 308.81,USD 926.42,USD,1.1764 2021-07-23T16:05:29.193871Z,MRNA,BUY - MARKET,2,USD 335.27,USD 670.54,USD,1.1765 2021-07-27T06:51:45.976639Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1793 2021-08-01T05:41:21.067616Z,,CUSTODY FEE,,,USD -1.12,USD,1.1999 2021-08-03T18:07:55.781076Z,MRNA,SELL - LIMIT,2,USD 370,USD 739.99,USD,1.1866 2021-08-03T18:10:06.118513Z,AMZN,BUY - MARKET,0.22221761,USD 3375.07,USD 750,USD,1.1866 2021-08-09T14:53:34.032557Z,GOOGL,SELL - MARKET,0.21915668,USD 2716.87,USD 595.41,USD,1.1751 2021-08-09T14:54:08.334621Z,MRNA,BUY - MARKET,1,USD 450.93,USD 450.93,USD,1.1752 2021-08-13T04:42:24.271612Z,AAPL,DIVIDEND,,,USD 2.62,USD,1.1742 2021-08-16T13:39:48.653719Z,AAPL,SELL - LIMIT,4,USD 150,USD 599.99,USD,1.1785 2021-08-19T13:30:23.348630Z,AAPL,BUY - LIMIT,5,USD 144.93,USD 724.65,USD,1.1697 2021-09-01T07:40:38.748966Z,,CUSTODY FEE,,,USD -1.15,USD,1.1800 2021-09-07T13:41:12.356305Z,AAPL,SELL - LIMIT,5,USD 155.05,USD 775.24,USD,1.1862 2021-09-10T16:13:16.888876Z,AAPL,BUY - MARKET,5,USD 149.97,USD 749.85,USD,1.1823 2021-09-17T14:05:43.934832Z,TSLA,SELL - MARKET,0.78607363,USD 758.73,USD 596.41,USD,1.1758 2021-09-17T14:06:29.208538Z,AAPL,BUY - MARKET,4,USD 146.83,USD 587.32,USD,1.1758 2021-10-01T03:10:46.826293Z,,CUSTODY FEE,,,USD -1.11,USD,1.1580 2021-10-01T08:38:11.538983Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1582 2021-10-19T15:35:49.113762Z,ANSS,SELL - MARKET,2,USD 364.67,USD 729.33,USD,1.1638 2021-10-19T15:36:40.367755Z,GOOGL,BUY - MARKET,0.25686385,USD 2859.18,USD 734.42,USD,1.1640 2021-10-21T14:37:31.105249Z,TSLA,SELL - MARKET,0.84141694,USD 895.48,USD 753.46,USD,1.1640 2021-10-25T13:30:27.810820Z,TSLA,SELL - LIMIT,1,USD 951.50,USD 951.49,USD,1.1614 2021-10-25T14:12:51.623985Z,TSLA,SELL - MARKET,0.98496385,USD 956.01,USD 941.63,USD,1.1613 2021-10-25T14:30:51.121969Z,TSLA,SELL - MARKET,0.99999994,USD 974.91,USD 974.90,USD,1.1615 2021-10-25T14:35:27.184763Z,,CASH WITHDRAWAL,,,USD -78.27,USD,1.1616 2021-10-25T16:30:55.577488Z,TSLA,SELL - MARKET,1,USD 992.83,USD 992.81,USD,1.1610 2021-10-26T13:33:01.736631Z,TSLA,BUY - MARKET,1,USD 1044.49,USD 1044.49,USD,1.1609 2021-10-26T13:45:33.604150Z,AAPL,BUY - MARKET,4,USD 150.48,USD 601.92,USD,1.1611 2021-10-27T16:17:31.917375Z,AAPL,BUY - MARKET,10,USD 149.25,USD 1492.49,USD,1.1603 2021-10-29T10:53:14.177467Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1652 2021-11-01T14:50:45.336203Z,TSLA,SELL - LIMIT,1,USD 1150,USD 1149.98,USD,1.1583 2021-11-01T20:36:56.194415Z,,CASH WITHDRAWAL,,,USD -100,USD,1.1609 2021-11-04T01:13:01.959445Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.1613 2021-11-04T03:17:16.783359Z,,CUSTODY FEE,,,USD -1.07,USD,1.1603 2021-11-04T06:29:23.316411Z,,CASH TOP-UP,,,USD 2000,USD,1.1586 2021-11-04T14:10:12.273414Z,NIO,SELL - MARKET,13,USD 43.54,USD 566.02,USD,1.1553 2021-11-04T14:22:38.394300Z,KO,BUY - MARKET,10,USD 56.29,USD 562.89,USD,1.1552 2021-11-04T14:23:41.524349Z,BAC,BUY - MARKET,10,USD 47.49,USD 474.89,USD,1.1551 2021-11-09T16:46:11.784013Z,TSLA,BUY - MARKET,1,USD 1065.78,USD 1065.78,USD,1.1586 2021-11-09T16:52:01.682293Z,SPCE,SELL - LIMIT,24,USD 20.99,USD 503.77,USD,1.1588 2021-11-10T15:33:05.030639Z,TSLA,BUY - MARKET,1,USD 1073.50,USD 1073.50,USD,1.1521 2021-11-17T07:09:11.457335Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1305 2021-11-18T19:06:58.592793Z,AAPL,SELL - LIMIT,2,USD 158,USD 315.99,USD,1.1372 2021-11-19T14:33:40.386692Z,AMZN,SELL - MARKET,0.22221761,USD 3734.13,USD 829.78,USD,1.1315 2021-11-19T16:55:21.098116Z,AAPL,SELL - LIMIT,5,USD 160,USD 799.99,USD,1.1318 2021-11-19T19:20:55.700535Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1292 2021-11-22T10:38:55.919887Z,,CASH WITHDRAWAL,,,USD -153.20,USD,1.1287 2021-11-22T14:38:56.905968Z,PYPL,SELL - MARKET,3,USD 191.85,USD 575.54,USD,1.1242 2021-11-22T14:40:07.462187Z,AAPL,BUY - MARKET,10,USD 163.08,USD 1630.79,USD,1.1243 2021-11-22T14:40:36.826246Z,TSLA,BUY - MARKET,0.5,USD 1181.76,USD 590.88,USD,1.1244 2021-11-22T17:28:58.134841Z,MRNA,BUY - LIMIT,1,USD 287.97,USD 287.97,USD,1.1255 2021-11-26T14:30:44.164387Z,MRNA,SELL - LIMIT,1,USD 320,USD 319.99,USD,1.1289 2021-11-26T15:11:21.748088Z,AAPL,BUY - LIMIT,2,USD 158.17,USD 316.34,USD,1.1300 2021-11-26T17:15:02.710330Z,MRNA,SELL - MARKET,1,USD 327.96,USD 327.95,USD,1.1300 2021-11-26T17:19:19.840447Z,AMZN,BUY - MARKET,0.09497631,USD 3527.09,USD 334.99,USD,1.1297 2021-11-30T20:55:44.227431Z,AAPL,SELL - LIMIT,7,USD 165,USD 1154.98,USD,1.1337 2021-12-01T16:17:49.426751Z,AAPL,SELL - LIMIT,15,USD 170,USD 2549.98,USD,1.1331 2021-12-02T06:08:45.125392Z,,CUSTODY FEE,,,USD -1.07,USD,1.1325 2021-12-02T09:09:32.353819Z,,CASH WITHDRAWAL,,,USD -300,USD,1.1325 2021-12-02T09:09:59.218758Z,,CASH TOP-UP,,,USD 100,USD,1.1324 2021-12-02T14:30:31.195638Z,AAPL,BUY - LIMIT,7,USD 158.72,USD 1111.04,USD,1.1345 2021-12-02T14:48:54.578317Z,AAPL,BUY - MARKET,3,USD 160.89,USD 482.67,USD,1.1349 2021-12-02T17:17:29.448590Z,AMZN,BUY - MARKET,0.08667514,USD 3461.20,USD 300,USD,1.1310 2021-12-02T17:22:47.526948Z,AAPL,BUY - MARKET,9,USD 163.26,USD 1469.33,USD,1.1307 2021-12-03T15:52:09.743899Z,SPCE,SELL - MARKET,12,USD 14.32,USD 171.84,USD,1.1280 2021-12-06T15:14:43.715974Z,AAPL,SELL - MARKET,4,USD 167.09,USD 668.35,USD,1.1290 2021-12-06T15:23:37.271485Z,,CASH TOP-UP,,,USD 50,USD,1.1293 2021-12-06T15:24:23.771651Z,TSLA,BUY - LIMIT,1,USD 992.90,USD 992.90,USD,1.1291 2021-12-10T20:40:03.360809Z,AAPL,SELL - MARKET,5,USD 178.17,USD 890.85,USD,1.1316 2021-12-10T20:46:05.031639Z,,CASH WITHDRAWAL,,,USD -26.65,USD,1.1319 2021-12-13T14:31:24.268753Z,AAPL,SELL - LIMIT,7,USD 181,USD 1266.98,USD,1.1294 2021-12-13T17:18:39.928392Z,AAPL,BUY - MARKET,4,USD 178.20,USD 712.80,USD,1.1302 2021-12-14T07:45:33.061233Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1279 2021-12-14T19:27:37.943686Z,TSLA,BUY - MARKET,0.5,USD 943.68,USD 471.84,USD,1.1264 2021-12-14T19:27:59.893606Z,AAPL,BUY - MARKET,4,USD 174.17,USD 696.68,USD,1.1264 2021-12-17T08:05:11.817525Z,KO,DIVIDEND,,,USD 3.57,USD,1.1323 2021-12-21T22:24:23.051009Z,,CASH TOP-UP,,,USD 550,USD,1.1288 2021-12-25T17:04:42.634707Z,,CASH TOP-UP,,,USD 100,USD,1.1315 2021-12-27T16:07:19.048883Z,TSLA,SELL - MARKET,0.5,USD 1102.70,USD 551.34,USD,1.1327 2021-12-28T15:52:44.354571Z,AMZN,BUY - MARKET,0.05822687,USD 3434.84,USD 200,USD,1.1295 2022-01-03T15:04:47.514435Z,TSLA,SELL - MARKET,1,USD 1153.59,USD 1153.57,USD,1.1309 2022-01-03T17:21:55.035249Z,ANSS,BUY - MARKET,2,USD 393.43,USD 786.86,USD,1.1288 2022-01-03T20:22:20.865769Z,TSLA,SELL - MARKET,0.5,USD 1194.86,USD 597.42,USD,1.1302 2022-01-04T05:38:05.560396Z,BAC,DIVIDEND,,,USD 1.78,USD,1.1307 2022-01-04T10:52:06.498921Z,,CUSTODY FEE,,,USD -1.16,USD,1.1303 2022-01-06T14:54:57.808284Z,TSLA,BUY - LIMIT,1,USD 1050,USD 1050,USD,1.1330 2022-01-11T14:44:35.020133Z,AAPL,BUY - LIMIT,6,USD 171,USD 1026,USD,1.1324 2022-02-02T13:11:56.907881Z,,CUSTODY FEE,,,USD -1.22,USD,1.1324 2022-02-02T14:35:03.638282Z,PYPL,SELL - MARKET,2.8,USD 136.33,USD 381.71,USD,1.1317 2022-02-02T14:38:16.310927Z,GOOGL,BUY - MARKET,0.1370781,USD 3006.68,USD 412.15,USD,1.1318 2022-02-15T05:59:54.545870Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1320 2022-02-17T19:14:51.499522Z,KO,SELL - LIMIT,10,USD 62,USD 619.99,USD,1.1365 2022-02-18T14:43:59.084299Z,TSLA,BUY - MARKET,0.5,USD 863.86,USD 431.93,USD,1.1344 2022-02-18T16:23:53.036317Z,O,BUY - MARKET,2,USD 67.03,USD 134.06,USD,1.1336 2022-02-28T12:59:53.335490Z,,CASH TOP-UP,,,USD 250,USD,1.1198 2022-02-28T14:38:21.778362Z,KO,BUY - MARKET,2,USD 61.93,USD 123.86,USD,1.1225 2022-03-02T06:56:23.623381Z,,CUSTODY FEE,,,USD -1.16,USD,1.1104 2022-03-02T16:10:30.245886Z,MSFT,BUY - MARKET,0.62199751,USD 297.67,USD 185.15,USD,1.1092 2022-03-16T05:35:16.177499Z,O,DIVIDEND,,,USD 0.42,USD,1.0978 2022-03-22T15:06:09.673524Z,TSLA,SELL - MARKET,0.5,USD 942.18,USD 471.08,USD,1.1033 2022-03-25T09:15:31.379423Z,,CASH WITHDRAWAL,,,USD -257.83,USD,1.1004 2022-03-28T04:32:31.012802Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0955 2022-04-02T04:06:59.837476Z,,CUSTODY FEE,,,USD -1.24,USD,1.1051 2022-04-04T04:35:23.159499Z,KO,DIVIDEND,,,USD 0.75,USD,1.1051 2022-04-13T19:27:21.376535Z,AAPL,BUY - MARKET,1,USD 170.66,USD 170.66,USD,1.0892 2022-04-14T11:17:15.965883Z,,CASH TOP-UP,,,USD 200,USD,1.0905 2022-04-14T13:30:19.229173Z,TWTR,BUY - LIMIT,4,USD 48.42,USD 193.68,USD,1.0829 2022-04-19T05:08:35.489675Z,O,DIVIDEND,,,USD 0.42,USD,1.0772 2022-04-19T13:30:44.030267Z,TWTR,BUY - LIMIT,1,USD 47.24,USD 47.24,USD,1.0798 2022-04-20T17:05:03.527689Z,O,SELL - LIMIT,2,USD 75,USD 149.99,USD,1.0848 2022-04-22T13:56:13.446949Z,O,BUY - LIMIT,2,USD 74,USD 148,USD,1.0817 2022-05-03T04:22:39.919354Z,,CUSTODY FEE,,,USD -1.11,USD,1.0519 2022-05-16T05:21:24.813176Z,O,DIVIDEND,,,USD 0.42,USD,1.0410 2022-05-16T05:26:42.889192Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0407 2022-05-20T08:17:11.587079Z,,CASH TOP-UP,,,USD 150,USD,1.0562 2022-05-20T13:30:08.229515Z,AAPL,BUY - LIMIT,1,USD 139.02,USD 139.02,USD,1.0564 2022-06-02T05:19:39.349765Z,,CUSTODY FEE,,,USD -1.05,USD,1.0657 2022-06-06T05:21:09.168520Z,AMZN,STOCK SPLIT,4.55768808,,USD 0,USD,1.0738 2022-06-07T15:18:23.292832Z,,CASH TOP-UP,,,USD 10,USD,1.0702 2022-06-07T15:19:02.548830Z,AMZN,BUY - MARKET,0.2024336,USD 122.26,USD 24.75,USD,1.0700 2022-06-10T04:51:36.764084Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0635 2022-06-16T04:24:09.940734Z,O,DIVIDEND,,,USD 0.42,USD,1.0441 2022-06-27T04:21:07.933377Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0571 2022-07-02T10:16:19.663439Z,,CUSTODY FEE,,,USD -0.96,USD,1.0432 2022-07-05T04:30:14.263191Z,KO,DIVIDEND,,,USD 0.75,USD,1.0442 2022-07-18T04:23:43.057183Z,O,DIVIDEND,,,USD 0.42,USD,1.0105 2022-07-18T05:13:29.606545Z,GOOGL,STOCK SPLIT,7.48489705,,USD 0,USD,1.0100 2022-07-21T16:32:01.558198Z,AAPL,SELL - LIMIT,1,USD 155.04,USD 155.02,USD,1.0194 2022-07-29T15:15:54.355733Z,,CASH TOP-UP,,,USD 150,USD,1.0209 2022-08-02T14:00:10.449611Z,,CUSTODY FEE,,,USD -1.13,USD,1.0210 2022-08-16T06:38:59.962142Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0171 2022-08-16T06:48:27.180503Z,O,DIVIDEND,,,USD 0.42,USD,1.0165 2022-08-25T08:29:28.839969Z,TSLA,STOCK SPLIT,6,,USD 0,USD,0.9997 2022-09-03T11:43:40.762285Z,,CUSTODY FEE,,,USD -1.08,USD,0.9961 2022-09-12T05:35:58.495990Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0096 2022-09-14T14:19:49.128161Z,AAPL,BUY - LIMIT,2,USD 155.78,USD 311.56,USD,0.9982 2022-09-16T05:17:20.255485Z,O,DIVIDEND,,,USD 0.42,USD,0.9995 2022-10-03T04:32:31.694830Z,BAC,DIVIDEND,,,USD 1.87,USD,0.9807 2022-10-04T04:31:18.366499Z,,CUSTODY FEE,,,USD -1,USD,0.9841 2022-10-04T06:15:22.053724Z,KO,DIVIDEND,,,USD 0.75,USD,0.9861 2022-10-05T14:17:47.799690Z,TWTR,SELL - MARKET,5,USD 50.93,USD 254.64,USD,0.9852 2022-10-17T04:30:26.662073Z,O,DIVIDEND,,,USD 0.42,USD,0.9748 2022-11-02T09:58:08.362246Z,,CUSTODY FEE,,,USD -1,USD,0.9906 2022-11-11T10:43:43.775454Z,AAPL,DIVIDEND,,,USD 7.04,USD,1.0271 2022-11-16T06:44:25.085056Z,O,DIVIDEND,,,USD 0.42,USD,1.0383 2022-12-02T06:58:53.260720Z,,CUSTODY FEE,,,USD -0.97,USD,1.0532 2022-12-09T07:49:09.937455Z,MSFT,DIVIDEND,,,USD 0.36,USD,1.0582 2022-12-16T06:53:22.378091Z,KO,DIVIDEND,,,USD 0.75,USD,1.0667 2022-12-16T06:58:57.301385Z,O,DIVIDEND,,,USD 0.42,USD,1.0662 2022-12-20T14:35:52.087523Z,AAPL,BUY - LIMIT,2,USD 130,USD 260,USD,1.0620 2023-01-03T05:33:54.622583Z,BAC,DIVIDEND,,,USD 1.87,USD,1.0672 2023-01-04T09:51:33.829102Z,,CUSTODY FEE,,,USD -0.84,USD,1.0625 2023-01-17T05:40:19.551093Z,O,DIVIDEND,,,USD 0.35,USD,1.0831 2023-01-23T16:49:31.990Z,AAPL,SELL - LIMIT,2,USD 143,USD 285.98,USD,1.0868 2023-01-23T16:50:31.944Z,TSLA,BUY - MARKET,2,USD 141.48,USD 282.96,USD,1.0866 2023-01-26T14:30:02.502Z,TSLA,SELL - LIMIT,2,USD 159.99,USD 319.96,USD,1.0901 2023-01-30T15:28:04.951Z,AAPL,BUY - MARKET,2,USD 143.94,USD 287.88,USD,1.0889 2023-02-01T04:47:19.689616Z,,CUSTODY FEE,,,USD -0.95,USD,1.0871 2023-02-16T07:10:29.099680Z,O,DIVIDEND,,,USD 0.35,USD,1.0707 2023-02-17T07:05:43.640146Z,AAPL,DIVIDEND,,,USD 6.12,USD,1.0641 2023-03-01T11:12:23.865134Z,,CASH TOP-UP,,,USD 250,USD,1.0669 2023-03-01T14:45:06.338Z,BRK.B,BUY - LIMIT,1,USD 303.16,USD 303.16,USD,1.0685 2023-03-02T08:37:29.518195Z,,CUSTODY FEE,,,USD -1,USD,1.0636 2023-03-13T05:01:07.362448Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0731 2023-03-16T05:53:51.457497Z,O,DIVIDEND,,,USD 0.36,USD,1.0618 2023-03-22T14:28:40.213Z,AAPL,SELL - LIMIT,2,USD 160,USD 319.98,USD,1.0794 2023-04-03T04:34:36.432266Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0809 2023-04-04T07:43:19.011071Z,KO,DIVIDEND,,,USD 0.64,USD,1.0919 2023-04-04T10:05:57.474134Z,,CUSTODY FEE,,,USD -1.08,USD,1.0941 2023-04-17T05:14:59.411865Z,O,DIVIDEND,,,USD 0.36,USD,1.1000 2023-05-02T16:58:09.717081Z,,CUSTODY FEE,,,USD -1.07,USD,1.1010 2023-05-05T13:33:41.989Z,AAPL,SELL - LIMIT,2,USD 172,USD 343.98,USD,1.0998 2023-05-08T16:49:22.657920Z,,CASH TOP-UP,,,USD 150,USD,1.1037 2023-05-08T16:50:05.075Z,TSLA,BUY - MARKET,1,USD 171.76,USD 171.76,USD,1.1037 2023-05-16T05:28:06.065980Z,O,DIVIDEND,,,USD 0.36,USD,1.0890 2023-05-19T06:32:05.730565Z,AAPL,DIVIDEND,,,USD 5.71,USD,1.0800 2023-05-23T13:45:40.451Z,TSLA,SELL - LIMIT,1,USD 190,USD 189.98,USD,1.0783 2023-05-23T13:53:42.530Z,AAPL,BUY - MARKET,1,USD 172.79,USD 172.79,USD,1.0783 2023-05-25T13:41:55.501Z,MSFT,SELL - MARKET,0.62199751,USD 321.63,USD 200.03,USD,1.0722 2023-05-26T14:28:00.905Z,TSLA,BUY - MARKET,1,USD 190.12,USD 190.12,USD,1.0743 2023-06-02T08:57:47.333209Z,,CUSTODY FEE,,,USD -1.13,USD,1.0788 2023-06-02T13:30:02.757Z,TSLA,SELL - LIMIT,1,USD 210,USD 209.98,USD,1.0779 2023-06-05T11:24:00.663315Z,,CASH TOP-UP,,,USD 100,USD,1.0703 2023-06-06T07:53:30.801799Z,,CASH WITHDRAWAL,,,USD -200,USD,1.0725 2023-06-06T15:58:37.683Z,AAPL,BUY - MARKET,4,USD 178.62,USD 714.50,USD,1.0706 2023-06-09T06:10:29.033529Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0787 2023-06-14T15:52:32.276Z,BRK.B,SELL - LIMIT,1,USD 340,USD 339.98,USD,1.0868 2023-06-14T16:30:12.174Z,TSLA,BUY - MARKET,1,USD 258,USD 258,USD,1.0872 2023-06-15T13:53:37.361Z,AAPL,SELL - LIMIT,19,USD 185.01,USD 3515.15,USD,1.0909 2023-06-15T14:32:54.586Z,BRK.B,BUY - MARKET,4,USD 338.24,USD 1352.95,USD,1.0927 2023-06-16T04:49:46.803865Z,O,DIVIDEND,,,USD 0.36,USD,1.0954 2023-06-20T17:34:39.166Z,TSLA,BUY - MARKET,2,USD 271.03,USD 542.06,USD,1.0929 2023-06-30T15:35:47.990Z,AAPL,BUY - MARKET,4,USD 192.45,USD 769.79,USD,1.0928 2023-07-03T04:42:47.064493Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0929 2023-07-04T06:14:58.867435Z,,CUSTODY FEE,,,USD -1.19,USD,1.0914 2023-07-05T04:38:30.594392Z,KO,DIVIDEND,,,USD 0.64,USD,1.0888 2023-07-17T04:29:28.019975Z,O,DIVIDEND,,,USD 0.36,USD,1.1239 2023-07-19T13:58:34.924Z,TSLA,BUY - MARKET,3,USD 296.58,USD 889.74,USD,1.1228 2023-08-02T09:34:03.883636Z,,CUSTODY FEE,,,USD -1.31,USD,1.0994 2023-08-16T04:35:04.390352Z,O,DIVIDEND,,,USD 0.36,USD,1.0928 2023-08-18T04:57:05.333405Z,AAPL,DIVIDEND,,,USD 4.03,USD,1.0901 2023-09-02T03:13:46.440774Z,,CUSTODY FEE,,,USD -1.27,USD,1.0790 2023-09-09T08:05:14.452584Z,,TRANSFER FROM REVOLUT BANK UAB TO REVOLUT SECURITIES EUROPE UAB,,,USD 117.44,USD,1.0719 2023-09-09T09:34:24.443702Z,GOOGL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,7.878839,,USD 0,USD,1.0719 2023-09-09T09:34:24.561658Z,O,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:24.660297Z,TSLA,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,15,,USD 0,USD,1.0719 2023-09-09T09:34:24.767410Z,BAC,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,10,,USD 0,USD,1.0719 2023-09-09T09:34:24.873457Z,BRK.B,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,4,,USD 0,USD,1.0719 2023-09-09T09:34:24.979123Z,KO,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.079904Z,ANSS,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.189128Z,AMZN,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,5,,USD 0,USD,1.0719 2023-09-09T09:34:25.292873Z,AAPL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,24,,USD 0,USD,1.0719 2023-09-13T15:07:29.260651Z,,CASH TOP-UP,,,USD 11.76,USD,1.0756 2023-09-13T15:08:11.622299Z,,CASH TOP-UP,,,USD 400,USD,1.0757 2023-09-13T15:09:28.691Z,AAPL,BUY - LIMIT,3,USD 175.02,USD 525.05,USD,1.0757 2023-09-18T10:59:47.342077Z,O,DIVIDEND,,,USD 0.36,USD,1.0686 2023-10-01T07:39:16.220080Z,,CUSTODY FEE,,,USD -1.25,USD,1.0595 2023-10-02T11:08:11.013935Z,BAC,DIVIDEND,,,USD 1.68,USD,1.0550 2023-10-03T12:35:09.127138Z,KO,DIVIDEND,,,USD 0.78,USD,1.0488 2023-10-16T13:27:58.306547Z,O,DIVIDEND,,,USD 0.43,USD,1.0557 2023-11-02T07:47:24.136368Z,,CUSTODY FEE,,,USD -1.17,USD,1.0617 2023-11-16T12:42:39.810501Z,O,DIVIDEND,,,USD 0.43,USD,1.0863 2023-11-16T14:31:16.694Z,AAPL,SELL - LIMIT,6,USD 190,USD 1139.98,USD,1.0885 2023-11-17T18:26:36.033179Z,AAPL,DIVIDEND,,,USD 5.51,USD,1.0913 2023-12-01T10:05:46.401211Z,,CUSTODY FEE,,,USD -1.19,USD,1.0922 2023-12-13T13:32:17.638Z,AAPL,SELL - LIMIT,7,USD 196,USD 1371.98,USD,1.0814 2023-12-14T11:33:48.192861Z,,CASH WITHDRAWAL,,,USD -490,USD,1.0942 2023-12-14T11:42:42.236702Z,,CASH WITHDRAWAL,,,USD -540,USD,1.0945 2023-12-14T11:44:57.481825Z,,CASH TOP-UP,,,EUR 493.36,EUR,1.0000 2023-12-14T11:46:14.224594Z,,CASH TOP-UP,,,EUR 22.55,EUR,1.0000 2023-12-14T11:46:28.633Z,EUNL,BUY - MARKET,6,EUR 81.89,EUR 491.33,EUR,1.0000 2023-12-14T11:46:58.960291Z,,CASH WITHDRAWAL,,,EUR -22.55,EUR,1.0000 2023-12-18T14:35:49.692078Z,O,DIVIDEND,,,USD 0.43,USD,1.0945 2023-12-18T14:42:19.088Z,AAPL,BUY - LIMIT,2,USD 195,USD 390,USD,1.0946 2023-12-18T16:03:32.089281Z,KO,DIVIDEND,,,USD 0.78,USD,1.0937 2023-12-22T14:53:30.293Z,ANSS,SELL - MARKET,2,USD 334.81,USD 669.60,USD,1.1060 2023-12-22T14:55:28Z,AAPL,BUY - MARKET,3,USD 195.24,USD 585.73,USD,1.1059 2023-12-29T17:03:07.509Z,AAPL,BUY - MARKET,3,USD 192.32,USD 576.95,USD,1.1082 2024-01-01T07:00:29.342845Z,,CUSTODY FEE,,,USD -1.18,USD,1.1060 2024-01-01T07:00:29.400142Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-01-03T17:20:49.193495Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0927 2024-01-08T09:32:34.413Z,AAPL,BUY - LIMIT,3,USD 180,USD 540,USD,1.0945 2024-01-16T12:06:46.872915Z,O,DIVIDEND,,,USD 0.43,USD,1.0909 2024-01-25T14:32:03.923Z,BRK.B,SELL - LIMIT,4,USD 380,USD 1519.98,USD,1.0876 2024-01-25T14:46:38.746Z,TSLA,SELL - MARKET,3,USD 187.76,USD 563.25,USD,1.0875 2024-01-25T14:53:37.441Z,NVDA,BUY - MARKET,3,USD 621.78,USD 1865.35,USD,1.0876 2024-01-29T15:13:05.633327Z,,CASH WITHDRAWAL,,,USD -288.99,USD,1.0829 2024-01-31T16:53:08.153Z,TSLA,SELL - LIMIT,3,USD 190,USD 569.98,USD,1.0877 2024-01-31T17:17:42.114Z,MSFT,BUY - MARKET,1,USD 402.58,USD 402.58,USD,1.0869 2024-02-01T03:25:42.443177Z,,CUSTODY FEE,,,USD -1.10,USD,1.0837 2024-02-01T03:25:42.504846Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-02-02T18:27:54.549Z,AMZN,SELL - MARKET,5,USD 171.96,USD 859.78,USD,1.0804 2024-02-02T18:28:56.258Z,NVDA,BUY - MARKET,1,USD 659.78,USD 659.78,USD,1.0805 2024-02-02T18:42:33.310Z,AAPL,BUY - MARKET,1,USD 186.01,USD 186.01,USD,1.0809 2024-02-05T19:01:24.403Z,TSLA,SELL - MARKET,3,USD 181.48,USD 544.43,USD,1.0765 2024-02-05T19:13:49.716Z,NVDA,BUY - MARKET,1,USD 688.87,USD 688.87,USD,1.0765 2024-02-09T18:38:36.240Z,NVDA,SELL - LIMIT,3,USD 720,USD 2159.97,USD,1.0809 2024-02-09T19:04:23.041Z,TSLA,SELL - MARKET,4,USD 192.78,USD 771.11,USD,1.0811 2024-02-13T14:35:34.549398Z,,CASH WITHDRAWAL,,,USD -755.30,USD,1.0737 2024-02-16T15:48:11.314342Z,O,DIVIDEND,,,USD 0.43,USD,1.0796 2024-02-16T17:20:34.309565Z,AAPL,DIVIDEND,,,USD 5.30,USD,1.0789 2024-02-21T21:25:57.106Z,NVDA,BUY - LIMIT,3,USD 679,USD 2037,USD,1.0838 2024-03-01T09:08:46.556Z,TSLA,SELL - LIMIT,2,USD 201.22,USD 402.43,USD,1.0834 2024-03-05T17:02:20.128Z,BRK.B,BUY - LIMIT,1,USD 400,USD 400,USD,1.0882 2024-03-11T09:45:10.733671Z,,CASH TOP-UP,,,USD 1091.80,USD,1.0964 2024-03-11T09:45:57.889Z,NVDA,BUY - LIMIT,1,USD 889.33,USD 889.33,USD,1.0964 2024-03-11T14:04:39.233521Z,,CASH TOP-UP,,,USD 126.74,USD,1.0941 2024-03-15T12:28:23.824579Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0914 2024-03-18T13:44:16.977280Z,O,DIVIDEND,,,USD 0.43,USD,1.0912 2024-03-28T12:59:32.090109Z,NVDA,DIVIDEND,,,USD 0.17,USD,1.0831 2024-04-01T14:18:52.459Z,AAPL,BUY - LIMIT,3,USD 170,USD 510,USD,1.0768 2024-04-02T17:32:27.807174Z,KO,DIVIDEND,,,USD 0.82,USD,1.0788 2024-04-02T17:50:08.293837Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0789 2024-04-12T13:53:08.110Z,GOOGL,SELL - LIMIT,5,USD 160,USD 799.98,USD,1.0659 2024-04-16T11:57:48.211880Z,O,DIVIDEND,,,USD 0.43,USD,1.0668 2024-04-22T13:42:17.982936Z,,CASH WITHDRAWAL,,,USD -720,USD,1.0653 2024-04-22T13:43:26.153902Z,,CASH TOP-UP,,,EUR 675.75,EUR,1.0000 2024-04-22T13:44:05.671Z,EUNL,BUY - MARKET,7,EUR 88.42,EUR 618.93,EUR,1.0000 2024-04-26T13:30:00.940Z,GOOGL,SELL - MARKET,2.878839,USD 174.33,USD 501.85,USD,1.0733 2024-04-30T14:37:07.030880Z,,CASH WITHDRAWAL,,,USD -398.79,USD,1.0728 2024-05-16T08:51:27.652167Z,O,DIVIDEND,,,USD 0.43,USD,1.0895 2024-05-17T10:26:14.210180Z,AAPL,DIVIDEND,,,USD 6.16,USD,1.0867 2024-05-20T13:54:41.117Z,NVDA,SELL - LIMIT,1,USD 950,USD 949.98,USD,1.0889 2024-05-22T21:14:39.325Z,NVDA,SELL - LIMIT,5,USD 1000,USD 4999.85,USD,1.0847 2024-05-28T15:44:41.483Z,NVDA,BUY - MARKET,3,USD 1120.59,USD 3361.77,USD,1.0899 2024-06-05T10:11:57.724Z,KO,SELL - LIMIT,2,USD 63.92,USD 127.83,USD,1.0890 2024-06-06T12:20:06.768Z,NVDA,BUY - LIMIT,2,USD 1249.18,USD 2498.35,USD,1.0907 2024-06-10T12:35:45.964651Z,NVDA,STOCK SPLIT,45,,USD 0,USD,1.0778 2024-06-11T14:16:51.891Z,AAPL,SELL - LIMIT,6,USD 200,USD 1199.96,USD,1.0748 2024-06-12T13:53:20.883Z,AAPL,BUY - MARKET,7,USD 213.95,USD 1497.64,USD,1.0856 2024-06-14T10:17:31.111265Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0709 2024-06-17T10:18:03.287961Z,O,DIVIDEND,,,USD 0.44,USD,1.0728 2024-06-17T18:01:31.892Z,MSFT,SELL - LIMIT,1,USD 450,USD 449.98,USD,1.0750 2024-06-20T15:19:16.531Z,AAPL,BUY - LIMIT,2,USD 210,USD 420,USD,1.0741 2024-07-01T11:01:29.101517Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.0772 2024-07-01T12:19:36.098603Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0768 2024-07-02T15:09:31.105Z,AAPL,SELL - LIMIT,9,USD 220,USD 1979.93,USD,1.0762 2024-07-03T14:43:34.756Z,TSLA,BUY - MARKET,2,USD 247.92,USD 495.85,USD,1.0825 2024-07-11T12:30:08.457Z,BAC,SELL - LIMIT,10,USD 42,USD 419.98,USD,1.0899 2024-07-11T13:25:05.444Z,TSM,BUY - LIMIT,10,USD 193.86,USD 1938.61,USD,1.0915 2024-07-16T08:59:29.967862Z,O,DIVIDEND,,,USD 0.44,USD,1.0923 2024-07-17T14:40:33.756Z,O,SELL - MARKET,2,USD 57.17,USD 114.32,USD,1.0957 2024-07-23T14:02:29.334480Z,,CASH TOP-UP,,,EUR 800,EUR,1.0000 2024-07-23T14:03:16.459Z,EXXT,BUY - MARKET,4.84403203,EUR 177.28,EUR 858.75,EUR,1.0000 2024-07-30T13:34:15.782Z,BRK.B,SELL - LIMIT,1,USD 440,USD 439.98,USD,1.0832 2024-08-01T21:50:35.835874Z,,CASH TOP-UP,,,USD 1077.48,USD,1.0809 2024-08-01T21:51:25.637Z,AAPL,BUY - LIMIT,5,USD 218.85,USD 1094.25,USD,1.0809 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,2,USD 204.90,USD 409.80,USD,1.0966 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,1,USD 204.90,USD 204.90,USD,1.0966 2024-08-16T15:20:28.266341Z,AAPL,DIVIDEND,,,USD 6.59,USD,1.1011 2024-08-29T11:33:30.727Z,AAPL,SELL - LIMIT,5,USD 230,USD 1149.96,USD,1.1113 2024-09-05T08:59:30.602Z,TSLA,SELL - LIMIT,2,USD 225.22,USD 450.43,USD,1.1118 2024-10-04T10:47:03.807610Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.1053 2024-10-10T08:38:54.394212Z,TSM,DIVIDEND,,,USD 4.93,USD,1.0958 2024-10-11T14:46:49.313Z,TSM,SELL - MARKET,10,USD 189.81,USD 1898.01,USD,1.0965 2024-10-17T10:50:43.300Z,NVDA,SELL - LIMIT,10,USD 140,USD 1399.95,USD,1.0885 2024-11-06T15:32:35.795880Z,,CASH TOP-UP,,,USD 34.98,USD,1.0750 2024-11-06T15:32:48.038Z,AAPL,BUY - MARKET,21,USD 225.81,USD 4741.95,USD,1.0750 2024-11-06T15:33:20.894832Z,,CASH WITHDRAWAL,,,USD -34.98,USD,1.0748 2024-11-15T10:57:21.547072Z,AAPL,DIVIDEND,,,USD 9.99,USD,1.0596 2024-11-25T15:51:08.045065Z,,CASH TOP-UP,,,USD 1004,USD,1.0525 2024-11-25T15:51:44.437Z,NVDA,BUY - MARKET,8,USD 137.70,USD 1101.58,USD,1.0526 2024-11-26T14:35:15.260Z,AAPL,SELL - LIMIT,9,USD 235,USD 2114.93,USD,1.0517 2024-11-29T12:41:10.527444Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.0574 2024-12-18T15:56:03.404813Z,EXXT,DIVIDEND,,,EUR 0.51,EUR,1.0000 2024-12-18T18:45:05.272532Z,,CASH TOP-UP,,,USD 2006.76,USD,1.0513 2024-12-18T18:45:59.510540Z,,CASH WITHDRAWAL,,,USD -2240.70,USD,1.0514 2024-12-18T18:47:39.084460Z,,CASH TOP-UP,,,EUR 2133.85,EUR,1.0000 2024-12-18T18:49:15.187Z,EXXT,BUY - LIMIT,10,EUR 203.80,EUR 2038,EUR,1.0000 2024-12-19T08:40:07.479915Z,,CASH TOP-UP,,,USD 0.02,USD,1.0415 2024-12-30T10:55:50.865219Z,NVDA,DIVIDEND,,,USD 0.41,USD,1.0464 2025-01-06T14:49:38.005Z,NVDA,SELL - LIMIT,20,USD 150,USD 2999.91,USD,1.0408 2025-01-07T09:50:04.477942Z,,CASH WITHDRAWAL,,,USD -3000,USD,1.0449 2025-01-07T15:54:48.223347Z,,CASH TOP-UP,,,USD 3001.30,USD,1.0396 2025-01-07T15:56:07.411Z,NVDA,BUY - LIMIT,21,USD 142.77,USD 2998.17,USD,1.0396 2025-01-28T08:48:36.329627Z,,CASH TOP-UP,,,USD 245,USD,1.0451 2025-01-28T09:07:04.086Z,NVDA,BUY - LIMIT,2,USD 123.58,USD 247.17,USD,1.0449 2025-02-14T20:37:33.255111Z,AAPL,DIVIDEND,,,USD 8.08,USD,1.0521 2025-03-19T15:56:49.384716Z,EXXT,DIVIDEND,,,EUR 1.67,EUR,1.0000 2025-04-03T15:56:21.046251Z,NVDA,DIVIDEND,,,USD 0.43,USD,1.1083 2025-05-16T18:36:19.943256Z,AAPL,DIVIDEND,,,USD 8.40,USD,1.1172 2025-05-28T20:38:28.721Z,NVDA,SELL - LIMIT,20,USD 140,USD 2799.99,USD,1.1318 2025-05-29T22:34:38.868352Z,,CASH WITHDRAWAL,,,USD -2818.20,USD,1.1398 2025-06-18T14:58:51.657905Z,EXXT,DIVIDEND,,,EUR 3.70,EUR,1.0000 2025-07-02T11:16:20.772081Z,,CASH TOP-UP,,,USD 2000,USD,1.1797 2025-07-03T14:46:34.490Z,NVDA,BUY - LIMIT,12,USD 159.89,USD 1918.68,USD,1.1784 2025-07-10T07:34:53.882147Z,NVDA,DIVIDEND,,,USD 0.26,USD,1.1761 2025-08-08T15:39:25.511Z,AAPL,SELL - LIMIT,3,USD 225,USD 674.99,USD,1.1692 2025-08-14T23:12:20.834326Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1674 2025-08-20T17:26:50.819936Z,,CASH WITHDRAWAL,,,USD -764.31,USD,1.1692 2025-10-02T19:05:09.782319Z,NVDA,DIVIDEND,,,USD 0.37,USD,1.1750 2025-10-16T08:44:53.616001Z,,CASH TOP-UP,,,USD 1502.57,USD,1.1685 2025-10-16T08:47:26.528Z,NVDA,BUY - LIMIT,8,USD 181.79,USD 1454.35,USD,1.1686 2025-11-11T15:34:00.722Z,AAPL,SELL - MARKET,5,USD 273.91,USD 1369.52,USD,1.1626 2025-11-11T16:59:52.307677Z,,CASH TOP-UP,,,USD 500,USD,1.1619 2025-11-11T18:05:47.274Z,NVDA,BUY - LIMIT,9,USD 193.60,USD 1742.36,USD,1.1619 2025-11-11T18:06:31.280523Z,,CASH WITHDRAWAL,,,USD -175,USD,1.1618 2025-11-13T21:09:36.155137Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1658 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/historico-ativos.csv Tamanho: 3416 bytes ======================================================================================== Período,EURUSD,AAPL,TSLA,NVDA,GOOGL ,1.1643,280.68,450.20,183.45,317.62 2018/12/31,0.8760,39.44,22.19,33.38, 2019/01/31,0.8850,41.61,20.47,35.94, 2019/02/28,0.8920,43.29,21.33,38.57, 2019/03/31,0.9000,47.81,19.28,45.57, 2019/04/30,0.9200,50.17,15.91,45.25, 2019/05/31,0.9500,43.77,12.34,33.87, 2019/06/30,0.9700,50.39,15.14,41.54, 2019/07/31,0.9750,53.26,16.11,42.18, 2019/08/31,0.9600,51.43,15.00,41.04, 2019/09/30,0.9200,55.99,16.06,43.52, 2019/10/31,0.8800,62.19,20.99,50.26, 2019/11/30,0.8800,66.04,22.32,52.31, 2019/12/31,0.8500,73.41,27.89,58.83, 2020/01/31,0.8800,77.38,43.37,59.11, 2020/02/29,0.8600,74.70,49.57,69.11, 2020/03/31,0.8500,63.57,34.93,65.90, 2020/04/30,0.8600,73.45,52.13,73.07, 2020/05/31,0.8600,80.46,59.87,88.06, 2020/06/30,0.8600,91.20,71.99,94.98, 2020/07/31,0.8600,106.26,95.38,106.15, 2020/08/31,0.8600,129.04,166.11,133.75, 2020/09/30,0.8300,115.81,143.00,135.31, 2020/10/31,0.8300,108.77,133.50,125.81, 2020/11/30,0.8300,119.05,189.20,134.01, 2020/12/31,0.8300,132.69,235.22,130.55, 2021/01/31,0.8200,134.14,279.94,132.37, 2021/02/28,0.8400,127.79,239.48,138.42, 2021/03/31,0.8400,122.15,222.64,133.48, 2021/04/30,0.8300,131.46,236.48,150.10, 2021/05/31,0.8200,124.28,207.97,162.65, 2021/06/30,0.8500,136.96,226.57,200.03, 2021/07/31,0.8600,145.52,236.56,197.50, 2021/08/31,0.8500,151.83,245.24,223.85, 2021/09/30,0.8600,141.50,258.49,207.16, 2021/10/31,0.8800,148.96,402.86,258.27, 2021/11/30,0.8800,165.30,381.59,326.76, 2021/12/31,0.8800,177.57,352.26,294.11, 2022/01/31,0.8800,174.78,312.24,244.86, 2022/02/28,0.8900,165.12,290.14,243.85, 2022/03/31,0.9200,174.61,359.20,272.86, 2022/04/30,0.9400,157.96,300.98,195.33, 2022/05/31,0.9500,148.84,252.75,186.72, 2022/06/30,0.9600,136.72,224.47,151.59, 2022/07/31,0.9700,161.51,297.28,184.41, 2022/08/31,0.9800,157.22,275.61,150.94, 2022/09/30,0.9700,138.20,265.25,121.39, 2022/10/31,0.9700,153.34,227.54,134.97, 2022/11/30,0.9800,148.03,194.70,169.23, 2022/12/30,0.9900,129.93,123.18,146.14, 2023/01/31,1.0000,144.29,173.22,195.37, 2023/02/28,1.0100,147.41,205.71,232.16, 2023/03/31,1.0800,164.90,207.46,277.77, 2023/04/30,1.1000,169.59,161.83,289.10, 2023/05/31,1.0800,177.25,203.93,378.34, 2023/06/30,1.0900,193.97,261.77,423.02, 2023/07/31,1.1100,196.45,267.43,467.29, 2023/08/31,1.0900,187.87,258.08,493.55, 2023/09/30,1.0600,173.75,251.60,447.82, 2023/10/31,1.0600,170.77,200.84,407.80, 2023/11/30,1.0900,189.95,240.08,467.70, 2023/12/31,1.1000,192.53,248.48,495.22, 2024/01/31,1.0800,184.40,187.29,61.53, 2024/02/29,1.0800,180.75,201.88,79.11, 2024/03/31,1.0800,170.03,175.22,90.36, 2024/04/30,1.0700,170.33,183.28,86.40, 2024/05/31,1.0800,192.25,178.08,109.63, 2024/06/27,1.0700,210.62,197.88,123.54, 2024/07/30,1.0900,222.08,232.07,117.02, 2024/08/31,1.1100,222.77,210.60,108.00, 2024/09/30,1.1100,233.00,261.63,121.44, 2024/10/31,1.0900,225.91,249.85,132.76, 2024/11/30,1.0800,239.59,357.09,134.29, 2024/12/31,1.0500,250.42,403.84,120.07, 2025/01/31,1.0800,236.00,292.98,124.92, 2025/02/28,1.0900,241.84,259.16,108.38, 2025/03/31,1.0900,222.13,282.16,108.92, 2025/04/30,1.1000,212.50,342.69,137.38, 2025/05/31,1.1200,201.70,317.66,157.99, 2025/06/30,1.1300,205.17,308.27,177.87, 2025/07/31,1.1400,207.57,329.36,170.78, 2025/08/31,1.1500,229.72,444.72,186.58, 2025/09/30,1.1600,254.63,456.56,202.49, 2025/10/31,1.1600,270.37,430.14,179.92, 2025/11/30,1.1600,283.10,454.48,183.38, 2025/12/31,1.1643,280.68,450.20,183.45,317.62 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/historico-cambio-date.txt Tamanho: 19 bytes ======================================================================================== 2025-12-08 17:36:36 ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/historico-cambio.json Tamanho: 8403 bytes ======================================================================================== { "2019-09-30": 1.0938, "2019-10-07": 1.1007, "2019-10-14": 1.1064, "2019-10-21": 1.1132, "2019-10-28": 1.1116, "2019-11-04": 1.1094, "2019-11-11": 1.1019, "2019-11-18": 1.1069, "2019-11-25": 1.1005, "2019-12-02": 1.1073, "2019-12-09": 1.1108, "2019-12-16": 1.1127, "2019-12-23": 1.1103, "2019-12-30": 1.1191, "2020-01-06": 1.1136, "2020-01-13": 1.1132, "2020-01-20": 1.1083, "2020-01-27": 1.1022, "2020-02-03": 1.1022, "2020-02-10": 1.0895, "2020-02-17": 1.0808, "2020-02-24": 1.0895, "2020-03-02": 1.1177, "2020-03-09": 1.1305, "2020-03-16": 1.0916, "2020-03-23": 1.0882, "2020-03-30": 1.0923, "2020-04-06": 1.0854, "2020-04-13": 1.0904, "2020-04-20": 1.0827, "2020-04-27": 1.0862, "2020-05-04": 1.0844, "2020-05-11": 1.0829, "2020-05-18": 1.0929, "2020-05-25": 1.1006, "2020-06-01": 1.1213, "2020-06-08": 1.1321, "2020-06-15": 1.1245, "2020-06-22": 1.1245, "2020-06-29": 1.1238, "2020-07-06": 1.1304, "2020-07-13": 1.1398, "2020-07-20": 1.1529, "2020-07-27": 1.1759, "2020-08-03": 1.1801, "2020-08-10": 1.1793, "2020-08-17": 1.1862, "2020-08-24": 1.1834, "2020-08-31": 1.1889, "2020-09-07": 1.1817, "2020-09-14": 1.1853, "2020-09-21": 1.17, "2020-09-28": 1.1712, "2020-10-05": 1.1779, "2020-10-12": 1.1755, "2020-10-19": 1.1825, "2020-10-26": 1.1756, "2020-11-02": 1.176, "2020-11-09": 1.1813, "2020-11-16": 1.1855, "2020-11-23": 1.1896, "2020-11-30": 1.2065, "2020-12-07": 1.2119, "2020-12-14": 1.2199, "2020-12-21": 1.2193, "2020-12-28": 1.2258, "2021-01-04": 1.2286, "2021-01-11": 1.2147, "2021-01-18": 1.2123, "2021-01-25": 1.2127, "2021-02-01": 1.2025, "2021-02-08": 1.2102, "2021-02-15": 1.2111, "2021-02-22": 1.2154, "2021-03-01": 1.202, "2021-03-08": 1.1911, "2021-03-15": 1.1911, "2021-03-22": 1.1844, "2021-03-29": 1.1749, "2021-04-05": 1.1864, "2021-04-12": 1.1944, "2021-04-19": 1.2041, "2021-04-26": 1.2091, "2021-05-03": 1.2038, "2021-05-10": 1.2132, "2021-05-17": 1.2194, "2021-05-24": 1.2209, "2021-05-31": 1.2183, "2021-06-07": 1.2168, "2021-06-14": 1.2036, "2021-06-21": 1.1924, "2021-06-28": 1.1878, "2021-07-05": 1.1846, "2021-07-12": 1.1824, "2021-07-19": 1.1771, "2021-07-26": 1.1834, "2021-08-02": 1.1858, "2021-08-09": 1.1741, "2021-08-16": 1.1726, "2021-08-23": 1.1744, "2021-08-30": 1.1834, "2021-09-06": 1.1846, "2021-09-13": 1.1792, "2021-09-20": 1.1722, "2021-09-27": 1.1642, "2021-10-04": 1.1582, "2021-10-11": 1.1579, "2021-10-18": 1.163, "2021-10-25": 1.1615, "2021-11-01": 1.1569, "2021-11-08": 1.1524, "2021-11-15": 1.1349, "2021-11-22": 1.1251, "2021-11-29": 1.1317, "2021-12-06": 1.1285, "2021-12-13": 1.1303, "2021-12-20": 1.1299, "2021-12-27": 1.1321, "2022-01-03": 1.1313, "2022-01-10": 1.1387, "2022-01-17": 1.136, "2022-01-24": 1.1229, "2022-01-31": 1.1298, "2022-02-07": 1.1429, "2022-02-14": 1.1351, "2022-02-21": 1.1281, "2022-02-28": 1.1094, "2022-03-07": 1.0971, "2022-03-14": 1.1001, "2022-03-21": 1.1005, "2022-03-28": 1.1066, "2022-04-04": 1.0935, "2022-04-11": 1.0866, "2022-04-18": 1.0834, "2022-04-25": 1.0606, "2022-05-02": 1.055, "2022-05-09": 1.0492, "2022-05-16": 1.0518, "2022-05-23": 1.0691, "2022-05-30": 1.0722, "2022-06-06": 1.069, "2022-06-13": 1.0445, "2022-06-20": 1.0521, "2022-06-27": 1.0492, "2022-07-04": 1.0253, "2022-07-11": 1.0054, "2022-07-18": 1.0193, "2022-07-25": 1.0166, "2022-08-01": 1.0213, "2022-08-08": 1.0262, "2022-08-15": 1.0144, "2022-08-22": 0.9968, "2022-08-29": 1.0003, "2022-09-05": 0.9958, "2022-09-12": 1.0053, "2022-09-19": 0.9904, "2022-09-26": 0.9662, "2022-10-03": 0.9845, "2022-10-10": 0.9716, "2022-10-17": 0.9779, "2022-10-24": 0.9945, "2022-10-31": 0.9879, "2022-11-07": 1.0058, "2022-11-14": 1.0364, "2022-11-21": 1.0327, "2022-11-28": 1.0439, "2022-12-05": 1.0542, "2022-12-12": 1.0599, "2022-12-19": 1.0618, "2022-12-26": 1.0645, "2023-01-02": 1.0586, "2023-01-09": 1.075, "2023-01-16": 1.0827, "2023-01-23": 1.0873, "2023-01-30": 1.0911, "2023-02-06": 1.0734, "2023-02-13": 1.0694, "2023-02-20": 1.0634, "2023-02-27": 1.0615, "2023-03-06": 1.0599, "2023-03-13": 1.0642, "2023-03-20": 1.078, "2023-03-27": 1.0844, "2023-04-03": 1.0906, "2023-04-10": 1.0975, "2023-04-17": 1.0962, "2023-04-24": 1.1017, "2023-05-01": 1.1024, "2023-05-08": 1.0954, "2023-05-15": 1.0841, "2023-05-22": 1.0774, "2023-05-29": 1.072, "2023-06-05": 1.0721, "2023-06-12": 1.083, "2023-06-19": 1.0929, "2023-06-26": 1.0922, "2023-07-03": 1.0892, "2023-07-10": 1.1074, "2023-07-17": 1.1205, "2023-07-24": 1.1068, "2023-07-31": 1.0971, "2023-08-07": 1.0984, "2023-08-14": 1.0908, "2023-08-21": 1.085, "2023-08-28": 1.0842, "2023-09-04": 1.0738, "2023-09-11": 1.0712, "2023-09-18": 1.0672, "2023-09-25": 1.0581, "2023-10-02": 1.0517, "2023-10-09": 1.0572, "2023-10-16": 1.0564, "2023-10-23": 1.0577, "2023-10-30": 1.0625, "2023-11-06": 1.0694, "2023-11-13": 1.0797, "2023-11-20": 1.0922, "2023-11-27": 1.0938, "2023-12-04": 1.0802, "2023-12-11": 1.0843, "2023-12-18": 1.0966, "2023-12-25": 1.1076, "2024-01-01": 1.0937, "2024-01-08": 1.0952, "2024-01-15": 1.0893, "2024-01-22": 1.0886, "2024-01-29": 1.0841, "2024-02-05": 1.0759, "2024-02-12": 1.0758, "2024-02-19": 1.0813, "2024-02-26": 1.0831, "2024-03-04": 1.0879, "2024-03-11": 1.092, "2024-03-18": 1.0864, "2024-03-25": 1.0829, "2024-04-01": 1.0806, "2024-04-08": 1.0786, "2024-04-15": 1.0653, "2024-04-22": 1.0685, "2024-04-29": 1.072, "2024-05-06": 1.0759, "2024-05-13": 1.0827, "2024-05-20": 1.085, "2024-05-27": 1.085, "2024-06-03": 1.0868, "2024-06-10": 1.0744, "2024-06-17": 1.0717, "2024-06-24": 1.0707, "2024-07-01": 1.0771, "2024-07-08": 1.0844, "2024-07-15": 1.0913, "2024-07-22": 1.0861, "2024-07-29": 1.0819, "2024-08-05": 1.093, "2024-08-12": 1.0976, "2024-08-19": 1.1099, "2024-08-26": 1.1123, "2024-09-02": 1.1069, "2024-09-09": 1.1043, "2024-09-16": 1.1142, "2024-09-23": 1.1152, "2024-09-30": 1.1084, "2024-10-07": 1.0958, "2024-10-14": 1.0886, "2024-10-21": 1.0813, "2024-10-28": 1.0835, "2024-11-04": 1.0811, "2024-11-11": 1.0603, "2024-11-18": 1.0526, "2024-11-25": 1.053, "2024-12-02": 1.0526, "2024-12-09": 1.0522, "2024-12-16": 1.0455, "2024-12-23": 1.0408, "2024-12-30": 1.0363, "2025-01-06": 1.0343, "2025-01-13": 1.0263, "2025-01-20": 1.0398, "2025-01-27": 1.0429, "2025-02-03": 1.0354, "2025-02-10": 1.0376, "2025-02-17": 1.0452, "2025-02-24": 1.0468, "2025-03-03": 1.0674, "2025-03-10": 1.0872, "2025-03-17": 1.0876, "2025-03-24": 1.0804, "2025-03-31": 1.0912, "2025-04-07": 1.1078, "2025-04-14": 1.1354, "2025-04-21": 1.1406, "2025-04-28": 1.1362, "2025-05-05": 1.1315, "2025-05-12": 1.1162, "2025-05-19": 1.1287, "2025-05-26": 1.1335, "2025-06-02": 1.1405, "2025-06-09": 1.1476, "2025-06-16": 1.1529, "2025-06-23": 1.1615, "2025-06-30": 1.1767, "2025-07-07": 1.1707, "2025-07-14": 1.1637, "2025-07-21": 1.1714, "2025-07-28": 1.1513, "2025-08-04": 1.1601, "2025-08-11": 1.1663, "2025-08-18": 1.1651, "2025-08-25": 1.1656, "2025-09-01": 1.1672, "2025-09-08": 1.1716, "2025-09-15": 1.1793, "2025-09-22": 1.1748, "2025-09-29": 1.1735, "2025-10-06": 1.163, "2025-10-13": 1.1615, "2025-10-20": 1.1611, "2025-10-27": 1.1602, "2025-11-03": 1.1518, "2025-11-10": 1.1598, "2025-11-17": 1.156, "2025-11-24": 1.1565, "2025-12-01": 1.1648, "2025-12-08": 1.16 } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/lucro-mensal.json Tamanho: 46810 bytes ======================================================================================== { "ok": true, "user": "tiago", "moeda": "EUR", "compatibilidade": true, "totalmeses": 75, "investimentoinicial": 8376.05, "series": [ { "mes": "2019-10", "ganhos": 0.01, "dividendos": 0, "taxas": 0, "net": 0.01, "deltarealizado": 0.01, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2019-10-31", "fxeurusdfimmes": 1.1116, "carteiravalor": 0, "investimentoacumulado": 9.02, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 9.02, "precofonte": "stooq" }, { "mes": "2019-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2019-11-30", "fxeurusdfimmes": 1.1005, "carteiravalor": 0, "investimentoacumulado": 9.02, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 9.02, "precofonte": "stooq" }, { "mes": "2019-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2019-12-31", "fxeurusdfimmes": 1.1191, "carteiravalor": 0, "investimentoacumulado": 9.02, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 9.02, "precofonte": "stooq" }, { "mes": "2020-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2020-01-31", "fxeurusdfimmes": 1.1022, "carteiravalor": 0, "investimentoacumulado": 325.86, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 325.86, "precofonte": "stooq" }, { "mes": "2020-02", "ganhos": -11.02, "dividendos": 0.67, "taxas": 0.01, "net": -10.36, "deltarealizado": -11.02, "deltanaorealizado": 0, "realizadoacumulado": -11.01, "naorealizadofimmes": 0, "fimmesusado": "2020-02-29", "fxeurusdfimmes": 1.0895, "carteiravalor": 0, "investimentoacumulado": 886.68, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 886.68, "precofonte": "stooq" }, { "mes": "2020-03", "ganhos": 30.8, "dividendos": 0, "taxas": 0.01, "net": 30.79, "deltarealizado": 30.8, "deltanaorealizado": 0, "realizadoacumulado": 19.79, "naorealizadofimmes": 0, "fimmesusado": "2020-03-31", "fxeurusdfimmes": 1.0923, "carteiravalor": 0, "investimentoacumulado": 1154.29, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 1154.29, "precofonte": "stooq" }, { "mes": "2020-04", "ganhos": 51.45, "dividendos": 0, "taxas": 0.01, "net": 51.44, "deltarealizado": 51.45, "deltanaorealizado": 0, "realizadoacumulado": 71.24, "naorealizadofimmes": 0, "fimmesusado": "2020-04-30", "fxeurusdfimmes": 1.0862, "carteiravalor": 0, "investimentoacumulado": 1546.08, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 1546.08, "precofonte": "stooq" }, { "mes": "2020-05", "ganhos": 54.59, "dividendos": 0.91, "taxas": 0.02, "net": 55.48, "deltarealizado": 54.59, "deltanaorealizado": 0, "realizadoacumulado": 125.83, "naorealizadofimmes": 0, "fimmesusado": "2020-05-31", "fxeurusdfimmes": 1.1006, "carteiravalor": 0, "investimentoacumulado": 2068.29, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 2068.29, "precofonte": "stooq" }, { "mes": "2020-06", "ganhos": 150.41, "dividendos": 1.26, "taxas": 0.03, "net": 151.65, "deltarealizado": 150.41, "deltanaorealizado": 0, "realizadoacumulado": 276.24, "naorealizadofimmes": 0, "fimmesusado": "2020-06-30", "fxeurusdfimmes": 1.1238, "carteiravalor": 0, "investimentoacumulado": 3185.52, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3185.52, "precofonte": "stooq" }, { "mes": "2020-07", "ganhos": 228.27, "dividendos": 0, "taxas": 0.03, "net": 228.24, "deltarealizado": 228.27, "deltanaorealizado": 0, "realizadoacumulado": 504.51, "naorealizadofimmes": 0, "fimmesusado": "2020-07-31", "fxeurusdfimmes": 1.1759, "carteiravalor": 0, "investimentoacumulado": 3299.56, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3299.56, "precofonte": "stooq" }, { "mes": "2020-08", "ganhos": 315.03, "dividendos": 0.3, "taxas": 0.02, "net": 315.31, "deltarealizado": 315.03, "deltanaorealizado": 0, "realizadoacumulado": 819.54, "naorealizadofimmes": 0, "fimmesusado": "2020-08-31", "fxeurusdfimmes": 1.1889, "carteiravalor": 0, "investimentoacumulado": 3524.76, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3524.76, "precofonte": "stooq" }, { "mes": "2020-09", "ganhos": 197.51, "dividendos": 0.3, "taxas": 0.03, "net": 197.78, "deltarealizado": 197.51, "deltanaorealizado": 0, "realizadoacumulado": 1017.05, "naorealizadofimmes": 0, "fimmesusado": "2020-09-30", "fxeurusdfimmes": 1.1712, "carteiravalor": 0, "investimentoacumulado": 2740.79, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 2740.79, "precofonte": "stooq" }, { "mes": "2020-10", "ganhos": 152.69, "dividendos": 0, "taxas": 0, "net": 152.69, "deltarealizado": 152.69, "deltanaorealizado": 0, "realizadoacumulado": 1169.74, "naorealizadofimmes": 0, "fimmesusado": "2020-10-31", "fxeurusdfimmes": 1.1756, "carteiravalor": 0, "investimentoacumulado": 848.15, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 848.15, "precofonte": "stooq" }, { "mes": "2020-11", "ganhos": 628.09, "dividendos": 0, "taxas": 0.02, "net": 628.07, "deltarealizado": 628.09, "deltanaorealizado": 0, "realizadoacumulado": 1797.83, "naorealizadofimmes": 0, "fimmesusado": "2020-11-30", "fxeurusdfimmes": 1.2065, "carteiravalor": 0, "investimentoacumulado": 231.98, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 231.98, "precofonte": "stooq" }, { "mes": "2020-12", "ganhos": 587.27, "dividendos": 0, "taxas": 0, "net": 587.27, "deltarealizado": 587.27, "deltanaorealizado": 0, "realizadoacumulado": 2385.1, "naorealizadofimmes": 0, "fimmesusado": "2020-12-31", "fxeurusdfimmes": 1.2258, "carteiravalor": 0, "investimentoacumulado": 4896.91, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 4896.91, "precofonte": "stooq" }, { "mes": "2021-01", "ganhos": 840.14, "dividendos": 0, "taxas": 0.03, "net": 840.11, "deltarealizado": 840.14, "deltanaorealizado": 0, "realizadoacumulado": 3225.24, "naorealizadofimmes": 0, "fimmesusado": "2021-01-31", "fxeurusdfimmes": 1.2127, "carteiravalor": 0, "investimentoacumulado": 6097.03, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6097.03, "precofonte": "stooq" }, { "mes": "2021-02", "ganhos": 434.55, "dividendos": 2.73, "taxas": 0.07, "net": 437.21, "deltarealizado": 434.55, "deltanaorealizado": 0, "realizadoacumulado": 3659.79, "naorealizadofimmes": 0, "fimmesusado": "2021-02-28", "fxeurusdfimmes": 1.2154, "carteiravalor": 0, "investimentoacumulado": 5785.82, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5785.82, "precofonte": "stooq" }, { "mes": "2021-03", "ganhos": 0, "dividendos": 0, "taxas": 0.07, "net": -0.07, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 3659.79, "naorealizadofimmes": 0, "fimmesusado": "2021-03-31", "fxeurusdfimmes": 1.1749, "carteiravalor": 0, "investimentoacumulado": 5935.78, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5935.78, "precofonte": "stooq" }, { "mes": "2021-04", "ganhos": -35.14, "dividendos": 0, "taxas": 0.83, "net": -35.97, "deltarealizado": -35.14, "deltanaorealizado": 0, "realizadoacumulado": 3624.65, "naorealizadofimmes": 0, "fimmesusado": "2021-04-30", "fxeurusdfimmes": 1.2091, "carteiravalor": 0, "investimentoacumulado": 5935.78, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5935.78, "precofonte": "stooq" }, { "mes": "2021-05", "ganhos": 76.83, "dividendos": 2.94, "taxas": 0.88, "net": 78.89, "deltarealizado": 76.83, "deltanaorealizado": 0, "realizadoacumulado": 3701.48, "naorealizadofimmes": 0, "fimmesusado": "2021-05-31", "fxeurusdfimmes": 1.2183, "carteiravalor": 0, "investimentoacumulado": 6025.92, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6025.92, "precofonte": "stooq" }, { "mes": "2021-06", "ganhos": 226.91, "dividendos": 0, "taxas": 0.84, "net": 226.07, "deltarealizado": 226.91, "deltanaorealizado": 0, "realizadoacumulado": 3928.4, "naorealizadofimmes": 0, "fimmesusado": "2021-06-30", "fxeurusdfimmes": 1.1878, "carteiravalor": 0, "investimentoacumulado": 6025.92, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6025.92, "precofonte": "stooq" }, { "mes": "2021-07", "ganhos": 330.87, "dividendos": 0, "taxas": 0.86, "net": 330.01, "deltarealizado": 330.87, "deltanaorealizado": 0, "realizadoacumulado": 4259.26, "naorealizadofimmes": 0, "fimmesusado": "2021-07-31", "fxeurusdfimmes": 1.1834, "carteiravalor": 0, "investimentoacumulado": 5760.1, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5760.1, "precofonte": "stooq" }, { "mes": "2021-08", "ganhos": 155.84, "dividendos": 2.23, "taxas": 0.93, "net": 157.13, "deltarealizado": 155.84, "deltanaorealizado": 0, "realizadoacumulado": 4415.1, "naorealizadofimmes": 0, "fimmesusado": "2021-08-31", "fxeurusdfimmes": 1.1834, "carteiravalor": 0, "investimentoacumulado": 5760.1, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5760.1, "precofonte": "stooq" }, { "mes": "2021-09", "ganhos": 127.34, "dividendos": 0, "taxas": 0.97, "net": 126.36, "deltarealizado": 127.34, "deltanaorealizado": 0, "realizadoacumulado": 4542.44, "naorealizadofimmes": 0, "fimmesusado": "2021-09-30", "fxeurusdfimmes": 1.1642, "carteiravalor": 0, "investimentoacumulado": 5760.1, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5760.1, "precofonte": "stooq" }, { "mes": "2021-10", "ganhos": 646.5, "dividendos": 0, "taxas": 0.96, "net": 645.54, "deltarealizado": 646.5, "deltanaorealizado": 0, "realizadoacumulado": 5188.94, "naorealizadofimmes": 0, "fimmesusado": "2021-10-31", "fxeurusdfimmes": 1.1615, "carteiravalor": 0, "investimentoacumulado": 5606.64, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5606.64, "precofonte": "stooq" }, { "mes": "2021-11", "ganhos": 14.25, "dividendos": 5.46, "taxas": 0.92, "net": 18.79, "deltarealizado": 14.25, "deltanaorealizado": 0, "realizadoacumulado": 5203.19, "naorealizadofimmes": 0, "fimmesusado": "2021-11-30", "fxeurusdfimmes": 1.1317, "carteiravalor": 0, "investimentoacumulado": 5255.95, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5255.95, "precofonte": "stooq" }, { "mes": "2021-12", "ganhos": 400.05, "dividendos": 3.15, "taxas": 0.94, "net": 402.26, "deltarealizado": 400.05, "deltanaorealizado": 0, "realizadoacumulado": 5603.25, "naorealizadofimmes": 0, "fimmesusado": "2021-12-31", "fxeurusdfimmes": 1.1321, "carteiravalor": 0, "investimentoacumulado": 5542.71, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5542.71, "precofonte": "stooq" }, { "mes": "2022-01", "ganhos": 202.99, "dividendos": 1.57, "taxas": 1.03, "net": 203.54, "deltarealizado": 202.99, "deltanaorealizado": 0, "realizadoacumulado": 5806.23, "naorealizadofimmes": 0, "fimmesusado": "2022-01-31", "fxeurusdfimmes": 1.1298, "carteiravalor": 0, "investimentoacumulado": 5542.71, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5542.71, "precofonte": "stooq" }, { "mes": "2022-02", "ganhos": -281.36, "dividendos": 5.45, "taxas": 1.08, "net": -276.98, "deltarealizado": -281.36, "deltanaorealizado": 0, "realizadoacumulado": 5524.88, "naorealizadofimmes": 0, "fimmesusado": "2022-02-28", "fxeurusdfimmes": 1.1094, "carteiravalor": 0, "investimentoacumulado": 5765.97, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5765.97, "precofonte": "stooq" }, { "mes": "2022-03", "ganhos": 47.55, "dividendos": 2.01, "taxas": 1.04, "net": 48.51, "deltarealizado": 47.55, "deltanaorealizado": 0, "realizadoacumulado": 5572.42, "naorealizadofimmes": 0, "fimmesusado": "2022-03-31", "fxeurusdfimmes": 1.1066, "carteiravalor": 0, "investimentoacumulado": 5531.66, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5531.66, "precofonte": "stooq" }, { "mes": "2022-04", "ganhos": 20, "dividendos": 1.07, "taxas": 1.12, "net": 19.95, "deltarealizado": 20, "deltanaorealizado": 0, "realizadoacumulado": 5592.43, "naorealizadofimmes": 0, "fimmesusado": "2022-04-30", "fxeurusdfimmes": 1.0606, "carteiravalor": 0, "investimentoacumulado": 5715.07, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5715.07, "precofonte": "stooq" }, { "mes": "2022-05", "ganhos": 0, "dividendos": 6.79, "taxas": 1.06, "net": 5.74, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5592.43, "naorealizadofimmes": 0, "fimmesusado": "2022-05-31", "fxeurusdfimmes": 1.0722, "carteiravalor": 0, "investimentoacumulado": 5857.08, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5857.08, "precofonte": "stooq" }, { "mes": "2022-06", "ganhos": 0, "dividendos": 2.4, "taxas": 0.99, "net": 1.41, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5592.43, "naorealizadofimmes": 0, "fimmesusado": "2022-06-30", "fxeurusdfimmes": 1.0492, "carteiravalor": 0, "investimentoacumulado": 5866.43, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5866.43, "precofonte": "stooq" }, { "mes": "2022-07", "ganhos": 19.91, "dividendos": 1.13, "taxas": 0.92, "net": 20.12, "deltarealizado": 19.91, "deltanaorealizado": 0, "realizadoacumulado": 5612.34, "naorealizadofimmes": 0, "fimmesusado": "2022-07-31", "fxeurusdfimmes": 1.0166, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-08", "ganhos": 0, "dividendos": 6.95, "taxas": 1.11, "net": 5.84, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5612.34, "naorealizadofimmes": 0, "fimmesusado": "2022-08-31", "fxeurusdfimmes": 1.0003, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-09", "ganhos": 0, "dividendos": 0.75, "taxas": 1.08, "net": -0.34, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5612.34, "naorealizadofimmes": 0, "fimmesusado": "2022-09-30", "fxeurusdfimmes": 0.9662, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-10", "ganhos": 35.87, "dividendos": 3.1, "taxas": 1.02, "net": 37.96, "deltarealizado": 35.87, "deltanaorealizado": 0, "realizadoacumulado": 5648.21, "naorealizadofimmes": 0, "fimmesusado": "2022-10-31", "fxeurusdfimmes": 0.9879, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-11", "ganhos": 0, "dividendos": 7.26, "taxas": 1.01, "net": 6.25, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5648.21, "naorealizadofimmes": 0, "fimmesusado": "2022-11-30", "fxeurusdfimmes": 1.0439, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-12", "ganhos": 0, "dividendos": 1.44, "taxas": 0.92, "net": 0.52, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5648.21, "naorealizadofimmes": 0, "fimmesusado": "2022-12-31", "fxeurusdfimmes": 1.0645, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2023-01", "ganhos": 52.18, "dividendos": 2.08, "taxas": 0.79, "net": 53.47, "deltarealizado": 52.18, "deltanaorealizado": 0, "realizadoacumulado": 5700.39, "naorealizadofimmes": 0, "fimmesusado": "2023-01-31", "fxeurusdfimmes": 1.0911, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2023-02", "ganhos": 0, "dividendos": 6.08, "taxas": 0.87, "net": 5.2, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5700.39, "naorealizadofimmes": 0, "fimmesusado": "2023-02-28", "fxeurusdfimmes": 1.0615, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2023-03", "ganhos": 32.98, "dividendos": 0.61, "taxas": 0.94, "net": 32.65, "deltarealizado": 32.98, "deltanaorealizado": 0, "realizadoacumulado": 5733.38, "naorealizadofimmes": 0, "fimmesusado": "2023-03-31", "fxeurusdfimmes": 1.0844, "carteiravalor": 0, "investimentoacumulado": 6247.68, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6247.68, "precofonte": "stooq" }, { "mes": "2023-04", "ganhos": 0, "dividendos": 2.34, "taxas": 0.99, "net": 1.35, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5733.38, "naorealizadofimmes": 0, "fimmesusado": "2023-04-30", "fxeurusdfimmes": 1.1017, "carteiravalor": 0, "investimentoacumulado": 6247.68, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6247.68, "precofonte": "stooq" }, { "mes": "2023-05", "ganhos": 41.28, "dividendos": 5.62, "taxas": 0.97, "net": 45.93, "deltarealizado": 41.28, "deltanaorealizado": 0, "realizadoacumulado": 5774.66, "naorealizadofimmes": 0, "fimmesusado": "2023-05-31", "fxeurusdfimmes": 1.072, "carteiravalor": 0, "investimentoacumulado": 6383.59, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6383.59, "precofonte": "stooq" }, { "mes": "2023-06", "ganhos": 546.47, "dividendos": 0.6, "taxas": 1.05, "net": 546.02, "deltarealizado": 546.47, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-06-30", "fxeurusdfimmes": 1.0922, "carteiravalor": 0, "investimentoacumulado": 6290.54, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6290.54, "precofonte": "stooq" }, { "mes": "2023-07", "ganhos": 0, "dividendos": 2.32, "taxas": 1.09, "net": 1.23, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-07-31", "fxeurusdfimmes": 1.0971, "carteiravalor": 0, "investimentoacumulado": 6290.54, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6290.54, "precofonte": "stooq" }, { "mes": "2023-08", "ganhos": 0, "dividendos": 4.03, "taxas": 1.19, "net": 2.83, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-08-31", "fxeurusdfimmes": 1.0842, "carteiravalor": 0, "investimentoacumulado": 6290.54, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6290.54, "precofonte": "stooq" }, { "mes": "2023-09", "ganhos": 0, "dividendos": 0.34, "taxas": 110.74, "net": -110.4, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-09-30", "fxeurusdfimmes": 1.0581, "carteiravalor": 0, "investimentoacumulado": 6673.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6673.32, "precofonte": "stooq" }, { "mes": "2023-10", "ganhos": 0, "dividendos": 2.74, "taxas": 1.18, "net": 1.56, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-10-31", "fxeurusdfimmes": 1.0625, "carteiravalor": 0, "investimentoacumulado": 6673.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6673.32, "precofonte": "stooq" }, { "mes": "2023-11", "ganhos": 141.25, "dividendos": 5.44, "taxas": 1.1, "net": 145.6, "deltarealizado": 141.25, "deltanaorealizado": 0, "realizadoacumulado": 6462.38, "naorealizadofimmes": 0, "fimmesusado": "2023-11-30", "fxeurusdfimmes": 1.0938, "carteiravalor": 0, "investimentoacumulado": 6673.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6673.32, "precofonte": "stooq" }, { "mes": "2023-12", "ganhos": 105.13, "dividendos": 1.11, "taxas": 1.09, "net": 105.14, "deltarealizado": 105.13, "deltanaorealizado": 0, "realizadoacumulado": 6567.51, "naorealizadofimmes": 0, "fimmesusado": "2023-12-31", "fxeurusdfimmes": 1.1076, "carteiravalor": 0, "investimentoacumulado": 6225.49, "saldocaixafimmes": 2.03, "valorcarteira": 2.03, "investimentoinicial": 6225.49, "precofonte": "stooq" }, { "mes": "2024-01", "ganhos": -410.16, "dividendos": 2.26, "taxas": 1.12, "net": -409.01, "deltarealizado": -410.16, "deltanaorealizado": 0, "realizadoacumulado": 6157.35, "naorealizadofimmes": 0, "fimmesusado": "2024-01-31", "fxeurusdfimmes": 1.0841, "carteiravalor": 0, "investimentoacumulado": 5958.62, "saldocaixafimmes": 1.98, "valorcarteira": 1.98, "investimentoinicial": 5958.62, "precofonte": "stooq" }, { "mes": "2024-02", "ganhos": -573.44, "dividendos": 5.31, "taxas": 1.07, "net": -569.19, "deltarealizado": -573.44, "deltanaorealizado": 0, "realizadoacumulado": 5583.91, "naorealizadofimmes": 0, "fimmesusado": "2024-02-29", "fxeurusdfimmes": 1.0831, "carteiravalor": 0, "investimentoacumulado": 5255.17, "saldocaixafimmes": 1.93, "valorcarteira": 1.93, "investimentoinicial": 5255.17, "precofonte": "stooq" }, { "mes": "2024-03", "ganhos": -278.08, "dividendos": 1.14, "taxas": 0, "net": -276.95, "deltarealizado": -278.08, "deltanaorealizado": 0, "realizadoacumulado": 5305.83, "naorealizadofimmes": 0, "fimmesusado": "2024-03-31", "fxeurusdfimmes": 1.0829, "carteiravalor": 0, "investimentoacumulado": 6366.81, "saldocaixafimmes": 1.93, "valorcarteira": 1.93, "investimentoinicial": 6366.81, "precofonte": "stooq" }, { "mes": "2024-04", "ganhos": 842.23, "dividendos": 3.05, "taxas": 0, "net": 845.28, "deltarealizado": 842.23, "deltanaorealizado": 0, "realizadoacumulado": 6148.06, "naorealizadofimmes": 0, "fimmesusado": "2024-04-30", "fxeurusdfimmes": 1.072, "carteiravalor": 0, "investimentoacumulado": 5994.97, "saldocaixafimmes": 58.75, "valorcarteira": 58.75, "investimentoinicial": 5994.97, "precofonte": "stooq" }, { "mes": "2024-05", "ganhos": 1531.43, "dividendos": 6.06, "taxas": 0, "net": 1537.5, "deltarealizado": 1531.43, "deltanaorealizado": 0, "realizadoacumulado": 7679.49, "naorealizadofimmes": 0, "fimmesusado": "2024-05-31", "fxeurusdfimmes": 1.085, "carteiravalor": 0, "investimentoacumulado": 5994.97, "saldocaixafimmes": 58.75, "valorcarteira": 58.75, "investimentoinicial": 5994.97, "precofonte": "stooq" }, { "mes": "2024-06", "ganhos": 219.78, "dividendos": 1.01, "taxas": 0, "net": 220.78, "deltarealizado": 219.78, "deltanaorealizado": 0, "realizadoacumulado": 7899.26, "naorealizadofimmes": 0, "fimmesusado": "2024-06-30", "fxeurusdfimmes": 1.0707, "carteiravalor": 0, "investimentoacumulado": 5994.97, "saldocaixafimmes": 58.75, "valorcarteira": 58.75, "investimentoinicial": 5994.97, "precofonte": "stooq" }, { "mes": "2024-07", "ganhos": 335.47, "dividendos": 2.69, "taxas": 0, "net": 338.15, "deltarealizado": 335.47, "deltanaorealizado": 0, "realizadoacumulado": 8234.73, "naorealizadofimmes": 0, "fimmesusado": "2024-07-31", "fxeurusdfimmes": 1.0819, "carteiravalor": 0, "investimentoacumulado": 6794.97, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 6794.97, "precofonte": "stooq" }, { "mes": "2024-08", "ganhos": 148.28, "dividendos": 5.98, "taxas": 0, "net": 154.26, "deltarealizado": 148.28, "deltanaorealizado": 0, "realizadoacumulado": 8383.01, "naorealizadofimmes": 0, "fimmesusado": "2024-08-31", "fxeurusdfimmes": 1.1123, "carteiravalor": 0, "investimentoacumulado": 7791.81, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 7791.81, "precofonte": "stooq" }, { "mes": "2024-09", "ganhos": -53.43, "dividendos": 0, "taxas": 0, "net": -53.43, "deltarealizado": -53.43, "deltanaorealizado": 0, "realizadoacumulado": 8329.58, "naorealizadofimmes": 0, "fimmesusado": "2024-09-30", "fxeurusdfimmes": 1.1084, "carteiravalor": 0, "investimentoacumulado": 7791.81, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 7791.81, "precofonte": "stooq" }, { "mes": "2024-10", "ganhos": 253.24, "dividendos": 9.38, "taxas": 0, "net": 262.62, "deltarealizado": 253.24, "deltanaorealizado": 0, "realizadoacumulado": 8582.83, "naorealizadofimmes": 0, "fimmesusado": "2024-10-31", "fxeurusdfimmes": 1.0835, "carteiravalor": 0, "investimentoacumulado": 7791.81, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 7791.81, "precofonte": "stooq" }, { "mes": "2024-11", "ganhos": 374.48, "dividendos": 18.86, "taxas": 0, "net": 393.33, "deltarealizado": 374.48, "deltanaorealizado": 0, "realizadoacumulado": 8957.3, "naorealizadofimmes": 0, "fimmesusado": "2024-11-30", "fxeurusdfimmes": 1.053, "carteiravalor": 0, "investimentoacumulado": 5916.77, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 5916.77, "precofonte": "stooq" }, { "mes": "2024-12", "ganhos": 0, "dividendos": 1.29, "taxas": 0, "net": 1.29, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 8957.3, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.0363, "carteiravalor": 0, "investimentoacumulado": 7606.01, "saldocaixafimmes": 96.36, "valorcarteira": 96.36, "investimentoinicial": 7606.01, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 834.89, "dividendos": 0, "taxas": 0, "net": 834.89, "deltarealizado": 834.89, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.0429, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 96.36, "valorcarteira": 96.36, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 15.36, "taxas": 0, "net": 15.36, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.0468, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 96.36, "valorcarteira": 96.36, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 1.67, "taxas": 0, "net": 1.67, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.0912, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 98.03, "valorcarteira": 98.03, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": 0, "dividendos": 0.78, "taxas": 0, "net": 0.78, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1362, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 98.03, "valorcarteira": 98.03, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 183.33, "dividendos": 15.04, "taxas": 0, "net": 198.37, "deltarealizado": 183.33, "deltanaorealizado": 0, "realizadoacumulado": 9975.53, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1335, "carteiravalor": 0, "investimentoacumulado": 3161.56, "saldocaixafimmes": 98.03, "valorcarteira": 98.03, "investimentoinicial": 3161.56, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 0, "dividendos": 3.7, "taxas": 0, "net": 3.7, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9975.53, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1767, "carteiravalor": 0, "investimentoacumulado": 3161.56, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 3161.56, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 0.44, "taxas": 0, "net": 0.44, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9975.53, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1513, "carteiravalor": 0, "investimentoacumulado": 6552.26, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 6552.26, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 19.43, "dividendos": 13.26, "taxas": 0, "net": 32.69, "deltarealizado": 19.43, "deltanaorealizado": 0, "realizadoacumulado": 9994.96, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1656, "carteiravalor": 0, "investimentoacumulado": 5244.85, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 5244.85, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9994.96, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1735, "carteiravalor": 0, "investimentoacumulado": 5244.85, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 5244.85, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 0.63, "taxas": 0, "net": 0.63, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9994.96, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1602, "carteiravalor": 0, "investimentoacumulado": 7816.64, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 7816.64, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 165.63, "dividendos": 13.28, "taxas": 0, "net": 178.91, "deltarealizado": 165.63, "deltanaorealizado": 0, "realizadoacumulado": 10160.59, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1565, "carteiravalor": 0, "investimentoacumulado": 8376.05, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 8376.05, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 2672.48, "dividendos": 0.7, "taxas": 6.43, "net": 2666.75, "deltarealizado": 0, "deltanaorealizado": 2672.48, "realizadoacumulado": 10160.59, "naorealizadofimmes": 2672.48, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 21418.51, "investimentoacumulado": 8376.05, "saldocaixafimmes": 102.43, "valorcarteira": 21520.94, "investimentoinicial": 8376.05, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 16:42:27", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/movimentos-caixa.csv Tamanho: 16619 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2019-10-13,Depósito,10,USD,CASH TOP-UP,1.109 2,2020-01-22,Depósito,150,USD,CASH TOP-UP,1.1087 3,2020-01-27,Depósito,100,USD,CASH TOP-UP,1.1016 4,2020-01-27,Depósito,100,USD,CASH TOP-UP,1.1017 5,2020-02-04,Depósito,100,USD,CASH TOP-UP,1.1043 6,2020-02-06,Depósito,100,USD,CASH TOP-UP,1.0977 7,2020-02-12,Levantamento,-12,USD,CASH WITHDRAWAL,1.0883 8,2020-02-14,Dividendo,0.73,USD,AAPL DIVIDEND,1.0841 9,2020-02-14,Depósito,23.44,USD,CASH TOP-UP,1.0844 10,2020-02-19,Depósito,100,USD,CASH TOP-UP,1.0786 11,2020-02-19,Depósito,100,USD,CASH TOP-UP,1.0786 12,2020-02-25,Depósito,100,USD,CASH TOP-UP,1.0852 13,2020-02-27,Depósito,100,USD,CASH TOP-UP,1.0989 14,2020-02-29,Outros,-0.01,USD,CUSTODY FEE,1.1085 15,2020-03-10,Depósito,100,USD,CASH TOP-UP,1.1392 16,2020-03-10,Depósito,100,USD,CASH TOP-UP,1.1385 17,2020-03-25,Depósito,100,USD,CASH TOP-UP,1.087 18,2020-03-31,Outros,-0.01,USD,CUSTODY FEE,1.103 19,2020-04-16,Depósito,150,USD,CASH TOP-UP,1.0846 20,2020-04-23,Depósito,65,USD,CASH TOP-UP,1.0835 21,2020-04-27,Depósito,150,USD,CASH TOP-UP,1.0849 22,2020-04-29,Depósito,60,USD,CASH TOP-UP,1.0862 23,2020-04-30,Outros,-0.01,USD,CUSTODY FEE,1.0945 24,2020-05-01,Depósito,70,USD,CASH TOP-UP,1.1 25,2020-05-11,Dividendo,0.2,USD,MA DIVIDEND,1.0849 26,2020-05-15,Dividendo,0.78,USD,AAPL DIVIDEND,1.0803 27,2020-05-15,Depósito,200,USD,CASH TOP-UP,1.0834 28,2020-05-21,Depósito,200,USD,CASH TOP-UP,1.0991 29,2020-05-27,Depósito,101,USD,CASH TOP-UP,1.0978 30,2020-05-31,Outros,-0.02,USD,CUSTODY FEE,1.1117 31,2020-06-01,Depósito,100,USD,CASH TOP-UP,1.1111 32,2020-06-03,Depósito,96.4,USD,CASH TOP-UP,1.1233 33,2020-06-04,Depósito,105.53,USD,CASH TOP-UP,1.1334 34,2020-06-04,Depósito,200,USD,CASH TOP-UP,1.133 35,2020-06-05,Depósito,113.81,USD,CASH TOP-UP,1.1302 36,2020-06-08,Depósito,102.63,USD,CASH TOP-UP,1.1304 37,2020-06-09,Depósito,100,USD,CASH TOP-UP,1.1277 38,2020-06-15,Depósito,150,USD,CASH TOP-UP,1.125 39,2020-06-16,Depósito,97.58,USD,CASH TOP-UP,1.1262 40,2020-06-18,Depósito,192.53,USD,CASH TOP-UP,1.1217 41,2020-06-26,Dividendo,1.37,USD,QCOM DIVIDEND,1.1215 42,2020-06-29,Dividendo,0.04,USD,NVDA DIVIDEND,1.1243 43,2020-06-30,Outros,-0.03,USD,CUSTODY FEE,1.1237 44,2020-07-17,Levantamento,-16,USD,CASH WITHDRAWAL,1.1414 45,2020-07-25,Depósito,150,USD,CASH TOP-UP,1.1714 46,2020-07-31,Outros,-0.03,USD,CUSTODY FEE,1.1837 47,2020-08-04,Levantamento,-16.5,USD,CASH WITHDRAWAL,1.1799 48,2020-08-06,Depósito,300,USD,CASH TOP-UP,1.185 49,2020-08-10,Dividendo,0.2,USD,MA DIVIDEND,1.1794 50,2020-08-14,Dividendo,0.15,USD,AAPL DIVIDEND,1.1819 51,2020-08-31,Levantamento,-16.66,USD,CASH WITHDRAWAL,1.1915 52,2020-08-31,Outros,-0.02,USD,CUSTODY FEE,1.194 53,2020-09-02,Depósito,200,USD,CASH TOP-UP,1.1844 54,2020-09-04,Levantamento,-200,USD,CASH WITHDRAWAL,1.1841 55,2020-09-04,Depósito,250,USD,CASH TOP-UP,1.1845 56,2020-09-04,Levantamento,-250,USD,CASH WITHDRAWAL,1.1846 57,2020-09-10,Depósito,250,USD,CASH TOP-UP,1.1832 58,2020-09-10,Levantamento,-250,USD,CASH WITHDRAWAL,1.1832 59,2020-09-11,Dividendo,0.32,USD,MSFT DIVIDEND,1.184 60,2020-09-17,Levantamento,-370.2,USD,CASH WITHDRAWAL,1.1805 61,2020-09-24,Levantamento,-329.15,USD,CASH WITHDRAWAL,1.1653 62,2020-09-25,Dividendo,0.03,USD,NVDA DIVIDEND,1.1674 63,2020-09-25,Levantamento,-219.22,USD,CASH WITHDRAWAL,1.1668 64,2020-09-30,Outros,-0.03,USD,CUSTODY FEE,1.173 65,2020-10-01,Levantamento,-16.4,USD,CASH WITHDRAWAL,1.1728 66,2020-10-02,Levantamento,-399.48,USD,CASH WITHDRAWAL,1.1719 67,2020-10-06,Levantamento,-272.23,USD,CASH WITHDRAWAL,1.1754 68,2020-10-15,Levantamento,-400,USD,CASH WITHDRAWAL,1.1708 69,2020-10-22,Levantamento,-680,USD,CASH WITHDRAWAL,1.1842 70,2020-10-22,Levantamento,-461.19,USD,CASH WITHDRAWAL,1.1819 71,2020-10-30,Depósito,230,USD,CASH TOP-UP,1.1655 72,2020-10-30,Levantamento,-230,USD,CASH WITHDRAWAL,1.165 73,2020-11-01,Outros,-0.01,USD,CUSTODY FEE,1.1764 74,2020-11-02,Depósito,0.01,USD,CASH TOP-UP,1.1643 75,2020-11-17,Levantamento,-731.22,USD,CASH WITHDRAWAL,1.1861 76,2020-11-26,Depósito,64.15,USD,CASH TOP-UP,1.1908 77,2020-11-30,Depósito,600,USD,CASH TOP-UP,1.1997 78,2020-11-30,Levantamento,-664.15,USD,CASH WITHDRAWAL,1.1995 79,2020-11-30,Outros,-0.01,USD,CUSTODY FEE,1.1938 80,2020-12-01,Depósito,0.01,USD,CASH TOP-UP,1.2075 81,2020-12-03,Depósito,283.13,USD,CASH TOP-UP,1.2146 82,2020-12-07,Depósito,245.04,USD,CASH TOP-UP,1.2091 83,2020-12-07,Levantamento,-1417.49,USD,CASH WITHDRAWAL,1.2098 84,2020-12-08,Depósito,600,USD,CASH TOP-UP,1.2104 85,2020-12-10,Depósito,1045.98,USD,CASH TOP-UP,1.2095 86,2020-12-14,Depósito,873.84,USD,CASH TOP-UP,1.2148 87,2020-12-17,Depósito,1011.96,USD,CASH TOP-UP,1.2241 88,2020-12-21,Depósito,934.75,USD,CASH TOP-UP,1.2192 89,2020-12-23,Depósito,440.8,USD,CASH TOP-UP,1.2179 90,2020-12-23,Depósito,1218.96,USD,CASH TOP-UP,1.2194 91,2020-12-24,Depósito,14.23,USD,CASH TOP-UP,1.2184 92,2020-12-31,Depósito,500,USD,CASH TOP-UP,1.2276 93,2020-12-31,Levantamento,-64.98,USD,CASH WITHDRAWAL,1.2273 94,2021-01-01,Outros,-0.04,USD,CUSTODY FEE,1.2219 95,2021-01-08,Depósito,549.96,USD,CASH TOP-UP,1.2246 96,2021-01-08,Levantamento,-71.85,USD,CASH WITHDRAWAL,1.2234 97,2021-01-13,Depósito,576.16,USD,CASH TOP-UP,1.2198 98,2021-01-27,Depósito,136.83,USD,CASH TOP-UP,1.208 99,2021-01-27,Depósito,470.71,USD,CASH TOP-UP,1.2077 100,2021-01-28,Depósito,1373.27,USD,CASH TOP-UP,1.2089 101,2021-02-01,Outros,-0.09,USD,CUSTODY FEE,1.2133 102,2021-02-01,Depósito,196.46,USD,CASH TOP-UP,1.2067 103,2021-02-04,Levantamento,-32.26,USD,CASH WITHDRAWAL,1.1962 104,2021-02-09,Levantamento,-500,USD,CASH WITHDRAWAL,1.2121 105,2021-02-12,Dividendo,3.31,USD,AAPL DIVIDEND,1.2126 106,2021-02-19,Levantamento,-41.9,USD,CASH WITHDRAWAL,1.2129 107,2021-03-01,Outros,-0.08,USD,CUSTODY FEE,1.209 108,2021-03-02,Depósito,0.08,USD,CASH TOP-UP,1.2091 109,2021-03-12,Depósito,178.93,USD,CASH TOP-UP,1.1937 110,2021-04-01,Outros,-0.97,USD,CUSTODY FEE,1.1737 111,2021-05-01,Outros,-1.07,USD,CUSTODY FEE,1.2142 112,2021-05-14,Dividendo,3.55,USD,AAPL DIVIDEND,1.2089 113,2021-05-24,Depósito,50,USD,CASH TOP-UP,1.2213 114,2021-05-27,Depósito,50,USD,CASH TOP-UP,1.2193 115,2021-05-27,Depósito,10,USD,CASH TOP-UP,1.2195 116,2021-06-01,Outros,-1.03,USD,CUSTODY FEE,1.2229 117,2021-07-01,Outros,-1.02,USD,CUSTODY FEE,1.1855 118,2021-07-14,Levantamento,-63.73,USD,CASH WITHDRAWAL,1.1839 119,2021-07-27,Levantamento,-250,USD,CASH WITHDRAWAL,1.1793 120,2021-08-01,Outros,-1.12,USD,CUSTODY FEE,1.1999 121,2021-08-13,Dividendo,2.62,USD,AAPL DIVIDEND,1.1742 122,2021-09-01,Outros,-1.15,USD,CUSTODY FEE,1.18 123,2021-10-01,Outros,-1.11,USD,CUSTODY FEE,1.158 124,2021-10-01,Levantamento,-50,USD,CASH WITHDRAWAL,1.1582 125,2021-10-25,Levantamento,-78.27,USD,CASH WITHDRAWAL,1.1616 126,2021-10-29,Levantamento,-50,USD,CASH WITHDRAWAL,1.1652 127,2021-11-01,Levantamento,-100,USD,CASH WITHDRAWAL,1.1609 128,2021-11-04,Levantamento,-2000,USD,CASH WITHDRAWAL,1.1613 129,2021-11-04,Outros,-1.07,USD,CUSTODY FEE,1.1603 130,2021-11-04,Depósito,2000,USD,CASH TOP-UP,1.1586 131,2021-11-17,Dividendo,6.17,USD,AAPL DIVIDEND,1.1305 132,2021-11-19,Levantamento,-150,USD,CASH WITHDRAWAL,1.1292 133,2021-11-22,Levantamento,-153.2,USD,CASH WITHDRAWAL,1.1287 134,2021-12-02,Outros,-1.07,USD,CUSTODY FEE,1.1325 135,2021-12-02,Levantamento,-300,USD,CASH WITHDRAWAL,1.1325 136,2021-12-02,Depósito,100,USD,CASH TOP-UP,1.1324 137,2021-12-06,Depósito,50,USD,CASH TOP-UP,1.1293 138,2021-12-10,Levantamento,-26.65,USD,CASH WITHDRAWAL,1.1319 139,2021-12-14,Levantamento,-150,USD,CASH WITHDRAWAL,1.1279 140,2021-12-17,Dividendo,3.57,USD,KO DIVIDEND,1.1323 141,2021-12-21,Depósito,550,USD,CASH TOP-UP,1.1288 142,2021-12-25,Depósito,100,USD,CASH TOP-UP,1.1315 143,2022-01-04,Dividendo,1.78,USD,BAC DIVIDEND,1.1307 144,2022-01-04,Outros,-1.16,USD,CUSTODY FEE,1.1303 145,2022-02-02,Outros,-1.22,USD,CUSTODY FEE,1.1324 146,2022-02-15,Dividendo,6.17,USD,AAPL DIVIDEND,1.132 147,2022-02-28,Depósito,250,USD,CASH TOP-UP,1.1198 148,2022-03-02,Outros,-1.16,USD,CUSTODY FEE,1.1104 149,2022-03-16,Dividendo,0.42,USD,O DIVIDEND,1.0978 150,2022-03-25,Levantamento,-257.83,USD,CASH WITHDRAWAL,1.1004 151,2022-03-28,Dividendo,1.78,USD,BAC DIVIDEND,1.0955 152,2022-04-02,Outros,-1.24,USD,CUSTODY FEE,1.1051 153,2022-04-04,Dividendo,0.75,USD,KO DIVIDEND,1.1051 154,2022-04-14,Depósito,200,USD,CASH TOP-UP,1.0905 155,2022-04-19,Dividendo,0.42,USD,O DIVIDEND,1.0772 156,2022-05-03,Outros,-1.11,USD,CUSTODY FEE,1.0519 157,2022-05-16,Dividendo,0.42,USD,O DIVIDEND,1.041 158,2022-05-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0407 159,2022-05-20,Depósito,150,USD,CASH TOP-UP,1.0562 160,2022-06-02,Outros,-1.05,USD,CUSTODY FEE,1.0657 161,2022-06-07,Depósito,10,USD,CASH TOP-UP,1.0702 162,2022-06-10,Dividendo,0.33,USD,MSFT DIVIDEND,1.0635 163,2022-06-16,Dividendo,0.42,USD,O DIVIDEND,1.0441 164,2022-06-27,Dividendo,1.78,USD,BAC DIVIDEND,1.0571 165,2022-07-02,Outros,-0.96,USD,CUSTODY FEE,1.0432 166,2022-07-05,Dividendo,0.75,USD,KO DIVIDEND,1.0442 167,2022-07-18,Dividendo,0.42,USD,O DIVIDEND,1.0105 168,2022-07-29,Depósito,150,USD,CASH TOP-UP,1.0209 169,2022-08-02,Outros,-1.13,USD,CUSTODY FEE,1.021 170,2022-08-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0171 171,2022-08-16,Dividendo,0.42,USD,O DIVIDEND,1.0165 172,2022-09-03,Outros,-1.08,USD,CUSTODY FEE,0.9961 173,2022-09-12,Dividendo,0.33,USD,MSFT DIVIDEND,1.0096 174,2022-09-16,Dividendo,0.42,USD,O DIVIDEND,0.9995 175,2022-10-03,Dividendo,1.87,USD,BAC DIVIDEND,0.9807 176,2022-10-04,Outros,-1,USD,CUSTODY FEE,0.9841 177,2022-10-04,Dividendo,0.75,USD,KO DIVIDEND,0.9861 178,2022-10-17,Dividendo,0.42,USD,O DIVIDEND,0.9748 179,2022-11-02,Outros,-1,USD,CUSTODY FEE,0.9906 180,2022-11-11,Dividendo,7.04,USD,AAPL DIVIDEND,1.0271 181,2022-11-16,Dividendo,0.42,USD,O DIVIDEND,1.0383 182,2022-12-02,Outros,-0.97,USD,CUSTODY FEE,1.0532 183,2022-12-09,Dividendo,0.36,USD,MSFT DIVIDEND,1.0582 184,2022-12-16,Dividendo,0.75,USD,KO DIVIDEND,1.0667 185,2022-12-16,Dividendo,0.42,USD,O DIVIDEND,1.0662 186,2023-01-03,Dividendo,1.87,USD,BAC DIVIDEND,1.0672 187,2023-01-04,Outros,-0.84,USD,CUSTODY FEE,1.0625 188,2023-01-17,Dividendo,0.35,USD,O DIVIDEND,1.0831 189,2023-02-01,Outros,-0.95,USD,CUSTODY FEE,1.0871 190,2023-02-16,Dividendo,0.35,USD,O DIVIDEND,1.0707 191,2023-02-17,Dividendo,6.12,USD,AAPL DIVIDEND,1.0641 192,2023-03-01,Depósito,250,USD,CASH TOP-UP,1.0669 193,2023-03-02,Outros,-1,USD,CUSTODY FEE,1.0636 194,2023-03-13,Dividendo,0.29,USD,MSFT DIVIDEND,1.0731 195,2023-03-16,Dividendo,0.36,USD,O DIVIDEND,1.0618 196,2023-04-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0809 197,2023-04-04,Dividendo,0.64,USD,KO DIVIDEND,1.0919 198,2023-04-04,Outros,-1.08,USD,CUSTODY FEE,1.0941 199,2023-04-17,Dividendo,0.36,USD,O DIVIDEND,1.1 200,2023-05-02,Outros,-1.07,USD,CUSTODY FEE,1.101 201,2023-05-08,Depósito,150,USD,CASH TOP-UP,1.1037 202,2023-05-16,Dividendo,0.36,USD,O DIVIDEND,1.089 203,2023-05-19,Dividendo,5.71,USD,AAPL DIVIDEND,1.08 204,2023-06-02,Outros,-1.13,USD,CUSTODY FEE,1.0788 205,2023-06-05,Depósito,100,USD,CASH TOP-UP,1.0703 206,2023-06-06,Levantamento,-200,USD,CASH WITHDRAWAL,1.0725 207,2023-06-09,Dividendo,0.29,USD,MSFT DIVIDEND,1.0787 208,2023-06-16,Dividendo,0.36,USD,O DIVIDEND,1.0954 209,2023-07-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0929 210,2023-07-04,Outros,-1.19,USD,CUSTODY FEE,1.0914 211,2023-07-05,Dividendo,0.64,USD,KO DIVIDEND,1.0888 212,2023-07-17,Dividendo,0.36,USD,O DIVIDEND,1.1239 213,2023-08-02,Outros,-1.31,USD,CUSTODY FEE,1.0994 214,2023-08-16,Dividendo,0.36,USD,O DIVIDEND,1.0928 215,2023-08-18,Dividendo,4.03,USD,AAPL DIVIDEND,1.0901 216,2023-09-02,Outros,-1.27,USD,CUSTODY FEE,1.079 218,2023-09-13,Depósito,11.76,USD,CASH TOP-UP,1.0756 219,2023-09-13,Depósito,400,USD,CASH TOP-UP,1.0757 220,2023-09-18,Dividendo,0.36,USD,O DIVIDEND,1.0686 221,2023-10-01,Outros,-1.25,USD,CUSTODY FEE,1.0595 222,2023-10-02,Dividendo,1.68,USD,BAC DIVIDEND,1.055 223,2023-10-03,Dividendo,0.78,USD,KO DIVIDEND,1.0488 224,2023-10-16,Dividendo,0.43,USD,O DIVIDEND,1.0557 225,2023-11-02,Outros,-1.17,USD,CUSTODY FEE,1.0617 226,2023-11-16,Dividendo,0.43,USD,O DIVIDEND,1.0863 227,2023-11-17,Dividendo,5.51,USD,AAPL DIVIDEND,1.0913 228,2023-12-01,Outros,-1.19,USD,CUSTODY FEE,1.0922 229,2023-12-14,Levantamento,-490,USD,CASH WITHDRAWAL,1.0942 230,2023-12-14,Levantamento,-540,USD,CASH WITHDRAWAL,1.0945 231,2023-12-14,Depósito,493.36,EUR,CASH TOP-UP,1 232,2023-12-14,Depósito,22.55,EUR,CASH TOP-UP,1 233,2023-12-14,Levantamento,-22.55,EUR,CASH WITHDRAWAL,1 234,2023-12-18,Dividendo,0.43,USD,O DIVIDEND,1.0945 235,2023-12-18,Dividendo,0.78,USD,KO DIVIDEND,1.0937 236,2024-01-01,Outros,-1.18,USD,CUSTODY FEE,1.106 237,2024-01-01,Outros,-0.05,EUR,CUSTODY FEE,1 238,2024-01-03,Dividendo,2.04,USD,BAC DIVIDEND,1.0927 239,2024-01-16,Dividendo,0.43,USD,O DIVIDEND,1.0909 240,2024-01-29,Levantamento,-288.99,USD,CASH WITHDRAWAL,1.0829 241,2024-02-01,Outros,-1.1,USD,CUSTODY FEE,1.0837 242,2024-02-01,Outros,-0.05,EUR,CUSTODY FEE,1 243,2024-02-13,Levantamento,-755.3,USD,CASH WITHDRAWAL,1.0737 244,2024-02-16,Dividendo,0.43,USD,O DIVIDEND,1.0796 245,2024-02-16,Dividendo,5.3,USD,AAPL DIVIDEND,1.0789 246,2024-03-11,Depósito,1091.8,USD,CASH TOP-UP,1.0964 247,2024-03-11,Depósito,126.74,USD,CASH TOP-UP,1.0941 248,2024-03-15,Dividendo,0.64,USD,MSFT DIVIDEND,1.0914 249,2024-03-18,Dividendo,0.43,USD,O DIVIDEND,1.0912 250,2024-03-28,Dividendo,0.17,USD,NVDA DIVIDEND,1.0831 251,2024-04-02,Dividendo,0.82,USD,KO DIVIDEND,1.0788 252,2024-04-02,Dividendo,2.04,USD,BAC DIVIDEND,1.0789 253,2024-04-16,Dividendo,0.43,USD,O DIVIDEND,1.0668 254,2024-04-22,Levantamento,-720,USD,CASH WITHDRAWAL,1.0653 255,2024-04-22,Depósito,675.75,EUR,CASH TOP-UP,1 256,2024-04-30,Levantamento,-398.79,USD,CASH WITHDRAWAL,1.0728 257,2024-05-16,Dividendo,0.43,USD,O DIVIDEND,1.0895 258,2024-05-17,Dividendo,6.16,USD,AAPL DIVIDEND,1.0867 259,2024-06-14,Dividendo,0.64,USD,MSFT DIVIDEND,1.0709 260,2024-06-17,Dividendo,0.44,USD,O DIVIDEND,1.0728 261,2024-07-01,Dividendo,0.42,USD,NVDA DIVIDEND,1.0772 262,2024-07-01,Dividendo,2.04,USD,BAC DIVIDEND,1.0768 263,2024-07-16,Dividendo,0.44,USD,O DIVIDEND,1.0923 264,2024-07-23,Depósito,800,EUR,CASH TOP-UP,1 265,2024-08-01,Depósito,1077.48,USD,CASH TOP-UP,1.0809 266,2024-08-16,Dividendo,6.59,USD,AAPL DIVIDEND,1.1011 267,2024-10-04,Dividendo,0.42,USD,NVDA DIVIDEND,1.1053 268,2024-10-10,Dividendo,4.93,USD,TSM DIVIDEND,1.0958 269,2024-11-06,Depósito,34.98,USD,CASH TOP-UP,1.075 270,2024-11-06,Levantamento,-34.98,USD,CASH WITHDRAWAL,1.0748 271,2024-11-15,Dividendo,9.99,USD,AAPL DIVIDEND,1.0596 272,2024-11-25,Depósito,1004,USD,CASH TOP-UP,1.0525 273,2024-11-29,Levantamento,-2000,USD,CASH WITHDRAWAL,1.0574 274,2024-12-18,Dividendo,0.51,EUR,EXXT DIVIDEND,1 275,2024-12-18,Depósito,2006.76,USD,CASH TOP-UP,1.0513 276,2024-12-18,Levantamento,-2240.7,USD,CASH WITHDRAWAL,1.0514 277,2024-12-18,Depósito,2133.85,EUR,CASH TOP-UP,1 278,2024-12-19,Depósito,0.02,USD,CASH TOP-UP,1.0415 279,2024-12-30,Dividendo,0.41,USD,NVDA DIVIDEND,1.0464 280,2025-01-07,Levantamento,-3000,USD,CASH WITHDRAWAL,1.0449 281,2025-01-07,Depósito,3001.3,USD,CASH TOP-UP,1.0396 282,2025-01-28,Depósito,245,USD,CASH TOP-UP,1.0451 283,2025-02-14,Dividendo,8.08,USD,AAPL DIVIDEND,1.0521 284,2025-03-19,Dividendo,1.67,EUR,EXXT DIVIDEND,1 285,2025-04-03,Dividendo,0.43,USD,NVDA DIVIDEND,1.1083 286,2025-05-16,Dividendo,8.4,USD,AAPL DIVIDEND,1.1172 287,2025-05-29,Levantamento,-2818.2,USD,CASH WITHDRAWAL,1.1398 288,2025-06-18,Dividendo,3.7,EUR,EXXT DIVIDEND,1 289,2025-07-02,Depósito,2000,USD,CASH TOP-UP,1.1797 290,2025-07-10,Dividendo,0.26,USD,NVDA DIVIDEND,1.1761 291,2025-08-14,Dividendo,7.74,USD,AAPL DIVIDEND,1.1674 292,2025-08-20,Levantamento,-764.31,USD,CASH WITHDRAWAL,1.1692 293,2025-10-02,Dividendo,0.37,USD,NVDA DIVIDEND,1.175 294,2025-10-16,Depósito,1502.57,USD,CASH TOP-UP,1.1685 295,2025-11-11,Depósito,500,USD,CASH TOP-UP,1.1619 296,2025-11-11,Levantamento,-175,USD,CASH WITHDRAWAL,1.1618 297,2025-11-13,Dividendo,7.74,USD,AAPL DIVIDEND,1.16584 298,2021-01-28,Levantamento,-1561.03,USD,Acerto Filipe Lucro Filipe,1.2089 299,2021-01-28,Levantamento,-12.45,USD,Acerto Filipe Lucro Maria,1.2089 300,2021-01-28,Outros,813.87,USD,Acerto,1.2089 301,2025-12-17,Dividendo,0.7,EUR,EXXT DIVIDEND,1 302,2025-12-26,Dividendo,0.51,USD,NVIDIA DIVIDEND, 302,2026-01-13,Levantamento,-1828.99,USD,CASH WITHDRAWAL, 303,2026-01-16,Levantamento,-1581.35,EUR,CASH WITHDRAWAL,1 304,2026-01-16,Levantamento,-4323.99,USD,CASH WITHDRAWAL, 305,2026-01-19,Levantamento,-3186.27,EUR,CASH WITHDRAWAL,1 306,2026-02-12,Dividendo,5.08,USD,AAPL DIVIDEND, 307,2026-04-01,Dividendo,0.31,USD,NVIDIA DIVIDEND, 308,2026-04-30,Depósito,600,USD,CASH TOP-UP, ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/precos-atuais.json Tamanho: 831 bytes ======================================================================================== { "precos": { "AAPL": { "preco": 277.24, "moeda": "USD", "timestamp": "2025-12-09 21:00:01", "fonte": "API" }, "NVDA": { "preco": 184.98, "moeda": "USD", "timestamp": "2025-12-09 21:00:01", "fonte": "API" }, "IWDA": { "preco": 110.95, "moeda": "EUR", "timestamp": "2025-12-09 21:00:01", "fonte": "manual" }, "NDXEX": { "preco": 213.35, "moeda": "EUR", "timestamp": "2025-12-09 21:00:01", "fonte": "manual" } }, "cambio": { "EUR_USD": 1.16, "USD_EUR": 0.8621, "fonte": "Exchange Rate API", "timestamp": "2025-12-09 21:00:01" } } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/transacoes-acoes.csv Tamanho: 29395 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2019-10-15","2019-10-16","NASDAQ:GOOGL","0.161663","0","10.00","10.05","1.1041","1.1083","USD" "2","2019-10-16","2020-02-10","NASDAQ:AMZN","0.11321","0","10.05","12.00","","","USD" "3","2020-01-22","2020-06-10","NASDAQ:AAPL","1.8870298","0","150.00","164.64","","","USD" "4","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28949064","0","100.00","112.51","","","USD" "5","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28812028","0","100.00","112.57","","","USD" "6","2020-02-04","2020-05-29","NASDAQ:ADBE","0.27270991","0","100.00","104.05","","","USD" "7","2020-02-06","2020-04-30","NASDAQ:TSLA","1.9305018","0","100.00","112.68","","","USD" "8","2020-02-19","2020-02-25","NYSE:MA","0.28609409","0","100.07","94.80","1.0787","1.1877","USD" "9","2020-02-19","2020-04-14","NASDAQ:TSLA","1.97749185","0","124.07","133.54","","","USD" "10","2020-02-25","2020-05-20","NYSE:MA","0.31256977","0","99.08","92.74","1.0854","1.1368","USD" "11","2020-02-27","2020-04-14","NASDAQ:AMZN","1.028983","0","100.09","102.44","","","USD" "12","2020-03-19","2020-04-13","NASDAQ:AMZN","1.0563286","0","100.00","120.33","1.0791","1.0908","USD" "13","2020-03-19","2020-05-05","NASDAQ:AAPL","1.57029008","0","100.00","117.24","","","USD" "14","2020-03-25","2020-03-25","NASDAQ:TSLA","2.72737185","0","100.01","133.53","","","USD" "15","2020-04-07","2020-05-25","NYSE:MCD","1.11594688","0","200.00","209.51","1.0787","1.1054","USD" "16","2020-04-14","2020-05-12","NASDAQ:NFLX","0.25100401","0","101.09","110.15","1.0962","1.0866","USD" "17","2020-04-15","2020-04-30","NASDAQ:TSLA","2.02850715","0","101.08","112.68","","","USD" "18","2020-04-16","2020-06-10","NASDAQ:AMZN","1.6590626","0","201.08","219.83","","","USD" "19","2020-04-16","2020-07-01","NASDAQ:NFLX","0.22745365","0","101.08","105.58","1.0879","1.1268","USD" "20","2020-04-27","2020-05-11","NASDAQ:GOOGL","3.1276144","0","201.08","217.44","1.0850","1.0812","USD" "21","2020-05-01","2020-06-09","NASDAQ:AMZN","0.8724708","0","101.09","109.89","","","USD" "22","2020-05-01","2020-05-06","NASDAQ:TSLA","3.1895439","0","151.09","167.02","","","USD" "23","2020-05-11","2020-07-09","NASDAQ:AMD","1.80733779","0","101.08","101.77","","","USD" "24","2020-05-12","2020-08-19","NYSE:MA","0.36659579","0","101.08","109.05","1.0852","1.0994","USD" "25","2020-05-14","2020-06-03","NASDAQ:GOOGL","2.9816034","0","201.07","213.99","1.0794","1.1248","USD" "26","2020-05-15","2020-05-29","NYSE:SQ","2.54097319","0","201.08","205.08","1.0834","1.1105","USD" "27","2020-05-20","2020-07-01","NASDAQ:NVDA","3.4223706","0","124.09","130.86","","","USD" "28","2020-05-21","2020-06-08","NYSE:KO","4.34023991","0","200.08","215.7","1.0984","1.1304","USD" "29","2020-05-27","2020-06-03","NASDAQ:ANSS","0.38406882","0","101.09","111.55","1.0979","1.1224","USD" "30","2020-05-28","2020-06-05","NASDAQ:QCOM","2.4789291","0","201.10","220.91","1.1055","1.1289","USD" "31","2020-05-29","2020-07-19","NASDAQ:MSFT","1.15486141","0","211.11","228.85","1.1104","1.1231","USD" "32","2020-06-01","2020-06-18","NASDAQ:UAL","6.8212824","0","201.11","271.98","1.1117","1.1212","USD" "33","2020-06-03","2020-07-01","NASDAQ:UAL","7.12250712","0","225.00","266.29","1.1218","1.1262","USD" "34","2020-06-03","2020-07-15","NASDAQ:UAL","6.44484412","0","216.12","219.50","1.1248","1.1453","USD" "35","2020-06-04","2020-08-10","NASDAQ:UAL","2.69444444","0","98.12","98.47","1.1261","1.1797","USD" "36","2020-06-04","2020-08-27","NASDAQ:UAL","2.78884462","0","106.13","104.54","1.1334","1.1803","USD" "37","2020-06-04","2020-08-27","NASDAQ:UAL","5.20231213","0","199.13","191.07","1.1330","1.1782","USD" "38","2020-06-05","2020-10-06","NASDAQ:UAL","2.4672489","0","114.12","90.74","1.1297","1.1797","USD" "39","2020-06-05","2020-10-08","NASDAQ:UAL","4.8456164","0","215","181.65","1.1287","1.1744","USD" "40","2020-06-08","2020-10-08","NASDAQ:UAL","4.86896252","0","224.80","181.65","1.1309","1.1743","USD" "41","2020-06-08","2020-07-30","NASDAQ:ANSS","0.35145678","0","100.00","108.80","1.1303","1.1801","USD" "42","2020-06-09","2020-09-15","NASDAQ:UAL","2.22121486","0","99.13","82.33","1.1346","1.1857","USD" "43","2020-06-10","2020-08-28","NASDAQ:UAL","2.43486729","0","101.13","90.13","1.1373","1.1899","USD" "44","2020-06-10","2020-08-03","NASDAQ:ANSS","1.03831377","0","301.13","327.64","","","USD" "45","2020-06-11","2020-07-01","NASDAQ:TSLA","4.5053613","0","301.14","336.05","","","USD" "46","2020-06-15","2020-07-06","NASDAQ:AAPL","1.78512984","0","151.11","166.73","","","USD" "47","2020-06-19","2020-06-20","NASDAQ:GOOGL","4.1551534","0","301.12","322.63","1.1231","1.1444","USD" "48","2020-06-19","2020-07-30","NASDAQ:QCOM","3.3463469","0","301.12","343.55","1.1226","1.1800","USD" "49","2020-06-22","2020-07-13","NASDAQ:AAPL","2.26321148","0","201.12","220.87","1.1228","1.1352","USD" "50","2020-07-01","2020-07-21","NYSE:KO","6.61229887","0","300","314.86","1.1269","1.145","USD" "51","2020-07-07","2020-07-10","NASDAQ:TSLA","5.3756118","0","500","549.91","1.1289","1.1304","USD" "52","2020-07-07","2020-07-15","NASDAQ:UAL","6.00781015","0","200.00","205.52","1.1289","1.1450","USD" "53","2020-07-07","2020-08-21","NASDAQ:ZM","0.55248618","0","150.00","160.37","1.1329","1.1768","USD" "54","2020-07-10","2020-08-31","NASDAQ:AMZN","0.6291998","0","100.00","109.86","1.1327","1.1961","USD" "55","2020-07-13","2020-08-18","NASDAQ:TSLA","2.6472144","0","300.01","330.61","1.1351","1.1934","USD" "56","2020-07-13","2020-11-13","NASDAQ:AMZN","1.8371096","0","300.01","286.13","1.135","1.1829","USD" "57","2020-07-14","2020-07-31","NASDAQ:AAPL","2.63296468","0","250.00","270.98","1.1369","1.1839","USD" "58","2020-07-15","2020-08-03","NASDAQ:AAPL","2.0317988","0","199.99","225.55","","","USD" "59","2020-07-15","2020-07-30","NASDAQ:TSLA","1.9946808","0","200.01","232.18","","","USD" "60","2020-07-20","2020-07-23","NASDAQ:UAL","9.17150718","0","300.00","307.96","1.1443","1.1618","USD" "61","2020-07-20","2020-08-03","NASDAQ:AAPL","3.05654608","0","300.00","339.31","","","USD" "62","2020-07-23","2020-11-13","NASDAQ:AMZN","1.9828548","0","300.01","327.75","","","USD" "63","2020-07-24","2020-07-24","NASDAQ:AMD","1.05263157","0","70.00","72.41","","","USD" "64","2020-07-24","2020-08-21","NASDAQ:ZM","0.28389503","0","70.00","82.40","1.1635","1.1768","USD" "65","2020-07-27","2020-08-13","NASDAQ:TSLA","1.5705051","0","150.00","168.30","1.1746","1.1839","USD" "66","2020-07-30","2020-09-01","NASDAQ:GOOGL","3.9853868","0","300.00","329.87","1.1804","1.1917","USD" "67","2020-07-30","2020-08-27","NASDAQ:MSFT","0.73800738","0","150.00","169.05","1.1802","1.1807","USD" "68","2020-07-31","2020-08-25","NASDAQ:GOOGL","3.3979624","0","250","272.70","1.1840","1.1828","USD" "69","2020-08-03","2020-08-13","NASDAQ:TSLA","3.0459945","0","300.00","331.46","1.1731","1.1859","USD" "70","2020-08-05","2020-09-01","NASDAQ:ANSS","0.95910994","0","300.00","330.23","","","USD" "71","2020-08-05","2020-09-29","NASDAQ:AMD","1.18990956","0","100.00","96.79","","","USD" "72","2020-08-06","2020-08-31","NASDAQ:AAPL","0.90019128","0","100.00","115.45","","","USD" "73","2020-08-10","2020-08-31","NASDAQ:AMD","1.23701138","0","100.00","111.16","","","USD" "74","2020-08-10","2020-08-27","NASDAQ:ANSS","0.32998944","0","100.00","109.43","","","USD" "75","2020-08-13","2020-08-18","NASDAQ:ZM","0.40695071","0","100.00","110.22","1.1851","1.1962","USD" "76","2020-08-14","2020-08-20","NYSE:SQ","0.7033338","0","100.00","109.90","1.1830","1.1847","USD" "77","2020-08-17","2020-08-18","NASDAQ:TSLA","0.88541535","0","100.00","111.14","","","USD" "78","2020-08-17","2020-08-31","NASDAQ:TSLA","0.842091","0","100.00","97.95","","","USD" "79","2020-08-17","2020-09-01","NYSE:SQ","0.66613375","0","100.00","110.62","1.1860","1.1977","USD" "80","2020-08-18","2020-08-24","NASDAQ:UAL","2.9620853","0","100.00","107.19","1.1937","1.1805","USD" "81","2020-08-19","2020-09-02","NASDAQ:NVDA","1.0171698","0","50.00","58.70","","","USD" "82","2020-08-20","2020-08-28","NASDAQ:TSLA","0.75513105","0","100.00","114.37","","","USD" "83","2020-08-21","2020-12-17","NASDAQ:AAPL","1.6575476","0","200.00","213.11","","","USD" "84","2020-08-21","2020-08-31","NASDAQ:TSLA","1.44357075","0","200.01","222.84","","","USD" "85","2020-08-21","2020-08-31","NASDAQ:TSLA","1.44357075","0","200.01","222.84","","","USD" "86","2020-08-24","2020-08-27","NASDAQ:TSLA","1.46742315","0","200.00","222.35","","","USD" "87","2020-08-25","2020-09-28","NYSE:BABA","0.17636684","0","50.00","48.62","1.1826","1.1662","USD" "88","2020-08-26","2020-09-01","NASDAQ:ZM","0.1661792","0","50.00","75.38","1.1821","1.1977","USD" "89","2020-08-26","2020-09-28","NYSE:BABA","0.17246731","0","50.00","47.54","1.1825","1.1662","USD" "90","2020-08-27","2020-12-03","NASDAQ:TSLA","1.3170429","0","200.01","257.80","","","USD" "91","2020-08-27","2020-11-13","NASDAQ:TSLA","3.29757285","0","500.01","445.11","","","USD" "92","2020-08-27","2020-08-31","NASDAQ:TSLA","3.29757285","0","499.99","548.72","","","USD" "93","2020-08-27","2020-12-17","NASDAQ:AAPL","1.60481444","0","200.01","206.33","","","USD" "94","2020-08-28","2020-09-02","NASDAQ:NVDA","0.9644131","0","50.00","55.67","","","USD" "95","2020-08-15","2020-12-03","NASDAQ:TSLA","3.22587582","0","500.01","631.53","","","USD" "96","2020-08-15","2020-12-15","NASDAQ:TSLA","1.23482196","0","200.00","263.70","","","USD" "97","2020-08-20","2020-08-31","NASDAQ:TSLA","0.75513105","0","100.00","122.78","","","USD" "98","2020-08-15","2020-12-15","NASDAQ:TSLA","3.02858988","0","499.99","649.98","","","USD" "99","2020-09-01","2020-09-22","NASDAQ:ZM","0.23466466","0","100.00","110.05","1.1988","1.1759","USD" "100","2020-09-01","2020-12-10","NASDAQ:TSLA","3.0358227","0","500.00","631.60","","","USD" "101","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.10","1.1969","1.1706","USD" "102","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.1","1.1952","1.1668","USD" "103","2020-09-01","2020-09-30","NYSE:NIO","10.07556675","0","200.00","222.96","1.1921","1.1695","USD" "104","2020-09-02","2020-09-02","NYSE:NIO","10","0","207.40","239.98","1.1832","1.1762","USD" "105","2020-09-02","2020-11-18","NASDAQ:TSLA","2.54919498","0","380.01","418.48","","","USD" "106","2020-09-04","2020-12-17","NASDAQ:AAPL","2.01871739","0","248.38","259.55","","","USD" "107","2020-09-04","2020-10-01","NASDAQ:TSLA","1.82127246","0","250.01","272.23","","","USD" "108","2020-09-10","2020-09-15","NASDAQ:TSLA","1.96494537","0","250.00","286.99","","","USD" "109","2020-09-17","2020-10-01","NASDAQ:ANSS","1.19565287","0","371.31","399.46","","","USD" "110","2020-09-24","2020-10-01","NASDAQ:TSLA","2.69316786","0","329.16","351.43","","","USD" "111","2020-09-24","2020-10-13","NASDAQ:ZM","0.74879082","0","351.43","382.32","","","USD" "112","2020-09-25","2020-10-09","NASDAQ:AAPL","2.02064706","0","219.22","235.02","","","USD" "113","2020-10-01","2020-10-21","NASDAQ:GOOGL","5.3886366","0","399.41","429.69","","","USD" "114","2020-10-02","2020-10-14","NASDAQ:TSLA","2.96907141","0","419.03","457.42","","","USD" "115","2020-10-06","2020-10-13","NASDAQ:AAPL","2.41595669","0","272.23","299.26","","","USD" "116","2020-10-13","2021-02-02","NASDAQ:Z","1","0","101.17","114.81","","","USD" "117","2020-10-15","2020-11-18","NASDAQ:TSLA","3","0","448.20","492.48","","","USD" "118","2020-10-15","2021-02-02","NASDAQ:ANSS","1","0","345.66","375.57","","","USD" "119","2020-10-20","2020-12-09","NASDAQ:ZM","0.8230289","0","429.69","338.03","","","USD" "120","2020-10-22","2020-10-29","NYSE:NIO","19.00692924","0","521.17","604.42","","","USD" "121","2020-10-30","2020-11-03","NYSE:NIO","19","0","581.21","654.36","","","USD" "122","2020-10-30","2020-11-05","NASDAQ:AAPL","2.37198781","0","258.07","282.79","","","USD" "123","2020-11-04","2020-11-05","NYSE:NIO","17.55848346","0","654.23","727.80","","","USD" "124","2020-11-06","2020-11-12","NYSE:NIO","20","0","824.80","980.00","","","USD" "125","2020-11-12","2020-11-23","NASDAQ:ZM","1","0","435.44","428.76","","","USD" "126","2020-11-13","2020-11-23","NYSE:NIO","12","0","541.20","660.00","","","USD" "127","2020-11-17","2020-11-23","NYSE:NIO","15","0","715.20","825.00","","","USD" "128","2020-11-18","2020-12-15","NASDAQ:AAPL","4","0","479.04","506.60","","","USD" "129","2020-11-23","2020-11-27","NASDAQ:MRNA","8","0","809.60","998.80","","","USD" "130","2020-11-23","2020-12-15","NASDAQ:AAPL","4","0","457.24","505.36","","","USD" "131","2020-11-24","2021-01-20","NYSE:NIO","11","0","584.32","659.98","","1.2101","USD" "132","2020-11-30","2020-12-17","NASDAQ:AAPL","2","0","234.84","255.76","","","USD" "133","2020-11-24","2021-01-12","NYSE:NIO","9","0","478.08","576.18","","","USD" "134","2020-11-25","2021-01-29","NASDAQ:MRNA","5","0","730.10","762.90","","","USD" "135","2020-12-03","2020-12-07","NASDAQ:AAPL","-2.06461594","0","-254.05","-249.61","","","USD" "136","2020-11-25","2021-01-26","NASDAQ:MRNA","5","0","730.10","870.00","","1.2153","USD" "137","2020-12-07","2021-02-04","NASDAQ:MRNA","3","0.01","466.20","515.99","","1.1965","USD" "138","2020-12-07","2020-12-21","NYSE:NIO","8","0","352.24","391.84","","","USD" "139","2020-12-08","2021-02-08","NASDAQ:MRNA","3","0.02","503.52","554.98","1.2104","1.2061","USD" "140","2020-12-10","2021-01-29","NASDAQ:MRNA","1","0","155.44","173.97","1.2139","1.2153","USD" "141","2020-12-10","2020-12-17","NASDAQ:TSLA","3","0","573.85","649.98","1.2112","1.2263","USD" "142","2020-12-11","2020-12-14","NASDAQ:TSLA","-1.17027156","0","-244.72","-240.85","","","USD" "143","2020-12-14","2020-12-30","NASDAQ:TSLA","3","0","617.43","694.98","","","USD" "144","2020-12-14","2020-12-21","NYSE:NIO","1","0","39.90","48.96","1.2163","","USD" "145","2020-12-15","2021-01-26","NASDAQ:MRNA","4","0","580.00","610.36","1.2161","","USD" "146","2020-12-17","2021-01-07","NASDAQ:TSLA","3","0","620.01","799.95","","","USD" "147","2020-12-22","2021-01-14","NASDAQ:TSLA","3","0","647.31","859.97","1.2225","1.2118","USD" "148","2020-12-23","2020-12-30","NASDAQ:TSLA","3","0","630.00","694.98","","","USD" "149","2020-12-31","2021-01-06","NYSE:NIO","10","0","485.00","550.00","1.2279","","USD" "150","2020-12-31","2021-01-07","NASDAQ:TSLA","2.581293","0","616.49","688.35","","","USD" "151","2020-12-31","2021-01-07","NASDAQ:TSLA","0.418707","0","100.00","111.66","","","USD" "152","2021-01-04","2021-07-09","NASDAQ:AAPL","1","0","130.00","145.03","","","USD" "153","2021-01-06","2021-02-02","NASDAQ:TSLA","0.71085433","0","546.91","619.87","1.228","1.2029","USD" "154","2021-01-07","2021-01-25","NASDAQ:TSLA","1","0","805.56","899.97","1.2275","1.2129","USD" "155","2021-01-08","2021-10-25","NASDAQ:TSLA","0.86743701","0","244.61","276.43","","","USD" "156","2021-01-08","2021-10-25","NASDAQ:TSLA","1.68863022","0","489.31","549.31","","","USD" "157","2021-01-08","2021-10-25","NASDAQ:TSLA","1.31136978","0","380.00","426.58","","","USD" "158","2021-01-13","2021-01-14","NASDAQ:PLUG","8","0.02","554.48","514.78","1.2167","1.2167","USD" "159","2021-01-11","2021-01-14","NYSE:NIO","2","0","129.78","87.08","1.2147","1.1553","USD" "160","2020-12-21","2021-04-15","NASDAQ:AMD","3","0","276.00","249.18","","","USD" "161","2020-12-23","2021-02-03","NASDAQ:AMZN","2.691074","0","430.01","457.37","","","USD" "162","2020-12-23","2021-02-03","NASDAQ:AMZN","0.4380818","0","70.00","74.46","","","USD" "163","2020-12-23","2021-07-14","NASDAQ:AAPL","4","0","528.68","596.64","","","USD" "164","2020-12-17","2021-07-09","NASDAQ:AAPL","3","0","386.94","435.12","","","USD" "165","2020-12-17","2021-01-25","NASDAQ:AAPL","5","0","643.15","721.47","1.2263","1.2129","USD" "166","2020-12-07","2021-04-15","NASDAQ:AMD","4","0","358.20","332.24","","","USD" "167","2021-01-14","2021-01-21","NASDAQ:MRNA","4","0","516.32","538.84","1.2168","","USD" "168","2021-01-15","2021-02-09","NYSE:NIO","15","0","860.7","939.87","1.2094","1.2121","USD" "169","2021-01-22","2021-10-21","NASDAQ:TSLA","2.52425082","0","700","753.46","1.2179","1.164","USD" "170","2021-01-25","2021-10-25","NASDAQ:TSLA","3","0","870","992.81","1.213","1.161","USD" "171","2021-01-25","2021-09-07","NASDAQ:AAPL","5","0","700.00","775.25","","","USD" "172","2021-01-25","2021-11-04","NYSE:NIO","1","0","59.62","43.54","1.2148","1.1553","USD" "173","2021-01-27","2021-11-18","NASDAQ:AAPL","2","0","286.62","316.00","","","USD" "174","2021-01-27","2021-02-04","NASDAQ:MRNA","2","0.01","316.18","343.99","1.2094","1.1965","USD" "175","2021-01-27","2021-02-08","NASDAQ:MRNA","3","0.01","497.58","554.97","1.2126","1.2061","USD" "176","2021-01-29","2021-10-25","NASDAQ:TSLA","3","0","840.99","951.49","1.2148","1.1614","USD" "177","2021-01-29","2021-05-03","NASDAQ:MRNA","6","0","1064.10","1121.21","1.2147","1.2067","USD" "178","2021-02-01","2021-02-04","NASDAQ:MRNA","1","0.01","156.50","171.99","1.2067","1.1965","USD" "179","2021-02-02","2021-08-16","NASDAQ:AAPL","4","0","542.68","600.00","","","USD" "180","2021-02-05","2021-02-11","NASDAQ:PYPL","3","0","801.54","900.00","1.2040","1.2140","USD" "181","2021-02-08","2021-07-23","NASDAQ:PYPL","3","0","842.85","926.42","1.2061","1.1764","USD" "182","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.25","","","USD" "183","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.27","","","USD" "184","2021-02-09","2021-05-03","NASDAQ:MRNA","3","0","536.46","560.6","1.2121","1.2067","USD" "185","2021-02-10","2021-10-25","NASDAQ:TSLA","2.08745436","0","581.52","665.19","","","USD" "186","2021-02-11","2021-11-22","NASDAQ:PYPL","3","0","855","575.54","1.2133","1.1242","USD" "187","2021-02-12","2022-02-02","NASDAQ:PYPL","2.8","0","818.92","381.71","1.2098","1.1317","USD" "188","2021-03-12","2021-06-28","NYSE:NIO","4","0","177.20","159.99","1.1933","1.1932","USD" "189","2021-04-19","2021-09-17","NASDAQ:TSLA","2.35822089","0","550","596.41","1.2032","1.1758","USD" "190","2021-05-04","2021-07-06","NASDAQ:GOOGL","1.9646364","0","225","247.64","1.2027","1.1841","USD" "191","2021-05-04","2021-05-27","NASDAQ:MRNA","4","0.01","701.88","708.19","1.2021","1.2200","USD" "192","2021-05-04","2021-10-19","NASDAQ:ANSS","2","0","700.18","729.33","","","USD" "193","2021-05-04","2021-07-06","NASDAQ:AMZN","0.5170316","0","85","93.61","1.2023","1.1841","USD" "194","2021-05-24","2021-05-27","NYSE:SPCE","0.2","0","49.86","56.03","1.2212","1.2198","USD" "195","2021-05-27","2021-06-07","NYSE:SPCE","0.2","0","114.12","135.42","1.2194","1.2198","USD" "196","2021-05-27","2021-06-07","NYSE:SPCE","1","0","704.26","778.55","1.2199","1.2198","USD" "197","2021-06-07","2021-06-28","NYSE:NIO","10","0","437.20","490.00","1.2198","1.1932","USD" "198","2021-06-08","2021-06-25","NYSE:SPCE","0.6","0","448.31","572.75","1.2188","1.1969","USD" "199","2021-07-01","2021-11-04","NYSE:NIO","10","0","520","435.40","1.1869","1.1553","USD" "200","2021-07-06","2021-08-09","NASDAQ:GOOGL","4.3831336","0","550","595.41","1.1830","1.1751","USD" "201","2021-07-07","2021-07-08","NYSE:SPCE","0.6","0","540","599.99","1.1807","1.1848","USD" "202","2021-07-12","2021-12-03","NYSE:SPCE","0.6","0","540.00","171.84","1.1858","1.1280","USD" "203","2021-07-15","2021-07-16","NASDAQ:MRNA","1","0.01","255.80","284.99","1.1817","1.1804","USD" "204","2021-07-16","2021-11-09","NYSE:SPCE","1.2","0","781.44","503.77","1.1811","1.1588","USD" "205","2021-07-16","2021-11-29","NASDAQ:AAPL","1","0","147.32","164.98","","","USD" "206","2021-07-16","2021-11-29","NASDAQ:AAPL","2","0","294.60","330.00","","","USD" "207","2021-07-23","2021-08-03","NASDAQ:MRNA","2","0.01","670.54","739.99","1.1765","1.1866","USD" "208","2021-08-03","2021-11-19","NASDAQ:AMZN","4.4443522","0","750","829.78","1.1866","1.1315","USD" "209","2021-08-09","2021-11-26","NASDAQ:MRNA","1","0","287.97","327.95","1.1255","1.1300","USD" "210","2021-08-19","2021-11-19","NASDAQ:AAPL","5","0","724.65","800.00","","","USD" "211","2021-09-10","2021-12-01","NASDAQ:AAPL","5","0","749.85","850.00","","","USD" "212","2021-09-17","2021-11-29","NASDAQ:AAPL","4","0","587.32","660.00","","","USD" "213","2021-10-26","2021-11-01","NASDAQ:TSLA","3","0","1044.49","1149.98","1.1609","1.1583","USD" "214","2021-10-26","2021-12-06","NASDAQ:AAPL","4","0","601.92","668.36","","","USD" "215","2021-10-27","2021-12-01","NASDAQ:AAPL","7","0","1044.75","1190.00","","","USD" "216","2021-10-27","2021-12-01","NASDAQ:AAPL","3","0","447.75","510.00","","","USD" "217","2021-11-04","2022-02-17","NYSE:KO","10","0","562.89","619.99","1.1552","1.1365","USD" "218","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "219","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "220","2021-12-02","2021-12-13","NASDAQ:AAPL","7","0","1111.04","1266.98","1.1345","1.1294","USD" "221","2021-12-02","2021-12-10","NASDAQ:AAPL","3","0","482.67","534.51","","","USD" "222","2021-12-06","2022-01-03","NASDAQ:TSLA","3","0","992.9","1153.57","1.1291","1.1309","USD" "223","2021-12-14","2021-12-27","NASDAQ:TSLA","1.2","0","377.47","441.07","","","USD" "224","2021-12-14","2021-12-27","NASDAQ:TSLA","0.3","0","94.37","110.27","","","USD" "225","2021-11-10","2022-01-03","NASDAQ:TSLA","1.5","0","536.75","597.42","","","USD" "226","2022-02-18","2022-03-22","NASDAQ:TSLA","1.2","0","345.54","376.86","","","USD" "227","2022-02-18","2022-03-22","NASDAQ:TSLA","0.3","0","86.38","94.22","","","USD" "228","2022-02-18","2022-04-20","NYSE:O","2","0","134.06","149.99","1.1336","1.0848","USD" "229","2022-04-14","2022-10-05","NYSE:TWTR","4","0","193.68","203.72","1.0829","0.9852","USD" "230","2022-04-19","2022-10-05","NYSE:TWTR","1","0","47.24","50.93","1.0798","0.9852","USD" "231","2022-05-20","2022-07-21","NASDAQ:AAPL","1","0","139.02","155.02","","","USD" "232","2022-07-27","2022-07-27","NASDAQ:AAPL","1","0","162.00","162.00","","","USD" "233","2022-01-03","2023-12-27","NASDAQ:ANSS","2","0","786.86","669.60","","","USD" "234","2022-01-11","2023-11-16","NASDAQ:AAPL","6","0","1026","1139.98","1.1324","1.0885","USD" "235","2022-02-02","2023-05-25","NASDAQ:MSFT","0.62199751","0","185.15","200.03","1.1092","1.0722","USD" "236","2021-11-09","2024-01-01","NASDAQ:TSLA","3","0","1065.78","1065.78","","","USD" "237","2021-11-22","2023-06-15","NASDAQ:AAPL","8.5","0","1386.18","1572.67","","","USD" "238","2021-11-22","2023-06-15","NASDAQ:AAPL","1.5","0","244.62","277.50","","","USD" "239","2021-12-02","2023-06-15","NASDAQ:AAPL","7","0","1142.82","1295.00","","","USD" "240","2021-12-02","2023-06-15","NASDAQ:AAPL","2","0","326.52","370.00","","","USD" "241","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","392.00","","","USD" "242","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","391.98","","","USD" "243","2021-12-14","2023-12-13","NASDAQ:AAPL","3","0","522.51","588.00","","","USD" "244","2022-04-13","2023-12-14","NASDAQ:AAPL","1","0","170.66","196.00","","","USD" "245","2022-09-14","2023-05-05","NASDAQ:AAPL","2","0","311.56","343.98","","","USD" "246","2022-12-20","2023-01-23","NASDAQ:AAPL","2","0","260.00","285.98","","","USD" "247","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "248","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "249","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "250","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "251","2023-03-01","2023-06-14","NYSE:BRK.B","1","0","303.16","339.98","1.0685","1.0868","USD" "252","2023-05-08","2023-05-23","NASDAQ:TSLA","1","0","171.76","189.98","","","USD" "253","2023-05-26","2023-06-02","NASDAQ:TSLA","1","0","190.12","209.98","","","USD" "254","2022-01-06","2024-01-25","NASDAQ:TSLA","2.7","0","945.00","506.93","","","USD" "255","2022-01-06","2024-01-25","NASDAQ:TSLA","0.3","0","105.00","56.32","","","USD" "256","2023-01-01","2024-04-26","NASDAQ:GOOGL","1.8369098","0","276.14","320.23","","","USD" "257","2022-02-02","2024-04-26","NASDAQ:GOOGL","0.9046522","0","136.00","157.69","","","USD" "258","2022-02-28","2024-06-05","NYSE:KO","2","0","123.86","127.83","1.1225","1.0890","USD" "259","2021-10-15","2024-04-12","NASDAQ:GOOGL","5","0","714.80","1498.30","","","USD" "260","2021-11-04","2024-07-11","NYSE:BAC","10","0","474.89","419.98","1.1551","1.0899","USD" "261","2024-01-01","2024-03-01","NASDAQ:TSLA","2","0","710.52","402.44","","","USD" "262","2024-01-01","2024-02-09","NASDAQ:TSLA","1","0","355.26","192.78","","","USD" "263","2021-11-10","2024-02-09","NASDAQ:TSLA","0.525","0","187.86","101.21","","","USD" "264","2021-11-10","2024-02-09","NASDAQ:TSLA","0.975","0","348.88","187.95","","","USD" "265","2021-11-22","2024-02-09","NASDAQ:TSLA","1.5","0","590.88","289.17","","","USD" "266","2021-11-26","2024-02-02","NASDAQ:AMZN","1.8995262","0","334.98","326.64","","","USD" "267","2021-12-02","2024-02-02","NASDAQ:AMZN","1.7335028","0","300.00","298.09","","","USD" "268","2021-12-14","2024-04-26","NASDAQ:AAPL","1","0","174.17","170.00","","","USD" "269","2021-12-28","2024-02-02","NASDAQ:AMZN","1.1645374","0","200.00","200.24","","","USD" "270","2024-04-22","2024-07-17","NYSE:O","2","0","148.00","114.32","1.0817","1.0957","USD" "271","2022-06-07","2024-02-02","NASDAQ:AMZN","0.2024336","0","24.75","34.81","","","USD" "272","2023-05-23","2024-06-11","NASDAQ:AAPL","1","0","172.79","199.96","","","USD" "273","2023-06-06","2024-07-02","NASDAQ:AAPL","3","0","535.89","660.00","","","USD" "274","2023-06-06","2024-04-26","NASDAQ:AAPL","1","0","178.63","170.00","","","USD" "275","2023-06-14","2024-01-31","NASDAQ:TSLA","1","0","258.00","189.98","","","USD" "276","2023-06-15","2024-01-25","NYSE:BRK.B","4","0","1352.95","1519.98","1.0927","1.0876","USD" "277","2023-06-20","2024-01-31","NASDAQ:TSLA","2","0","542.06","380.00","","","USD" "278","2023-06-30","2024-08-28","NASDAQ:AAPL","4","0","769.80","919.96","","","USD" "279","2023-07-19","2024-02-07","NASDAQ:TSLA","2","0","593.16","362.96","","","USD" "280","2023-07-19","2024-02-07","NASDAQ:TSLA","1","0","296.58","181.47","","","USD" "281","2023-09-13","2024-07-02","NASDAQ:AAPL","3","0","525.06","660.00","","","USD" "282","2023-12-14","2024-08-28","NASDAQ:AAPL","1","0","196.00","230.00","","","USD" "283","2023-12-18","2024-11-26","NASDAQ:AAPL","2","0","390.00","470.00","","","USD" "284","2023-12-22","2024-11-26","NASDAQ:AAPL","3","0","585.72","705.00","","","USD" "285","2024-01-01","2024-11-26","NASDAQ:AAPL","3","0","576.96","705.00","","","USD" "286","2024-01-08","2024-07-02","NASDAQ:AAPL","3","0","540.00","659.93","","","USD" "287","2024-01-25","2024-02-09","NASDAQ:NVDA","30","0","1865.35","2159.97","1.0876","1.0809","USD" "288","2024-01-31","2024-06-17","NASDAQ:MSFT","1","0","402.58","449.98","1.0869","1.0750","USD" "289","2024-02-02","2024-05-20","NASDAQ:NVDA","10","0","659.78","949.98","1.0805","1.0889","USD" "290","2024-02-02","2024-11-26","NASDAQ:AAPL","1","0","186.01","234.93","","","USD" "291","2024-02-05","2024-05-22","NASDAQ:NVDA","10","0","688.87","999.85","","","USD" "292","2024-02-21","2024-05-22","NASDAQ:NVDA","30","0","2037.00","3000.00","","","USD" "293","2024-03-05","2024-07-30","NYSE:BRK.B","1","0","400.00","439.98","1.0882","1.0832","USD" "294","2024-03-11","2024-05-22","NASDAQ:NVDA","10","0","889.33","1000.00","","","USD" "295","2024-04-01","2024-06-11","NASDAQ:AAPL","2","0","340.00","400.00","","","USD" "296","2021-10-15","2024-04-26","NASDAQ:GOOGL","0.137277","0","19.63","23.93","","","USD" "297","2024-04-26","2024-06-11","NASDAQ:AAPL","3","0","510.00","600.00","","","USD" "298","2024-07-03","2024-09-05","NASDAQ:TSLA","2","0","495.86","450.44","","","USD" "299","2024-07-11","2024-11-10","NYSE:TSM","10","0","1938.61","1898.01","1.0915","1.0965","USD" "300","2024-05-28","2024-10-17","NASDAQ:NVDA","10","0.05","1120.60","1399.95","","","USD" "301","2023-12-14","2026-01-14","AMS:IWDA","6","0.05","491.33","682.58","","","EUR" "302","2024-04-22","2026-01-14","AMS:IWDA","7","0.06","618.93","796.34","","","EUR" "303","2024-05-28","2025-01-06","NASDAQ:NVDA","20","0.09","2241.20","2999.91","","","USD" "304","2024-06-06","2025-05-28","NASDAQ:NVDA","20","0","2498.35","2799.99","1.0907","1.1318","USD" "305","2024-06-12","2026-01-12","NASDAQ:AAPL","7","0.01","1497.65","1819.99","","","USD" "306","2024-06-20","","NASDAQ:AAPL","2","0","420.00","","","","USD" "307","2024-07-23","2026-01-15","INDEXNASDAQ:NDX","4.84403203","0","858.75","1039.77","","","EUR" "308","2024-08-01","2025-11-11","NASDAQ:AAPL","5","0","1094.25","1369.52","1.0809","1.1626","USD" "309","2024-08-05","2025-08-08","NASDAQ:AAPL","1","0","204.90","225.00","","","USD" "310","2024-08-05","2025-08-08","NASDAQ:AAPL","2","0","409.80","449.98","","","USD" "3","2024-11-06","","NASDAQ:AAPL","21","0","4741.95","","","","USD" "3","2024-11-25","2025-02-24","NASDAQ:NVDA","8","0.01","1101.58","1559.99","","","USD" "313","2024-12-18","2026-01-15","INDEXNASDAQ:NDX","10","0","2038.00","2146.50","","","EUR" "314","2025-01-06","2026-01-15","NASDAQ:NVDA","21","0.01","2998.17","3947.99","","","USD" "315","2025-01-27","2026-01-15","NASDAQ:NVDA","2","0.01","247.18","376","","","USD" "316","2025-07-03","2026-04-15","NASDAQ:NVDA","12","0.06","1918.68","2399.94","","","USD" "317","2025-10-16","","NASDAQ:NVDA","8","0","1454.35","","","","USD" "318","2025-11-11","","NASDAQ:NVDA","9","0","1742.36","","","","USD" "319","2026-02-27","","NASDAQ:NVDA","8","0","1464","","","","USD" "320","2026-04-29","","NASDAQ:NVDA","11","0","2298.12","","","","USD" ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/tiago/transacoes-vistos.json Tamanho: 66 bytes ======================================================================================== { "versao": "1.0", "vistos": {}, "ultima_atualizacao": "" } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/transacoes-acoes.csv Tamanho: 29114 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2019-10-15","2019-10-16","NASDAQ:GOOGL","0.00808315","0","10.00","10.05","1.1041","1.1083","USD" "2","2019-10-16","2020-02-10","NASDAQ:AMZN","0.0056605","0","10.05","12.00","","","USD" "3","2020-01-22","2020-06-10","NASDAQ:AAPL","0.47175745","0","150.00","164.64","","","USD" "4","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28949064","0","100.00","112.51","","","USD" "5","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28812028","0","100.00","112.57","","","USD" "6","2020-02-04","2020-05-29","NASDAQ:ADBE","0.27270991","0","100.00","104.05","","","USD" "7","2020-02-06","2020-04-30","NASDAQ:TSLA","0.12870012","0","100.00","112.68","","","USD" "8","2020-02-19","2020-02-25","NYSE:MA","0.28609409","0","100.07","94.80","1.0787","1.1877","USD" "9","2020-02-19","2020-04-14","NASDAQ:TSLA","0.13183279","0","124.07","133.54","","","USD" "10","2020-02-25","2020-05-20","NYSE:MA","0.31256977","0","98.08","92.74","1.0854","1.1368","USD" "11","2020-02-27","2020-04-14","NASDAQ:AMZN","0.05144915","0","100.09","102.44","","","USD" "12","2020-03-19","2020-04-13","NASDAQ:AMZN","0.05281643","0","100.00","120.33","1.0791","1.0908","USD" "13","2020-03-19","2020-05-05","NASDAQ:AAPL","1.57029008","0","100.00","117.24","","","USD" "14","2020-03-25","2020-03-25","NASDAQ:TSLA","2.72737185","0","100.01","133.53","","","USD" "15","2020-04-07","2020-05-25","NYSE:MCD","1.11594688","0","200.00","209.51","1.0787","1.1054","USD" "16","2020-04-14","2020-05-12","NASDAQ:NFLX","0.25100401","0","101.09","110.15","1.0962","1.0866","USD" "17","2020-04-15","2020-04-30","NASDAQ:TSLA","0.13523381","0","101.08","112.68","","","USD" "18","2020-04-16","2020-06-10","NASDAQ:AMZN","0.08295313","0","201.08","219.83","","","USD" "19","2020-04-16","2020-07-01","NASDAQ:NFLX","0.22745365","0","101.08","105.58","1.0879","1.1268","USD" "20","2020-04-27","2020-05-11","NASDAQ:GOOGL","0.15638072","0","201.08","217.44","1.0850","1.0812","USD" "21","2020-05-01","2020-06-09","NASDAQ:AMZN","0.04362354","0","101.09","109.89","","","USD" "22","2020-05-01","2020-05-06","NASDAQ:TSLA","0.21263626","0","151.09","167.02","","","USD" "23","2020-05-11","2020-07-09","NASDAQ:AMD","1.80733779","0","101.08","101.77","","","USD" "24","2020-05-12","2020-08-19","NYSE:MA","0.36659579","0","101.08","109.05","1.0852","1.0994","USD" "25","2020-05-14","2020-06-03","NASDAQ:GOOGL","0.14908017","","201.07","213.99","1.0794","1.1248","USD" "26","2020-05-15","2020-05-29","NYSE:SQ","2.54097319","0","201.08","205.08","1.0834","1.1105","USD" "27","2020-05-20","2020-07-01","NASDAQ:NVDA","0.34223706","0","124.09","130.86","","","USD" "28","2020-05-21","2020-06-08","NYSE:KO","4.34023991","0","200.08","215.7","1.0984","1.1304","USD" "29","2020-05-27","2020-06-03","NASDAQ:ANSS","0.38406882","0","101.09","111.55","1.0979","1.1224","USD" "30","2020-05-28","2020-06-05","NASDAQ:QCOM","2.4789291","0","201.10","220.91","1.1055","1.1289","USD" "31","2020-05-29","2020-07-19","NASDAQ:MSFT","1.15486141","0","211.11","228.85","1.1104","1.1231","USD" "32","2020-06-01","2020-06-18","NASDAQ:UAL","6.8212824","0","201.11","271.98","1.1117","1.1212","USD" "33","2020-06-03","2020-07-01","NASDAQ:UAL","7.12250712","0","225.00","266.29","1.1218","1.1262","USD" "34","2020-06-03","2020-07-15","NASDAQ:UAL","6.44484412","0","216.12","219.50","1.1248","1.1453","USD" "35","2020-06-04","2020-08-10","NASDAQ:UAL","2.69444444","0","98.12","98.47","1.1261","1.1797","USD" "36","2020-06-04","2020-08-27","NASDAQ:UAL","2.78884462","0","106.13","104.54","1.1334","1.1803","USD" "37","2020-06-04","2020-08-27","NASDAQ:UAL","5.20231213","0","199.13","191.07","1.1330","1.1782","USD" "38","2020-06-05","2020-10-06","NASDAQ:UAL","2.4672489","0","114.12","90.74","1.1297","1.1797","USD" "39","2020-06-05","2020-10-08","NASDAQ:UAL","4.8456164","0","215","181.65","1.1287","1.1744","USD" "40","2020-06-08","2020-10-08","NASDAQ:UAL","4.86896252","0","224.80","182.14","1.1309","1.1743","USD" "41","2020-06-08","2020-07-30","NASDAQ:ANSS","0.35145678","0","100.00","108.80","1.1303","1.1801","USD" "42","2020-06-09","2020-09-15","NASDAQ:UAL","2.22121486","0","99.13","82.33","1.1346","1.1857","USD" "43","2020-06-10","2020-08-28","NASDAQ:UAL","2.43486729","0","101.13","90.13","1.1373","1.1899","USD" "44","2020-06-10","2020-08-03","NASDAQ:ANSS","1.03831377","0","301.13","327.64","","","USD" "45","2020-06-11","2020-07-01","NASDAQ:TSLA","0.30035742","0","301.14","336.05","","","USD" "46","2020-06-15","2020-07-06","NASDAQ:AAPL","0.44628246","0","151.11","166.73","","","USD" "47","2020-06-19","2020-06-20","NASDAQ:GOOGL","4.1551534","0","301.12","322.63","1.1231","1.1444","USD" "48","2020-06-19","2020-07-30","NASDAQ:QCOM","3.3463469","0","301.12","343.55","1.1226","1.1800","USD" "49","2020-06-22","2020-07-13","NASDAQ:AAPL","0.56580287","0","201.12","220.87","1.1228","1.1352","USD" "50","2020-07-01","2020-07-21","NYSE:KO","6.61229887","0","300","314.86","1.1269","1.145","USD" "51","2020-07-07","2020-07-10","NASDAQ:TSLA","0.35837412","0","500","549.91","1.1289","1.1304","USD" "52","2020-07-07","2020-07-15","NASDAQ:UAL","6.00781015","0","200.00","205.52","1.1289","1.1450","USD" "53","2020-07-07","2020-08-21","NASDAQ:ZM","0.55248618","0","150.00","160.37","1.1329","1.1768","USD" "54","2020-07-10","2020-08-31","NASDAQ:AMZN","0.03145999","0","100.00","109.86","1.1327","1.1961","USD" "55","2020-07-13","2020-08-18","NASDAQ:TSLA","0.17648096","0","300.01","330.61","1.1351","1.1934","USD" "56","2020-07-13","2020-11-13","NASDAQ:AMZN","0.09185548","0","300.01","286.13","1.135","1.1829","USD" "57","2020-07-14","2020-07-31","NASDAQ:AAPL","0.65824117","0","250.00","270.98","1.1369","1.1839","USD" "58","2020-07-15","2020-08-03","NASDAQ:AAPL","2.0317988","0","199.99","225.55","","","USD" "59","2020-07-15","2020-07-30","NASDAQ:TSLA","1.9946808","0","200.01","232.18","","","USD" "60","2020-07-20","2020-07-23","NASDAQ:UAL","9.17150718","0","300.00","307.98","1.1443","1.1618","USD" "61","2020-07-20","2020-08-03","NASDAQ:AAPL","3.05654608","0","300.00","339.31","","","USD" "62","2020-07-23","2020-11-13","NASDAQ:AMZN","1.9828548","0","300.01","327.75","","","USD" "63","2020-07-24","2020-07-24","NASDAQ:AMD","1.05263157","0","70.00","72.41","","","USD" "64","2020-07-24","2020-08-21","NASDAQ:ZM","0.28389503","0","70.00","82.40","1.1635","1.1768","USD" "65","2020-07-27","2020-08-13","NASDAQ:TSLA","0.10470034","0","150.00","168.30","1.1746","1.1839","USD" "66","2020-07-30","2020-09-01","NASDAQ:GOOGL","0.19926934","0","300.00","329.87","1.1804","1.1917","USD" "67","2020-07-30","2020-08-27","NASDAQ:MSFT","0.73800738","0","150.00","169.05","1.1802","1.1807","USD" "68","2020-07-31","2020-08-25","NASDAQ:GOOGL","0.16989812","0","250","272.70","1.1840","1.1828","USD" "69","2020-08-03","2020-08-13","NASDAQ:TSLA","0.2030663","0","300.00","331.46","1.1731","1.1859","USD" "70","2020-08-05","2020-09-01","NASDAQ:ANSS","0.95910994","0","300.00","330.23","","","USD" "71","2020-08-05","2020-09-29","NASDAQ:AMD","1.18990956","0","100.00","96.79","","","USD" "72","2020-08-06","2020-08-31","NASDAQ:AAPL","0.22504782","0","100.00","115.45","","","USD" "73","2020-08-10","2020-08-31","NASDAQ:AMD","1.23701138","0","100.00","111.16","","","USD" "74","2020-08-10","2020-08-27","NASDAQ:ANSS","0.32998944","0","100.00","109.43","","","USD" "75","2020-08-13","2020-08-18","NASDAQ:ZM","0.40695071","0","100.00","110.22","1.1851","1.1962","USD" "76","2020-08-14","2020-08-20","NYSE:SQ","0.7033338","0","100.00","109.90","1.1830","1.1847","USD" "77","2020-08-17","2020-08-18","NASDAQ:TSLA","0.05902769","0","100.00","111.14","","","USD" "78","2020-08-17","2020-08-31","NASDAQ:TSLA","0.842091","0","100.00","97.95","","","USD" "79","2020-08-17","2020-09-01","NYSE:SQ","0.66613375","0","100.00","110.62","1.1860","1.1977","USD" "80","2020-08-18","2020-08-24","NASDAQ:UAL","2.9620853","0","100.00","107.19","1.1937","1.1805","USD" "81","2020-08-19","2020-09-02","NASDAQ:NVDA","0.10171698","0","50.00","58.70","","","USD" "82","2020-08-20","2020-08-28","NASDAQ:TSLA","0.05034207","0","100.00","114.37","","","USD" "83","2020-08-21","2020-12-17","NASDAQ:AAPL","1.6575476","0","200.00","213.11","","","USD" "84","2020-08-21","2020-08-31","NASDAQ:TSLA","0.09623805","0","200.01","222.84","","","USD" "85","2020-08-21","2020-08-31","NASDAQ:TSLA","0.09623805","0","200.01","222.84","","","USD" "86","2020-08-24","2020-08-27","NASDAQ:TSLA","0.09782821","0","200.00","222.35","","","USD" "87","2020-08-25","2020-09-28","NYSE:BABA","0.17636684","0","50.00","48.62","1.1826","1.1662","USD" "88","2020-08-26","2020-09-01","NASDAQ:ZM","0.1661792","0","50.00","75.38","1.1821","1.1977","USD" "89","2020-08-26","2020-09-28","NYSE:BABA","0.17246731","0","50.00","47.54","1.1825","1.1662","USD" "90","2020-08-27","2020-12-03","NASDAQ:TSLA","1.3170429","0","200.01","257.80","","","USD" "91","2020-08-27","2020-11-13","NASDAQ:TSLA","0.21983819","0","500.01","445.11","","","USD" "92","2020-08-27","2020-08-31","NASDAQ:TSLA","0.21983819","0","499.99","548.72","","","USD" "93","2020-08-27","2020-12-17","NASDAQ:AAPL","1.60481444","0","200.01","206.33","","","USD" "94","2020-08-28","2020-09-02","NASDAQ:NVDA","0.09644131","0","50.00","55.67","","","USD" "95","2020-08-15","2020-12-03","NASDAQ:TSLA","3.22587582","0","500.01","631.53","","","USD" "96","2020-08-15","2020-12-15","NASDAQ:TSLA","1.23482196","0","200.00","263.70","","","USD" "97","2020-08-20","2020-08-31","NASDAQ:TSLA","0.05034207","0","100.00","122.78","","","USD" "98","2020-08-15","2020-12-15","NASDAQ:TSLA","3.02858988","0","499.99","649.98","","","USD" "99","2020-09-01","2020-09-22","NASDAQ:ZM","0.23466466","0","100.00","110.05","1.1988","1.1759","USD" "100","2020-09-01","2020-12-10","NASDAQ:TSLA","3.0358227","0","500.00","631.60","","","USD" "101","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.10","1.1969","1.1706","USD" "102","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.19","1.1952","1.1668","USD" "103","2020-09-01","2020-09-30","NYSE:NIO","10.07556675","0","200.00","222.96","1.1921","1.1695","USD" "104","2020-09-02","2020-09-02","NYSE:NIO","10","0","207.40","239.98","1.1832","1.1762","USD" "105","2020-09-02","2020-11-18","NASDAQ:TSLA","2.54919498","0","380.01","418.48","","","USD" "106","2020-09-04","2020-12-17","NASDAQ:AAPL","2.01871739","0","248.38","259.55","","","USD" "107","2020-09-04","2020-10-01","NASDAQ:TSLA","1.82127246","0","250.01","272.23","","","USD" "108","2020-09-10","2020-09-15","NASDAQ:TSLA","1.96494537","0","250.00","287.02","","","USD" "109","2020-09-17","2020-10-01","NASDAQ:ANSS","1.19565287","0","371.31","399.46","","","USD" "110","2020-09-24","2020-10-01","NASDAQ:TSLA","2.69316786","0","329.16","351.43","","","USD" "111","2020-09-24","2020-10-13","NASDAQ:ZM","0.74879082","0","351.43","382.32","","","USD" "112","2020-09-25","2020-10-09","NASDAQ:AAPL","2.02064706","0","219.22","235.02","","","USD" "113","2020-10-01","2020-10-21","NASDAQ:GOOGL","5.3886366","0","399.41","429.69","","","USD" "114","2020-10-02","2020-10-14","NASDAQ:TSLA","2.96907141","0","419.03","457.42","","","USD" "115","2020-10-06","2020-10-13","NASDAQ:AAPL","2.41595669","0","272.23","299.26","","","USD" "116","2020-10-13","2021-02-02","NASDAQ:Z","1","0","101.17","114.81","","","USD" "117","2020-10-15","2020-11-18","NASDAQ:TSLA","3","0","448.20","492.48","","","USD" "118","2020-10-15","2021-02-02","NASDAQ:ANSS","1","0","345.66","375.57","","","USD" "119","2020-10-20","2020-12-09","NASDAQ:ZM","0.8230289","0","429.69","338.03","","","USD" "120","2020-10-22","2020-10-29","NYSE:NIO","19.00692924","0","521.17","604.42","","","USD" "121","2020-10-30","2020-11-03","NYSE:NIO","19","0","581.21","654.36","","","USD" "122","2020-10-30","2020-11-05","NASDAQ:AAPL","2.37198781","0","258.07","282.79","","","USD" "123","2020-11-04","2020-11-05","NYSE:NIO","17.55848346","0","654.23","727.80","","","USD" "124","2020-11-06","2020-11-12","NYSE:NIO","20","0","824.80","980.00","","","USD" "125","2020-11-12","2020-11-23","NASDAQ:ZM","1","0","435.44","428.76","","","USD" "126","2020-11-13","2020-11-23","NYSE:NIO","12","0","541.20","660.00","","","USD" "127","2020-11-17","2020-11-23","NYSE:NIO","15","0","715.20","825.00","","","USD" "128","2020-11-18","2020-12-15","NASDAQ:AAPL","4","0","479.04","506.60","","","USD" "129","2020-11-23","2020-11-27","NASDAQ:MRNA","8","0","809.60","998.80","","","USD" "130","2020-11-23","2020-12-15","NASDAQ:AAPL","4","0","457.24","505.36","","","USD" "131","2020-11-24","2021-01-20","NYSE:NIO","11","0","584.32","659.98","","1.2101","USD" "132","2020-11-30","2020-12-17","NASDAQ:AAPL","2","0","234.84","255.76","","","USD" "133","2020-11-24","2021-01-12","NYSE:NIO","9","0","478.08","576.18","","","USD" "134","2020-11-25","2021-01-29","NASDAQ:MRNA","5","0","730.10","762.90","","","USD" "135","2020-12-03","2020-12-07","NASDAQ:AAPL","-2.06461594","0","-254.05","-249.61","","","USD" "136","2020-11-25","2021-01-26","NASDAQ:MRNA","5","0","730.10","870.00","","1.2153","USD" "137","2020-12-07","2021-02-04","NASDAQ:MRNA","3","0.01","466.20","515.99","","1.1965","USD" "138","2020-12-07","2020-12-21","NYSE:NIO","8","0","352.24","391.84","","","USD" "139","2020-12-08","2021-02-08","NASDAQ:MRNA","3","0.02","503.52","554.98","1.2104","1.2061","USD" "140","2020-12-10","2021-01-29","NASDAQ:MRNA","1","0","155.44","173.97","1.2139","1.2153","USD" "141","2020-12-10","2020-12-17","NASDAQ:TSLA","1","0","573.85","649.98","1.2112","1.2263","USD" "142","2020-12-11","2020-12-14","NASDAQ:TSLA","-1.17027156","0","-244.72","-240.85","","","USD" "143","2020-12-14","2020-12-30","NASDAQ:TSLA","3","0","617.43","694.98","","","USD" "144","2020-12-14","2020-12-21","NYSE:NIO","1","0","39.90","48.96","1.2163","","USD" "145","2020-12-15","2021-01-26","NASDAQ:MRNA","4","0","580.00","610.36","1.2161","","USD" "146","2020-12-17","2021-01-07","NASDAQ:TSLA","3","0","620.01","799.95","","","USD" "147","2020-12-22","2021-01-14","NASDAQ:TSLA","1","0","647.31","859.97","1.2225","1.2118","USD" "148","2020-12-23","2020-12-30","NASDAQ:TSLA","3","0","630.00","694.98","","","USD" "149","2020-12-31","2021-01-06","NYSE:NIO","10","0","485.00","550.00","1.2279","","USD" "150","2020-12-31","2021-01-07","NASDAQ:TSLA","2.581293","0","616.49","688.35","","","USD" "151","2020-12-31","2021-01-07","NASDAQ:TSLA","0.418707","0","100.00","111.66","","","USD" "152","2021-01-04","2021-07-09","NASDAQ:AAPL","1","0","130.00","145.03","","","USD" "153","2021-01-06","2021-02-02","NASDAQ:TSLA","0.71085433","0","546.91","619.87","1.228","1.2029","USD" "154","2021-01-07","2021-01-25","NASDAQ:TSLA","1","0","805.56","899.97","1.2275","1.2129","USD" "155","2021-01-08","2021-10-25","NASDAQ:TSLA","0.86743701","0","244.74","276.43","","","USD" "156","2021-01-08","2021-10-25","NASDAQ:TSLA","1.68863022","0","489.31","549.31","","","USD" "157","2021-01-08","2021-10-25","NASDAQ:TSLA","1.31136978","0","380.00","426.58","","","USD" "158","2021-01-13","2021-01-14","NASDAQ:PLUG","8","0.02","554.48","514.78","1.2167","1.2167","USD" "159","2021-01-11","2021-01-14","NYSE:NIO","2","0","129.78","87.08","1.2147","1.1553","USD" "160","2020-12-21","2021-04-15","NASDAQ:AMD","3","0","276.00","249.18","","","USD" "161","2020-12-23","2021-02-03","NASDAQ:AMZN","2.691074","0","430.01","457.37","","","USD" "162","2020-12-23","2021-02-03","NASDAQ:AMZN","0.4380818","0","70.00","74.46","","","USD" "163","2020-12-23","2021-07-14","NASDAQ:AAPL","4","0","528.68","596.64","","","USD" "164","2020-12-17","2021-07-09","NASDAQ:AAPL","3","0","386.94","435.12","","","USD" "165","2020-12-17","2021-01-25","NASDAQ:AAPL","5","0","643.15","721.47","1.2263","1.2129","USD" "166","2020-12-07","2021-04-15","NASDAQ:AMD","4","0","358.20","332.24","","","USD" "167","2021-01-14","2021-01-21","NASDAQ:MRNA","4","0","516.32","538.84","1.2168","","USD" "168","2021-01-15","2021-02-09","NYSE:NIO","15","0","860.7","939.87","1.2094","1.2121","USD" "169","2021-01-22","2021-10-21","NASDAQ:TSLA","0.84141694","0","700","753.46","1.2179","1.164","USD" "170","2021-01-25","2021-10-25","NASDAQ:TSLA","1","0","870","992.81","1.213","1.161","USD" "171","2021-01-25","2021-09-07","NASDAQ:AAPL","5","0","700.00","775.25","","","USD" "172","2021-01-25","2021-11-04","NYSE:NIO","1","0","59.62","43.54","1.2148","1.1553","USD" "173","2021-01-27","2021-11-18","NASDAQ:AAPL","2","0","286.62","316.00","","","USD" "174","2021-01-27","2021-02-04","NASDAQ:MRNA","2","0.01","316.18","343.99","1.2094","1.1965","USD" "175","2021-01-27","2021-02-08","NASDAQ:MRNA","3","0.01","497.58","554.97","1.2126","1.2061","USD" "176","2021-01-29","2021-10-25","NASDAQ:TSLA","1","0","840.99","951.49","1.2148","1.1614","USD" "177","2021-01-29","2021-05-03","NASDAQ:MRNA","6","0","1064.10","1121.21","1.2147","1.2067","USD" "178","2021-02-01","2021-02-04","NASDAQ:MRNA","1","0.01","156.50","171.99","1.2067","1.1965","USD" "179","2021-02-02","2021-08-16","NASDAQ:AAPL","4","0","542.68","600.00","","","USD" "180","2021-02-05","2021-02-11","NASDAQ:PYPL","3","0","801.54","900.00","1.2040","1.2140","USD" "181","2021-02-08","2021-07-23","NASDAQ:PYPL","3","0","842.85","926.42","1.2061","1.1764","USD" "182","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.25","","","USD" "183","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.27","","","USD" "184","2021-02-09","2021-05-03","NASDAQ:MRNA","3","0","536.46","560.6","1.2121","1.2067","USD" "185","2021-02-10","2021-10-25","NASDAQ:TSLA","2.08745436","0","581.52","665.19","","","USD" "186","2021-02-11","2021-11-22","NASDAQ:PYPL","3","0","855","575.54","1.2133","1.1242","USD" "187","2021-02-12","2022-02-02","NASDAQ:PYPL","2.8","0","818.92","381.71","1.2098","1.1317","USD" "188","2021-03-12","2021-06-28","NYSE:NIO","4","0","177.20","159.99","1.1933","1.1932","USD" "189","2021-04-19","2021-09-17","NASDAQ:TSLA","0.78607363","0","550","596.41","1.2032","1.1758","USD" "190","2021-05-04","2021-07-06","NASDAQ:GOOGL","0.09823182","0","225","247.64","1.2027","1.1841","USD" "191","2021-05-04","2021-05-27","NASDAQ:MRNA","4","0.01","701.88","708.19","1.2021","1.2200","USD" "192","2021-05-04","2021-10-19","NASDAQ:ANSS","2","0","700.18","729.33","","","USD" "193","2021-05-04","2021-07-06","NASDAQ:AMZN","0.02585158","0","85","93.61","1.2023","1.1841","USD" "194","2021-05-24","2021-05-27","NYSE:SPCE","2","0","49.86","56.03","1.2212","1.2198","USD" "195","2021-05-27","2021-06-07","NYSE:SPCE","4","0","114.12","135.42","1.2194","1.2198","USD" "196","2021-05-27","2021-06-07","NYSE:SPCE","23","0","704.26","778.55","1.2199","1.2198","USD" "197","2021-06-07","2021-06-28","NYSE:NIO","10","0","437.20","490.00","1.2198","1.1932","USD" "198","2021-06-08","2021-06-25","NYSE:SPCE","12","0","448.31","572.75","1.2188","1.1969","USD" "199","2021-07-01","2021-11-04","NYSE:NIO","10","0","520","435.40","1.1869","1.1553","USD" "200","2021-07-06","2021-08-09","NASDAQ:GOOGL","0.21915668","0","550","595.41","1.1830","1.1751","USD" "201","2021-07-07","2021-07-08","NYSE:SPCE","12","0","540","599.99","1.1807","1.1848","USD" "202","2021-07-12","2021-12-03","NYSE:SPCE","12","0","540.00","171.84","1.1858","1.1280","USD" "203","2021-07-15","2021-07-16","NASDAQ:MRNA","1","0.01","255.80","284.99","1.1817","1.1804","USD" "204","2021-07-16","2021-11-09","NYSE:SPCE","24","0","781.44","503.77","1.1811","1.1588","USD" "205","2021-07-16","2021-11-29","NASDAQ:AAPL","1","0","147.32","164.98","","","USD" "206","2021-07-16","2021-11-29","NASDAQ:AAPL","2","0","294.60","330.00","","","USD" "207","2021-07-23","2021-08-03","NASDAQ:MRNA","2","0.01","670.54","739.99","1.1765","1.1866","USD" "208","2021-08-03","2021-11-19","NASDAQ:AMZN","0.22221761","0","750","829.78","1.1866","1.1315","USD" "209","2021-08-09","2021-11-26","NASDAQ:MRNA","1","0","287.97","327.95","1.1255","1.1300","USD" "210","2021-08-19","2021-11-19","NASDAQ:AAPL","5","0","724.65","800.00","","","USD" "211","2021-09-10","2021-12-01","NASDAQ:AAPL","5","0","749.85","850.00","","","USD" "212","2021-09-17","2021-11-29","NASDAQ:AAPL","4","0","587.32","660.00","","","USD" "213","2021-10-26","2021-11-01","NASDAQ:TSLA","1","0","1044.49","1149.98","1.1609","1.1583","USD" "214","2021-10-26","2021-12-06","NASDAQ:AAPL","4","0","601.92","668.36","","","USD" "215","2021-10-27","2021-12-01","NASDAQ:AAPL","7","0","1044.75","1190.00","","","USD" "216","2021-10-27","2021-12-01","NASDAQ:AAPL","3","0","447.75","510.00","","","USD" "217","2021-11-04","2022-02-17","NYSE:KO","10","0","562.89","619.99","1.1552","1.1365","USD" "218","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "219","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "220","2021-12-02","2021-12-13","NASDAQ:AAPL","7","0","1111.04","1266.98","1.1345","1.1294","USD" "221","2021-12-02","2021-12-10","NASDAQ:AAPL","3","0","482.67","534.51","","","USD" "222","2021-12-06","2022-01-03","NASDAQ:TSLA","1","0","992.9","1153.57","1.1291","1.1309","USD" "223","2021-12-14","2021-12-27","NASDAQ:TSLA","1.2","0","377.47","441.07","","","USD" "224","2021-12-14","2021-12-27","NASDAQ:TSLA","0.3","0","94.37","110.27","","","USD" "225","2021-11-10","2022-01-03","NASDAQ:TSLA","1.5","0","536.75","597.42","","","USD" "226","2022-02-18","2022-03-22","NASDAQ:TSLA","1.2","0","345.54","376.86","","","USD" "227","2022-02-18","2022-03-22","NASDAQ:TSLA","0.3","0","86.38","94.22","","","USD" "228","2022-02-18","2022-04-20","NYSE:O","2","0","134.06","149.99","1.1336","1.0848","USD" "229","2022-04-14","2022-10-05","NYSE:TWTR","4","0","193.68","203.72","1.0829","0.9852","USD" "230","2022-04-19","2022-10-05","NYSE:TWTR","1","0","47.24","50.93","1.0798","0.9852","USD" "231","2022-05-20","2022-07-21","NASDAQ:AAPL","1","0","139.02","155.02","","","USD" "232","2022-07-27","2022-07-27","NASDAQ:AAPL","1","0","162.00","162.00","","","USD" "233","2022-01-03","2023-12-27","NASDAQ:ANSS","2","0","786.86","669.60","","","USD" "234","2022-01-11","2023-11-16","NASDAQ:AAPL","6","0","1026","1139.98","1.1324","1.0885","USD" "235","2022-02-02","2023-05-25","NASDAQ:MSFT","0.62199751","0","185.15","200.03","1.1092","1.0722","USD" "236","2021-11-09","2024-01-01","NASDAQ:TSLA","3","0","1065.78","1065.78","","","USD" "237","2021-11-22","2023-06-15","NASDAQ:AAPL","8.5","0","1386.18","1572.67","","","USD" "238","2021-11-22","2023-06-15","NASDAQ:AAPL","1.5","0","244.62","277.50","","","USD" "239","2021-12-02","2023-06-15","NASDAQ:AAPL","7","0","1142.82","1295.00","","","USD" "240","2021-12-02","2023-06-15","NASDAQ:AAPL","2","0","326.52","370.00","","","USD" "241","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","392.00","","","USD" "242","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","391.98","","","USD" "243","2021-12-14","2023-12-13","NASDAQ:AAPL","3","0","522.51","588.00","","","USD" "244","2022-04-13","2023-12-14","NASDAQ:AAPL","1","0","170.66","196.00","","","USD" "245","2022-09-14","2023-05-05","NASDAQ:AAPL","2","0","311.56","343.98","","","USD" "246","2022-12-20","2023-01-23","NASDAQ:AAPL","2","0","260.00","285.98","","","USD" "247","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "248","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "249","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "250","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "251","2023-03-01","2023-06-14","NYSE:BRK.B","1","0","303.16","339.98","1.0685","1.0868","USD" "252","2023-05-08","2023-05-23","NASDAQ:TSLA","1","0","171.76","189.98","","","USD" "253","2023-05-26","2023-06-02","NASDAQ:TSLA","1","0","190.12","209.98","","","USD" "254","2022-01-06","2024-01-25","NASDAQ:TSLA","2.7","0","945.00","506.93","","","USD" "255","2022-01-06","2024-01-25","NASDAQ:TSLA","0.3","0","105.00","56.32","","","USD" "256","2023-01-01","2024-04-26","NASDAQ:GOOGL","1.8369098","0","276.14","320.23","","","USD" "257","2022-02-02","2024-04-26","NASDAQ:GOOGL","0.9046522","0","136.00","157.69","","","USD" "258","2022-02-28","2024-06-05","NYSE:KO","2","0","123.86","127.83","1.1225","1.0890","USD" "259","2021-10-15","2024-04-12","NASDAQ:GOOGL","5","0","714.80","1498.30","","","USD" "260","2021-11-04","2024-07-11","NYSE:BAC","10","0","474.89","419.98","1.1551","1.0899","USD" "261","2024-01-01","2024-03-01","NASDAQ:TSLA","2","0","710.52","402.44","","","USD" "262","2024-01-01","2024-02-09","NASDAQ:TSLA","1","0","355.26","192.78","","","USD" "263","2021-11-10","2024-02-09","NASDAQ:TSLA","0.525","0","187.86","101.21","","","USD" "264","2021-11-10","2024-02-09","NASDAQ:TSLA","0.975","0","348.88","187.95","","","USD" "265","2021-11-22","2024-02-09","NASDAQ:TSLA","1.5","0","590.88","289.17","","","USD" "266","2021-11-26","2024-02-02","NASDAQ:AMZN","1.8995262","0","334.98","326.64","","","USD" "267","2021-12-02","2024-02-02","NASDAQ:AMZN","1.7335028","0","300.00","298.09","","","USD" "268","2021-12-14","2024-04-26","NASDAQ:AAPL","1","0","174.17","170.00","","","USD" "269","2021-12-28","2024-02-02","NASDAQ:AMZN","1.1645374","0","200.00","200.24","","","USD" "270","2024-04-22","2024-07-17","NYSE:O","2","0","148.00","114.32","1.0817","1.0957","USD" "271","2022-06-07","2024-02-02","NASDAQ:AMZN","0.2024336","0","24.75","34.81","","","USD" "272","2023-05-23","2024-06-11","NASDAQ:AAPL","1","0","172.79","199.96","","","USD" "273","2023-06-06","2024-07-02","NASDAQ:AAPL","3","0","535.89","660.00","","","USD" "274","2023-06-06","2024-04-26","NASDAQ:AAPL","1","0","178.63","170.00","","","USD" "275","2023-06-14","2024-01-31","NASDAQ:TSLA","1","0","258.00","189.98","","","USD" "276","2023-06-15","2024-01-25","NYSE:BRK.B","4","0","1352.95","1519.98","1.0927","1.0876","USD" "277","2023-06-20","2024-01-31","NASDAQ:TSLA","2","0","542.06","380.00","","","USD" "278","2023-06-30","2024-08-28","NASDAQ:AAPL","4","0","769.80","919.96","","","USD" "279","2023-07-19","2024-02-07","NASDAQ:TSLA","2","0","593.16","362.96","","","USD" "280","2023-07-19","2024-02-07","NASDAQ:TSLA","1","0","296.58","181.47","","","USD" "281","2023-09-13","2024-07-02","NASDAQ:AAPL","3","0","525.06","660.00","","","USD" "282","2023-12-14","2024-08-28","NASDAQ:AAPL","1","0","196.00","230.00","","","USD" "283","2023-12-18","2024-11-26","NASDAQ:AAPL","2","0","390.00","470.00","","","USD" "284","2023-12-22","2024-11-26","NASDAQ:AAPL","3","0","585.72","705.00","","","USD" "285","2024-01-01","2024-11-26","NASDAQ:AAPL","3","0","576.96","705.00","","","USD" "286","2024-01-08","2024-07-02","NASDAQ:AAPL","3","0","540.00","659.93","","","USD" "287","2024-01-25","2024-02-09","NASDAQ:NVDA","3","0","1865.35","2159.97","1.0876","1.0809","USD" "288","2024-01-31","2024-06-17","NASDAQ:MSFT","1","0","402.58","449.98","1.0869","1.0750","USD" "289","2024-02-02","2024-05-20","NASDAQ:NVDA","1","0","659.78","949.98","1.0805","1.0889","USD" "290","2024-02-02","2024-11-26","NASDAQ:AAPL","1","0","186.01","234.93","","","USD" "291","2024-02-05","2024-05-22","NASDAQ:NVDA","10","0","688.87","999.85","","","USD" "292","2024-02-21","2024-05-22","NASDAQ:NVDA","30","0","2037.00","3000.00","","","USD" "293","2024-03-05","2024-07-30","NYSE:BRK.B","1","0","400.00","439.98","1.0882","1.0832","USD" "294","2024-03-11","2024-05-22","NASDAQ:NVDA","10","0","889.33","1000.00","","","USD" "295","2024-04-01","2024-06-11","NASDAQ:AAPL","2","0","340.00","400.00","","","USD" "296","2021-10-15","2024-04-26","NASDAQ:GOOGL","0.137277","0","19.63","23.93","","","USD" "297","2024-04-26","2024-06-11","NASDAQ:AAPL","3","0","510.00","600.00","","","USD" "298","2024-07-03","2024-09-05","NASDAQ:TSLA","2","0","495.86","450.44","","","USD" "299","2024-07-11","2024-11-10","NYSE:TSM","10","0","1938.61","1898.01","1.0915","1.0965","USD" "300","2024-05-28","2024-10-17","NASDAQ:NVDA","10","0","1120.60","1400.00","","","USD" "301","2023-12-14","","AMS:IWDA","6","0.05","491.33","","","","EUR" "302","2024-04-22","","AMS:IWDA","7","0.06","618.93","","","","EUR" "303","2024-05-28","2025-01-06","NASDAQ:NVDA","20","0","2241.20","3000.00","","","USD" "304","2024-06-06","2025-05-28","NASDAQ:NVDA","2","0","2498.35","2799.99","1.0907","1.1318","USD" "305","2024-06-12","","NASDAQ:AAPL","7","0","1497.65","","","","USD" "306","2024-06-20","","NASDAQ:AAPL","2","0","420.00","","","","USD" "307","2024-07-23","","INDEXNASDAQ:NDX","4.84403203","0","858.75","","","","EUR" "308","2024-08-01","2025-11-11","NASDAQ:AAPL","5","0","1094.25","1369.52","1.0809","1.1626","USD" "309","2024-08-05","2025-08-08","NASDAQ:AAPL","1","0","204.90","225.00","","","USD" "310","2024-08-05","2025-08-08","NASDAQ:AAPL","2","0","409.80","449.98","","","USD" "311","2024-11-06","","NASDAQ:AAPL","21","0","4742.01","","","","USD" "312","2024-11-25","","NASDAQ:NVDA","8","0","1101.60","","","","USD" "313","2024-12-18","","INDEXNASDAQ:NDX","10","0","2038.00","","","","EUR" "314","2025-01-06","","NASDAQ:NVDA","21","0","2998.17","","","","USD" "315","2025-01-27","","NASDAQ:NVDA","2","0","247.18","","","","USD" "316","2025-07-03","","NASDAQ:NVDA","12","0","1918.68","","","","USD" "317","2025-10-16","","NASDAQ:NVDA","8","0","1454.32","","","","USD" "318","2025-11-11","","NASDAQ:NVDA","9","0","1742.40","","","","USD" ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/transacoes-vistos.json Tamanho: 66 bytes ======================================================================================== { "versao": "1.0", "vistos": {}, "ultima_atualizacao": "" } ======================================================================================== FICHEIRO: backup_20260611_153533/dados_csv/variacao-dia.json Tamanho: 2328 bytes ======================================================================================== { "ok": true, "timestamp": "2025-12-14 11:13:10", "variacao": { "IWDA": { "ticker": "IWDA", "moeda": "EUR", "preco": 110.31, "pct_dia": -0.6037, "prev_close": 110.98, "fonte_preco": "stooq:EUNL.DE", "fonte_prevclose": "stooq:eunl.de", "ts_preco": "2025-12-14 00:06:18" }, "AAPL": { "ticker": "AAPL", "moeda": "USD", "preco": 278.28, "pct_dia": 0.0899, "prev_close": 278.029999, "fonte_preco": "twelveAAPL", "fonte_prevclose": "twelveAAPL", "ts_preco": "2025-12-14 00:06:18" }, "NDXEX": { "ticker": "NDXEX", "moeda": "EUR", "preco": 208.6, "pct_dia": -1.0906, "prev_close": 210.9, "fonte_preco": "stooq:EXXT.DE", "fonte_prevclose": "stooq:exxt.de", "ts_preco": "2025-12-14 00:06:18" }, "NVDA": { "ticker": "NVDA", "moeda": "USD", "preco": 175.020004, "pct_dia": -3.2664, "prev_close": 180.92999, "fonte_preco": "twelveNVDA", "fonte_prevclose": "twelveNVDA", "ts_preco": "2025-12-14 00:06:18" }, "GOOGL": { "ticker": "GOOGL", "moeda": "USD", "preco": 309.29001, "pct_dia": -1.005, "prev_close": 312.42999, "fonte_preco": "twelveGOOGL", "fonte_prevclose": "twelveGOOGL", "ts_preco": "2025-12-14 00:06:18" }, "VUSA": { "ticker": "VUSA", "moeda": "EUR", "preco": 110.235, "pct_dia": -0.6131, "prev_close": 110.915, "fonte_preco": "stooq:VUSA.DE", "fonte_prevclose": "stooq:vusa.de", "ts_preco": "2025-12-14 00:06:18" }, "XAUEUR": { "ticker": "XAUEUR", "moeda": "EUR", "preco": 3677.2689145299146, "pct_dia": 0, "prev_close": null, "fonte_preco": "twelveXAU\/USD->EUR", "fonte_prevclose": null, "ts_preco": "2025-12-14 00:06:18" } } } ======================================================================================== FICHEIRO: backup_20260611_153533/exportar_projeto.php Tamanho: 2764 bytes ======================================================================================== ======================================================================================== FICHEIRO: backup_20260611_153533/gerar_movimentos_caixa.php Tamanho: 4083 bytes ======================================================================================== 10) $valorNum = 0.0; if ($totalAmount !== '') { // remover possíveis prefixos de moeda (USD , EUR , etc.) $valorLimpo = preg_replace('/^[A-Z]{3}\s*/', '', $totalAmount); $valorLimpo = str_replace(',', '.', $valorLimpo); $valorNum = floatval($valorLimpo); } // Tipo final para o movimentos-caixa $tipoCaixa = ''; if ($type === 'CASH TOP-UP') { $tipoCaixa = 'Depósito'; } elseif ($type === 'CASH WITHDRAWAL') { $tipoCaixa = 'Levantamento'; } elseif ($type === 'DIVIDEND') { $tipoCaixa = 'Dividendo'; } else { // CUSTODY FEE e afins $tipoCaixa = 'Outros'; } // Descrição $descricao = $type; if ($type === 'DIVIDEND') { // ex: "AAPL DIVIDEND" $t = trim($ticker); if ($t !== '') { $descricao = $t . ' DIVIDEND'; } else { $descricao = 'DIVIDEND'; } } // Construir linha para movimentos-caixa.csv $movimentos[] = [ 'Ordem' => $ordem, 'Data' => $dataSimples, 'Tipo' => $tipoCaixa, 'Valor' => $valorNum, 'Moeda' => $currency, 'Descricao' => $descricao, ]; $ordem++; } fclose($fh); // Escrever movimentos-caixa.csv $out = fopen($ficheiroCaixa, 'w'); if ($out === false) { die("Não foi possível criar/gravar movimentos-caixa.csv\n"); } // Cabeçalho fputcsv($out, ['Ordem','Data','Tipo','Valor','Moeda','Descricao']); // Linhas foreach ($movimentos as $m) { // Garantir tipos corretos $linha = [ $m['Ordem'], $m['Data'], $m['Tipo'], $m['Valor'], $m['Moeda'], $m['Descricao'], ]; fputcsv($out, $linha); } fclose($out); echo "movimentos-caixa.csv gerado com sucesso. Total de linhas: " . count($movimentos) . PHP_EOL; ======================================================================================== FICHEIRO: backup_20260611_153533/gravar_historico_mensal.php Tamanho: 4452 bytes ======================================================================================== ['capital_investido'=>, 'dividendos'=>, 'outros'=>]] if (file_exists($ficheiroCaixa)) { if (($fh = fopen($ficheiroCaixa, 'r')) !== false) { $cab = fgetcsv($fh, 0, ','); // cabeçalho: Ordem,Data,Tipo,Valor,Moeda,Descricao while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 6) continue; list($ordem, $data, $tipo, $valor, $moeda, $desc) = $row; $data = trim($data); if ($data === '') continue; $mes = substr($data, 0, 7); // YYYY-MM $tipo = trim($tipo); $moeda = trim($moeda); $valorNum = floatval(str_replace(',', '.', $valor)); if (!isset($mensal[$mes])) { $mensal[$mes] = [ 'capital_investido' => 0.0, 'dividendos' => 0.0, 'outros' => 0.0, ]; } // CONVENÇÃO: // - Depósito em EUR: entrada positiva de capital investido // - Levantamento em EUR: saída (valor negativo em capital investido) // - Dividendos: somar sempre (em qualquer moeda, depois podes converter) // - Outros: fees, juros, etc. if ($tipo === 'Depósito' && $moeda === 'EUR') { $mensal[$mes]['capital_investido'] += $valorNum; } elseif ($tipo === 'Levantamento' && $moeda === 'EUR') { $mensal[$mes]['capital_investido'] -= abs($valorNum); } elseif ($tipo === 'Dividendo') { $mensal[$mes]['dividendos'] += $valorNum; } else { // Outros (custos, fees, juros, correções, etc.) $mensal[$mes]['outros'] += $valorNum; } } fclose($fh); } } // ----------------------------------------------------------------------------- // 2. (Opcional) Ler valor da carteira por mês // ----------------------------------------------------------------------------- // // Se já tens noutro lado um JSON com histórico diário/mensal de valor da carteira, // podes lê-lo aqui e juntar a este array. Caso ainda não exista, deixamos // esse campo em branco. // // Exemplo: se tiveres um ficheiro 'valor-carteira-mensal.json' com: // { "2024-01": 12345.67, "2024-02": 13000.12, ... } // // Podes fazer: // // $ficheiroValorMensal = $baseDir . '/valor-carteira-mensal.json'; // $valorMensal = []; // if (file_exists($ficheiroValorMensal)) { // $txt = file_get_contents($ficheiroValorMensal); // $valorMensal = json_decode($txt, true) ?: []; // } // // E depois, ao montar a saída, juntar: // 'valor_carteira' => $valorMensal[$mes] ?? null; // ----------------------------------------------------------------------------- // 3. Montar array final por mês // ----------------------------------------------------------------------------- ksort($mensal); // ordenar por mês $saida = []; foreach ($mensal as $mes => $dados) { $saida[] = [ 'mes' => $mes, 'capital_investido' => round($dados['capital_investido'], 2), 'dividendos' => round($dados['dividendos'], 2), 'outros' => round($dados['outros'], 2), // 'valor_carteira' => $valorMensal[$mes] ?? null, // se adicionares o ficheiro de valor ]; } // Gravar em historico-carteira.json file_put_contents($ficheiroHistorico, json_encode($saida, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); // Devolver resposta echo json_encode([ 'ok' => true, 'historico' => $saida, ]); ======================================================================================== FICHEIRO: backup_20260611_153533/importar_revolut.php Tamanho: 3998 bytes ======================================================================================== $ordem++, 'data' => $data, 'tipo' => mapearTipo($tipoRevolut), 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $descricao, 'taxa' => $fxRate, ]; if ($moeda === 'USD') $usdCount++; if ($moeda === 'EUR') $eurCount++; } // ---------- GERAR CSV ---------- $csvContent = "Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio\n"; foreach ($movimentos as $mov) { $valorFormatado = number_format($mov['valor'], 2, '.', ''); $taxaFormatada = $mov['taxa'] !== '' ? $mov['taxa'] : ''; $descEscapada = str_replace('"', '""', $mov['descricao']); $csvContent .= "{$mov['ordem']},{$mov['data']},{$mov['tipo']},{$valorFormatado},{$mov['moeda']},\"{$descEscapada}\",{$taxaFormatada}\n"; } // Guardar diretamente no ficheiro do utilizador if (file_put_contents($ficheiroSaida, $csvContent) === false) { die("⌠Erro ao gravar CSV em {$ficheiroSaida}\n"); } echo "✅ EUR + USD PROCESSADO!\n"; echo "📊 USD: {$usdCount} | EUR: {$eurCount} | Total: " . count($movimentos) . "\n"; echo "💾 Movimentos gravados em: {$ficheiroSaida}\n"; echo "📂 Utilizador: {$user}\n"; ?> ======================================================================================== FICHEIRO: backup_20260611_153533/info.php Tamanho: 81 bytes ======================================================================================== true]); ======================================================================================== FICHEIRO: backup_20260611_153533/login.php Tamanho: 1995 bytes ======================================================================================== $data) { if (isset($data["email"]) && $data["email"] === $email) { $found = [$username, $data]; break; } } if ($found && password_verify($password, $found[1]["password_hash"])) { // login ok $_SESSION["user"] = ["name" => $found[0], "email" => $email]; // redirecionar para a página principal (pode ser index.html ou resumo.html) header("Location: resumo.html"); exit; } else { $error = "Credenciais inválidas"; } } ?> Login ======================================================================================== FICHEIRO: backup_20260611_153533/logout.php Tamanho: 99 bytes ======================================================================================== ======================================================================================== FICHEIRO: backup_20260611_153533/users.json Tamanho: 139 bytes ======================================================================================== { "tiago": { "email": "tiago@example.com", "password_hash": "$2y$10$q5/jRIGfJDuqPqsCbH2YCuKTvifC.GI2isRKU2c3E3NrCtQNP3EQW" } } ======================================================================================== FICHEIRO: backup_20260611_153533/verificar_diferencas_revolut.php Tamanho: 23201 bytes ======================================================================================== require_once __DIR__ . '/api/utilizador.php'; // getUserId() e userFilePath() vêm de api/utilizador.php function vistosLoad(): array { $path = userFilePath('transacoes-vistos.json'); if (!is_file($path)) return ['vistos' => []]; $raw = @file_get_contents($path); $j = json_decode((string)$raw, true); if (!is_array($j)) $j = []; $vistos = $j['vistos'] ?? []; if (!is_array($vistos)) $vistos = []; foreach (['alterarlinha', 'adicionartransacao', 'removertransacao'] as $t) { if (!isset($vistos[$t]) || !is_array($vistos[$t])) $vistos[$t] = []; } return ['vistos' => $vistos]; } function vistoCheck(array $vistos, string $tipo, string $id): bool { return isset($vistos['vistos'][$tipo]) && is_array($vistos['vistos'][$tipo]) && !empty($vistos['vistos'][$tipo][$id]); } function vistoIdLinha($linha): string { return 'L:' . trim((string)$linha); } // Ficheiros específicos do utilizador atual $ficheiroRevolut = userFilePath('extrato-revolut.csv'); $ficheiroTransacoes = userFilePath('transacoes-acoes.csv'); $ficheiroCaixa = userFilePath('movimentos-caixa.csv'); // Filtro opcional por ano (?ano=2020, 2021, ...) $anoFiltro = isset($_GET['ano']) && preg_match('/^\d{4}$/', $_GET['ano']) ? $_GET['ano'] : null; // Verificações iniciais if (!file_exists($ficheiroRevolut)) { echo json_encode([ 'ok' => false, 'error' => 'Extrato Revolut não encontrado para este utilizador. Importe primeiro o ficheiro (extrato-revolut.csv).', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if (!file_exists($ficheiroTransacoes)) { echo json_encode([ 'ok' => false, 'error' => 'Ficheiro de transações (transacoes-acoes.csv) não encontrado para este utilizador.', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // FILTRO POR ANO function filtrarPorAno($items, $ano) { if (!$ano || empty($items)) return $items; return array_filter($items, function($item) use ($ano) { $camposData = ['data', 'dataCompra', 'dataVenda']; foreach ($camposData as $campo) { if (isset($item[$campo]) && !empty($item[$campo])) { if (preg_match('/^' . $ano . '[-\/]/', $item[$campo])) { return true; } } } return false; }); } // ✅ NORMALIZAR TICKER - VERSÃO COMPLETA COM TODOS OS MAPEAMENTOS function normalizarTicker($nomeAcao) { $n = strtoupper(trim($nomeAcao)); // ✅ MAPEAMENTO EXPLÃCITO DE ETFs if (strpos($n, 'IWDA') !== false || strpos($n, 'EUNL') !== false) { return 'IWDA'; } if (strpos($n, 'NDX') !== false || strpos($n, 'EXXT') !== false || strpos($n, 'EQQQ') !== false) { return 'EQQQ'; } // ✅ MAPEAMENTO DE AÇÕES ESPECÃFICAS $mapa = [ 'SQ' => 'SQ', // Block (Square) 'Z' => 'Z', // Zillow 'BRK.B' => 'BRKB', // Berkshire Hathaway 'BRKB' => 'BRKB', // Já normalizado 'AAPL' => 'AAPL', 'NVDA' => 'NVDA', 'TSLA' => 'TSLA', 'GOOGL' => 'GOOGL', 'AMZN' => 'AMZN', 'MSFT' => 'MSFT', 'TSM' => 'TSM', 'BAC' => 'BAC', 'O' => 'O', 'KO' => 'KO', ]; // Remove prefixos de bolsa $n = preg_replace('/^(NASDAQ|NYSE|INDEXNASDAQ|AMS):?/', '', $n); // Remove caracteres especiais e pontos $n = preg_replace('/[^A-Z0-9]/', '', $n); // Verifica se está no mapa if (isset($mapa[$n])) { return $mapa[$n]; } return $n; } // LER REVOLUT (extrato) function lerRevolut($ficheiro) { if (!file_exists($ficheiro)) { return ['error' => 'Ficheiro não encontrado: ' . basename($ficheiro)]; } $fh = fopen($ficheiro, 'r'); if (!$fh) { return ['error' => 'Erro ao abrir: ' . basename($ficheiro)]; } // Cabeçalho: // Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate fgetcsv($fh, 0, ','); $movimentos = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 8) continue; $dataCompleta = trim($row[0]); $data = substr($dataCompleta, 0, 10); // YYYY-MM-DD $ticker = trim($row[1]); $tipo = trim($row[2]); $quantidade = trim($row[3]); $preco = trim($row[4]); $totalAmount = trim($row[5]); $moeda = trim($row[6]); $fxRaw = trim($row[7]); // Limpeza de valor total $valorLimpo = preg_replace('/[A-Z]{3}\s*/', '', $totalAmount); $valorLimpo = str_replace(',', '.', $valorLimpo); $valorNum = floatval($valorLimpo); // Limpeza de preço $precoLimpo = preg_replace('/[A-Z]{3}\s*/', '', $preco); $precoLimpo = str_replace(',', '.', $precoLimpo); $precoNum = floatval($precoLimpo); // FX rate $fxNum = $fxRaw !== '' ? floatval(str_replace(',', '.', $fxRaw)) : null; $movimentos[] = [ 'data' => $data, 'ticker' => strtoupper($ticker), 'tipo' => $tipo, 'quantidade' => floatval(str_replace(',', '.', $quantidade)), 'preco' => $precoNum, 'valor' => $valorNum, 'moeda' => $moeda, 'fx' => $fxNum, ]; } fclose($fh); return $movimentos; } // LER TRANSAÇÕES (formato novo: 11 colunas) function lerTransacoesAtuais($ficheiro) { if (!file_exists($ficheiro)) return []; $fh = fopen($ficheiro, 'r'); if (!$fh) return []; // Cabeçalho: Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes, // CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda fgetcsv($fh, 0, ','); $transacoes = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 11) continue; $transacoes[] = [ 'ordem' => trim($row[0]), 'dataCompra' => trim($row[1]), 'dataVenda' => trim($row[2]), 'nomeAcao' => trim($row[3]), 'numAcoes' => floatval(str_replace(',', '.', $row[4])), 'comissoes' => floatval(str_replace(',', '.', $row[5])), 'custoInicial' => floatval(str_replace(',', '.', $row[6])), 'custoFinal' => floatval(str_replace(',', '.', $row[7])), 'taxaCompra' => isset($row[8]) ? floatval(str_replace(',', '.', $row[8])) : 0.0, 'taxaVenda' => isset($row[9]) ? floatval(str_replace(',', '.', $row[9])) : 0.0, 'moeda' => trim($row[10]), ]; } fclose($fh); return $transacoes; } // COMPARAR COM LÓGICA RESTRITIVA function compararDados($revolut, $transacoesAtuais, $vistos) { $diferencas = [ 'duplicatasexatas' => [], 'alterarlinha' => [], 'adicionartransacao' => [], 'removertransacao' => [], 'totais' => [ 'revolutcompras' => 0, 'revolutvendas' => 0, 'transacoestotal' => count($transacoesAtuais) ] ]; // Agrupar Revolut por ticker $revolutPorTicker = []; foreach ($revolut as $mov) { $ticker = strtoupper($mov['ticker']); if (!isset($revolutPorTicker[$ticker])) { $revolutPorTicker[$ticker] = ['compras' => [], 'vendas' => []]; } if (stripos($mov['tipo'], 'BUY') !== false) { $revolutPorTicker[$ticker]['compras'][] = $mov; $diferencas['totais']['revolutcompras']++; } elseif (stripos($mov['tipo'], 'SELL') !== false) { $revolutPorTicker[$ticker]['vendas'][] = $mov; $diferencas['totais']['revolutvendas']++; } } // Verificar cada transação do CSV foreach ($transacoesAtuais as $t) { $linhaId = vistoIdLinha($t['ordem']); $tickerNormalizado = normalizarTicker($t['nomeAcao']); if (!isset($revolutPorTicker[$tickerNormalizado])) { // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'removertransacao', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'] ?? '', 'status' => 'OK' ]; continue; } $diferencas['removertransacao'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Ticker não encontrado no Revolut (normalizado: ' . $tickerNormalizado . ')' ]; continue; } $comprasTicker = $revolutPorTicker[$tickerNormalizado]['compras']; $vendasTicker = $revolutPorTicker[$tickerNormalizado]['vendas']; // ✅ PROCURAR COMPRA (tolerância: 0 dias, 1€) $compraEncontrada = null; foreach ($comprasTicker as $compra) { $diasDiff = abs(strtotime($compra['data']) - strtotime($t['dataCompra'])) / 86400; $custoDiff = abs($compra['valor'] - $t['custoInicial']); if ($diasDiff <= 0 && $custoDiff <= 1) { $compraEncontrada = $compra; break; } } // ✅ PROCURAR VENDA (tolerância: 0 dias, 1€) $vendaEncontrada = null; $temDataVendaCSV = !empty($t['dataVenda']); if ($temDataVendaCSV) { foreach ($vendasTicker as $venda) { $diasDiff = abs(strtotime($venda['data']) - strtotime($t['dataVenda'])) / 86400; $custoDiff = abs($venda['valor'] - $t['custoFinal']); if ($diasDiff <= 0 && $custoDiff <= 1) { $vendaEncontrada = $venda; break; } } } // Se não existe compra no Revolut e (não há venda no CSV ou também não existe venda no Revolut), // então esta linha do CSV muito provavelmente não corresponde a nada no extrato => remover. $naoExisteCompra = ($compraEncontrada === null); $naoExisteVenda = ($temDataVendaCSV && $vendaEncontrada === null); if ($naoExisteCompra && (!$temDataVendaCSV || $naoExisteVenda)) { $diferencas['removertransacao'][] = [ 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Compra e venda não encontradas no Revolut. Provável linha extra no CSV.' ]; continue; } // ✅ ANÃLISE DE DIFERENÇAS (DETALHADA) $diferencasCount = 0; $detalhes = []; if ($compraEncontrada) { // Data compra if ($compraEncontrada['data'] !== $t['dataCompra']) { $diferencasCount++; $detalhes[] = "Data Compra: {$t['dataCompra']} → {$compraEncontrada['data']}"; } // Quantidade if (abs($compraEncontrada['quantidade'] - $t['numAcoes']) > 0.00001) { $diferencasCount++; $detalhes[] = "Qtd: {$t['numAcoes']} → {$compraEncontrada['quantidade']}"; } // Custo compra if (abs($compraEncontrada['valor'] - $t['custoInicial']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Compra: {$t['custoInicial']} € → {$compraEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "COMPRA não encontrada no Revolut"; } if ($temDataVendaCSV) { if ($vendaEncontrada) { // Data venda if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } // Custo venda if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} € → {$vendaEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "VENDA não encontrada no Revolut"; } } // ✅ RESULTADO POR LINHA if ($diferencasCount === 0) { // Match perfeito $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $item = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'dataCompra' => $t['dataCompra'], 'dataVenda' => $t['dataVenda'], 'diferencas' => $diferencasCount, 'detalhes' => implode(' | ', $detalhes), 'valoratualcompra' => $t['custoInicial'], 'valoratualvenda' => $t['custoFinal'], 'sugestaocompra' => null, 'sugestaovenda' => null ]; // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'alterarlinha', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $diferencas['alterarlinha'][] = $item; } } // <-- ESTA chaveta é a que te falta (fecha o else do diferencasCount) } // fecha foreach ($transacoesAtuais as $t) return $diferencas; } // ========================== // NOVO: COMPARAR CAIXA // movimentos-caixa.csv <-> extrato-revolut.csv (CASH TOP-UP / CASH WITHDRAWAL / DIVIDEND / FEES) // ========================== function fnum_local($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([' ', "\t"], '', $s); // Se vier "USD -1.25" ou "EUR 493.36" $s = preg_replace('/^[A-Z]{3}/', '', $s); $s = trim($s); // vírgulas para ponto $s = str_replace(',', '.', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function normCaixaTipo($tipo): string { $t = mb_strtolower(trim((string)$tipo), 'UTF-8'); // Fallback manual (caso iconv falhe ou não exista translit completo) $t = strtr($t, [ 'á'=>'a','à'=>'a','â'=>'a','ã'=>'a', 'é'=>'e','ê'=>'e', 'í'=>'i', 'ó'=>'o','ô'=>'o','õ'=>'o', 'ú'=>'u', 'ç'=>'c' ]); // Tentar translit (se funcionar, melhora ainda mais) $tt = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $t); if ($tt !== false && $tt !== null && $tt !== '') { $t = $tt; } $t = preg_replace('/[^a-z0-9]+/', ' ', (string)$t); // Depósito (apanha "deposito", "deposit", "top up", "cash top-up", etc.) if (strpos($t, 'depos') !== false || strpos($t, 'deposit') !== false || strpos($t, 'top up') !== false || strpos($t, 'topup') !== false || strpos($t, 'cash top up') !== false || strpos($t, 'cash topup') !== false) { return 'Depósito'; } if (strpos($t, 'levant') !== false || strpos($t, 'withdraw') !== false) return 'Levantamento'; if (strpos($t, 'divid') !== false || strpos($t, 'dividend') !== false) return 'Dividendo'; return 'Outros'; } function mapRevolutCashTypeToCaixaTipo(string $type): ?string { $t = strtoupper(trim($type)); if ($t === '') return null; // Tipos típicos vistos no extrato if (strpos($t, 'CASH TOP-UP') !== false) return 'Depósito'; if (strpos($t, 'CASH WITHDRAWAL') !== false) return 'Levantamento'; if (strpos($t, 'DIVIDEND') !== false) return 'Dividendo'; // Fees e afins if (strpos($t, 'FEE') !== false || strpos($t, 'TAX') !== false || strpos($t, 'COMMISSION') !== false) return 'Outros'; if (strpos($t, 'CUSTODY FEE') !== false) return 'Outros'; return null; // não é movimento de caixa que nos interesse aqui } function filtrarRevolutCaixa(array $revolutMovs): array { $out = []; foreach ($revolutMovs as $m) { $type = (string)($m['tipo'] ?? ''); $tipoCaixa = mapRevolutCashTypeToCaixaTipo($type); if ($tipoCaixa === null) continue; $data = (string)($m['data'] ?? ''); $moeda = strtoupper(trim((string)($m['moeda'] ?? ''))); $valor = (float)($m['valor'] ?? 0.0); $ticker = trim((string)($m['ticker'] ?? '')); $descricao = strtoupper(trim($type)); if ($ticker !== '' && strpos($descricao, 'DIVIDEND') !== false) { $descricao = $ticker . ' DIVIDEND'; } $out[] = [ 'data' => $data, 'tipo' => $tipoCaixa, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $descricao, ]; } return $out; } function lerMovimentosCaixaCSV(string $ficheiroCaixa): array { if (!file_exists($ficheiroCaixa)) return ['_erro' => 'movimentos-caixa.csv não encontrado.']; $fh = fopen($ficheiroCaixa, 'r'); if (!$fh) return ['_erro' => 'Não foi possível abrir movimentos-caixa.csv.']; $cab = fgetcsv($fh, 0, ','); // Ordem,Data,Tipo,Valor,Moeda,Descricao $rows = []; while (($r = fgetcsv($fh, 0, ',')) !== false) { if (count($r) < 6) continue; $ordem = trim((string)$r[0]); $data = substr(trim((string)$r[1]), 0, 10); $tipo = normCaixaTipo($r[2] ?? ''); $valor = fnum_local($r[3] ?? 0); $moeda = strtoupper(trim((string)($r[4] ?? ''))); $desc = trim((string)($r[5] ?? '')); if ($data === '' || strlen($data) < 10) continue; $rows[] = [ 'ordem' => $ordem, 'data' => $data, 'tipo' => $tipo, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $desc, ]; } fclose($fh); return $rows; } function compararCaixaComRevolut(array $revolutMovs, string $ficheiroCaixa): array { $revCaixa = filtrarRevolutCaixa($revolutMovs); $caixaCsv = lerMovimentosCaixaCSV($ficheiroCaixa); if (isset($caixaCsv['_erro'])) { return [ 'resumo' => ['duplicatas' => 0, 'alterar' => 0, 'adicionar' => 0, 'remover' => 0], 'detalhes' => ['duplicatasexatas' => [], 'alterarlinha' => [], 'adicionar' => [], 'remover' => []], 'aviso' => $caixaCsv['_erro'], ]; } // Vamos “consumir†linhas do CSV à medida que casam, para evitar reuso. $usado = array_fill(0, count($caixaCsv), false); $duplicatas = []; $alterar = []; $adicionar = []; $remover = []; // 1) Revolut -> procurar no movimentos-caixa.csv foreach ($revCaixa as $rc) { $matchIdx = null; $match = null; // Tentativa A: data + moeda + valor (tolerância) for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $c = $caixaCsv[$i]; if ($c['moeda'] !== $rc['moeda']) continue; $dias = abs(strtotime($c['data']) - strtotime($rc['data'])) / 86400; if ($dias > 0) continue; if (abs(((float)$c['valor']) - ((float)$rc['valor'])) > 0.01) continue; $matchIdx = $i; $match = $c; break; } if ($matchIdx === null) { $adicionar[] = [ 'origem' => 'Revolut', 'motivo' => 'Movimento de caixa não encontrado em movimentos-caixa.csv', 'sugestao' => $rc, ]; continue; } $usado[$matchIdx] = true; // Comparar tipo (e opcionalmente descrição) $diffs = []; if ($match['tipo'] !== $rc['tipo']) { $diffs[] = "Tipo: CSV={$match['tipo']} vs Revolut={$rc['tipo']}"; } if (count($diffs) === 0) { $duplicatas[] = [ 'data' => $rc['data'], 'tipo' => $rc['tipo'], 'valor' => $rc['valor'], 'moeda' => $rc['moeda'], 'status' => 'OK', ]; } else { $alterar[] = [ 'linha' => $match['ordem'], 'data' => $rc['data'], 'diferencas' => count($diffs), 'detalhes' => implode(' | ', $diffs), 'csv' => $match, 'revolut' => $rc, ]; } } // 2) Tudo o que ficou no CSV sem match -> remover/rever for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $remover[] = [ 'origem' => 'CSV', 'linha' => $caixaCsv[$i]['ordem'], 'motivo' => 'Movimento existe em movimentos-caixa.csv mas não aparece no extrato Revolut (tipos de caixa)', 'csv' => $caixaCsv[$i], ]; } return [ 'resumo' => [ 'duplicatas' => count($duplicatas), 'alterar' => count($alterar), 'adicionar' => count($adicionar), 'remover' => count($remover), ], 'detalhes' => [ 'duplicatasexatas' => $duplicatas, 'alterarlinha' => $alterar, 'adicionar' => $adicionar, 'remover' => $remover, ], ]; } $revolut = lerRevolut($ficheiroRevolut); if (isset($revolut['error'])) { echo json_encode(['ok' => false, 'error' => $revolut['error'], 'user' => getUserId()], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // Normalizar tickers do Revolut para casar com normalizarTicker() foreach ($revolut as &$m) { if (isset($m['ticker']) && $m['ticker'] !== '') { $m['ticker'] = normalizarTicker($m['ticker']); } } unset($m); $revolut = filtrarPorAno($revolut, $anoFiltro); $transacoesAtuais = lerTransacoesAtuais($ficheiroTransacoes); $transacoesAtuais = filtrarPorAno($transacoesAtuais, $anoFiltro); $vistos = vistosLoad(); $diferencas = compararDados($revolut, $transacoesAtuais, $vistos); // --- NOVO: comparar CAIXA (movimentos-caixa.csv) com extrato-revolut.csv --- $caixaDiff = compararCaixaComRevolut($revolut, $ficheiroCaixa); echo json_encode([ 'ok' => true, 'ficheirorevolut' => basename($ficheiroRevolut), 'utilizador' => getUserId(), 'anofiltro' => $anoFiltro ? $anoFiltro : 'TODOS', 'dataverificacao' => date('Y-m-d H:i:s'), // (mantém o resumo/detalhes das AÇÕES como está no teu ficheiro) 'resumo' => [ 'duplicatas' => count($diferencas['duplicatasexatas'] ?? []), 'alterar' => count($diferencas['alterarlinha'] ?? []), 'adicionar' => count($diferencas['adicionartransacao'] ?? []), 'remover' => count($diferencas['removertransacao'] ?? []), ], 'detalhes' => $diferencas, // --- NOVO: resultados de CAIXA --- 'caixa' => $caixaDiff, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; ======================================================================================== FICHEIRO: base-dados-dinheiro.html Tamanho: 16609 bytes ======================================================================================== Base de dados de Dinheiro

Transações de Dinheiro

Dados calculados automaticamente a partir do ficheiro de transações guardado no servidor.

+ Adicionar linha
Nº Data Tipo Valor Moeda Descrição Taxa Câmbio Ações
======================================================================================== FICHEIRO: caixa.html Tamanho: 29056 bytes ======================================================================================== Folha de Caixa

Folha de Caixa

Controlo de saldo disponível e origem dos fundos

Saldo em EUR
0,00 €
Dinheiro disponível em Euros
Saldo em USD
0,00 $
Dinheiro disponível em Dólares
Total (convertido)
0,00 €
Saldo total convertido para EUR

Origem dos Fundos (EUR)

+ Depósitos 0,00 €
- Levantamentos 0,00 €
- Compras Ações 0,00 €
+ Vendas Ações 0,00 €
+ Dividendos 0,00 €
- Taxas 0,00 €
= Saldo EUR 0,00 €

Origem dos Fundos (USD)

+ Depósitos 0,00 $
- Levantamentos 0,00 $
- Compras Ações 0,00 $
+ Vendas Ações 0,00 $
+ Dividendos 0,00 $
- Taxas 0,00 $
= Saldo USD 0,00 $

Histórico de Movimentos Recentes

Data Tipo Descrição Moeda Valor Saldo Acumulado
======================================================================================== FICHEIRO: converter.php Tamanho: 1791 bytes ======================================================================================== ======================================================================================== FICHEIRO: dados_csv/agostinha/lucro-mensal.json Tamanho: 8128 bytes ======================================================================================== { "ok": true, "user": "agostinha", "moeda": "EUR", "compatibilidade": true, "totalmeses": 13, "investimentoinicial": 10000, "series": [ { "mes": "2024-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 10000, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 580.31, "dividendos": 0, "taxas": 0, "net": 580.31, "deltarealizado": 0, "deltanaorealizado": 580.31, "realizadoacumulado": 0, "naorealizadofimmes": 580.31, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 10469.39, "investimentoacumulado": 10000, "saldocaixafimmes": 0, "valorcarteira": 10469.39, "investimentoinicial": 10000, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 15:58:45", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: dados_csv/agostinha/movimentos-caixa.csv Tamanho: 231 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2024-12-19,Depósito,10000,EUR,Deposito Inicial,1 2,2024-12-19,Levantamento,-2000,EUR,Transferencia para Dolar,1 3,2024-12-19,Depósito,2077.98,USD,Transferencia para Dolar,1.03899 ======================================================================================== FICHEIRO: dados_csv/agostinha/transacoes-acoes.csv Tamanho: 338 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2024-12-19","","INDEXNASDAQ:NDX","20.08062405","9.98","4000","","1","","EUR" "2","2024-12-19","","AMS:IWDA","38.58620157","0","4000","","1","","EUR" "3","2024-12-19","","NASDAQ:AAPL","8.27211292","4.99","2077.98","","","","USD" ======================================================================================== FICHEIRO: dados_csv/cache-hpm/hpm_aapl.us_m.json Tamanho: 14133 bytes ======================================================================================== { "ts": "2025-12-23 22:22:29", "data": { "1984-09": 0.0941941, "1984-10": 0.0932972, "1984-11": 0.0926865, "1984-12": 0.109243, "1985-01": 0.108938, "1985-02": 0.0926865, "1985-03": 0.083058, "1985-04": 0.0797468, "1985-05": 0.0652894, "1985-06": 0.0677138, "1985-07": 0.0595734, "1985-08": 0.0562721, "1985-09": 0.0592878, "1985-10": 0.0698227, "1985-11": 0.0755289, "1985-12": 0.0824471, "1986-01": 0.0866846, "1986-02": 0.0939084, "1986-03": 0.105932, "1986-04": 0.113482, "1986-05": 0.138727, "1986-06": 0.134482, "1986-07": 0.117333, "1986-08": 0.138727, "1986-09": 0.125542, "1986-10": 0.130027, "1986-11": 0.150171, "1986-12": 0.151995, "1987-01": 0.208257, "1987-02": 0.26243, "1987-03": 0.24192, "1987-04": 0.297364, "1987-05": 0.296724, "1987-06": 0.304166, "1987-07": 0.309989, "1987-08": 0.406272, "1987-09": 0.424999, "1987-10": 0.290517, "1987-11": 0.248307, "1987-12": 0.315981, "1988-01": 0.312375, "1988-02": 0.323551, "1988-03": 0.301041, "1988-04": 0.308481, "1988-05": 0.312375, "1988-06": 0.347843, "1988-07": 0.334065, "1988-08": 0.300055, "1988-09": 0.325284, "1988-10": 0.290517, "1988-11": 0.282857, "1988-12": 0.302767, "1989-01": 0.28408, "1989-02": 0.27262, "1989-03": 0.267858, "1989-04": 0.293345, "1989-05": 0.359243, "1989-06": 0.310205, "1989-07": 0.29913, "1989-08": 0.334676, "1989-09": 0.334676, "1989-10": 0.349724, "1989-11": 0.332774, "1989-12": 0.265148, "1990-01": 0.255826, "1990-02": 0.255826, "1990-03": 0.302767, "1990-04": 0.296449, "1990-05": 0.310205, "1990-06": 0.336696, "1990-07": 0.315981, "1990-08": 0.278324, "1990-09": 0.218181, "1990-10": 0.231445, "1990-11": 0.276541, "1990-12": 0.323551, "1991-01": 0.417684, "1991-02": 0.430644, "1991-03": 0.511475, "1991-04": 0.413851, "1991-05": 0.353589, "1991-06": 0.312375, "1991-07": 0.347843, "1991-08": 0.398745, "1991-09": 0.372528, "1991-10": 0.387655, "1991-11": 0.381959, "1991-12": 0.424358, "1992-01": 0.48725, "1992-02": 0.50773, "1992-03": 0.438193, "1992-04": 0.452374, "1992-05": 0.449596, "1992-06": 0.361147, "1992-07": 0.351794, "1992-08": 0.346077, "1992-09": 0.339524, "1992-10": 0.394801, "1992-11": 0.432752, "1992-12": 0.449596, "1993-01": 0.447813, "1993-02": 0.398745, "1993-03": 0.387655, "1993-04": 0.38541, "1993-05": 0.425835, "1993-06": 0.297364, "1993-07": 0.208848, "1993-08": 0.199261, "1993-09": 0.175765, "1993-10": 0.231445, "1993-11": 0.23715, "1993-12": 0.219974, "1994-01": 0.246404, "1994-02": 0.274452, "1994-03": 0.250081, "1994-04": 0.225689, "1994-05": 0.219974, "1994-06": 0.199261, "1994-07": 0.25341, "1994-08": 0.272016, "1994-09": 0.25341, "1994-10": 0.324792, "1994-11": 0.280139, "1994-12": 0.293345, "1995-01": 0.303917, "1995-02": 0.297364, "1995-03": 0.265148, "1995-04": 0.287648, "1995-05": 0.3127, "1995-06": 0.349401, "1995-07": 0.33853, "1995-08": 0.323551, "1995-09": 0.280139, "1995-10": 0.27327, "1995-11": 0.286761, "1995-12": 0.23988, "1996-01": 0.207899, "1996-02": 0.206975, "1996-03": 0.184782, "1996-04": 0.183243, "1996-05": 0.19651, "1996-06": 0.158026, "1996-07": 0.165556, "1996-08": 0.182318, "1996-09": 0.166696, "1996-10": 0.173035, "1996-11": 0.181488, "1996-12": 0.157119, "1997-01": 0.125248, "1997-02": 0.122123, "1997-03": 0.137221, "1997-04": 0.127839, "1997-05": 0.125248, "1997-06": 0.107124, "1997-07": 0.131831, "1997-08": 0.163731, "1997-09": 0.163139, "1997-10": 0.128165, "1997-11": 0.133595, "1997-12": 0.0987078, "1998-01": 0.13786, "1998-02": 0.177913, "1998-03": 0.206975, "1998-04": 0.20589, "1998-05": 0.200391, "1998-06": 0.215794, "1998-07": 0.26034, "1998-08": 0.23443, "1998-09": 0.286761, "1998-10": 0.27927, "1998-11": 0.240434, "1998-12": 0.307988, "1999-01": 0.309645, "1999-02": 0.262093, "1999-03": 0.270254, "1999-04": 0.346077, "1999-05": 0.331582, "1999-06": 0.348483, "1999-07": 0.418927, "1999-08": 0.490778, "1999-09": 0.476321, "1999-10": 0.602732, "1999-11": 0.736366, "1999-12": 0.77342, "2000-01": 0.780516, "2000-02": 0.862609, "2000-03": 1.02156, "2000-04": 0.933565, "2000-05": 0.632, "2000-06": 0.788104, "2000-07": 0.764651, "2000-08": 0.916909, "2000-09": 0.387655, "2000-10": 0.29433, "2000-11": 0.248307, "2000-12": 0.223836, "2001-01": 0.325284, "2001-02": 0.274452, "2001-03": 0.332204, "2001-04": 0.383398, "2001-05": 0.300055, "2001-06": 0.349724, "2001-07": 0.282602, "2001-08": 0.27927, "2001-09": 0.23324, "2001-10": 0.264241, "2001-11": 0.320505, "2001-12": 0.329571, "2002-01": 0.371908, "2002-02": 0.326554, "2002-03": 0.356289, "2002-04": 0.365088, "2002-05": 0.350593, "2002-06": 0.266578, "2002-07": 0.229585, "2002-08": 0.222121, "2002-09": 0.218181, "2002-10": 0.24192, "2002-11": 0.23324, "2002-12": 0.215794, "2003-01": 0.216091, "2003-02": 0.225689, "2003-03": 0.212711, "2003-04": 0.213923, "2003-05": 0.269989, "2003-06": 0.286761, "2003-07": 0.317232, "2003-08": 0.340123, "2003-09": 0.311793, "2003-10": 0.344589, "2003-11": 0.31477, "2003-12": 0.321657, "2004-01": 0.339524, "2004-02": 0.359856, "2004-03": 0.406903, "2004-04": 0.387913, "2004-05": 0.422169, "2004-06": 0.489607, "2004-07": 0.486631, "2004-08": 0.519063, "2004-09": 0.583219, "2004-10": 0.7884, "2004-11": 1.00886, "2004-12": 0.969045, "2005-01": 1.15711, "2005-02": 1.35003, "2005-03": 1.25396, "2005-04": 1.08503, "2005-05": 1.19658, "2005-06": 1.10769, "2005-07": 1.28331, "2005-08": 1.41113, "2005-09": 1.61326, "2005-10": 1.73319, "2005-11": 2.04115, "2005-12": 2.16347, "2006-01": 2.27287, "2006-02": 2.06108, "2006-03": 1.88752, "2006-04": 2.11823, "2006-05": 1.79873, "2006-06": 1.72345, "2006-07": 2.04543, "2006-08": 2.04214, "2006-09": 2.31672, "2006-10": 2.44031, "2006-11": 2.75902, "2006-12": 2.55286, "2007-01": 2.57974, "2007-02": 2.54577, "2007-03": 2.79607, "2007-04": 3.00341, "2007-05": 3.64715, "2007-06": 3.67208, "2007-07": 3.96516, "2007-08": 4.16651, "2007-09": 4.61806, "2007-10": 5.71657, "2007-11": 5.48342, "2007-12": 5.9615, "2008-01": 4.07407, "2008-02": 3.76205, "2008-03": 4.31855, "2008-04": 5.23449, "2008-05": 5.68011, "2008-06": 5.03955, "2008-07": 4.78342, "2008-08": 5.10124, "2008-09": 3.42029, "2008-10": 3.23826, "2008-11": 2.78857, "2008-12": 2.56882, "2009-01": 2.7124, "2009-02": 2.68804, "2009-03": 3.16346, "2009-04": 3.78611, "2009-05": 4.08688, "2009-06": 4.28615, "2009-07": 4.91696, "2009-08": 5.0623, "2009-09": 5.57775, "2009-10": 5.67293, "2009-11": 6.01559, "2009-12": 6.3413, "2010-01": 5.77948, "2010-02": 6.15751, "2010-03": 7.07215, "2010-04": 7.85731, "2010-05": 7.73007, "2010-06": 7.56945, "2010-07": 7.74159, "2010-08": 7.31585, "2010-09": 8.53896, "2010-10": 9.05753, "2010-11": 9.36423, "2010-12": 9.70719, "2011-01": 10.211, "2011-02": 10.6296, "2011-03": 10.4866, "2011-04": 10.5361, "2011-05": 10.4682, "2011-06": 10.1014, "2011-07": 11.7512, "2011-08": 11.5816, "2011-09": 11.4742, "2011-10": 12.1809, "2011-11": 11.502, "2011-12": 12.1866, "2012-01": 13.7379, "2012-02": 16.3249, "2012-03": 18.0416, "2012-04": 17.5735, "2012-05": 17.3842, "2012-06": 17.5745, "2012-07": 18.3817, "2012-08": 20.1044, "2012-09": 20.1615, "2012-10": 17.9933, "2012-11": 17.7715, "2012-12": 16.1564, "2013-01": 13.8287, "2013-02": 13.4798, "2013-03": 13.5171, "2013-04": 13.52, "2013-05": 13.8247, "2013-06": 12.2606, "2013-07": 13.9105, "2013-08": 15.163, "2013-09": 14.8377, "2013-10": 16.2686, "2013-11": 17.3074, "2013-12": 17.4591, "2014-01": 15.5799, "2014-02": 16.4777, "2014-03": 16.8037, "2014-04": 18.4753, "2014-05": 19.9308, "2014-06": 20.4805, "2014-07": 21.0709, "2014-08": 22.7029, "2014-09": 22.3176, "2014-10": 23.9201, "2014-11": 26.4608, "2014-12": 24.5577, "2015-01": 26.0655, "2015-02": 28.6861, "2015-03": 27.7872, "2015-04": 27.948, "2015-05": 29.2103, "2015-06": 28.1261, "2015-07": 27.1999, "2015-08": 25.4001, "2015-09": 24.8504, "2015-10": 26.9219, "2015-11": 26.7663, "2015-12": 23.8177, "2016-01": 22.0199, "2016-02": 21.9925, "2016-03": 24.7912, "2016-04": 21.3214, "2016-05": 22.8527, "2016-06": 21.879, "2016-07": 23.85, "2016-08": 24.4157, "2016-09": 26.0094, "2016-10": 26.1227, "2016-11": 25.5598, "2016-12": 26.7858, "2017-01": 28.0669, "2017-02": 31.8198, "2017-03": 33.3669, "2017-04": 33.365, "2017-05": 35.6259, "2017-06": 33.5917, "2017-07": 34.6857, "2017-08": 38.3982, "2017-09": 36.085, "2017-10": 39.5847, "2017-11": 40.3809, "2017-12": 39.767, "2018-01": 39.3463, "2018-02": 42.0326, "2018-03": 39.5915, "2018-04": 38.9953, "2018-05": 44.2608, "2018-06": 43.8459, "2018-07": 45.071, "2018-08": 54.1049, "2018-09": 53.6576, "2018-10": 52.0227, "2018-11": 42.5943, "2018-12": 37.6255, "2019-01": 39.7009, "2019-02": 41.4787, "2019-03": 45.4996, "2019-04": 48.0687, "2019-05": 42.0996, "2019-06": 47.5918, "2019-07": 51.2283, "2019-08": 50.3886, "2019-09": 54.0608, "2019-10": 60.0455, "2019-11": 64.7028, "2019-12": 71.0911, "2020-01": 74.9374, "2020-02": 66.3379, "2020-03": 61.709, "2020-04": 71.299, "2020-05": 77.3669, "2020-06": 88.7671, "2020-07": 103.436, "2020-08": 125.829, "2020-09": 112.918, "2020-10": 106.149, "2020-11": 116.29, "2020-12": 129.613, "2021-01": 128.894, "2021-02": 118.616, "2021-03": 119.491, "2021-04": 128.599, "2021-05": 122.104, "2021-06": 134.214, "2021-07": 142.929, "2021-08": 149.007, "2021-09": 138.857, "2021-10": 147.006, "2021-11": 162.459, "2021-12": 174.514, "2022-01": 171.772, "2022-02": 162.489, "2022-03": 171.822, "2022-04": 155.138, "2022-05": 146.682, "2022-06": 134.738, "2022-07": 160.155, "2022-08": 155.156, "2022-09": 136.385, "2022-10": 151.326, "2022-11": 146.328, "2022-12": 128.437, "2023-01": 142.632, "2023-02": 145.938, "2023-03": 163.255, "2023-04": 167.985, "2023-05": 175.723, "2023-06": 192.298, "2023-07": 194.757, "2023-08": 186.504, "2023-09": 169.965, "2023-10": 169.527, "2023-11": 188.816, "2023-12": 191.382, "2024-01": 183.299, "2024-02": 179.9, "2024-03": 170.674, "2024-04": 169.529, "2024-05": 191.606, "2024-06": 209.914, "2024-07": 221.336, "2024-08": 228.497, "2024-09": 232.488, "2024-10": 225.414, "2024-11": 237.069, "2024-12": 250.145, "2025-01": 235.741, "2025-02": 241.84, "2025-03": 222.13, "2025-04": 212.5, "2025-05": 200.85, "2025-06": 205.17, "2025-07": 207.57, "2025-08": 232.14, "2025-09": 254.63, "2025-10": 270.37, "2025-11": 278.85, "2025-12": 270.97 } } ======================================================================================== FICHEIRO: dados_csv/cache-hpm/hpm_eunl.de_m.json Tamanho: 4385 bytes ======================================================================================== { "ts": "2025-12-23 22:22:28", "data": { "2010-07": 19.21, "2010-08": 19.4, "2010-09": 19.44, "2010-10": 19.56, "2010-11": 20.49, "2010-12": 21.5, "2011-01": 21.34, "2011-02": 21.88, "2011-03": 21.04, "2011-04": 20.97, "2011-05": 21.08, "2012-04": 22.39, "2012-05": 21.84, "2012-06": 22.41, "2012-07": 23.45, "2012-08": 23.54, "2012-09": 23.55, "2012-10": 23.19, "2012-11": 23.44, "2012-12": 23.38, "2013-07": 26.86, "2013-08": 26.25, "2013-09": 26.97, "2013-10": 27.99, "2013-11": 28.41, "2013-12": 28.51, "2014-01": 28.06, "2014-02": 28.92, "2014-03": 28.92, "2014-04": 29.02, "2014-05": 30.1, "2014-06": 30.56, "2014-07": 30.83, "2015-02": 38.4399, "2015-03": 39.97, "2015-04": 38.84, "2015-05": 39.58, "2015-06": 38.1399, "2015-07": 39.28, "2015-08": 36.08, "2015-09": 34.78, "2015-10": 38.17, "2015-11": 39.66, "2015-12": 38.03, "2016-01": 35.45, "2016-02": 35.59, "2016-03": 35.99, "2016-04": 36.05, "2016-05": 37.56, "2016-06": 37.14, "2016-07": 38.57, "2016-08": 38.67, "2016-09": 38.71, "2016-10": 38.91, "2016-11": 41, "2016-12": 42.18, "2017-01": 41.77, "2017-02": 43.86, "2017-03": 44.07, "2017-04": 43.8, "2017-05": 43.31, "2017-06": 42.9, "2017-07": 42.55, "2017-08": 42.2, "2017-09": 43.41, "2017-10": 44.89, "2017-11": 44.8, "2017-12": 45.43, "2018-01": 46.361, "2018-02": 45.053, "2018-03": 43.403, "2018-04": 45.098, "2018-05": 46.741, "2018-06": 46.839, "2018-07": 47.997, "2018-08": 48.904, "2018-09": 49.26, "2018-10": 46.841, "2018-11": 47.037, "2018-12": 43.099, "2019-01": 46.497, "2019-02": 48.346, "2019-03": 49.556, "2019-04": 51.362, "2019-05": 48.904, "2019-06": 50.81, "2019-07": 52.644, "2019-08": 51.776, "2019-09": 53.352, "2019-10": 53.4, "2019-11": 55.75, "2019-12": 56.608, "2020-01": 56.752, "2020-02": 51.712, "2020-03": 46.109, "2020-04": 50.556, "2020-05": 51.816, "2020-06": 52.698, "2020-07": 52.532, "2020-08": 55.664, "2020-09": 54.968, "2020-10": 53.46, "2020-11": 58.588, "2020-12": 59.712, "2021-01": 59.966, "2021-02": 61.888, "2021-03": 65.694, "2021-04": 66.97, "2021-05": 66.77, "2021-06": 69.934, "2021-07": 71.216, "2021-08": 73.434, "2021-09": 72.014, "2021-10": 75.708, "2021-11": 76.196, "2021-12": 79.246, "2022-01": 74.934, "2022-02": 73.652, "2022-03": 77.098, "2022-04": 75.09, "2022-05": 72.492, "2022-06": 67.886, "2022-07": 74.852, "2022-08": 73.428, "2022-09": 69.26, "2022-10": 72.402, "2022-11": 72.62, "2022-12": 68.478, "2023-01": 71.818, "2023-02": 72.244, "2023-03": 72.378, "2023-04": 72.566, "2023-05": 74.336, "2023-06": 77.2, "2023-07": 79.01, "2023-08": 78.55, "2023-09": 77.28, "2023-10": 74.61, "2023-11": 78.97, "2023-12": 82.26, "2024-01": 85.04, "2024-02": 88.2, "2024-03": 91.45, "2024-04": 89.58, "2024-05": 90.73, "2024-06": 95.19, "2024-07": 95.37, "2024-08": 95.13, "2024-09": 96.396, "2024-10": 97.572, "2024-11": 104.805, "2024-12": 103.59, "2025-01": 108.18, "2025-02": 105.525, "2025-03": 97.178, "2025-04": 93.36, "2025-05": 99.308, "2025-06": 100.155, "2025-07": 105, "2025-08": 104.585, "2025-09": 107.195, "2025-10": 111.835, "2025-11": 111.465, "2025-12": 111.165 } } ======================================================================================== FICHEIRO: dados_csv/cache-hpm/hpm_exxt.de_m.json Tamanho: 5255 bytes ======================================================================================== { "ts": "2025-12-23 22:22:29", "data": { "2007-01": 12.5833, "2007-02": 12.3523, "2007-03": 12.2969, "2007-04": 12.879, "2007-05": 13.2577, "2007-06": 13.3132, "2007-07": 13.4795, "2007-08": 13.4333, "2007-09": 13.6088, "2007-10": 14.2186, "2007-11": 13.1746, "2007-12": 13.3317, "2008-01": 11.1698, "2008-02": 10.754, "2008-03": 10.3752, "2008-04": 11.6409, "2008-05": 12.0382, "2008-06": 10.8464, "2008-07": 11.0497, "2008-08": 11.8904, "2008-09": 10.1627, "2008-10": 9.69158, "2008-11": 8.49053, "2008-12": 7.77914, "2009-01": 8.81389, "2009-02": 8.19489, "2009-03": 8.65683, "2009-04": 9.85788, "2009-05": 9.28507, "2009-06": 9.73778, "2009-07": 10.5877, "2009-08": 10.4306, "2009-09": 10.7725, "2009-10": 10.5138, "2009-11": 10.8141, "2009-12": 12.0475, "2010-01": 11.7241, "2010-02": 12.3339, "2010-03": 13.461, "2010-04": 14.1077, "2010-05": 14.0153, "2010-06": 13.3432, "2010-07": 13.1675, "2010-08": 12.9086, "2010-09": 13.5467, "2010-10": 14.1662, "2010-11": 15.0539, "2010-12": 15.5625, "2011-01": 15.396, "2011-02": 15.7937, "2011-03": 15.2296, "2011-04": 15.0354, "2011-05": 15.2204, "2011-06": 14.8928, "2011-07": 15.3744, "2011-08": 14.5408, "2011-09": 15.1336, "2011-10": 15.8745, "2011-11": 15.856, "2011-12": 16.4765, "2012-01": 17.5231, "2012-02": 18.3474, "2012-03": 19.3106, "2012-04": 19.1856, "2012-05": 19.0383, "2012-06": 19.172, "2012-07": 20.1278, "2012-08": 20.6285, "2012-09": 20.3702, "2012-10": 19.0825, "2012-11": 19.2569, "2012-12": 18.5939, "2013-01": 18.8587, "2013-02": 19.7483, "2013-03": 20.5884, "2013-04": 20.5194, "2013-05": 21.9097, "2013-06": 21.081, "2013-07": 21.9792, "2013-08": 21.936, "2013-09": 22.4169, "2013-10": 23.5513, "2013-11": 24.2144, "2013-12": 24.4927, "2014-01": 24.5501, "2014-02": 25.4005, "2014-03": 24.6904, "2014-04": 24.3273, "2014-05": 25.924, "2014-06": 26.6448, "2014-07": 27.6105, "2017-11": 51.3296, "2017-12": 51.7912, "2018-01": 53.83, "2018-02": 54.5129, "2018-03": 51.1182, "2018-04": 53.2164, "2018-05": 57.7987, "2018-06": 58.5332, "2018-07": 59.6527, "2018-08": 63.6553, "2018-09": 63.4584, "2018-10": 59.4545, "2018-11": 58.8599, "2018-12": 53.2914, "2019-01": 58.2425, "2019-02": 60.4552, "2019-03": 63.496, "2019-04": 66.9137, "2019-05": 62.3535, "2019-06": 65.2438, "2019-07": 69.3943, "2019-08": 67.6923, "2019-09": 68.8646, "2019-10": 70.2188, "2019-11": 74.2117, "2019-12": 76.0908, "2020-01": 79.2305, "2020-02": 73.7585, "2020-03": 70.5841, "2020-04": 79.795, "2020-05": 82.4396, "2020-06": 87.2151, "2020-07": 89.0442, "2020-08": 98.2894, "2020-09": 95.201, "2020-10": 92.4924, "2020-11": 98.989, "2020-12": 102.3, "2021-01": 104.2, "2021-02": 104.76, "2021-03": 108.92, "2021-04": 112.5, "2021-05": 108.94, "2021-06": 119.6, "2021-07": 122.6, "2021-08": 128.52, "2021-09": 124.36, "2021-10": 132.7, "2021-11": 139.52, "2021-12": 142.04, "2022-01": 128.1, "2022-02": 123.94, "2022-03": 131.96, "2022-04": 122.14, "2022-05": 114.62, "2022-06": 107.14, "2022-07": 122.14, "2022-08": 119.54, "2022-09": 111.88, "2022-10": 112.48, "2022-11": 109.1, "2022-12": 98.88, "2023-01": 107.86, "2023-02": 110.76, "2023-03": 117.08, "2023-04": 116.02, "2023-05": 130, "2023-06": 134.92, "2023-07": 138.68, "2023-08": 139.24, "2023-09": 136.06, "2023-10": 131.88, "2023-11": 141.56, "2023-12": 148.68, "2024-01": 154.62, "2024-02": 161.42, "2024-03": 164.24, "2024-04": 160.62, "2024-05": 164.04, "2024-06": 180.24, "2024-07": 173.6, "2024-08": 170.6, "2024-09": 174.48, "2024-10": 178.74, "2024-11": 192.88, "2024-12": 197.92, "2025-01": 203.95, "2025-02": 193.08, "2025-03": 171.66, "2025-04": 166, "2025-05": 182.48, "2025-06": 187.039, "2025-07": 199.039, "2025-08": 194.48, "2025-09": 203.55, "2025-10": 218.35, "2025-11": 212.55, "2025-12": 210.7 } } ======================================================================================== FICHEIRO: dados_csv/cache-hpm/hpm_googl.us_m.json Tamanho: 7203 bytes ======================================================================================== { "ts": "2025-12-23 22:26:50", "data": { "2004-08": 2.55001, "2004-09": 3.2283, "2004-10": 4.74879, "2004-11": 4.53306, "2004-12": 4.80234, "2005-01": 4.87284, "2005-02": 4.68277, "2005-03": 4.49646, "2005-04": 5.48013, "2005-05": 6.90695, "2005-06": 7.32694, "2005-07": 7.16801, "2005-08": 7.12418, "2005-09": 7.88293, "2005-10": 9.2699, "2005-11": 10.0864, "2005-12": 10.3341, "2006-01": 10.7774, "2006-02": 9.03276, "2006-03": 9.71478, "2006-04": 10.4108, "2006-05": 9.26193, "2006-06": 10.4451, "2006-07": 9.63009, "2006-08": 9.42881, "2006-09": 10.0112, "2006-10": 11.8669, "2006-11": 12.0763, "2006-12": 11.4705, "2007-01": 12.4922, "2007-02": 11.1954, "2007-03": 11.4126, "2007-04": 11.7419, "2007-05": 12.403, "2007-06": 13.0203, "2007-07": 12.7039, "2007-08": 12.8344, "2007-09": 14.1307, "2007-10": 17.6111, "2007-11": 17.2624, "2007-12": 17.2246, "2008-01": 14.0565, "2008-02": 11.7369, "2008-03": 10.9722, "2008-04": 14.3051, "2008-05": 14.5921, "2008-06": 13.113, "2008-07": 11.8012, "2008-08": 11.5402, "2008-09": 9.97682, "2008-10": 8.95155, "2008-11": 7.29755, "2008-12": 7.66322, "2009-01": 8.43244, "2009-02": 8.41947, "2009-03": 8.67006, "2009-04": 9.86325, "2009-05": 10.3933, "2009-06": 10.5019, "2009-07": 11.036, "2009-08": 11.5003, "2009-09": 12.3512, "2009-10": 13.3546, "2009-11": 14.5224, "2009-12": 15.4435, "2010-01": 13.2007, "2010-02": 13.1225, "2010-03": 14.1237, "2010-04": 13.0885, "2010-05": 12.0856, "2010-06": 11.0838, "2010-07": 12.0773, "2010-08": 11.2099, "2010-09": 13.0975, "2010-10": 15.2871, "2010-11": 13.8428, "2010-12": 14.7953, "2011-01": 14.9548, "2011-02": 15.2796, "2011-03": 14.616, "2011-04": 13.5534, "2011-05": 13.1777, "2011-06": 12.6137, "2011-07": 15.038, "2011-08": 13.4752, "2011-09": 12.8295, "2011-10": 14.7625, "2011-11": 14.9309, "2011-12": 16.0892, "2012-01": 14.4506, "2012-02": 15.4002, "2012-03": 15.9731, "2012-04": 15.0664, "2012-05": 14.4691, "2012-06": 14.4496, "2012-07": 15.7669, "2012-08": 17.0651, "2012-09": 18.7944, "2012-10": 16.9461, "2012-11": 17.396, "2012-12": 17.6206, "2013-01": 18.8237, "2013-02": 19.9576, "2013-03": 19.7832, "2013-04": 20.5396, "2013-05": 21.7018, "2013-06": 21.9296, "2013-07": 22.1139, "2013-08": 21.096, "2013-09": 21.8189, "2013-10": 25.6715, "2013-11": 26.3938, "2013-12": 27.9168, "2014-01": 29.4174, "2014-02": 30.2818, "2014-03": 27.7624, "2014-04": 26.6474, "2014-05": 28.4793, "2014-06": 29.1279, "2014-07": 28.8728, "2014-08": 29.0128, "2014-09": 29.3143, "2014-10": 28.2909, "2014-11": 27.3548, "2014-12": 26.4372, "2015-01": 26.7804, "2015-02": 28.03, "2015-03": 27.6348, "2015-04": 27.3394, "2015-05": 27.1675, "2015-06": 26.9045, "2015-07": 32.7563, "2015-08": 32.274, "2015-09": 31.8032, "2015-10": 36.7363, "2015-11": 38.0047, "2015-12": 38.76, "2016-01": 37.8592, "2016-02": 35.7319, "2016-03": 38.0072, "2016-04": 35.2661, "2016-05": 37.3072, "2016-06": 35.0494, "2016-07": 39.424, "2016-08": 39.3498, "2016-09": 40.0578, "2016-10": 40.3488, "2016-11": 38.6538, "2016-12": 39.4795, "2017-01": 40.8614, "2017-02": 42.094, "2017-03": 42.2369, "2017-04": 46.059, "2017-05": 49.1762, "2017-06": 46.3126, "2017-07": 47.1042, "2017-08": 47.5895, "2017-09": 48.4922, "2017-10": 51.4654, "2017-11": 51.6213, "2017-12": 52.4798, "2018-01": 58.8975, "2018-02": 54.9966, "2018-03": 51.6698, "2018-04": 50.745, "2018-05": 54.8013, "2018-06": 56.2556, "2018-07": 61.1394, "2018-08": 61.3676, "2018-09": 60.136, "2018-10": 54.332, "2018-11": 55.2821, "2018-12": 52.0592, "2019-01": 56.0912, "2019-02": 56.124, "2019-03": 58.6319, "2019-04": 59.7314, "2019-05": 55.1252, "2019-06": 53.9444, "2019-07": 60.69, "2019-08": 59.3115, "2019-09": 60.8365, "2019-10": 62.7126, "2019-11": 64.9689, "2019-12": 66.7276, "2020-01": 71.3803, "2020-02": 66.7206, "2020-03": 57.8877, "2020-04": 67.0918, "2020-05": 71.4171, "2020-06": 70.6463, "2020-07": 74.1287, "2020-08": 81.1823, "2020-09": 73.0153, "2020-10": 80.5136, "2020-11": 87.4031, "2020-12": 87.3154, "2021-01": 91.0381, "2021-02": 100.731, "2021-03": 102.753, "2021-04": 117.25, "2021-05": 117.416, "2021-06": 121.649, "2021-07": 134.241, "2021-08": 144.175, "2021-09": 133.193, "2021-10": 147.511, "2021-11": 141.384, "2021-12": 144.329, "2022-01": 134.815, "2022-02": 134.569, "2022-03": 138.566, "2022-04": 113.698, "2022-05": 113.351, "2022-06": 108.57, "2022-07": 115.9, "2022-08": 107.829, "2022-09": 95.3045, "2022-10": 94.1687, "2022-11": 100.625, "2022-12": 87.9113, "2023-01": 98.483, "2023-02": 89.7348, "2023-03": 103.356, "2023-04": 106.952, "2023-05": 122.426, "2023-06": 119.268, "2023-07": 132.24, "2023-08": 135.679, "2023-09": 130.388, "2023-10": 123.632, "2023-11": 132.052, "2023-12": 139.185, "2024-01": 139.594, "2024-02": 137.96, "2024-03": 150.385, "2024-04": 162.192, "2024-05": 171.877, "2024-06": 181.701, "2024-07": 171.117, "2024-08": 162.976, "2024-09": 165.66, "2024-10": 170.914, "2024-11": 168.757, "2024-12": 189.3, "2025-01": 204.02, "2025-02": 170.28, "2025-03": 154.64, "2025-04": 158.8, "2025-05": 171.74, "2025-06": 176.23, "2025-07": 191.9, "2025-08": 212.91, "2025-09": 243.1, "2025-10": 281.19, "2025-11": 320.18, "2025-12": 309.78 } } ======================================================================================== FICHEIRO: dados_csv/cache-hpm/hpm_nvda.us_m.json Tamanho: 9299 bytes ======================================================================================== { "ts": "2025-12-23 22:22:29", "data": { "1999-01": 0.0362297, "1999-02": 0.0419634, "1999-03": 0.0403518, "1999-04": 0.0348559, "1999-05": 0.0325554, "1999-06": 0.0364567, "1999-07": 0.0385123, "1999-08": 0.0536499, "1999-09": 0.0366834, "1999-10": 0.04218, "1999-11": 0.066251, "1999-12": 0.0896361, "2000-01": 0.0708444, "2000-02": 0.122218, "2000-03": 0.16141, "2000-04": 0.170354, "2000-05": 0.218034, "2000-06": 0.242819, "2000-07": 0.229306, "2000-08": 0.303287, "2000-09": 0.312932, "2000-10": 0.237565, "2000-11": 0.154758, "2000-12": 0.125184, "2001-01": 0.197415, "2001-02": 0.170814, "2001-03": 0.248059, "2001-04": 0.318186, "2001-05": 0.327121, "2001-06": 0.354452, "2001-07": 0.30908, "2001-08": 0.323706, "2001-09": 0.210008, "2001-10": 0.327591, "2001-11": 0.417567, "2001-12": 0.511357, "2002-01": 0.502291, "2002-02": 0.38974, "2002-03": 0.339103, "2002-04": 0.265934, "2002-05": 0.25564, "2002-06": 0.131383, "2002-07": 0.0846137, "2002-08": 0.0772747, "2002-09": 0.0653525, "2002-10": 0.091014, "2002-11": 0.130913, "2002-12": 0.0880387, "2003-01": 0.0788823, "2003-02": 0.0965259, "2003-03": 0.0983632, "2003-04": 0.109137, "2003-05": 0.199933, "2003-06": 0.17517, "2003-07": 0.145833, "2003-08": 0.138963, "2003-09": 0.121988, "2003-10": 0.135048, "2003-11": 0.162318, "2003-12": 0.177235, "2004-01": 0.170124, "2004-02": 0.170124, "2004-03": 0.201768, "2004-04": 0.156826, "2004-05": 0.179303, "2004-06": 0.156356, "2004-07": 0.117854, "2004-08": 0.0951479, "2004-09": 0.110976, "2004-10": 0.110506, "2004-11": 0.146281, "2004-12": 0.179991, "2005-01": 0.17517, "2005-02": 0.22148, "2005-03": 0.181598, "2005-04": 0.16759, "2005-05": 0.207021, "2005-06": 0.204285, "2005-07": 0.206791, "2005-08": 0.23457, "2005-09": 0.262029, "2005-10": 0.256336, "2005-11": 0.276277, "2005-12": 0.279512, "2006-01": 0.343648, "2006-02": 0.360142, "2006-03": 0.437728, "2006-04": 0.446643, "2006-05": 0.351287, "2006-06": 0.325334, "2006-07": 0.338433, "2006-08": 0.445075, "2006-09": 0.452424, "2006-10": 0.533133, "2006-11": 0.565435, "2006-12": 0.565655, "2007-01": 0.468352, "2007-02": 0.473842, "2007-03": 0.439952, "2007-04": 0.50279, "2007-05": 0.52945, "2007-06": 0.631456, "2007-07": 0.699566, "2007-08": 0.782062, "2007-09": 0.830901, "2007-10": 0.811169, "2007-11": 0.72311, "2007-12": 0.780064, "2008-01": 0.56384, "2008-02": 0.490428, "2008-03": 0.453784, "2008-04": 0.471147, "2008-05": 0.566254, "2008-06": 0.429239, "2008-07": 0.262278, "2008-08": 0.289838, "2008-09": 0.245613, "2008-10": 0.20085, "2008-11": 0.171264, "2008-12": 0.185045, "2009-01": 0.182276, "2009-02": 0.189856, "2009-03": 0.226062, "2009-04": 0.263227, "2009-05": 0.239163, "2009-06": 0.258854, "2009-07": 0.296499, "2009-08": 0.332965, "2009-09": 0.344567, "2009-10": 0.27418, "2009-11": 0.299422, "2009-12": 0.42831, "2010-01": 0.352933, "2010-02": 0.371475, "2010-03": 0.398945, "2010-04": 0.360142, "2010-05": 0.30122, "2010-06": 0.23413, "2010-07": 0.210684, "2010-08": 0.21368, "2010-09": 0.267758, "2010-10": 0.275597, "2010-11": 0.312063, "2010-12": 0.353183, "2011-01": 0.548442, "2011-02": 0.519514, "2011-03": 0.423178, "2011-04": 0.458566, "2011-05": 0.459483, "2011-06": 0.365465, "2011-07": 0.317057, "2011-08": 0.305134, "2011-09": 0.286841, "2011-10": 0.339333, "2011-11": 0.358403, "2011-12": 0.317756, "2012-01": 0.338653, "2012-02": 0.34736, "2012-03": 0.353183, "2012-04": 0.298065, "2012-05": 0.285076, "2012-06": 0.316807, "2012-07": 0.310447, "2012-08": 0.3217, "2012-09": 0.305784, "2012-10": 0.27465, "2012-11": 0.276197, "2012-12": 0.28299, "2013-01": 0.28299, "2013-02": 0.293953, "2013-03": 0.297865, "2013-04": 0.319704, "2013-05": 0.337757, "2013-06": 0.327591, "2013-07": 0.336957, "2013-08": 0.345923, "2013-09": 0.364936, "2013-10": 0.356209, "2013-11": 0.367883, "2013-12": 0.377817, "2014-01": 0.370227, "2014-02": 0.435332, "2014-03": 0.424177, "2014-04": 0.437498, "2014-05": 0.452184, "2014-06": 0.441112, "2014-07": 0.416437, "2014-08": 0.464877, "2014-09": 0.440932, "2014-10": 0.467024, "2014-11": 0.503308, "2014-12": 0.481181, "2015-01": 0.460781, "2015-02": 0.531556, "2015-03": 0.504157, "2015-04": 0.534682, "2015-05": 0.535712, "2015-06": 0.486782, "2015-07": 0.482889, "2015-08": 0.546412, "2015-09": 0.599187, "2015-10": 0.68959, "2015-11": 0.773925, "2015-12": 0.80419, "2016-01": 0.714653, "2016-02": 0.767932, "2016-03": 0.872537, "2016-04": 0.870071, "2016-05": 1.14701, "2016-06": 1.15418, "2016-07": 1.40198, "2016-08": 1.50875, "2016-09": 1.68548, "2016-10": 1.7503, "2016-11": 2.27119, "2016-12": 2.62948, "2017-01": 2.68927, "2017-02": 2.50336, "2017-03": 2.68657, "2017-04": 2.57255, "2017-05": 3.56409, "2017-06": 3.56927, "2017-07": 4.01241, "2017-08": 4.18734, "2017-09": 4.41811, "2017-10": 5.11127, "2017-11": 4.9634, "2017-12": 4.78507, "2018-01": 6.07892, "2018-02": 5.98837, "2018-03": 5.73067, "2018-04": 5.56528, "2018-05": 6.24429, "2018-06": 5.86605, "2018-07": 6.06326, "2018-08": 6.95323, "2018-09": 6.96172, "2018-10": 5.22309, "2018-11": 4.05264, "2018-12": 3.31047, "2019-01": 3.56479, "2019-02": 3.82928, "2019-03": 4.45774, "2019-04": 4.49329, "2019-05": 3.36657, "2019-06": 4.08162, "2019-07": 4.19304, "2019-08": 4.16707, "2019-09": 4.33052, "2019-10": 5.00084, "2019-11": 5.39616, "2019-12": 5.85806, "2020-01": 5.8861, "2020-02": 6.72787, "2020-03": 6.5664, "2020-04": 7.28084, "2020-05": 8.84379, "2020-06": 9.46818, "2020-07": 10.5813, "2020-08": 13.3331, "2020-09": 13.4928, "2020-10": 12.4984, "2020-11": 13.3641, "2020-12": 13.0216, "2021-01": 12.9567, "2021-02": 13.6807, "2021-03": 13.3191, "2021-04": 14.9767, "2021-05": 16.2079, "2021-06": 19.9633, "2021-07": 19.462, "2021-08": 22.3449, "2021-09": 20.6781, "2021-10": 25.522, "2021-11": 32.6173, "2021-12": 29.3623, "2022-01": 24.4455, "2022-02": 24.3448, "2022-03": 27.2454, "2022-04": 18.5195, "2022-05": 18.6443, "2022-06": 15.1397, "2022-07": 18.1397, "2022-08": 15.0747, "2022-09": 12.127, "2022-10": 13.4837, "2022-11": 16.9106, "2022-12": 14.6034, "2023-01": 19.5229, "2023-02": 23.1992, "2023-03": 27.7615, "2023-04": 27.7335, "2023-05": 37.813, "2023-06": 42.2828, "2023-07": 46.7078, "2023-08": 49.3326, "2023-09": 43.4829, "2023-10": 40.7649, "2023-11": 46.7527, "2023-12": 49.508, "2024-01": 61.5095, "2024-02": 79.0896, "2024-03": 90.3347, "2024-04": 86.3815, "2024-05": 109.607, "2024-06": 123.52, "2024-07": 117.002, "2024-08": 119.352, "2024-09": 121.432, "2024-10": 132.751, "2024-11": 138.24, "2024-12": 134.29, "2025-01": 120.07, "2025-02": 124.92, "2025-03": 108.38, "2025-04": 108.92, "2025-05": 135.13, "2025-06": 157.99, "2025-07": 177.87, "2025-08": 174.18, "2025-09": 186.58, "2025-10": 202.49, "2025-11": 177, "2025-12": 183.69 } } ======================================================================================== FICHEIRO: dados_csv/cache-hpm/hpm_vusa.de_m.json Tamanho: 2742 bytes ======================================================================================== { "ts": "2025-12-23 22:26:50", "data": { "2017-10": 39.859, "2017-11": 40.0772, "2017-12": 40.6497, "2018-01": 41.4613, "2018-02": 40.7297, "2018-03": 38.8283, "2018-04": 40.2486, "2018-05": 42.3787, "2018-06": 42.7849, "2018-07": 43.9044, "2018-08": 45.6077, "2018-09": 45.9342, "2018-10": 43.9522, "2018-11": 44.3561, "2018-12": 40.1955, "2019-01": 43.3255, "2019-02": 45.1587, "2019-03": 46.4736, "2019-04": 48.3344, "2019-05": 45.9104, "2019-06": 47.7385, "2019-07": 50.2055, "2019-08": 49.3929, "2019-09": 50.6856, "2019-10": 50.5464, "2019-11": 53.2371, "2019-12": 54.0467, "2020-01": 54.645, "2020-02": 49.625, "2020-03": 45.0337, "2020-04": 49.9471, "2020-05": 50.9646, "2020-06": 51.4585, "2020-07": 51.6869, "2020-08": 55.2815, "2020-09": 54.3453, "2020-10": 52.9834, "2020-11": 57.067, "2020-12": 57.704, "2021-01": 58.322, "2021-02": 60.312, "2021-03": 64.322, "2021-04": 65.954, "2021-05": 65.172, "2021-06": 68.688, "2021-07": 70.328, "2021-08": 72.932, "2021-09": 71.17, "2021-10": 75.41, "2021-11": 77.248, "2021-12": 80.274, "2022-01": 75.534, "2022-02": 74.068, "2022-03": 78.37, "2022-04": 76.056, "2022-05": 73.04, "2022-06": 68.464, "2022-07": 76.146, "2022-08": 75.162, "2022-09": 70.822, "2022-10": 74.34, "2022-11": 72.83, "2022-12": 67.9, "2023-01": 70.596, "2023-02": 71.238, "2023-03": 71.162, "2023-04": 71.29, "2023-05": 74.216, "2023-06": 77.06, "2023-07": 78.81, "2023-08": 79.15, "2023-09": 77.22, "2023-10": 74.82, "2023-11": 79.15, "2023-12": 82.03, "2024-01": 85.4, "2024-02": 89.14, "2024-03": 92.11, "2024-04": 90.11, "2024-05": 91.17, "2024-06": 97.28, "2024-07": 96.83, "2024-08": 96.12, "2024-09": 97.512, "2024-10": 100.085, "2024-11": 108.555, "2024-12": 107.345, "2025-01": 111.445, "2025-02": 107.4, "2025-03": 97.366, "2025-04": 92.196, "2025-05": 98.552, "2025-06": 99.776, "2025-07": 105.88, "2025-08": 104.68, "2025-09": 107.355, "2025-10": 112.435, "2025-11": 111.9, "2025-12": 110.765 } } ======================================================================================== FICHEIRO: dados_csv/cache-hpm/hpm_xaueur_m.json Tamanho: 17938 bytes ======================================================================================== { "ts": "2025-12-23 22:26:51", "data": { "1971-01": 71.5, "1971-02": 72.91, "1971-03": 72.77, "1971-04": 74.32, "1971-05": 74.78, "1971-06": 72.44, "1971-07": 75.76, "1971-08": 71.44, "1971-09": 72.95, "1971-10": 72.92, "1971-11": 74.53, "1971-12": 73.42, "1972-01": 78.01, "1972-02": 79.13, "1972-03": 78.97, "1972-04": 81.38, "1972-05": 97.22, "1972-06": 104.85, "1972-07": 111.67, "1972-08": 109.8, "1972-09": 105.93, "1972-10": 106.18, "1972-11": 104.63, "1972-12": 107.04, "1973-01": 107.25, "1973-02": 123.95, "1973-03": 131.61, "1973-04": 132.44, "1973-05": 159.04, "1973-06": 153.89, "1973-07": 138.04, "1973-08": 131.01, "1973-09": 124.2, "1973-10": 123.32, "1973-11": 136.13, "1973-12": 158.81, "1974-01": 187.33, "1974-02": 223.26, "1974-03": 225.06, "1974-04": 213.4, "1974-05": 203.1, "1974-06": 188.77, "1974-07": 206.12, "1974-08": 213.38, "1974-09": 206.23, "1974-10": 221.08, "1974-11": 234.94, "1974-12": 229.43, "1975-01": 213.56, "1975-02": 213.71, "1975-03": 215.95, "1975-04": 203.49, "1975-05": 203.1, "1975-06": 202.61, "1975-07": 228.34, "1975-08": 215.49, "1975-09": 193.05, "1975-10": 187.28, "1975-11": 198.98, "1975-12": 199.89, "1976-01": 177.86, "1976-02": 179.79, "1976-03": 172.79, "1976-04": 172.3, "1976-05": 172.96, "1976-06": 166.38, "1976-07": 148.89, "1976-08": 133.77, "1976-09": 144.96, "1976-10": 152.33, "1976-11": 163.54, "1976-12": 166.49, "1977-01": 171.34, "1977-02": 178.83, "1977-03": 185.09, "1977-04": 178.64, "1977-05": 177.94, "1977-06": 175.37, "1977-07": 172.77, "1977-08": 176.04, "1977-09": 185.15, "1977-10": 187.81, "1977-11": 184.94, "1977-12": 180.17, "1978-01": 196.56, "1978-02": 193.42, "1978-03": 190.82, "1978-04": 181.41, "1978-05": 206.69, "1978-06": 201.04, "1978-07": 219.25, "1978-08": 214.72, "1978-09": 219.6, "1978-10": 216.48, "1978-11": 194.19, "1978-12": 213.7, "1979-01": 227.24, "1979-02": 240.17, "1979-03": 233.46, "1979-04": 242.65, "1979-05": 275.16, "1979-06": 267.33, "1979-07": 279.52, "1979-08": 305.7, "1979-09": 361.23, "1979-10": 356.8, "1979-11": 381.89, "1979-12": 478.8, "1980-01": 629.47, "1980-02": 583.14, "1980-03": 519.36, "1980-04": 467.93, "1980-05": 506.11, "1980-06": 591.53, "1980-07": 586.09, "1980-08": 602.72, "1980-09": 639.99, "1980-10": 627.44, "1980-11": 636.86, "1980-12": 606.66, "1981-01": 560.29, "1981-02": 531.64, "1981-03": 568.72, "1981-04": 554.23, "1981-05": 588.41, "1981-06": 526.03, "1981-07": 536.24, "1981-08": 556.6, "1981-09": 528.07, "1981-10": 496.03, "1981-11": 469.18, "1981-12": 462.19, "1982-01": 465.38, "1982-02": 446.31, "1982-03": 414.28, "1982-04": 414.13, "1982-05": 396, "1982-06": 400.76, "1982-07": 449.54, "1982-08": 535.78, "1982-09": 524.9, "1982-10": 555.26, "1982-11": 567.56, "1982-12": 553.32, "1983-01": 655.04, "1983-02": 528.77, "1983-03": 526.05, "1983-04": 548.32, "1983-05": 541.75, "1983-06": 545.28, "1983-07": 580.39, "1983-08": 587.47, "1983-09": 550.26, "1983-10": 511.13, "1983-11": 566.01, "1983-12": 542.13, "1984-01": 547.66, "1984-02": 531.44, "1984-03": 524.47, "1984-04": 529.72, "1984-05": 551.34, "1984-06": 536.44, "1984-07": 521.98, "1984-08": 530.37, "1984-09": 553.32, "1984-10": 522.14, "1984-11": 531.81, "1984-12": 501.05, "1985-01": 498.54, "1985-02": 495.03, "1985-03": 528.14, "1985-04": 502.86, "1985-05": 501.18, "1985-06": 493.48, "1985-07": 481.13, "1985-08": 489.77, "1985-09": 449.31, "1985-10": 438.76, "1985-11": 421.67, "1985-12": 415.38, "1986-01": 432.1, "1986-02": 390.12, "1986-03": 402.6, "1986-04": 386.43, "1986-05": 413.76, "1986-06": 392.39, "1986-07": 396.89, "1986-08": 410.5, "1986-09": 446.82, "1986-10": 428.51, "1986-11": 399.43, "1986-12": 401.32, "1987-01": 384.34, "1987-02": 381.78, "1987-03": 390.56, "1987-04": 420.97, "1987-05": 426.49, "1987-06": 423.45, "1987-07": 452.86, "1987-08": 425.91, "1987-09": 433.53, "1987-10": 417.58, "1987-11": 418.2, "1987-12": 393.8, "1988-01": 394.58, "1988-02": 373.91, "1988-03": 388.81, "1988-04": 388.63, "1988-05": 407.66, "1988-06": 407.81, "1988-07": 430.05, "1988-08": 423.75, "1988-09": 383.4, "1988-10": 379.26, "1988-11": 382.44, "1988-12": 374.92, "1989-01": 381.2, "1989-02": 364.96, "1989-03": 379.27, "1989-04": 366.89, "1989-05": 371.36, "1989-06": 378.13, "1989-07": 362.29, "1989-08": 366.9, "1989-09": 357.21, "1989-10": 356.53, "1989-11": 381.03, "1989-12": 351.04, "1990-01": 361.64, "1990-02": 355.75, "1990-03": 324.68, "1990-04": 319.73, "1990-05": 321.14, "1990-06": 307.4, "1990-07": 308.67, "1990-08": 314.51, "1990-09": 327.79, "1990-10": 296.34, "1990-11": 296.67, "1990-12": 304.11, "1991-01": 279.25, "1991-02": 288.55, "1991-03": 314.3, "1991-04": 314.93, "1991-05": 325.34, "1991-06": 344.22, "1991-07": 331.87, "1991-08": 316.42, "1991-09": 304.4, "1991-10": 307.37, "1991-11": 309.56, "1991-12": 276.74, "1992-01": 295.73, "1992-02": 297.19, "1992-03": 291.61, "1992-04": 286.4, "1992-05": 278.84, "1992-06": 269.04, "1992-07": 274.27, "1992-08": 248.13, "1992-09": 253.35, "1992-10": 268.88, "1992-11": 274.15, "1992-12": 276.62, "1993-01": 272.76, "1993-02": 279.47, "1993-03": 281.62, "1993-04": 290.12, "1993-05": 307.94, "1993-06": 330.14, "1993-07": 376.89, "1993-08": 330.29, "1993-09": 307.69, "1993-10": 323.76, "1993-11": 332.23, "1993-12": 350.63, "1994-01": 342.23, "1994-02": 336.08, "1994-03": 338.9, "1994-04": 323.71, "1994-05": 330.31, "1994-06": 319.23, "1994-07": 317.59, "1994-08": 318.9, "1994-09": 319.98, "1994-10": 302.78, "1994-11": 313.11, "1994-12": 311.89, "1995-01": 302.57, "1995-02": 296.35, "1995-03": 293.3, "1995-04": 291.79, "1995-05": 294.25, "1995-06": 288.49, "1995-07": 285.41, "1995-08": 299.98, "1995-09": 295.66, "1995-10": 294.04, "1995-11": 303.57, "1995-12": 302.94, "1996-01": 329.19, "1996-02": 318.47, "1996-03": 314.89, "1996-04": 319.35, "1996-05": 315.45, "1996-06": 306.15, "1996-07": 303.52, "1996-08": 303.73, "1996-09": 302.62, "1996-10": 299.36, "1996-11": 296.49, "1996-12": 294.78, "1997-01": 291.83, "1997-02": 316.89, "1997-03": 301.18, "1997-04": 301.56, "1997-05": 302.28, "1997-06": 296.57, "1997-07": 302.53, "1997-08": 298.12, "1997-09": 300.76, "1997-10": 272.6, "1997-11": 264.59, "1997-12": 262.88, "1998-01": 280.97, "1998-02": 274.98, "1998-03": 279.56, "1998-04": 278.39, "1998-05": 265.74, "1998-06": 271.26, "1998-07": 258.3, "1998-08": 243.91, "1998-09": 251.87, "1998-10": 246.21, "1998-11": 252.87, "1998-12": 245.93, "1999-01": 251.74, "1999-02": 260.41, "1999-03": 260.15, "1999-04": 270.75, "1999-05": 259.45, "1999-06": 252.32, "1999-07": 239.09, "1999-08": 242.14, "1999-09": 280.1, "1999-10": 283.66, "1999-11": 288.14, "1999-12": 286.25, "2000-01": 292.48, "2000-02": 302.92, "2000-03": 291.74, "2000-04": 299.73, "2000-05": 290.18, "2000-06": 304.63, "2000-07": 299.44, "2000-08": 312.68, "2000-09": 310.34, "2000-10": 311.66, "2000-11": 310.08, "2000-12": 288.95, "2001-01": 284.18, "2001-02": 289.44, "2001-03": 293.53, "2001-04": 297.05, "2001-05": 313.95, "2001-06": 318.65, "2001-07": 304.46, "2001-08": 301.13, "2001-09": 322.27, "2001-10": 310.66, "2001-11": 306.32, "2001-12": 313.36, "2002-01": 329.7, "2002-02": 341.29, "2002-03": 347.22, "2002-04": 342.84, "2002-05": 350.19, "2002-06": 321.33, "2002-07": 311.76, "2002-08": 318.5, "2002-09": 327.83, "2002-10": 319.51, "2002-11": 320.88, "2002-12": 326.55, "2003-01": 341.23, "2003-02": 322.02, "2003-03": 307.17, "2003-04": 301.18, "2003-05": 306.71, "2003-06": 300.32, "2003-07": 315.87, "2003-08": 342.08, "2003-09": 332.9, "2003-10": 332.04, "2003-11": 331.86, "2003-12": 331.52, "2004-01": 321.97, "2004-02": 317.62, "2004-03": 344.08, "2004-04": 324.21, "2004-05": 320.89, "2004-06": 324.88, "2004-07": 322.19, "2004-08": 334.36, "2004-09": 334.45, "2004-10": 334.66, "2004-11": 339.43, "2004-12": 322.91, "2005-01": 323.37, "2005-02": 329.83, "2005-03": 330.12, "2005-04": 337.53, "2005-05": 338.34, "2005-06": 359.49, "2005-07": 354.13, "2005-08": 351.54, "2005-09": 389.6, "2005-10": 388.19, "2005-11": 419.2, "2005-12": 436.01, "2006-01": 469.33, "2006-02": 470.57, "2006-03": 479.41, "2006-04": 514.53, "2006-05": 502.58, "2006-06": 480.14, "2006-07": 496.95, "2006-08": 488.21, "2006-09": 472.23, "2006-10": 474.3, "2006-11": 488.14, "2006-12": 481.81, "2007-01": 500.77, "2007-02": 506.13, "2007-03": 496.85, "2007-04": 498.94, "2007-05": 491.04, "2007-06": 480.09, "2007-07": 486.95, "2007-08": 493.51, "2007-09": 522.15, "2007-10": 549.62, "2007-11": 536.16, "2007-12": 570.92, "2008-01": 623.45, "2008-02": 639.39, "2008-03": 578.6, "2008-04": 556.67, "2008-05": 570.1, "2008-06": 588.71, "2008-07": 585.87, "2008-08": 566.38, "2008-09": 620.04, "2008-10": 568.04, "2008-11": 644.32, "2008-12": 630.64, "2009-01": 724.67, "2009-02": 739.46, "2009-03": 695.66, "2009-04": 672.7, "2009-05": 691.36, "2009-06": 660.69, "2009-07": 669.12, "2009-08": 663.78, "2009-09": 688.27, "2009-10": 707.15, "2009-11": 785.77, "2009-12": 765.41, "2010-01": 779.2, "2010-02": 819.35, "2010-03": 823.6, "2010-04": 886.22, "2010-05": 988.62, "2010-06": 1014.4, "2010-07": 904.51, "2010-08": 982.78, "2010-09": 959.79, "2010-10": 974.54, "2010-11": 1068.4, "2010-12": 1061.2, "2011-01": 973.29, "2011-02": 1022.4, "2011-03": 1010.9, "2011-04": 1055.8, "2011-05": 1066.6, "2011-06": 1034.6, "2011-07": 1128.4, "2011-08": 1269.4, "2011-09": 1212.9, "2011-10": 1238.8, "2011-11": 1301.6, "2011-12": 1207.5, "2012-01": 1328, "2012-02": 1271.9, "2012-03": 1250.4, "2012-04": 1256.7, "2012-05": 1261.08, "2012-06": 1262.19, "2012-07": 1312.16, "2012-08": 1345.32, "2012-09": 1377.55, "2012-10": 1327.27, "2012-11": 1320.44, "2012-12": 1271.03, "2013-01": 1225.15, "2013-02": 1209.58, "2013-03": 1245.93, "2013-04": 1121.29, "2013-05": 1065.76, "2013-06": 947.08, "2013-07": 996.05, "2013-08": 1054.78, "2013-09": 982.59, "2013-10": 973.93, "2013-11": 922.77, "2013-12": 875.09, "2014-01": 922.99, "2014-02": 958.91, "2014-03": 932.31, "2014-04": 931.24, "2014-05": 917.44, "2014-06": 969.24, "2014-07": 957.96, "2014-08": 979.65, "2014-09": 956.61, "2014-10": 935.74, "2014-11": 940.1, "2014-12": 977.4, "2015-01": 1136.32, "2015-02": 1082.81, "2015-03": 1102.14, "2015-04": 1055.71, "2015-05": 1083.99, "2015-06": 1052.72, "2015-07": 997.45, "2015-08": 1012.13, "2015-09": 997.889, "2015-10": 1038.12, "2015-11": 1007.47, "2015-12": 977.354, "2016-01": 1031.74, "2016-02": 1139.03, "2016-03": 1083.46, "2016-04": 1129.65, "2016-05": 1092.12, "2016-06": 1190.53, "2016-07": 1209.52, "2016-08": 1173.13, "2016-09": 1172.92, "2016-10": 1163.16, "2016-11": 1107.78, "2016-12": 1093.52, "2017-01": 1121.15, "2017-02": 1180.93, "2017-03": 1169.22, "2017-04": 1164.29, "2017-05": 1127.9, "2017-06": 1086.97, "2017-07": 1071.97, "2017-08": 1108.96, "2017-09": 1083.41, "2017-10": 1091.47, "2017-11": 1070.98, "2017-12": 1086.04, "2018-01": 1084, "2018-02": 1081.02, "2018-03": 1077.54, "2018-04": 1089.65, "2018-05": 1110.64, "2018-06": 1072.67, "2018-07": 1045.87, "2018-08": 1033.2, "2018-09": 1026.59, "2018-10": 1074.21, "2018-11": 1079.46, "2018-12": 1118.46, "2019-01": 1154.29, "2019-02": 1154.23, "2019-03": 1152.01, "2019-04": 1144.42, "2019-05": 1168.96, "2019-06": 1240.94, "2019-07": 1276.17, "2019-08": 1386.45, "2019-09": 1351.13, "2019-10": 1356.9, "2019-11": 1328.81, "2019-12": 1353.15, "2020-01": 1430.87, "2020-02": 1428.82, "2020-03": 1427.49, "2020-04": 1539.87, "2020-05": 1559.63, "2020-06": 1585.08, "2020-07": 1675.56, "2020-08": 1648.28, "2020-09": 1608.99, "2020-10": 1612.81, "2020-11": 1489.35, "2020-12": 1554.28, "2021-01": 1518.47, "2021-02": 1431.73, "2021-03": 1455.77, "2021-04": 1470.42, "2021-05": 1559.47, "2021-06": 1492.99, "2021-07": 1529.29, "2021-08": 1535.71, "2021-09": 1517.31, "2021-10": 1542.29, "2021-11": 1565.28, "2021-12": 1608.2, "2022-01": 1599.65, "2022-02": 1701.19, "2022-03": 1750.71, "2022-04": 1797.74, "2022-05": 1711.91, "2022-06": 1723.83, "2022-07": 1722.97, "2022-08": 1702.05, "2022-09": 1695.66, "2022-10": 1652.48, "2022-11": 1699.28, "2022-12": 1703.4, "2023-01": 1774.86, "2023-02": 1727.07, "2023-03": 1817.14, "2023-04": 1805.17, "2023-05": 1836.93, "2023-06": 1759.5, "2023-07": 1787.55, "2023-08": 1789.34, "2023-09": 1748.36, "2023-10": 1875.78, "2023-11": 1870.47, "2023-12": 1868.7, "2024-01": 1885.9, "2024-02": 1892.3, "2024-03": 2070.6, "2024-04": 2142.49, "2024-05": 2145.24, "2024-06": 2170.81, "2024-07": 2260.99, "2024-08": 2264.02, "2024-09": 2366.64, "2024-10": 2521.93, "2024-11": 2504.58, "2024-12": 2535.07, "2025-01": 2700.15, "2025-02": 2752.12, "2025-03": 2886.94, "2025-04": 2902.84, "2025-05": 2901.27, "2025-06": 2803.54, "2025-07": 2881.8, "2025-08": 2951.1, "2025-09": 3288.04, "2025-10": 3469.48, "2025-11": 3665.33, "2025-12": 3778.64 } } ======================================================================================== FICHEIRO: dados_csv/cache/atualizar_hpm_perplexity.php Tamanho: 12870 bytes ======================================================================================== false, 'erro' => 'Falta a API key. Define PPLXAPIKEY, PPLX_API_KEY ou PERPLEXITY_API_KEY no ambiente do PHP.', ], 500); } if ($toMonth === null) { respond([ 'ok' => false, 'erro' => 'Não foi possível calcular o último mês fechado.', ], 500); } $files = []; if ($singleFile !== '') { $target = realpath($cacheDir . DIRECTORY_SEPARATOR . basename($singleFile)); if ($target === false || !is_file($target)) { respond([ 'ok' => false, 'erro' => 'Ficheiro não encontrado.', 'file' => $singleFile, ], 404); } $files[] = $target; } else { $files = glob($cacheDir . DIRECTORY_SEPARATOR . 'hpm_*_m.json') ?: []; sort($files, SORT_NATURAL | SORT_FLAG_CASE); } if (!$files) { respond([ 'ok' => false, 'erro' => 'Não foram encontrados ficheiros hpm_*_m.json nesta pasta.', 'pasta' => $cacheDir, ], 404); } $resultados = []; $totais = [ 'ficheiros' => 0, 'atualizados' => 0, 'meses_escritos' => 0, 'meses_falhados' => 0, 'sem_alteracoes' => 0, ]; foreach ($files as $filePath) { $totais['ficheiros']++; $base = basename($filePath); if (!preg_match('/^hpm_(.+)_m\.json$/i', $base, $m)) { $resultados[] = [ 'ficheiro' => $base, 'ok' => false, 'erro' => 'Nome de ficheiro inválido. Esperado: hpm__m.json', ]; $totais['meses_falhados']++; continue; } $symbol = strtolower(trim($m[1])); $currency = inferCurrencyFromSymbol($symbol); $payload = readJsonFile($filePath); if (!is_array($payload)) { $payload = [ 'ts' => date('Y-m-d H:i:s'), 'data' => [], ]; } if (!isset($payload['data']) || !is_array($payload['data'])) { $payload['data'] = []; } $payload['data'] = normalizeMonthlyMap($payload['data']); $existingMonths = array_keys($payload['data']); sort($existingMonths, SORT_STRING); $lastExisting = !empty($existingMonths) ? end($existingMonths) : null; $monthsToFetch = []; if ($fromParam !== null) { $monthsToFetch = monthRange($fromParam, $toMonth); } else { if ($lastExisting === null) { $resultados[] = [ 'ficheiro' => $base, 'simbolo' => $symbol, 'ok' => false, 'erro' => 'Ficheiro vazio/sem histórico. Usa ?from=YYYY-MM para inicializar.', ]; $totais['meses_falhados']++; continue; } if ($forceLast && $lastExisting <= $toMonth) { $monthsToFetch[] = $lastExisting; } $next = nextMonth($lastExisting); if ($next !== null && $next <= $toMonth) { $monthsToFetch = array_merge($monthsToFetch, monthRange($next, $toMonth)); } } $monthsToFetch = array_values(array_unique(array_filter($monthsToFetch, static function ($ym) use ($toMonth) { return is_string($ym) && preg_match('/^\d{4}-\d{2}$/', $ym) && $ym <= $toMonth; }))); sort($monthsToFetch, SORT_STRING); if (empty($monthsToFetch)) { $resultados[] = [ 'ficheiro' => $base, 'simbolo' => $symbol, 'moeda' => $currency, 'ok' => true, 'alterado' => false, 'mensagem' => 'Sem meses novos para atualizar.', 'ultimo_mes_existente' => $lastExisting, 'ultimo_mes_fechado' => $toMonth, ]; $totais['sem_alteracoes']++; continue; } $updates = []; $errors = []; $alterado = false; foreach ($monthsToFetch as $index => $month) { $res = fetchMonthlyCloseFromPerplexity($symbol, $currency, $month, $apiKey, $model, $timeout); if (!empty($res['ok'])) { $newValue = (float)$res['valor']; $oldValue = isset($payload['data'][$month]) ? (float)$payload['data'][$month] : null; $payload['data'][$month] = $newValue; $alterado = true; $totais['meses_escritos']++; $updates[] = [ 'mes' => $month, 'anterior' => $oldValue, 'novo' => $newValue, 'resposta' => $res['conteudo'] ?? null, ]; } else { $totais['meses_falhados']++; $errors[] = [ 'mes' => $month, 'erro' => $res['erro'] ?? 'Erro desconhecido', 'conteudo' => $res['conteudo'] ?? null, 'http_code' => $res['http_code'] ?? null, ]; } if ($sleepMs > 0 && $index < count($monthsToFetch) - 1) { usleep($sleepMs * 1000); } } ksort($payload['data'], SORT_STRING); $payload['ts'] = date('Y-m-d H:i:s'); if ($alterado && !$dryRun) { $json = json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if ($json === false || file_put_contents($filePath, $json, LOCK_EX) === false) { $errors[] = [ 'mes' => null, 'erro' => 'Falha ao gravar o ficheiro atualizado.', ]; } else { $totais['atualizados']++; } } $resultados[] = [ 'ficheiro' => $base, 'simbolo' => $symbol, 'moeda' => $currency, 'ok' => empty($errors), 'alterado' => $alterado, 'months_pedidos' => $monthsToFetch, 'updates' => $updates, 'erros' => $errors, 'ultimo_mes_no_ficheiro' => !empty($payload['data']) ? array_key_last($payload['data']) : null, 'ts' => $payload['ts'], 'dry_run' => $dryRun, ]; } respond([ 'ok' => true, 'modelo' => $model, 'pasta' => $cacheDir, 'force_last' => $forceLast, 'dry_run' => $dryRun, 'from' => $fromParam, 'to' => $toMonth, 'sleep_ms' => $sleepMs, 'totais' => $totais, 'resultados' => $resultados, ]); function respond(array $data, int $httpCode = 200): void { http_response_code($httpCode); echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } function readJsonFile(string $path): ?array { if (!is_file($path)) { return null; } $raw = file_get_contents($path); if (!is_string($raw) || trim($raw) === '') { return null; } $data = json_decode($raw, true); return is_array($data) ? $data : null; } function normalizeMonth(string $ym): ?string { $ym = trim($ym); return preg_match('/^\d{4}-\d{2}$/', $ym) ? $ym : null; } function lastCompletedMonth(): ?string { try { $dt = new DateTime('first day of last month'); return $dt->format('Y-m'); } catch (Throwable $e) { return null; } } function nextMonth(string $ym): ?string { if (!preg_match('/^\d{4}-\d{2}$/', $ym)) { return null; } $dt = DateTime::createFromFormat('Y-m-d', $ym . '-01'); if (!$dt) { return null; } $dt->modify('+1 month'); return $dt->format('Y-m'); } function monthRange(string $from, string $to): array { if (!preg_match('/^\d{4}-\d{2}$/', $from) || !preg_match('/^\d{4}-\d{2}$/', $to) || $from > $to) { return []; } $out = []; $dt = DateTime::createFromFormat('Y-m-d', $from . '-01'); $end = DateTime::createFromFormat('Y-m-d', $to . '-01'); if (!$dt || !$end) { return []; } while ($dt <= $end) { $out[] = $dt->format('Y-m'); $dt->modify('+1 month'); } return $out; } function normalizeMonthlyMap(array $data): array { $out = []; foreach ($data as $k => $v) { $month = normalizeMonth((string)$k); if ($month === null) { continue; } if (is_numeric($v)) { $n = (float)$v; if (is_finite($n) && $n > 0) { $out[$month] = $n; } } } ksort($out, SORT_STRING); return $out; } function inferCurrencyFromSymbol(string $symbol): string { $s = strtolower(trim($symbol)); if (substr($s, -3) === '.us') { return 'USD'; } if (substr($s, -3) === '.de') { return 'EUR'; } if ($s === 'xaueur') { return 'EUR'; } return 'USD'; } function fetchMonthlyCloseFromPerplexity( string $symbol, string $currency, string $month, string $apiKey, string $model, int $timeout ): array { $prompt = buildPrompt($symbol, $currency, $month); $ch = curl_init('https://api.perplexity.ai/chat/completions'); if ($ch === false) { return [ 'ok' => false, 'erro' => 'Falha ao iniciar cURL.', ]; } $payload = [ 'model' => $model, 'messages' => [ [ 'role' => 'system', 'content' => 'Return only the requested numeric value. Use dot as decimal separator. No text. No JSON. No currency symbol.', ], [ 'role' => 'user', 'content' => $prompt, ], ], 'temperature' => 0, 'max_tokens' => 50, ]; curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey, ], CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), CURLOPT_TIMEOUT => $timeout, CURLOPT_SSL_VERIFYPEER => true, ]); $resp = curl_exec($ch); $curlError = curl_error($ch); $httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if (!is_string($resp) || trim($resp) === '') { return [ 'ok' => false, 'erro' => 'Resposta vazia da API Perplexity.', 'http_code' => $httpCode, 'curl_error' => $curlError ?: null, ]; } $decoded = json_decode($resp, true); $content = null; if (is_array($decoded)) { $content = $decoded['choices'][0]['message']['content'] ?? null; } if (!is_string($content) || trim($content) === '') { return [ 'ok' => false, 'erro' => 'Resposta inválida da API Perplexity.', 'http_code' => $httpCode, 'curl_error' => $curlError ?: null, 'raw' => $resp, ]; } $value = extractNumericValue($content); if ($value === null || $value <= 0) { return [ 'ok' => false, 'erro' => 'Não foi possível extrair um número válido.', 'http_code' => $httpCode, 'curl_error' => $curlError ?: null, 'conteudo' => trim($content), ]; } return [ 'ok' => true, 'valor' => round($value, 6), 'http_code' => $httpCode, 'conteudo' => trim($content), ]; } function buildPrompt(string $symbol, string $currency, string $month): string { $upper = strtoupper($symbol); return implode(' ', [ 'Return ONLY ONE decimal number.', 'Asset symbol:', $upper . '.', 'Required value:', 'the monthly closing price for', $month . ',', 'defined as the close on the last trading day of that month.', 'Currency:', strtoupper($currency) . '.', 'No words. No explanation. No JSON. No currency sign.', ]); } function extractNumericValue(string $content): ?float { $clean = trim($content); if (preg_match('/^-?\d+,\d+$/', $clean)) { $clean = str_replace(',', '.', $clean); } if (preg_match('/-?\d+(?:\.\d+)?/', $clean, $m)) { $v = (float)$m[0]; if (is_finite($v)) { return $v; } } return null; } ======================================================================================== FICHEIRO: dados_csv/cache/csv/aapl_us_m.csv Tamanho: 28451 bytes ======================================================================================== Date,Open,High,Low,Close,Volume 1984-09-30,0.0991725,0.108466,0.0919896,0.0937853,2557980634 1984-10-31,0.0935009,0.102175,0.084179,0.0928924,4246970059 1984-11-30,0.0935009,0.0991725,0.0817949,0.0922843,4016926232 1984-12-31,0.0922843,0.109369,0.0910771,0.108768,4118197809 1985-01-31,0.108768,0.116255,0.104265,0.108466,7588423258 1985-02-28,0.108466,0.114773,0.0922843,0.0922843,5641942898 1985-03-31,0.0922843,0.0970725,0.0773008,0.0826976,5501529992 1985-04-30,0.0826976,0.0860043,0.0731111,0.0794008,3418535091 1985-05-31,0.0794008,0.0830017,0.0629256,0.0650061,5529591063 1985-06-30,0.0635245,0.0692156,0.055135,0.0674199,6926860793 1985-07-31,0.0677142,0.068028,0.0593149,0.0593149,3099768559 1985-08-31,0.0593149,0.0602374,0.0539379,0.0560279,2167846299 1985-09-30,0.0560279,0.064427,0.055135,0.0590306,2150384720 1985-10-31,0.0590306,0.0718941,0.0560279,0.0695196,4512603764 1985-11-30,0.0695196,0.0773008,0.0695196,0.0752011,3438372797 1985-12-31,0.0752011,0.0853958,0.0718941,0.0820893,4256688349 1986-01-31,0.0820893,0.0922843,0.0812061,0.0863085,7499486803 1986-02-28,0.0863085,0.0997923,0.0853958,0.0935009,4077480551 1986-03-31,0.0935009,0.110557,0.0904787,0.105472,5082853617 1986-04-30,0.105472,0.122202,0.0979751,0.112989,5319278899 1986-05-31,0.112989,0.139932,0.111163,0.138125,5904960707 1986-06-30,0.138125,0.146223,0.121299,0.133899,4843305161 1986-07-31,0.133899,0.141138,0.112056,0.116824,6784124744 1986-08-31,0.116255,0.141943,0.114146,0.138125,4342874732 1986-09-30,0.138734,0.138734,0.118072,0.124998,4265018927 1986-10-31,0.124704,0.131503,0.120435,0.129463,3556812362 1986-11-30,0.129727,0.154023,0.12644,0.149519,6205464663 1986-12-31,0.149519,0.163934,0.146223,0.151335,5676732648 1987-01-31,0.151039,0.213603,0.149833,0.207353,9856099243 1987-02-28,0.207353,0.266373,0.192656,0.261291,7886123621 1987-03-31,0.262477,0.26341,0.232539,0.24087,7103184885 1987-04-30,0.235485,0.298752,0.233119,0.296074,8120919764 1987-05-31,0.296898,0.307143,0.271142,0.295436,4575828554 1987-06-30,0.297507,0.323579,0.284378,0.302847,4168873386 1987-07-31,0.305025,0.334959,0.273261,0.308644,3659578687 1987-08-31,0.306651,0.406328,0.299038,0.404509,3718037610 1987-09-30,0.410201,0.440166,0.363191,0.423154,3665813122 1987-10-31,0.425135,0.447645,0.206997,0.289256,7837877283 1987-11-30,0.290284,0.299735,0.228299,0.24723,5046982962 1987-12-31,0.251057,0.327817,0.222865,0.31461,5604843968 1988-01-31,0.320261,0.346333,0.286399,0.311019,7415810231 1988-02-29,0.312768,0.327817,0.282847,0.322147,4015030353 1988-03-31,0.323873,0.357684,0.290284,0.299735,5819201654 1988-04-30,0.297831,0.317623,0.288312,0.307143,3930953600 1988-05-31,0.305327,0.32306,0.280139,0.311019,3144957771 1988-06-30,0.311019,0.350267,0.308859,0.346333,4213208097 1988-07-31,0.348206,0.355969,0.316437,0.332615,2606093158 1988-08-31,0.333224,0.3428,0.293916,0.298752,3162606145 1988-09-30,0.297831,0.33133,0.282847,0.323873,3647737748 1988-10-31,0.322147,0.323873,0.281062,0.289256,4247677271 1988-11-30,0.288312,0.297831,0.266039,0.28163,3504160411 1988-12-31,0.282847,0.31461,0.281062,0.301453,3511556656 1989-01-31,0.301453,0.329592,0.271437,0.282847,8755835706 1989-02-28,0.282847,0.301453,0.263998,0.271437,5824167867 1989-03-31,0.271437,0.273261,0.251057,0.266695,4600525785 1989-04-30,0.266039,0.311646,0.253782,0.292073,4727762278 1989-05-31,0.288312,0.367036,0.288312,0.357684,6261747220 1989-06-30,0.357684,0.37628,0.296074,0.308859,4697792092 1989-07-31,0.312768,0.31461,0.282847,0.297831,4396647707 1989-08-31,0.297831,0.3428,0.293916,0.333224,3995766847 1989-09-30,0.333224,0.350267,0.322147,0.333224,2408743025 1989-10-31,0.333224,0.377545,0.318179,0.348206,4916835931 1989-11-30,0.346333,0.353861,0.318179,0.33133,3009590783 1989-12-31,0.333224,0.3428,0.243334,0.263998,7081571617 1990-01-31,0.263998,0.290284,0.240557,0.254716,4466814138 1990-02-28,0.258246,0.263998,0.241539,0.254716,2960663748 1990-03-31,0.251057,0.325137,0.248995,0.301453,5431069926 1990-04-30,0.299735,0.33133,0.285516,0.295163,4341633168 1990-05-31,0.297831,0.320261,0.290284,0.308859,4905608473 1990-06-30,0.310096,0.336118,0.281062,0.335235,4710634822 1990-07-31,0.333224,0.357684,0.299735,0.31461,4963039455 1990-08-31,0.31461,0.327817,0.251057,0.277116,3728810702 1990-09-30,0.273261,0.281062,0.204124,0.217234,2630563334 1990-10-31,0.221157,0.239644,0.181527,0.23044,6026617280 1990-11-30,0.228299,0.288312,0.222865,0.275341,3879316425 1990-12-31,0.278923,0.338926,0.277116,0.322147,4879937056 1991-01-31,0.320261,0.419463,0.31461,0.415871,8388089151 1991-02-28,0.415871,0.4662,0.410201,0.428775,6610270280 1991-03-31,0.426961,0.526133,0.426961,0.509255,6210751281 1991-04-30,0.509255,0.5487,0.408052,0.412054,8633324914 1991-05-31,0.35958,0.402674,0.329592,0.352055,9503197246 1991-06-30,0.352055,0.370911,0.301453,0.311019,4877039796 1991-07-31,0.316437,0.361345,0.312768,0.346333,4509720404 1991-08-31,0.344576,0.415871,0.3428,0.397016,4973572319 1991-09-30,0.395219,0.400947,0.348206,0.370911,2852410275 1991-10-31,0.368931,0.421268,0.348206,0.385972,4283841905 1991-11-30,0.383738,0.413743,0.355969,0.380302,4405471781 1991-12-31,0.380302,0.434476,0.363191,0.422517,3107604937 1992-01-31,0.417747,0.51681,0.415871,0.485135,5605912010 1992-02-29,0.485135,0.524366,0.462636,0.505526,3021579113 1992-03-31,0.507393,0.512886,0.432671,0.436292,3558747873 1992-04-30,0.428775,0.458741,0.397016,0.450412,4686004391 1992-05-31,0.44947,0.473695,0.436292,0.447645,3222693486 1992-06-30,0.428775,0.44587,0.320261,0.35958,5782943401 1992-07-31,0.35958,0.370911,0.325961,0.350267,4330112371 1992-08-31,0.350267,0.353861,0.311019,0.344576,3273716539 1992-09-30,0.346333,0.374524,0.327817,0.338051,3642184150 1992-10-31,0.335235,0.404509,0.311019,0.393088,4209269957 1992-11-30,0.393088,0.44587,0.385972,0.430874,3726674987 1992-12-31,0.428775,0.458741,0.408052,0.447645,3974327206 1993-01-31,0.44587,0.488648,0.428775,0.44587,6606078518 1993-02-28,0.443738,0.460861,0.385972,0.397016,5544075680 1993-03-31,0.397016,0.432671,0.37628,0.385972,4364341173 1993-04-30,0.383738,0.393088,0.350267,0.383738,4665766205 1993-05-31,0.383738,0.442827,0.38202,0.423987,3814877032 1993-06-30,0.423154,0.436292,0.288312,0.296074,9147465339 1993-07-31,0.292073,0.297831,0.191211,0.207941,8513964313 1993-08-31,0.211474,0.23044,0.193861,0.198395,4390132989 1993-09-30,0.198395,0.202242,0.172284,0.175002,4372084169 1993-10-31,0.170507,0.241539,0.164838,0.23044,7038825325 1993-11-30,0.23044,0.262184,0.222865,0.236121,4114726976 1993-12-31,0.239644,0.243334,0.198395,0.219019,4716495548 1994-01-31,0.221157,0.263998,0.215458,0.245334,8739388938 1994-02-28,0.24723,0.286399,0.241539,0.273261,5106843523 1994-03-31,0.275341,0.288312,0.236121,0.248995,6267234159 1994-04-30,0.241539,0.256443,0.202242,0.224709,4818007122 1994-05-31,0.224709,0.25288,0.213287,0.219019,4006913953 1994-06-30,0.213287,0.214545,0.184557,0.198395,5568519058 1994-07-31,0.197431,0.254716,0.189926,0.25231,5778631589 1994-08-31,0.251675,0.280139,0.240557,0.270836,5453030219 1994-09-30,0.265088,0.278923,0.2502,0.25231,3853137533 1994-10-31,0.251675,0.327817,0.243334,0.323382,9194056216 1994-11-30,0.321184,0.3257,0.27272,0.278923,4826124109 1994-12-31,0.277116,0.298752,0.260367,0.292073,4514846679 1995-01-31,0.291148,0.360168,0.283769,0.302598,9728782184 1995-02-28,0.305327,0.333224,0.284673,0.296074,6316534775 1995-03-31,0.297831,0.305327,0.253782,0.263998,8340216669 1995-04-30,0.266039,0.296594,0.251675,0.286399,6763459312 1995-05-31,0.286399,0.332615,0.281062,0.311343,7610183237 1995-06-30,0.313724,0.375407,0.311019,0.347883,6581861955 1995-07-31,0.348206,0.373669,0.322147,0.337062,6793589627 1995-08-31,0.336118,0.346333,0.313724,0.322147,6308872039 1995-09-30,0.322147,0.340984,0.260367,0.278923,8714891913 1995-10-31,0.282847,0.29634,0.251675,0.272084,7745870557 1995-11-30,0.274162,0.318179,0.266039,0.285516,5797975452 1995-12-31,0.284673,0.30051,0.237083,0.238839,7819454684 1996-01-31,0.241539,0.266039,0.200983,0.206997,12277297753 1996-02-29,0.206077,0.226553,0.204124,0.206077,5545050440 1996-03-31,0.206997,0.206997,0.172284,0.18398,3989145376 1996-04-30,0.188208,0.198395,0.177974,0.182448,3417400413 1996-05-31,0.182448,0.216369,0.176197,0.195658,4295656321 1996-06-30,0.193861,0.194755,0.147076,0.15734,5571082183 1996-07-31,0.158221,0.170507,0.119886,0.164838,5725499461 1996-08-31,0.164838,0.187227,0.155513,0.181527,3799177849 1996-09-30,0.180701,0.184557,0.15163,0.165973,3830376180 1996-10-31,0.164838,0.207941,0.164838,0.172284,6933522364 1996-11-30,0.175002,0.197431,0.173184,0.180701,3076847003 1996-12-31,0.180701,0.191211,0.155513,0.156437,4943575191 1997-01-31,0.158221,0.166533,0.123487,0.124704,10814213688 1997-02-28,0.12644,0.133899,0.113242,0.121593,5452162436 1997-03-31,0.123487,0.145065,0.118964,0.136625,5366430227 1997-04-30,0.13216,0.148892,0.125537,0.127284,4540985576 1997-05-31,0.12644,0.13487,0.122545,0.124704,2732782870 1997-06-30,0.127284,0.128196,0.104864,0.10666,3066047250 1997-07-31,0.104265,0.135742,0.0955813,0.131259,8084221149 1997-08-31,0.13216,0.221452,0.131503,0.163021,21068483935 1997-09-30,0.164838,0.174048,0.15734,0.16243,4298246419 1997-10-31,0.16243,0.18554,0.118964,0.127609,7664263332 1997-11-30,0.131503,0.161155,0.12644,0.133016,6612299604 1997-12-31,0.132417,0.134544,0.0955813,0.0982793,6076292039 1998-01-31,0.10186,0.149833,0.101273,0.137262,12171647389 1998-02-28,0.138423,0.178917,0.130051,0.177141,8765768212 1998-03-31,0.176465,0.209794,0.162089,0.206077,12665589834 1998-04-30,0.205538,0.222022,0.184903,0.204996,9633171077 1998-05-31,0.206077,0.237083,0.192142,0.199521,8109211839 1998-06-30,0.198395,0.217234,0.192142,0.214858,4660319355 1998-07-31,0.216369,0.285516,0.213287,0.259209,13025179942 1998-08-31,0.256443,0.327817,0.232229,0.233414,15758563619 1998-09-30,0.234895,0.300882,0.22947,0.285516,9631302111 1998-10-31,0.275341,0.309496,0.213287,0.278058,15412963692 1998-11-30,0.281062,0.295163,0.237879,0.239391,12066691580 1998-12-31,0.239644,0.311019,0.237083,0.306651,15404834262 1999-01-31,0.315543,0.354449,0.277745,0.308301,18031045489 1999-02-28,0.312224,0.314022,0.258246,0.260956,9674448683 1999-03-31,0.260956,0.278058,0.239644,0.269081,11862239362 1999-04-30,0.27021,0.352958,0.251057,0.344576,18938791411 1999-05-31,0.345096,0.374524,0.306651,0.330144,10618932900 1999-06-30,0.337062,0.367036,0.315167,0.34697,8246621395 1999-07-31,0.34697,0.423987,0.338367,0.417109,13667545388 1999-08-31,0.41648,0.493458,0.390408,0.488648,11019066173 1999-09-30,0.501797,0.600117,0.430296,0.474254,22608195826 1999-10-31,0.465317,0.607376,0.44587,0.600117,17245663851 1999-11-30,0.599233,0.777129,0.579019,0.733171,10001705280 1999-12-31,0.756525,0.883884,0.682343,0.770063,11226001726 2000-01-31,0.785568,0.910184,0.647902,0.777129,14965091831 2000-02-29,0.778895,0.898309,0.726596,0.858865,8724784413 2000-03-31,0.888105,1.12626,0.853958,1.01712,10367970304 2000-04-30,1.01517,1.0449,0.785568,0.929513,10325117432 2000-05-31,0.935499,0.945703,0.61248,0.629256,11690307256 2000-06-30,0.61248,0.863378,0.602079,0.784685,9660965243 2000-07-31,0.780661,0.908025,0.70236,0.761333,6849839282 2000-08-31,0.753875,0.921371,0.66262,0.91293,6717909827 2000-09-30,0.918721,0.960618,0.380302,0.385972,17303394537 2000-10-31,0.400043,0.400947,0.262184,0.293054,26110514145 2000-11-30,0.291148,0.344576,0.241539,0.24723,10117681516 2000-12-31,0.254716,0.262184,0.204124,0.222865,10559412760 2001-01-31,0.222865,0.337062,0.216369,0.323873,16340935114 2001-02-28,0.310096,0.328749,0.269699,0.273261,8371949043 2001-03-31,0.266695,0.355969,0.2577,0.330762,12871897672 2001-04-30,0.330762,0.406328,0.281062,0.381735,13300913094 2001-05-31,0.380852,0.400043,0.289256,0.298752,8901969184 2001-06-30,0.301453,0.376063,0.290061,0.348206,9104398987 2001-07-31,0.354192,0.377811,0.267618,0.281376,10316413368 2001-08-31,0.284939,0.298145,0.258896,0.278058,6113918431 2001-09-30,0.277116,0.285831,0.219892,0.232229,6593276105 2001-10-31,0.232229,0.290853,0.222287,0.263095,8992334162 2001-11-30,0.264187,0.32306,0.258246,0.319113,6400445079 2001-12-31,0.315543,0.360168,0.300882,0.328141,5518517608 2002-01-31,0.330455,0.370599,0.303128,0.370295,10149868160 2002-02-28,0.378241,0.389163,0.313724,0.325137,9341784945 2002-03-31,0.328405,0.379025,0.326904,0.354743,6339462922 2002-04-30,0.350267,0.392155,0.344576,0.363504,7655672566 2002-05-31,0.363771,0.389163,0.331694,0.349071,7123256312 2002-06-30,0.350582,0.351181,0.239391,0.265421,10379484515 2002-07-31,0.265421,0.281376,0.206705,0.228588,9676711462 2002-08-31,0.22629,0.243334,0.209482,0.221157,6140531139 2002-09-30,0.217234,0.227446,0.21069,0.217234,6307583762 2002-10-31,0.218422,0.246279,0.200112,0.24087,7880469908 2002-11-30,0.238839,0.260367,0.224709,0.232229,5401566468 2002-12-31,0.238163,0.241213,0.206391,0.214858,5400038189 2003-01-31,0.215153,0.23044,0.203172,0.215153,7206305379 2003-02-28,0.216075,0.229176,0.206705,0.224709,4904026697 2003-03-31,0.224709,0.227155,0.210394,0.211788,4801640430 2003-04-30,0.2127,0.223788,0.190585,0.212995,9294473015 2003-05-31,0.213287,0.284673,0.209794,0.268816,12907946935 2003-06-30,0.271142,0.295163,0.248995,0.285516,7293728970 2003-07-31,0.282847,0.323382,0.277422,0.315856,6211117287 2003-08-31,0.31461,0.342459,0.290853,0.338647,5134209626 2003-09-30,0.339463,0.349364,0.301725,0.310441,6382207532 2003-10-31,0.310441,0.374786,0.302598,0.343094,8393833039 2003-11-30,0.341868,0.349071,0.297507,0.313405,5935600983 2003-12-31,0.315167,0.328141,0.288312,0.320261,6519614734 2004-01-31,0.32306,0.372121,0.317326,0.338051,9449443216 2004-02-29,0.336413,0.361051,0.325137,0.358295,5866767898 2004-03-31,0.360796,0.421546,0.353565,0.405137,13834111688 2004-04-30,0.402969,0.443151,0.381735,0.38623,10634169448 2004-05-31,0.389459,0.431191,0.38202,0.420337,6321572873 2004-06-30,0.416197,0.511906,0.413499,0.487483,9807083216 2004-07-31,0.480622,0.50376,0.430571,0.48452,11559821077 2004-08-31,0.468033,0.527116,0.444977,0.51681,9551374432 2004-09-30,0.513768,0.588538,0.511906,0.580689,9150485219 2004-10-31,0.585986,0.797146,0.564007,0.784977,19216868345 2004-11-30,0.786549,1.04208,0.779486,1.00449,20796783804 2004-12-31,1.00449,1.0181,0.922939,0.96484,19056902696 2005-01-31,0.971607,1.16706,0.93795,1.15208,30731852420 2005-02-28,1.1542,1.36146,1.14724,1.34417,25597712918 2005-03-31,1.35115,1.35154,1.16354,1.24852,17513657697 2005-04-30,1.26128,1.33193,1.0186,1.08032,23182471459 2005-05-31,1.08611,1.22663,0.992012,1.19139,15383838326 2005-06-30,1.19553,1.22132,1.06424,1.10289,13549750398 2005-07-31,1.10358,1.32986,1.08738,1.27774,12152221168 2005-08-31,1.27629,1.44808,1.25911,1.40501,11264257521 2005-09-30,1.40827,1.63491,1.38096,1.60626,14701429244 2005-10-31,1.62285,1.73716,1.43425,1.72568,22208111485 2005-11-30,1.71567,2.12916,1.70409,2.0323,16020828954 2005-12-31,2.06401,2.26154,2.06157,2.15408,15537600631 2006-01-31,2.16967,2.58896,2.12308,2.263,26044989105 2006-02-28,2.24699,2.29048,1.88464,2.05214,22337478686 2006-03-31,2.06735,2.09736,1.72794,1.87933,27612054244 2006-04-30,1.9074,2.1589,1.8293,2.10904,23955626347 2006-05-31,2.12033,2.21157,1.75856,1.79091,18585373047 2006-06-30,1.79328,1.89063,1.66033,1.71597,21366060870 2006-07-31,1.71821,2.05615,1.50284,2.03654,20831299325 2006-08-31,2.01418,2.09754,1.87514,2.03329,21309071388 2006-09-30,2.05155,2.3308,2.0323,2.30667,21120953745 2006-10-31,2.24729,2.47525,2.17518,2.42972,17122521177 2006-11-30,2.43039,2.79091,2.33099,2.74705,16479042128 2006-12-31,2.75125,2.76638,2.30069,2.54178,20134641883 2007-01-31,2.58525,2.93054,2.45334,2.56855,32372050891 2007-02-28,2.5809,2.72132,2.48308,2.53473,16352728960 2007-03-31,2.51675,2.90118,2.50888,2.78394,18972006272 2007-04-30,2.82063,3.07143,2.68492,2.99038,16046928700 2007-05-31,2.98381,3.65929,2.95339,3.63132,20696493229 2007-06-30,3.62836,3.82315,3.45724,3.65614,27740130698 2007-07-31,3.62895,4.4619,3.57402,3.94796,28606951859 2007-08-31,4.00389,4.1855,3.34459,4.14842,28986221873 2007-09-30,4.19463,4.64392,3.89459,4.59802,24899675709 2007-10-31,4.63302,5.6967,4.58271,5.69176,27617325593 2007-11-30,5.65098,5.77295,4.51373,5.45962,31190780241 2007-12-31,5.44688,6.08151,5.30379,5.93563,20529266689 2008-01-31,5.97732,6.00029,3.77938,4.05638,41833316396 2008-02-29,4.08346,4.092,3.4587,3.74573,29571175638 2008-03-31,3.72739,4.36684,3.53565,4.29981,27317913051 2008-04-30,4.38352,5.39331,4.30346,5.21176,27131589321 2008-05-31,5.24236,5.76008,5.15389,5.65546,21586137512 2008-06-30,5.64831,5.69176,4.919,5.01767,23194092920 2008-07-31,4.91572,5.42065,4.39088,4.76266,23411435638 2008-08-31,4.79231,5.40753,4.58231,5.0791,15588551166 2008-09-30,5.17017,5.19834,3.01424,3.40545,28663321745 2008-10-31,3.35205,3.48786,2.54716,3.2242,49170679109 2008-11-30,3.17356,3.3494,2.37173,2.77647,28147830190 2008-12-31,2.73625,3.10441,2.53314,2.55768,24085750327 2009-01-31,2.56425,2.91051,2.34318,2.70063,21464851190 2009-02-28,2.66695,3.08644,2.59258,2.67638,16242109862 2009-03-31,2.63704,3.29515,2.46671,3.14973,18368096258 2009-04-30,3.11784,3.81187,3.11285,3.76967,14049133632 2009-05-31,3.76967,4.07208,3.57615,4.06914,11249060888 2009-06-30,4.08543,4.38647,3.9815,4.26756,15067366372 2009-07-31,4.30021,4.94339,4.02723,4.89562,12992000040 2009-08-31,4.94784,5.1682,4.7769,5.04033,9709232726 2009-09-30,5.03408,5.6599,4.918,5.55355,11873467101 2009-10-31,5.55773,6.25412,5.41458,5.64831,15367372260 2009-11-30,5.68787,6.23176,5.56071,5.98949,10040753042 2009-12-31,6.05995,6.41045,5.65351,6.31378,13542770491 2010-01-31,6.397,6.45997,5.70012,5.75441,18013475455 2010-02-28,5.77048,6.14738,5.71859,6.13079,12810149755 2010-03-31,6.16453,7.11595,6.1562,7.04146,14446436390 2010-04-30,7.12083,8.16388,6.97425,7.82321,14694246398 2010-05-31,7.92271,8.0267,5.96995,7.69653,21508043226 2010-06-30,7.78159,8.36011,7.25685,7.53661,19806668164 2010-07-31,7.61392,7.97089,7.17963,7.708,18623949350 2010-08-31,7.80339,7.91897,7.05844,7.2841,11407547064 2010-09-30,7.4162,8.83025,7.37979,8.5019,14100129562 2010-10-31,8.57903,9.55813,8.32262,9.01823,14487323484 2010-11-30,9.06788,9.62678,8.92149,9.3236,11301133269 2010-12-31,9.45803,9.7877,9.43644,9.66507,8290499932 2011-01-31,9.73177,10.4441,9.73177,10.1666,12874274689 2011-02-28,10.2342,10.9339,10.1183,10.5835,11051552507 2011-03-31,10.6444,10.8366,9.77496,10.4411,13455367860 2011-04-30,10.5198,10.6405,9.59343,10.4904,10988962127 2011-05-31,10.4775,10.5412,9.87011,10.4227,8230162120 2011-06-30,10.4588,10.5501,9.30397,10.0576,11022743379 2011-07-31,10.0664,12.1191,10.0142,11.7002,12663159881 2011-08-31,11.9245,11.9701,10.5775,11.5313,19161429140 2011-09-30,11.5628,12.6714,10.981,11.4244,14251029353 2011-10-31,11.3976,12.7844,10.6139,12.128,15621544642 2011-11-30,11.911,12.2242,10.8866,11.4521,10675468075 2011-12-31,11.4586,12.2584,11.3162,12.1336,7501671092 2012-01-31,12.2809,13.7302,12.2554,13.6782,8168897994 2012-02-29,13.736,16.409,13.6028,16.254,13540787505 2012-03-31,16.4209,18.6206,15.467,17.9634,18395606289 2012-04-30,18.0311,19.2948,16.6288,17.4972,18355537471 2012-05-31,17.5256,17.8811,15.6467,17.3087,13094617612 2012-06-30,17.0537,17.6785,16.4335,17.4982,9299053850 2012-07-31,17.5199,18.5737,17.0802,18.3019,10610975908 2012-08-31,18.4547,20.4889,17.9846,20.0172,9820121992 2012-09-30,20.0317,21.215,19.7401,20.074,10911366997 2012-10-31,20.1965,20.3664,17.6865,17.9151,14403684694 2012-11-30,18.0015,18.1438,15.2875,17.6943,15279464548 2012-12-31,17.9447,17.9733,15.1511,16.0862,14320387032 2013-01-31,16.7406,16.776,13.1493,13.7686,15489711916 2013-02-28,13.8782,14.7429,13.3075,13.4212,10981713381 2013-03-31,13.3184,14.2887,12.7391,13.4584,10777498873 2013-04-30,13.4437,13.537,11.7089,13.4613,12868719855 2013-05-31,13.5125,14.1709,12.8196,13.7646,11044116019 2013-06-30,13.7949,13.9089,11.9721,12.2074,8191728624 2013-07-31,12.3252,13.9992,12.2799,13.8502,7627195390 2013-08-31,13.9452,15.8261,13.8724,15.0972,9344635842 2013-09-30,15.1922,15.6496,13.7785,14.7734,9997324367 2013-10-31,14.739,16.6141,14.7341,16.198,9069046000 2013-11-30,16.1559,17.3009,15.8781,17.2323,6023067422 2013-12-31,17.2913,17.8229,16.6955,17.3832,8126578732 2014-01-31,17.2197,17.359,15.2944,15.5123,10143776532 2014-02-28,15.576,17.1831,15.4719,16.4061,6755383616 2014-03-31,16.3051,17.1146,16.3002,16.7308,5735388669 2014-04-30,16.7632,18.6855,15.94,18.3952,7366175347 2014-05-31,18.4547,20.1946,18.1918,19.8442,6540292887 2014-06-30,19.8736,20.8589,19.5146,20.3916,5498293091 2014-07-31,20.5214,21.8216,20.3142,20.9794,4714035508 2014-08-31,20.8244,22.6939,20.5692,22.6044,4229103190 2014-09-30,22.728,22.877,21.1993,22.2207,6917969202 2014-10-31,22.1845,23.8259,20.9913,23.8163,6164857123 2014-11-30,23.8694,26.5156,23.7564,26.3458,3704880402 2014-12-31,26.3134,26.4127,23.5355,24.4511,4845351510 2015-01-31,24.669,26.5734,23.1725,25.9524,6189050876 2015-02-28,26.1476,29.7055,25.7103,28.5616,5110327728 2015-03-31,28.74,28.9726,27.0426,27.6666,5120836442 2015-04-30,27.7521,29.9196,27.3693,27.8268,4479115208 2015-05-31,28.0385,29.6879,27.4341,29.0835,4275091887 2015-06-30,29.2985,29.3413,27.7941,28.0041,3934273376 2015-07-31,28.3338,29.6879,26.6187,27.0819,4739417348 2015-08-31,27.128,27.3674,20.6341,25.2898,7171084452 2015-09-30,24.7082,26.2184,24.0772,24.7426,5378708033 2015-10-31,24.4669,27.1888,24.0654,26.805,4965067772 2015-11-30,26.8885,27.7685,25.0026,26.6501,3334476388 2015-12-31,26.7522,26.9993,23.6101,23.7143,4073218711 2016-01-31,23.1136,23.8448,20.8118,21.9244,5409657478 2016-02-29,21.7302,22.3974,20.9708,21.8971,3382546543 2016-03-31,22.1147,25.0084,22.0628,24.6835,3197140451 2016-04-30,24.6345,25.4548,20.9531,21.2289,3595797581 2016-05-31,21.2798,22.9536,20.3866,22.7535,3764647523 2016-06-30,22.5613,23.215,20.8491,21.784,3151075588 2016-07-31,21.7586,23.824,21.5035,23.7466,2770818827 2016-08-31,23.7917,25.2529,23.7006,24.3098,2536591184 2016-09-30,24.3195,26.6157,23.4885,25.8966,4005988532 2016-10-31,25.8207,27.1918,25.7237,26.0094,2833709438 2016-11-30,25.9896,26.0663,23.9624,25.4489,3023559739 2016-12-31,25.4128,27.176,24.9291,26.6695,2497119091 2017-01-31,26.6648,28.1945,26.4187,27.9451,2292208017 2017-02-28,29.2491,31.7919,29.2432,31.6818,2353440288 2017-03-31,31.8898,33.4185,31.6975,33.2221,2326608907 2017-04-30,33.2341,33.6393,32.3902,33.2202,1572163094 2017-05-31,33.5558,36.379,33.3645,35.4713,2813598702 2017-06-30,35.5705,36.2229,33.0212,33.4459,2939683092 2017-07-31,33.6413,35.7576,33.0713,34.5352,1807554348 2017-08-31,34.6236,38.3512,34.4635,38.2315,2820357979 2017-09-30,38.417,38.4511,34.7747,35.9283,2908451188 2017-10-31,35.9618,39.5482,35.5437,39.413,2160269780 2017-11-30,39.6024,41.0887,38.5326,40.2057,2564997421 2017-12-31,39.7613,41.4547,38.941,39.5945,2261010758 2018-01-31,39.813,42.1396,38.5346,39.1756,2809496905 2018-02-28,39.1144,42.4321,35.2958,41.8502,3939857535 2018-03-31,41.9463,43.1122,38.7533,39.4197,3038083568 2018-04-30,39.444,42.0386,37.735,38.8261,2836292732 2018-05-31,39.095,44.8223,38.829,44.0687,2638556570 2018-06-30,44.3317,45.8005,42.6194,43.6557,2237281811 2018-07-31,43.3494,46.2158,43.2571,44.8755,1670013404 2018-08-31,46.9632,54.1656,46.5287,53.87,2963043934 2018-09-30,54.0594,54.3549,50.9521,53.4248,2868978527 2018-10-31,53.9486,55.2538,48.7737,51.7969,3337059755 2018-11-30,51.8401,52.6212,40.4342,42.4095,4052047168 2018-12-31,43.8058,43.9206,34.8138,37.4622,3785143305 2019-01-31,36.787,40.1351,33.7227,39.5286,3486944907 2019-02-28,39.652,41.9493,39.4081,41.2987,1984150117 2019-03-31,41.5646,47.1478,40.4266,45.3021,2729434466 2019-04-30,45.7073,49.7207,44.9323,47.8601,2122050506 2019-05-31,50.0572,51.3533,41.8993,41.9169,3092523335 2019-06-30,42.0456,48.2616,40.766,47.3853,2151922060 2019-07-31,48.6412,53.0029,47.5039,51.006,1979583896 2019-08-31,51.2119,52.2012,46.1079,50.17,2847893825 2019-09-30,49.6118,54.4177,49.0838,53.8262,2277715241 2019-10-31,54.0949,60.0215,51.7046,59.785,2590795161 2019-11-30,59.9715,64.6036,59.8812,64.422,1863207262 2019-12-31,64.427,70.861,61.7771,70.7826,2484388551 2020-01-31,71.4084,79.0288,70.5707,74.6123,3049164891 2020-02-29,73.3544,79.066,61.9456,66.05,3126901985 2020-03-31,68.2039,73.4525,51.3729,61.4412,6499020139 2020-04-30,59.5612,71.1644,57.2397,70.9896,3379317891 2020-05-31,69.1665,78.5578,69.0695,77.0312,2898248018 2020-06-30,76.9849,90.2217,76.8535,88.3818,3346957588 2020-07-31,88.46,103.135,86.394,102.988,3116698381 2020-08-31,104.844,127.167,104.548,125.283,4193977491 2020-09-30,128.892,133.959,100.102,112.428,4003423393 2020-10-31,114.206,121.731,104.568,105.688,2982196846 2020-11-30,105.934,118.64,104.189,115.786,2184199594 2020-12-31,117.688,134.979,116.726,129.05,2388349981 2021-01-31,129.855,141.099,122.918,128.334,2304143402 2021-02-28,130.08,134.29,115.313,118.101,1883546382 2021-03-31,120.534,125.372,113.182,118.974,2721619213 2021-04-30,120.445,133.514,119.295,128.041,1940415986 2021-05-31,128.609,130.583,119.265,121.574,1755313599 2021-06-30,122.034,134.066,120.131,133.631,1646686782 2021-07-31,133.281,146.349,132.455,142.309,1967024892 2021-08-31,142.797,149.979,141.196,148.36,1497932324 2021-09-30,149.343,153.659,138.027,138.255,1840064200 2021-10-31,138.645,149.666,135.105,146.368,1601739999 2021-11-30,145.575,162.148,144.309,161.754,1728503686 2021-12-31,163.884,178.22,154.415,173.755,2499267622 2022-01-31,174.009,179.012,151.375,171.027,2155545935 2022-02-28,170.281,173.077,148.929,161.784,1663230255 2022-03-31,161.362,175.981,147.066,171.076,2225879599 2022-04-30,170.507,174.883,152.238,154.464,1722698311 2022-05-31,153.54,163.118,130.119,146.045,2447659807 2022-06-30,147.086,148.892,126.617,134.153,1782771066 2022-07-31,133.484,160.557,133.114,159.46,1475060233 2022-08-31,157.988,173.082,154.403,154.482,1537465785 2022-09-30,153.915,161.398,135.597,135.793,2121720539 2022-10-31,135.803,154.757,132.029,150.67,1901491855 2022-11-30,152.379,152.742,132.26,145.693,1753067836 2022-12-31,145.872,148.539,123.883,127.88,1702603396 2023-01-31,128.223,144.905,122.211,142.013,1466803193 2023-02-28,141.698,154.897,139.09,145.305,1327199418 2023-03-31,144.733,162.644,141.843,162.546,1542488384 2023-04-30,161.923,167.424,157.499,167.256,983825606 2023-05-31,166.863,177.033,161.963,174.96,1292845762 2023-06-30,175.405,191.968,174.646,191.463,1314846971 2023-07-31,191.277,195.672,184.19,193.913,1009406878 2023-08-31,193.7,194.191,169.968,185.695,1340075610 2023-09-30,187.291,187.778,165.679,169.228,1353553147 2023-10-31,169.238,180.228,163.751,168.791,1186591069 2023-11-30,169.019,190.947,168.149,187.997,1111786637 2023-12-31,188.374,197.567,185.523,190.551,1074225940 2024-01-31,185.224,194.36,178.316,182.503,1199826844 2024-02-29,182.094,189.087,177.408,179.118,1172767124 2024-03-31,177.932,178.902,166.97,169.933,1446194592 2024-04-30,169.645,176.751,162.595,168.793,1257178117 2024-05-31,168.05,191.519,167.585,190.774,1347669466 2024-06-30,191.419,218.511,190.675,209.002,1737317679 2024-07-31,210.463,235.41,210.293,220.375,1162112141 2024-08-31,222.649,231.399,194.495,227.505,1130636045 2024-09-30,227.059,231.568,212.523,231.479,1240487324 2024-10-31,228.023,235.94,219.886,224.436,936950525 2024-11-30,219.523,236.519,218.277,236.041,896771460 2024-12-31,235.981,258.687,235.872,249.059,983284200 2025-01-31,247.577,247.746,218.188,234.717,1206848423 2025-02-28,228.74,248.915,224.474,240.79,866326500 2025-03-31,240.74,242.969,207.516,221.166,1120167030 2025-04-30,218.851,224.212,168.475,211.578,1614323863 2025-05-31,208.172,213.629,192.411,200.241,1200099822 2025-06-30,199.672,206.761,194.478,204.548,1103853333 2025-07-31,206.038,215.574,205.515,206.94,1083222185 2025-08-31,210.225,234.672,200.889,231.698,1221056756 2025-09-30,228.814,257.11,225.52,254.145,1267948554 2025-10-31,254.555,276.792,243.536,269.855,1099233514 2025-11-30,269.905,280.118,265.072,278.589,878634775 2025-12-31,277.75,288.35,266.7,271.606,925394100 2026-01-31,272,277.58,243.192,259.237,1040990432 2026-02-28,259.787,280.642,255.45,264.18,988944026 2026-03-31,262.41,266.53,245.51,253.79,900035758 2026-04-30,254.08,275.77,245.7,270.71,785642376 ======================================================================================== FICHEIRO: dados_csv/cache/debug_pplx.php Tamanho: 1516 bytes ======================================================================================== true, 'php_sapi' => PHP_SAPI, 'vars' => [ 'PPLXAPIKEY' => [ 'set' => is_string($k1) && trim($k1) !== '', 'mask' => mask_key($k1), ], 'PPLX_API_KEY' => [ 'set' => is_string($k2) && trim($k2) !== '', 'mask' => mask_key($k2), ], 'PERPLEXITY_API_KEY' => [ 'set' => is_string($k3) && trim($k3) !== '', 'mask' => mask_key($k3), ], ], 'chosen_env' => $chosenName, 'chosen_mask' => mask_key($chosen), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ======================================================================================== FICHEIRO: dados_csv/cache/hpm_aapl.us_m.json Tamanho: 14133 bytes ======================================================================================== { "ts": "2025-12-26 15:30:57", "data": { "1984-09": 0.0941941, "1984-10": 0.0932972, "1984-11": 0.0926865, "1984-12": 0.109243, "1985-01": 0.108938, "1985-02": 0.0926865, "1985-03": 0.083058, "1985-04": 0.0797468, "1985-05": 0.0652894, "1985-06": 0.0677138, "1985-07": 0.0595734, "1985-08": 0.0562721, "1985-09": 0.0592878, "1985-10": 0.0698227, "1985-11": 0.0755289, "1985-12": 0.0824471, "1986-01": 0.0866846, "1986-02": 0.0939084, "1986-03": 0.105932, "1986-04": 0.113482, "1986-05": 0.138727, "1986-06": 0.134482, "1986-07": 0.117333, "1986-08": 0.138727, "1986-09": 0.125542, "1986-10": 0.130027, "1986-11": 0.150171, "1986-12": 0.151995, "1987-01": 0.208257, "1987-02": 0.26243, "1987-03": 0.24192, "1987-04": 0.297364, "1987-05": 0.296724, "1987-06": 0.304166, "1987-07": 0.309989, "1987-08": 0.406272, "1987-09": 0.424999, "1987-10": 0.290517, "1987-11": 0.248307, "1987-12": 0.315981, "1988-01": 0.312375, "1988-02": 0.323551, "1988-03": 0.301041, "1988-04": 0.308481, "1988-05": 0.312375, "1988-06": 0.347843, "1988-07": 0.334065, "1988-08": 0.300055, "1988-09": 0.325284, "1988-10": 0.290517, "1988-11": 0.282857, "1988-12": 0.302767, "1989-01": 0.28408, "1989-02": 0.27262, "1989-03": 0.267858, "1989-04": 0.293345, "1989-05": 0.359243, "1989-06": 0.310205, "1989-07": 0.29913, "1989-08": 0.334676, "1989-09": 0.334676, "1989-10": 0.349724, "1989-11": 0.332774, "1989-12": 0.265148, "1990-01": 0.255826, "1990-02": 0.255826, "1990-03": 0.302767, "1990-04": 0.296449, "1990-05": 0.310205, "1990-06": 0.336696, "1990-07": 0.315981, "1990-08": 0.278324, "1990-09": 0.218181, "1990-10": 0.231445, "1990-11": 0.276541, "1990-12": 0.323551, "1991-01": 0.417684, "1991-02": 0.430644, "1991-03": 0.511475, "1991-04": 0.413851, "1991-05": 0.353589, "1991-06": 0.312375, "1991-07": 0.347843, "1991-08": 0.398745, "1991-09": 0.372528, "1991-10": 0.387655, "1991-11": 0.381959, "1991-12": 0.424358, "1992-01": 0.48725, "1992-02": 0.50773, "1992-03": 0.438193, "1992-04": 0.452374, "1992-05": 0.449596, "1992-06": 0.361147, "1992-07": 0.351794, "1992-08": 0.346077, "1992-09": 0.339524, "1992-10": 0.394801, "1992-11": 0.432752, "1992-12": 0.449596, "1993-01": 0.447813, "1993-02": 0.398745, "1993-03": 0.387655, "1993-04": 0.38541, "1993-05": 0.425835, "1993-06": 0.297364, "1993-07": 0.208848, "1993-08": 0.199261, "1993-09": 0.175765, "1993-10": 0.231445, "1993-11": 0.23715, "1993-12": 0.219974, "1994-01": 0.246404, "1994-02": 0.274452, "1994-03": 0.250081, "1994-04": 0.225689, "1994-05": 0.219974, "1994-06": 0.199261, "1994-07": 0.25341, "1994-08": 0.272016, "1994-09": 0.25341, "1994-10": 0.324792, "1994-11": 0.280139, "1994-12": 0.293345, "1995-01": 0.303917, "1995-02": 0.297364, "1995-03": 0.265148, "1995-04": 0.287648, "1995-05": 0.3127, "1995-06": 0.349401, "1995-07": 0.33853, "1995-08": 0.323551, "1995-09": 0.280139, "1995-10": 0.27327, "1995-11": 0.286761, "1995-12": 0.23988, "1996-01": 0.207899, "1996-02": 0.206975, "1996-03": 0.184782, "1996-04": 0.183243, "1996-05": 0.19651, "1996-06": 0.158026, "1996-07": 0.165556, "1996-08": 0.182318, "1996-09": 0.166696, "1996-10": 0.173035, "1996-11": 0.181488, "1996-12": 0.157119, "1997-01": 0.125248, "1997-02": 0.122123, "1997-03": 0.137221, "1997-04": 0.127839, "1997-05": 0.125248, "1997-06": 0.107124, "1997-07": 0.131831, "1997-08": 0.163731, "1997-09": 0.163139, "1997-10": 0.128165, "1997-11": 0.133595, "1997-12": 0.0987078, "1998-01": 0.13786, "1998-02": 0.177913, "1998-03": 0.206975, "1998-04": 0.20589, "1998-05": 0.200391, "1998-06": 0.215794, "1998-07": 0.26034, "1998-08": 0.23443, "1998-09": 0.286761, "1998-10": 0.27927, "1998-11": 0.240434, "1998-12": 0.307988, "1999-01": 0.309645, "1999-02": 0.262093, "1999-03": 0.270254, "1999-04": 0.346077, "1999-05": 0.331582, "1999-06": 0.348483, "1999-07": 0.418927, "1999-08": 0.490778, "1999-09": 0.476321, "1999-10": 0.602732, "1999-11": 0.736366, "1999-12": 0.77342, "2000-01": 0.780516, "2000-02": 0.862609, "2000-03": 1.02156, "2000-04": 0.933565, "2000-05": 0.632, "2000-06": 0.788104, "2000-07": 0.764651, "2000-08": 0.916909, "2000-09": 0.387655, "2000-10": 0.29433, "2000-11": 0.248307, "2000-12": 0.223836, "2001-01": 0.325284, "2001-02": 0.274452, "2001-03": 0.332204, "2001-04": 0.383398, "2001-05": 0.300055, "2001-06": 0.349724, "2001-07": 0.282602, "2001-08": 0.27927, "2001-09": 0.23324, "2001-10": 0.264241, "2001-11": 0.320505, "2001-12": 0.329571, "2002-01": 0.371908, "2002-02": 0.326554, "2002-03": 0.356289, "2002-04": 0.365088, "2002-05": 0.350593, "2002-06": 0.266578, "2002-07": 0.229585, "2002-08": 0.222121, "2002-09": 0.218181, "2002-10": 0.24192, "2002-11": 0.23324, "2002-12": 0.215794, "2003-01": 0.216091, "2003-02": 0.225689, "2003-03": 0.212711, "2003-04": 0.213923, "2003-05": 0.269989, "2003-06": 0.286761, "2003-07": 0.317232, "2003-08": 0.340123, "2003-09": 0.311793, "2003-10": 0.344589, "2003-11": 0.31477, "2003-12": 0.321657, "2004-01": 0.339524, "2004-02": 0.359856, "2004-03": 0.406903, "2004-04": 0.387913, "2004-05": 0.422169, "2004-06": 0.489607, "2004-07": 0.486631, "2004-08": 0.519063, "2004-09": 0.583219, "2004-10": 0.7884, "2004-11": 1.00886, "2004-12": 0.969045, "2005-01": 1.15711, "2005-02": 1.35003, "2005-03": 1.25396, "2005-04": 1.08503, "2005-05": 1.19658, "2005-06": 1.10769, "2005-07": 1.28331, "2005-08": 1.41113, "2005-09": 1.61326, "2005-10": 1.73319, "2005-11": 2.04115, "2005-12": 2.16347, "2006-01": 2.27287, "2006-02": 2.06108, "2006-03": 1.88752, "2006-04": 2.11823, "2006-05": 1.79873, "2006-06": 1.72345, "2006-07": 2.04543, "2006-08": 2.04214, "2006-09": 2.31672, "2006-10": 2.44031, "2006-11": 2.75902, "2006-12": 2.55286, "2007-01": 2.57974, "2007-02": 2.54577, "2007-03": 2.79607, "2007-04": 3.00341, "2007-05": 3.64715, "2007-06": 3.67208, "2007-07": 3.96516, "2007-08": 4.16651, "2007-09": 4.61806, "2007-10": 5.71657, "2007-11": 5.48342, "2007-12": 5.9615, "2008-01": 4.07407, "2008-02": 3.76205, "2008-03": 4.31855, "2008-04": 5.23449, "2008-05": 5.68011, "2008-06": 5.03955, "2008-07": 4.78342, "2008-08": 5.10124, "2008-09": 3.42029, "2008-10": 3.23826, "2008-11": 2.78857, "2008-12": 2.56882, "2009-01": 2.7124, "2009-02": 2.68804, "2009-03": 3.16346, "2009-04": 3.78611, "2009-05": 4.08688, "2009-06": 4.28615, "2009-07": 4.91696, "2009-08": 5.0623, "2009-09": 5.57775, "2009-10": 5.67293, "2009-11": 6.01559, "2009-12": 6.3413, "2010-01": 5.77948, "2010-02": 6.15751, "2010-03": 7.07215, "2010-04": 7.85731, "2010-05": 7.73007, "2010-06": 7.56945, "2010-07": 7.74159, "2010-08": 7.31585, "2010-09": 8.53896, "2010-10": 9.05753, "2010-11": 9.36423, "2010-12": 9.70719, "2011-01": 10.211, "2011-02": 10.6296, "2011-03": 10.4866, "2011-04": 10.5361, "2011-05": 10.4682, "2011-06": 10.1014, "2011-07": 11.7512, "2011-08": 11.5816, "2011-09": 11.4742, "2011-10": 12.1809, "2011-11": 11.502, "2011-12": 12.1866, "2012-01": 13.7379, "2012-02": 16.3249, "2012-03": 18.0416, "2012-04": 17.5735, "2012-05": 17.3842, "2012-06": 17.5745, "2012-07": 18.3817, "2012-08": 20.1044, "2012-09": 20.1615, "2012-10": 17.9933, "2012-11": 17.7715, "2012-12": 16.1564, "2013-01": 13.8287, "2013-02": 13.4798, "2013-03": 13.5171, "2013-04": 13.52, "2013-05": 13.8247, "2013-06": 12.2606, "2013-07": 13.9105, "2013-08": 15.163, "2013-09": 14.8377, "2013-10": 16.2686, "2013-11": 17.3074, "2013-12": 17.4591, "2014-01": 15.5799, "2014-02": 16.4777, "2014-03": 16.8037, "2014-04": 18.4753, "2014-05": 19.9308, "2014-06": 20.4805, "2014-07": 21.0709, "2014-08": 22.7029, "2014-09": 22.3176, "2014-10": 23.9201, "2014-11": 26.4608, "2014-12": 24.5577, "2015-01": 26.0655, "2015-02": 28.6861, "2015-03": 27.7872, "2015-04": 27.948, "2015-05": 29.2103, "2015-06": 28.1261, "2015-07": 27.1999, "2015-08": 25.4001, "2015-09": 24.8504, "2015-10": 26.9219, "2015-11": 26.7663, "2015-12": 23.8177, "2016-01": 22.0199, "2016-02": 21.9925, "2016-03": 24.7912, "2016-04": 21.3214, "2016-05": 22.8527, "2016-06": 21.879, "2016-07": 23.85, "2016-08": 24.4157, "2016-09": 26.0094, "2016-10": 26.1227, "2016-11": 25.5598, "2016-12": 26.7858, "2017-01": 28.0669, "2017-02": 31.8198, "2017-03": 33.3669, "2017-04": 33.365, "2017-05": 35.6259, "2017-06": 33.5917, "2017-07": 34.6857, "2017-08": 38.3982, "2017-09": 36.085, "2017-10": 39.5847, "2017-11": 40.3809, "2017-12": 39.767, "2018-01": 39.3463, "2018-02": 42.0326, "2018-03": 39.5915, "2018-04": 38.9953, "2018-05": 44.2608, "2018-06": 43.8459, "2018-07": 45.071, "2018-08": 54.1049, "2018-09": 53.6576, "2018-10": 52.0227, "2018-11": 42.5943, "2018-12": 37.6255, "2019-01": 39.7009, "2019-02": 41.4787, "2019-03": 45.4996, "2019-04": 48.0687, "2019-05": 42.0996, "2019-06": 47.5918, "2019-07": 51.2283, "2019-08": 50.3886, "2019-09": 54.0608, "2019-10": 60.0455, "2019-11": 64.7028, "2019-12": 71.0911, "2020-01": 74.9374, "2020-02": 66.3379, "2020-03": 61.709, "2020-04": 71.299, "2020-05": 77.3669, "2020-06": 88.7671, "2020-07": 103.436, "2020-08": 125.829, "2020-09": 112.918, "2020-10": 106.149, "2020-11": 116.29, "2020-12": 129.613, "2021-01": 128.894, "2021-02": 118.616, "2021-03": 119.491, "2021-04": 128.599, "2021-05": 122.104, "2021-06": 134.214, "2021-07": 142.929, "2021-08": 149.007, "2021-09": 138.857, "2021-10": 147.006, "2021-11": 162.459, "2021-12": 174.514, "2022-01": 171.772, "2022-02": 162.489, "2022-03": 171.822, "2022-04": 155.138, "2022-05": 146.682, "2022-06": 134.738, "2022-07": 160.155, "2022-08": 155.156, "2022-09": 136.385, "2022-10": 151.326, "2022-11": 146.328, "2022-12": 128.437, "2023-01": 142.632, "2023-02": 145.938, "2023-03": 163.255, "2023-04": 167.985, "2023-05": 175.723, "2023-06": 192.298, "2023-07": 194.757, "2023-08": 186.504, "2023-09": 169.965, "2023-10": 169.527, "2023-11": 188.816, "2023-12": 191.382, "2024-01": 183.299, "2024-02": 179.9, "2024-03": 170.674, "2024-04": 169.529, "2024-05": 191.606, "2024-06": 209.914, "2024-07": 221.336, "2024-08": 228.497, "2024-09": 232.488, "2024-10": 225.414, "2024-11": 237.069, "2024-12": 250.145, "2025-01": 235.741, "2025-02": 241.84, "2025-03": 222.13, "2025-04": 212.5, "2025-05": 200.85, "2025-06": 205.17, "2025-07": 207.57, "2025-08": 232.14, "2025-09": 254.63, "2025-10": 270.37, "2025-11": 278.85, "2025-12": 273.81 } } ======================================================================================== FICHEIRO: dados_csv/cache/hpm_eunl.de_m.json Tamanho: 4385 bytes ======================================================================================== { "ts": "2025-12-26 15:30:56", "data": { "2010-07": 19.21, "2010-08": 19.4, "2010-09": 19.44, "2010-10": 19.56, "2010-11": 20.49, "2010-12": 21.5, "2011-01": 21.34, "2011-02": 21.88, "2011-03": 21.04, "2011-04": 20.97, "2011-05": 21.08, "2012-04": 22.39, "2012-05": 21.84, "2012-06": 22.41, "2012-07": 23.45, "2012-08": 23.54, "2012-09": 23.55, "2012-10": 23.19, "2012-11": 23.44, "2012-12": 23.38, "2013-07": 26.86, "2013-08": 26.25, "2013-09": 26.97, "2013-10": 27.99, "2013-11": 28.41, "2013-12": 28.51, "2014-01": 28.06, "2014-02": 28.92, "2014-03": 28.92, "2014-04": 29.02, "2014-05": 30.1, "2014-06": 30.56, "2014-07": 30.83, "2015-02": 38.4399, "2015-03": 39.97, "2015-04": 38.84, "2015-05": 39.58, "2015-06": 38.1399, "2015-07": 39.28, "2015-08": 36.08, "2015-09": 34.78, "2015-10": 38.17, "2015-11": 39.66, "2015-12": 38.03, "2016-01": 35.45, "2016-02": 35.59, "2016-03": 35.99, "2016-04": 36.05, "2016-05": 37.56, "2016-06": 37.14, "2016-07": 38.57, "2016-08": 38.67, "2016-09": 38.71, "2016-10": 38.91, "2016-11": 41, "2016-12": 42.18, "2017-01": 41.77, "2017-02": 43.86, "2017-03": 44.07, "2017-04": 43.8, "2017-05": 43.31, "2017-06": 42.9, "2017-07": 42.55, "2017-08": 42.2, "2017-09": 43.41, "2017-10": 44.89, "2017-11": 44.8, "2017-12": 45.43, "2018-01": 46.361, "2018-02": 45.053, "2018-03": 43.403, "2018-04": 45.098, "2018-05": 46.741, "2018-06": 46.839, "2018-07": 47.997, "2018-08": 48.904, "2018-09": 49.26, "2018-10": 46.841, "2018-11": 47.037, "2018-12": 43.099, "2019-01": 46.497, "2019-02": 48.346, "2019-03": 49.556, "2019-04": 51.362, "2019-05": 48.904, "2019-06": 50.81, "2019-07": 52.644, "2019-08": 51.776, "2019-09": 53.352, "2019-10": 53.4, "2019-11": 55.75, "2019-12": 56.608, "2020-01": 56.752, "2020-02": 51.712, "2020-03": 46.109, "2020-04": 50.556, "2020-05": 51.816, "2020-06": 52.698, "2020-07": 52.532, "2020-08": 55.664, "2020-09": 54.968, "2020-10": 53.46, "2020-11": 58.588, "2020-12": 59.712, "2021-01": 59.966, "2021-02": 61.888, "2021-03": 65.694, "2021-04": 66.97, "2021-05": 66.77, "2021-06": 69.934, "2021-07": 71.216, "2021-08": 73.434, "2021-09": 72.014, "2021-10": 75.708, "2021-11": 76.196, "2021-12": 79.246, "2022-01": 74.934, "2022-02": 73.652, "2022-03": 77.098, "2022-04": 75.09, "2022-05": 72.492, "2022-06": 67.886, "2022-07": 74.852, "2022-08": 73.428, "2022-09": 69.26, "2022-10": 72.402, "2022-11": 72.62, "2022-12": 68.478, "2023-01": 71.818, "2023-02": 72.244, "2023-03": 72.378, "2023-04": 72.566, "2023-05": 74.336, "2023-06": 77.2, "2023-07": 79.01, "2023-08": 78.55, "2023-09": 77.28, "2023-10": 74.61, "2023-11": 78.97, "2023-12": 82.26, "2024-01": 85.04, "2024-02": 88.2, "2024-03": 91.45, "2024-04": 89.58, "2024-05": 90.73, "2024-06": 95.19, "2024-07": 95.37, "2024-08": 95.13, "2024-09": 96.396, "2024-10": 97.572, "2024-11": 104.805, "2024-12": 103.59, "2025-01": 108.18, "2025-02": 105.525, "2025-03": 97.178, "2025-04": 93.36, "2025-05": 99.308, "2025-06": 100.155, "2025-07": 105, "2025-08": 104.585, "2025-09": 107.195, "2025-10": 111.835, "2025-11": 111.465, "2025-12": 111.415 } } ======================================================================================== FICHEIRO: dados_csv/cache/hpm_exxt.de_m.json Tamanho: 5257 bytes ======================================================================================== { "ts": "2025-12-26 15:30:57", "data": { "2007-01": 12.5833, "2007-02": 12.3523, "2007-03": 12.2969, "2007-04": 12.879, "2007-05": 13.2577, "2007-06": 13.3132, "2007-07": 13.4795, "2007-08": 13.4333, "2007-09": 13.6088, "2007-10": 14.2186, "2007-11": 13.1746, "2007-12": 13.3317, "2008-01": 11.1698, "2008-02": 10.754, "2008-03": 10.3752, "2008-04": 11.6409, "2008-05": 12.0382, "2008-06": 10.8464, "2008-07": 11.0497, "2008-08": 11.8904, "2008-09": 10.1627, "2008-10": 9.69158, "2008-11": 8.49053, "2008-12": 7.77914, "2009-01": 8.81389, "2009-02": 8.19489, "2009-03": 8.65683, "2009-04": 9.85788, "2009-05": 9.28507, "2009-06": 9.73778, "2009-07": 10.5877, "2009-08": 10.4306, "2009-09": 10.7725, "2009-10": 10.5138, "2009-11": 10.8141, "2009-12": 12.0475, "2010-01": 11.7241, "2010-02": 12.3339, "2010-03": 13.461, "2010-04": 14.1077, "2010-05": 14.0153, "2010-06": 13.3432, "2010-07": 13.1675, "2010-08": 12.9086, "2010-09": 13.5467, "2010-10": 14.1662, "2010-11": 15.0539, "2010-12": 15.5625, "2011-01": 15.396, "2011-02": 15.7937, "2011-03": 15.2296, "2011-04": 15.0354, "2011-05": 15.2204, "2011-06": 14.8928, "2011-07": 15.3744, "2011-08": 14.5408, "2011-09": 15.1336, "2011-10": 15.8745, "2011-11": 15.856, "2011-12": 16.4765, "2012-01": 17.5231, "2012-02": 18.3474, "2012-03": 19.3106, "2012-04": 19.1856, "2012-05": 19.0383, "2012-06": 19.172, "2012-07": 20.1278, "2012-08": 20.6285, "2012-09": 20.3702, "2012-10": 19.0825, "2012-11": 19.2569, "2012-12": 18.5939, "2013-01": 18.8587, "2013-02": 19.7483, "2013-03": 20.5884, "2013-04": 20.5194, "2013-05": 21.9097, "2013-06": 21.081, "2013-07": 21.9792, "2013-08": 21.936, "2013-09": 22.4169, "2013-10": 23.5513, "2013-11": 24.2144, "2013-12": 24.4927, "2014-01": 24.5501, "2014-02": 25.4005, "2014-03": 24.6904, "2014-04": 24.3273, "2014-05": 25.924, "2014-06": 26.6448, "2014-07": 27.6105, "2017-11": 51.3296, "2017-12": 51.7912, "2018-01": 53.83, "2018-02": 54.5129, "2018-03": 51.1182, "2018-04": 53.2164, "2018-05": 57.7987, "2018-06": 58.5332, "2018-07": 59.6527, "2018-08": 63.6553, "2018-09": 63.4584, "2018-10": 59.4545, "2018-11": 58.8599, "2018-12": 53.2914, "2019-01": 58.2425, "2019-02": 60.4552, "2019-03": 63.496, "2019-04": 66.9137, "2019-05": 62.3535, "2019-06": 65.2438, "2019-07": 69.3943, "2019-08": 67.6923, "2019-09": 68.8646, "2019-10": 70.2188, "2019-11": 74.2117, "2019-12": 76.0908, "2020-01": 79.2305, "2020-02": 73.7585, "2020-03": 70.5841, "2020-04": 79.795, "2020-05": 82.4396, "2020-06": 87.2151, "2020-07": 89.0442, "2020-08": 98.2894, "2020-09": 95.201, "2020-10": 92.4924, "2020-11": 98.989, "2020-12": 102.3, "2021-01": 104.2, "2021-02": 104.76, "2021-03": 108.92, "2021-04": 112.5, "2021-05": 108.94, "2021-06": 119.6, "2021-07": 122.6, "2021-08": 128.52, "2021-09": 124.36, "2021-10": 132.7, "2021-11": 139.52, "2021-12": 142.04, "2022-01": 128.1, "2022-02": 123.94, "2022-03": 131.96, "2022-04": 122.14, "2022-05": 114.62, "2022-06": 107.14, "2022-07": 122.14, "2022-08": 119.54, "2022-09": 111.88, "2022-10": 112.48, "2022-11": 109.1, "2022-12": 98.88, "2023-01": 107.86, "2023-02": 110.76, "2023-03": 117.08, "2023-04": 116.02, "2023-05": 130, "2023-06": 134.92, "2023-07": 138.68, "2023-08": 139.24, "2023-09": 136.06, "2023-10": 131.88, "2023-11": 141.56, "2023-12": 148.68, "2024-01": 154.62, "2024-02": 161.42, "2024-03": 164.24, "2024-04": 160.62, "2024-05": 164.04, "2024-06": 180.24, "2024-07": 173.6, "2024-08": 170.6, "2024-09": 174.48, "2024-10": 178.74, "2024-11": 192.88, "2024-12": 197.92, "2025-01": 203.95, "2025-02": 193.08, "2025-03": 171.66, "2025-04": 166, "2025-05": 182.48, "2025-06": 187.039, "2025-07": 199.039, "2025-08": 194.48, "2025-09": 203.55, "2025-10": 218.35, "2025-11": 212.55, "2025-12": 210.649 } } ======================================================================================== FICHEIRO: dados_csv/cache/hpm_nvda.us_m.json Tamanho: 9299 bytes ======================================================================================== { "ts": "2025-12-26 15:30:57", "data": { "1999-01": 0.0362297, "1999-02": 0.0419634, "1999-03": 0.0403518, "1999-04": 0.0348559, "1999-05": 0.0325554, "1999-06": 0.0364567, "1999-07": 0.0385123, "1999-08": 0.0536499, "1999-09": 0.0366834, "1999-10": 0.04218, "1999-11": 0.066251, "1999-12": 0.0896361, "2000-01": 0.0708444, "2000-02": 0.122218, "2000-03": 0.16141, "2000-04": 0.170354, "2000-05": 0.218034, "2000-06": 0.242819, "2000-07": 0.229306, "2000-08": 0.303287, "2000-09": 0.312932, "2000-10": 0.237565, "2000-11": 0.154758, "2000-12": 0.125184, "2001-01": 0.197415, "2001-02": 0.170814, "2001-03": 0.248059, "2001-04": 0.318186, "2001-05": 0.327121, "2001-06": 0.354452, "2001-07": 0.30908, "2001-08": 0.323706, "2001-09": 0.210008, "2001-10": 0.327591, "2001-11": 0.417567, "2001-12": 0.511357, "2002-01": 0.502291, "2002-02": 0.38974, "2002-03": 0.339103, "2002-04": 0.265934, "2002-05": 0.25564, "2002-06": 0.131383, "2002-07": 0.0846137, "2002-08": 0.0772747, "2002-09": 0.0653525, "2002-10": 0.091014, "2002-11": 0.130913, "2002-12": 0.0880387, "2003-01": 0.0788823, "2003-02": 0.0965259, "2003-03": 0.0983632, "2003-04": 0.109137, "2003-05": 0.199933, "2003-06": 0.17517, "2003-07": 0.145833, "2003-08": 0.138963, "2003-09": 0.121988, "2003-10": 0.135048, "2003-11": 0.162318, "2003-12": 0.177235, "2004-01": 0.170124, "2004-02": 0.170124, "2004-03": 0.201768, "2004-04": 0.156826, "2004-05": 0.179303, "2004-06": 0.156356, "2004-07": 0.117854, "2004-08": 0.0951479, "2004-09": 0.110976, "2004-10": 0.110506, "2004-11": 0.146281, "2004-12": 0.179991, "2005-01": 0.17517, "2005-02": 0.22148, "2005-03": 0.181598, "2005-04": 0.16759, "2005-05": 0.207021, "2005-06": 0.204285, "2005-07": 0.206791, "2005-08": 0.23457, "2005-09": 0.262029, "2005-10": 0.256336, "2005-11": 0.276277, "2005-12": 0.279512, "2006-01": 0.343648, "2006-02": 0.360142, "2006-03": 0.437728, "2006-04": 0.446643, "2006-05": 0.351287, "2006-06": 0.325334, "2006-07": 0.338433, "2006-08": 0.445075, "2006-09": 0.452424, "2006-10": 0.533133, "2006-11": 0.565435, "2006-12": 0.565655, "2007-01": 0.468352, "2007-02": 0.473842, "2007-03": 0.439952, "2007-04": 0.50279, "2007-05": 0.52945, "2007-06": 0.631456, "2007-07": 0.699566, "2007-08": 0.782062, "2007-09": 0.830901, "2007-10": 0.811169, "2007-11": 0.72311, "2007-12": 0.780064, "2008-01": 0.56384, "2008-02": 0.490428, "2008-03": 0.453784, "2008-04": 0.471147, "2008-05": 0.566254, "2008-06": 0.429239, "2008-07": 0.262278, "2008-08": 0.289838, "2008-09": 0.245613, "2008-10": 0.20085, "2008-11": 0.171264, "2008-12": 0.185045, "2009-01": 0.182276, "2009-02": 0.189856, "2009-03": 0.226062, "2009-04": 0.263227, "2009-05": 0.239163, "2009-06": 0.258854, "2009-07": 0.296499, "2009-08": 0.332965, "2009-09": 0.344567, "2009-10": 0.27418, "2009-11": 0.299422, "2009-12": 0.42831, "2010-01": 0.352933, "2010-02": 0.371475, "2010-03": 0.398945, "2010-04": 0.360142, "2010-05": 0.30122, "2010-06": 0.23413, "2010-07": 0.210684, "2010-08": 0.21368, "2010-09": 0.267758, "2010-10": 0.275597, "2010-11": 0.312063, "2010-12": 0.353183, "2011-01": 0.548442, "2011-02": 0.519514, "2011-03": 0.423178, "2011-04": 0.458566, "2011-05": 0.459483, "2011-06": 0.365465, "2011-07": 0.317057, "2011-08": 0.305134, "2011-09": 0.286841, "2011-10": 0.339333, "2011-11": 0.358403, "2011-12": 0.317756, "2012-01": 0.338653, "2012-02": 0.34736, "2012-03": 0.353183, "2012-04": 0.298065, "2012-05": 0.285076, "2012-06": 0.316807, "2012-07": 0.310447, "2012-08": 0.3217, "2012-09": 0.305784, "2012-10": 0.27465, "2012-11": 0.276197, "2012-12": 0.28299, "2013-01": 0.28299, "2013-02": 0.293953, "2013-03": 0.297865, "2013-04": 0.319704, "2013-05": 0.337757, "2013-06": 0.327591, "2013-07": 0.336957, "2013-08": 0.345923, "2013-09": 0.364936, "2013-10": 0.356209, "2013-11": 0.367883, "2013-12": 0.377817, "2014-01": 0.370227, "2014-02": 0.435332, "2014-03": 0.424177, "2014-04": 0.437498, "2014-05": 0.452184, "2014-06": 0.441112, "2014-07": 0.416437, "2014-08": 0.464877, "2014-09": 0.440932, "2014-10": 0.467024, "2014-11": 0.503308, "2014-12": 0.481181, "2015-01": 0.460781, "2015-02": 0.531556, "2015-03": 0.504157, "2015-04": 0.534682, "2015-05": 0.535712, "2015-06": 0.486782, "2015-07": 0.482889, "2015-08": 0.546412, "2015-09": 0.599187, "2015-10": 0.68959, "2015-11": 0.773925, "2015-12": 0.80419, "2016-01": 0.714653, "2016-02": 0.767932, "2016-03": 0.872537, "2016-04": 0.870071, "2016-05": 1.14701, "2016-06": 1.15418, "2016-07": 1.40198, "2016-08": 1.50875, "2016-09": 1.68548, "2016-10": 1.7503, "2016-11": 2.27119, "2016-12": 2.62948, "2017-01": 2.68927, "2017-02": 2.50336, "2017-03": 2.68657, "2017-04": 2.57255, "2017-05": 3.56409, "2017-06": 3.56927, "2017-07": 4.01241, "2017-08": 4.18734, "2017-09": 4.41811, "2017-10": 5.11127, "2017-11": 4.9634, "2017-12": 4.78507, "2018-01": 6.07892, "2018-02": 5.98837, "2018-03": 5.73067, "2018-04": 5.56528, "2018-05": 6.24429, "2018-06": 5.86605, "2018-07": 6.06326, "2018-08": 6.95323, "2018-09": 6.96172, "2018-10": 5.22309, "2018-11": 4.05264, "2018-12": 3.31047, "2019-01": 3.56479, "2019-02": 3.82928, "2019-03": 4.45774, "2019-04": 4.49329, "2019-05": 3.36657, "2019-06": 4.08162, "2019-07": 4.19304, "2019-08": 4.16707, "2019-09": 4.33052, "2019-10": 5.00084, "2019-11": 5.39616, "2019-12": 5.85806, "2020-01": 5.8861, "2020-02": 6.72787, "2020-03": 6.5664, "2020-04": 7.28084, "2020-05": 8.84379, "2020-06": 9.46818, "2020-07": 10.5813, "2020-08": 13.3331, "2020-09": 13.4928, "2020-10": 12.4984, "2020-11": 13.3641, "2020-12": 13.0216, "2021-01": 12.9567, "2021-02": 13.6807, "2021-03": 13.3191, "2021-04": 14.9767, "2021-05": 16.2079, "2021-06": 19.9633, "2021-07": 19.462, "2021-08": 22.3449, "2021-09": 20.6781, "2021-10": 25.522, "2021-11": 32.6173, "2021-12": 29.3623, "2022-01": 24.4455, "2022-02": 24.3448, "2022-03": 27.2454, "2022-04": 18.5195, "2022-05": 18.6443, "2022-06": 15.1397, "2022-07": 18.1397, "2022-08": 15.0747, "2022-09": 12.127, "2022-10": 13.4837, "2022-11": 16.9106, "2022-12": 14.6034, "2023-01": 19.5229, "2023-02": 23.1992, "2023-03": 27.7615, "2023-04": 27.7335, "2023-05": 37.813, "2023-06": 42.2828, "2023-07": 46.7078, "2023-08": 49.3326, "2023-09": 43.4829, "2023-10": 40.7649, "2023-11": 46.7527, "2023-12": 49.508, "2024-01": 61.5095, "2024-02": 79.0896, "2024-03": 90.3347, "2024-04": 86.3815, "2024-05": 109.607, "2024-06": 123.52, "2024-07": 117.002, "2024-08": 119.352, "2024-09": 121.432, "2024-10": 132.751, "2024-11": 138.24, "2024-12": 134.29, "2025-01": 120.07, "2025-02": 124.92, "2025-03": 108.38, "2025-04": 108.92, "2025-05": 135.13, "2025-06": 157.99, "2025-07": 177.87, "2025-08": 174.18, "2025-09": 186.58, "2025-10": 202.49, "2025-11": 177, "2025-12": 188.61 } } ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-06c3aa3b46204b8a839cad65fd4aacae2c09a5d8.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-1fa134046098bf2bad8b14b3b8a3fb863879f1fe.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-1fef489aa8a128b144b1a811322576d3ce0bf95e.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-2afd55491aeacfdfebc48d1b11cb7487e916340f.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-2b5f7fb577a745a3b957342c4065f6615753e1ba.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-2d294b32d9ff1c6a95cd057d25656040d673d5dc.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-2ddbd195729fbb92e4c082dab8a4b29dac48046a.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-37bbf65b466e5ec91101090eed79e2bd5fc1643c.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-423cfc18946eb0698b694482028eaaed747555f4.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-44b07be58971483320e80614feaf88b29cffc237.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-44de178821cde3c1540a627a3e5e02728ea991ee.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-5417d97a53c609e55d7e157b1bfda61b8df09625.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-547ff7c7fdac97796db259805a244af8d58ba9e3.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-5fee8f0307a9ec74b73c917fb49f35d639c1709c.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-68c4ad23606545c32310bded97f7b8b3b9a4d3a3.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-696ce06e6c0901d79c748b644bce548ffd7ae548.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-6e6584baf4f6eb53d74314a3a28a0ceedaaea8ba.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-7a35e0760610450573ee55d7f9bd4b3e610a6059.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-879901cc1d48f82db24e4d0d6788b93389040929.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-a2c5e523dad5904b0bce547076200364ca7617ca.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-bcf30f295c073cf1df3dc1c0f95680d632325bae.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-c0b224252032246d5154931bffd1dffc3c3306e7.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-c5ccb3e128b3efd5cd7a5b078d7e8cf626e82598.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-cac0498649e83daf78cb6b0b7133630629eb98c3.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-ce611600b0536e816f9cf218ce854f6f014ed4e4.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-ceb2d11e26f03767cdb78367cfcf70ac919e15a4.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-d63dff8eb9abf6edf9522f77bf8a00726a446c1f.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-e61b1df2a99a4f2d8d480564f44915f1468ea10d.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-e6b0073a0d6affc4b325ef927f354250615a6a3a.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/cache/stooq-monthclose-f33fc7772217864c1c83b9c08a3a5182ff4822b0.json Tamanho: 2 bytes ======================================================================================== [] ======================================================================================== FICHEIRO: dados_csv/converter.php Tamanho: 10888 bytes ======================================================================================== = 70 ? '19' : '20') . $year; } return sprintf('%04d-%02d', (int)$year, (int)$m[2]); } function parseDecimal(?string $value): ?float { if ($value === null) { return null; } $value = trim($value); if ($value === '' || $value === '-' || strtoupper($value) === 'NULL') { return null; } $value = str_replace(' ', '', $value); $value = str_replace('.', '', $value); $value = str_replace(',', '.', $value); if (!is_numeric($value)) { return null; } return (float)$value; } function normalizeTicker(string $raw): array { $raw = strtoupper(trim($raw)); $manualMap = [ 'AAPL' => ['ticker' => 'AAPL', 'stooq' => 'aapl.us', 'moeda' => 'USD'], 'TSLA' => ['ticker' => 'TSLA', 'stooq' => 'tsla.us', 'moeda' => 'USD'], 'PYPL' => ['ticker' => 'PYPL', 'stooq' => 'pypl.us', 'moeda' => 'USD'], 'GOOGL' => ['ticker' => 'GOOGL', 'stooq' => 'googl.us', 'moeda' => 'USD'], 'AMZN' => ['ticker' => 'AMZN', 'stooq' => 'amzn.us', 'moeda' => 'USD'], 'KO' => ['ticker' => 'KO', 'stooq' => 'ko.us', 'moeda' => 'USD'], 'BAC' => ['ticker' => 'BAC', 'stooq' => 'bac.us', 'moeda' => 'USD'], 'ANSS' => ['ticker' => 'ANSS', 'stooq' => 'anss.us', 'moeda' => 'USD'], 'AMD' => ['ticker' => 'AMD', 'stooq' => 'amd.us', 'moeda' => 'USD'], 'NVDA' => ['ticker' => 'NVDA', 'stooq' => 'nvda.us', 'moeda' => 'USD'], 'ADBE' => ['ticker' => 'ADBE', 'stooq' => 'adbe.us', 'moeda' => 'USD'], 'MSFT' => ['ticker' => 'MSFT', 'stooq' => 'msft.us', 'moeda' => 'USD'], 'SPCE' => ['ticker' => 'SPCE', 'stooq' => 'spce.us', 'moeda' => 'USD'], 'MRNA' => ['ticker' => 'MRNA', 'stooq' => 'mrna.us', 'moeda' => 'USD'], 'SQ' => ['ticker' => 'SQ', 'stooq' => 'sq.us', 'moeda' => 'USD'], 'NFLX' => ['ticker' => 'NFLX', 'stooq' => 'nflx.us', 'moeda' => 'USD'], 'NIO' => ['ticker' => 'NIO', 'stooq' => 'nio.us', 'moeda' => 'USD'], 'BRKB' => ['ticker' => 'BRKB', 'stooq' => 'brk-b.us', 'moeda' => 'USD'], 'PLUG' => ['ticker' => 'PLUG', 'stooq' => 'plug.us', 'moeda' => 'USD'], 'MA' => ['ticker' => 'MA', 'stooq' => 'ma.us', 'moeda' => 'USD'], 'MCD' => ['ticker' => 'MCD', 'stooq' => 'mcd.us', 'moeda' => 'USD'], 'UAL' => ['ticker' => 'UAL', 'stooq' => 'ual.us', 'moeda' => 'USD'], 'ZM' => ['ticker' => 'ZM', 'stooq' => 'zm.us', 'moeda' => 'USD'], 'BABA' => ['ticker' => 'BABA', 'stooq' => 'baba.us', 'moeda' => 'USD'], 'Z' => ['ticker' => 'Z', 'stooq' => 'z.us', 'moeda' => 'USD'], 'O' => ['ticker' => 'O', 'stooq' => 'o.us', 'moeda' => 'USD'], 'TWTR' => ['ticker' => 'TWTR', 'stooq' => 'twtr.us', 'moeda' => 'USD'], 'IWDA' => ['ticker' => 'IWDA', 'stooq' => 'eunl.de', 'moeda' => 'EUR'], 'QCOM' => ['ticker' => 'QCOM', 'stooq' => 'qcom.us', 'moeda' => 'USD'], 'TSM' => ['ticker' => 'TSM', 'stooq' => 'tsm.us', 'moeda' => 'USD'], 'NDXEX' => ['ticker' => 'NDXEX', 'stooq' => 'exxt.de', 'moeda' => 'EUR'], 'VUSA' => ['ticker' => 'VUSA', 'stooq' => 'vusa.de', 'moeda' => 'EUR'], 'XAUEUR' => ['ticker' => 'XAUEUR', 'stooq' => 'xaueur', 'moeda' => 'EUR'], ]; $aliasMap = [ 'NASDAQ:AAP' => 'AAPL', 'NASDAQ:PYP' => 'PYPL', 'NASDAQ:GOO' => 'GOOGL', 'NASDAQ:AMZ' => 'AMZN', 'NASDAQ:ANS' => 'ANSS', 'NASDAQ:NVD' => 'NVDA', 'NASDAQ:ADB' => 'ADBE', 'NASDAQ:MSF' => 'MSFT', 'NASDAQ:MRN' => 'MRNA', 'NASDAQ:NFL' => 'NFLX', 'NASDAQ:PLU' => 'PLUG', 'NASDAQ:QCO' => 'QCOM', 'NYSE:BRK.B' => 'BRKB', 'AMS:IWDA' => 'IWDA', 'AMS:VUSA' => 'VUSA', 'INDEXNASDAQ:NDX' => 'NDXEX', 'CURRENCY:XAUEUR' => 'XAUEUR', ]; if (isset($aliasMap[$raw])) { return $manualMap[$aliasMap[$raw]]; } $parts = strpos($raw, ':') !== false ? explode(':', $raw, 2) : ['', $raw]; $market = strtoupper(trim($parts[0] ?? '')); $ticker = strtoupper(trim($parts[1] ?? $raw)); $ticker = preg_replace('/[^A-Z0-9.\-]/', '', $ticker) ?: $ticker; if ($ticker === 'BRK.B') { $ticker = 'BRKB'; } $shortAliases = [ 'AAP' => 'AAPL', 'PYP' => 'PYPL', 'GOO' => 'GOOGL', 'AMZ' => 'AMZN', 'ANS' => 'ANSS', 'NVD' => 'NVDA', 'ADB' => 'ADBE', 'MSF' => 'MSFT', 'MRN' => 'MRNA', 'NFL' => 'NFLX', 'PLU' => 'PLUG', 'QCO' => 'QCOM', 'XAU' => 'XAUEUR', 'GOLD' => 'XAUEUR', 'OURO' => 'XAUEUR', 'XAUEUR' => 'XAUEUR', ]; if (isset($shortAliases[$ticker])) { $ticker = $shortAliases[$ticker]; } if (isset($manualMap[$ticker])) { return $manualMap[$ticker]; } $suffixByMarket = [ 'NASDAQ' => '.us', 'NYSE' => '.us', 'AMEX' => '.us', 'ARCA' => '.us', 'BATS' => '.us', 'AMS' => '.de', 'XETR' => '.de', 'ETR' => '.de', 'FWB' => '.de', 'DE' => '.de', 'EURONEXT' => '.eu', 'CURRENCY' => '', 'INDEX' => '', ]; $moedaByMarket = [ 'AMS' => 'EUR', 'XETR' => 'EUR', 'ETR' => 'EUR', 'FWB' => 'EUR', 'DE' => 'EUR', 'CURRENCY' => 'EUR', 'INDEX' => 'EUR', ]; $moeda = $moedaByMarket[$market] ?? 'USD'; $suffix = $suffixByMarket[$market] ?? '.us'; $tickerClean = str_replace('.', '', $ticker); $stooqTicker = strtolower($tickerClean . $suffix); return [ 'ticker' => $tickerClean, 'stooq' => $stooqTicker, 'moeda' => $moeda, ]; } function buildDateColumnMap(array $header): array { $map = []; foreach ($header as $index => $cell) { $monthKey = parseMonthKey((string)$cell); if ($monthKey !== null) { $map[$index] = $monthKey; } } return $map; } function createMeta(int $totalTickers): array { return [ 'user' => 'tiago', 'todos' => false, 'encerradas' => false, 'mindatacompra' => '2019-10-15', 'minmesguardado' => '2019-10', 'debugtickersamostra' => ['AAPL', 'NVDA'], 'fontes_prioridade_default' => ['stooq', 'twelvedata', 'eodhd', 'perplexity', 'manual'], 'ttlcachesegundos' => 2592000, 'forcar' => false, 'stats' => [ 'totaltickers' => $totalTickers, 'atualizados' => 0, 'ignoradossemmapa' => 0, 'semdados' => 0, 'erros' => 0, 'porfonte' => [ 'stooq' => 0, 'twelvedata' => 0, 'eodhd' => 0, 'perplexity' => 0, 'manual' => 0, ], ], 'timestamp' => date('Y-m-d H:i:s'), ]; } try { header('Content-Type: application/json; charset=utf-8'); $csvPath = __DIR__ . '/dadosacoes.csv'; $outputDir = __DIR__ ; $jsonPath = $outputDir . '/historico-precos-mensal.json'; if (!is_file($csvPath)) { throw new RuntimeException("Ficheiro CSV não encontrado em: {$csvPath}"); } if (!is_dir($outputDir) && !mkdir($outputDir, 0775, true) && !is_dir($outputDir)) { throw new RuntimeException("Não foi possível criar a pasta: {$outputDir}"); } $content = readFileUtf8($csvPath); $lines = preg_split('/\R/', trim($content)); if (!$lines || count($lines) < 5) { throw new RuntimeException('O CSV não tem linhas suficientes para ser processado.'); } $header = parseCsvLine($lines[0]); $dateColumnMap = buildDateColumnMap($header); if (!$dateColumnMap) { throw new RuntimeException('Não foi possível detetar colunas de datas no CSV.'); } $ativos = []; foreach ($lines as $lineNumber => $line) { if ($lineNumber < 4) { continue; } $line = trim($line); if ($line === '') { continue; } $cols = parseCsvLine($line); $symbolRaw = strtoupper(trim((string)($cols[1] ?? ''))); if ($symbolRaw === '') { continue; } $looksLikeSymbol = strpos($symbolRaw, ':') !== false || in_array($symbolRaw, ['XAU', 'XAUEUR', 'GOLD', 'OURO'], true) || str_starts_with($symbolRaw, 'INDEX') || str_starts_with($symbolRaw, 'CURRENCY'); if (!$looksLikeSymbol) { continue; } $mapped = normalizeTicker($symbolRaw); $mensal = []; foreach ($dateColumnMap as $index => $monthKey) { $value = parseDecimal($cols[$index] ?? null); if ($value !== null) { $mensal[$monthKey] = $value; } } if (!$mensal) { continue; } ksort($mensal); $ativos[$mapped['ticker']] = [ 'stooq' => $mapped['stooq'], 'moeda' => $mapped['moeda'], 'mensal' => $mensal, ]; } ksort($ativos); $result = [ 'meta' => createMeta(count($ativos)), 'ativos' => $ativos, ]; $json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); if ($json === false) { throw new RuntimeException('Falha ao gerar JSON.'); } if (file_put_contents($jsonPath, $json . PHP_EOL) === false) { throw new RuntimeException("Não foi possível gravar o ficheiro JSON em: {$jsonPath}"); } echo $json; } catch (Throwable $e) { http_response_code(500); echo json_encode([ 'erro' => $e->getMessage(), ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); } ======================================================================================== FICHEIRO: dados_csv/dadosacoes.csv Tamanho: 20258 bytes ======================================================================================== ;;;;;;31/12/18;31/01/19;28/02/19;31/03/19;30/04/19;31/05/19;30/06/19;31/07/19;31/08/19;30/09/19;31/10/19;30/11/19;31/12/19;31/01/20;29/02/20;31/03/20;30/04/20;31/05/20;30/06/20;31/07/20;31/08/20;30/09/20;31/10/20;30/11/20;31/12/20;31/01/21;28/02/21;31/03/21;30/04/21;31/05/21;30/06/21;31/07/21;31/08/21;30/09/21;31/10/21;30/11/21;31/12/21;31/01/22;28/02/22;31/03/22;30/04/22;31/05/22;30/06/22;31/07/22;31/08/22;30/09/22;31/10/22;30/11/22;30/12/22;31/01/23;28/02/23;31/03/23;30/04/23;31/05/23;30/06/23;31/07/23;31/08/23;30/09/23;31/10/23;30/11/23;31/12/23;31/01/24;29/02/24;31/03/24;30/04/24;31/05/24;27/06/24;30/07/24;31/08/24;30/09/24;31/10/24;30/11/24;31/12/24;31/01/25;28/02/25;31/03/25;30/04/25;31/05/25;30/06/25;31/07/25;31/08/25;30/09/25;31/10/25;30/11/25;31/12/25;31/01/26;28/02/26;31/03/26;30/04/26;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026;2Ê026 ;;;;;;2Ê018;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê019;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê020;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê021;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê022;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê023;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê024;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê025;2Ê026;2Ê026;2Ê026;2Ê026;5;6;7;8;9;10;11;12 ;;;;;;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;5;6;7;8;9;10;11;12;1;2;3;4;31;30;31;31;30;31;30;31 N¼;Tipo A›es;;;;;31;31;28;31;30;31;30;31;31;30;31;30;31;31;29;31;30;31;30;31;31;30;31;30;31;31;28;31;30;31;30;31;31;30;31;30;31;31;28;31;30;31;30;31;31;30;31;30;30;31;28;31;30;31;30;31;31;30;31;30;31;31;29;29;30;31;27;30;31;30;31;30;31;31;28;31;30;31;30;31;31;30;31;30;31;31;28;31;30;;;;;;;; 1;NASDAQ:AAPL;;;;;39,44;41,61;43,29;47,81;50,17;43,77;50,39;53,26;51,43;55,99;62,19;66,04;73,41;77,38;74,7;63,57;73,45;80,46;91,2;106,26;129,04;115,81;108,77;119,05;132,69;134,14;127,79;122,15;131,46;124,28;136,96;145,52;151,83;141,5;148,96;165,3;177,57;174,78;165,12;174,61;157,96;148,84;136,72;161,51;157,22;138,2;153,34;148,03;129,93;144,29;147,41;164,9;169,59;177,25;193,97;196,45;187,87;173,75;170,77;189,95;192,53;184,4;180,75;170,03;170,33;192,25;210,62;222,08;222,77;233;225,91;239,59;250,42;236;241,84;222,13;212,5;201,7;205,17;207,57;229,72;254,63;270,37;283,1;271,86;270,01;264,72;253,79;271,35;;;;;;;; 2;NASDAQ:TSLA;;;;;22,19;20,47;21,33;19,28;15,91;12,34;15,14;16,11;15;16,06;20,99;22,32;27,89;43,37;49,57;34,93;52,13;59,87;71,99;95,38;166,11;143;133,5;189,2;235,22;279,94;239,48;222,64;236,48;207,97;226,57;236,56;245,24;258,49;402,86;381,59;352,26;312,24;290,14;359,2;300,98;252,75;224,47;297,28;275,61;265,25;227,54;194,7;123,18;173,22;205,71;207,46;161,83;203,93;261,77;267,43;258,08;251,6;200,84;240,08;248,48;187,29;201,88;175,22;183,28;178,08;197,88;232,07;210,6;261,63;249,85;357,09;403,84;404,6;292,98;259,16;282,16;342,69;317,66;308,27;329,36;444,72;456,56;430,14;449,72;421,81;403,32;371,75;381,63;;;;;;;; 3;NASDAQ:PYPL;;;;;84,09;88,76;98,07;105,55;112,77;109,75;115,03;110,4;106,75;103,59;104,1;106,21;108,17;113,89;112,86;95,74;123;154,53;174,23;196,07;204,14;197,03;187,76;214,12;234,2;241,85;273,63;242,84;262,29;259,27;291,48;270,99;288,66;260,21;231,28;184,89;188,58;171,94;111,93;115,65;91,53;85,21;69,84;88,57;93,44;86,07;83,58;78,41;71,22;81,49;73,6;75,94;75,11;61,99;66,73;75,82;62,51;58,56;51,8;57,61;61,41;61,35;60,34;65,03;67,92;62,99;58,03;65,78;72;78,03;79,3;86,53;85,35;88,58;71,05;65,25;65,84;70,93;74,32;68,76;69,25;67,06;69,27;62,58;58,38;52,33;45,63;45,23;50,14;;;;;;;; 4;NASDAQ:GOOGL;;;;;52,25;56,29;56,33;59,95;59,95;55,33;55;60,91;58,48;61,06;62,94;64,44;66,97;71,64;69,32;58,1;67,34;71,74;70,9;74,4;81,48;73,28;81,22;87,72;87,63;94,65;103,48;103,13;117,68;119,06;122,09;134,85;144,7;133,68;143,5;141,9;144,85;135,3;135,06;139,07;116,58;113,76;108,96;114,86;108,22;95,65;94,51;100,99;88,23;98,84;90,06;103,73;107,2;122,87;119,7;132,72;136,17;134,17;124,08;132,53;139,69;140,1;138,46;155,49;162,78;172,5;182,15;171,54;157,36;165,85;171,11;171,49;189,3;204,02;170,28;154,64;158,8;169,03;176,23;191,9;211,35;243,1;281,19;314,89;313;343,69;306,52;287,56;384,8;;;;;;;; 5;NASDAQ:AMZN;;;;;75,1;85,94;81,99;90,71;96,33;88,75;96,11;93,34;89,49;86,8;88,83;89,08;92,39;100,44;97,7;97,49;123,7;123,55;137,94;158,23;172,55;157,44;150,22;158,4;162,85;167,14;157,31;154,7;173,37;160,93;172,01;166,57;173,54;164,25;165,91;175,35;166,72;135,3;153,56;163;124,5;120,21;106,21;135,39;126,77;113;102,44;96,54;84;103,13;94,23;103,29;102,05;120,58;130,36;133,68;138,01;129,46;133,09;146,09;151,94;155,2;176,76;180,97;175;176,44;193,25;186,98;176,25;186,33;186,4;210,71;219,39;237,68;212,28;190,26;184,42;206,65;219,39;234,11;225,34;219,57;244,22;233,88;230,82;242,96;208,39;208,27;265,06;;;;;;;; 6;NYSE:KO;;;;;47,35;48,13;45,34;46,72;49,06;49,13;51,6;52,63;55,3;54,44;54,43;53,75;55,35;58,4;55,92;44,25;45,89;46,99;44,68;47,24;49,53;49,37;48,62;51,6;54,84;48,48;49,9;52,71;53,98;55,28;54,11;56,88;56,31;52,47;56,17;52,45;59,21;61,01;62,24;62;63,44;63,38;62,91;64,52;61,71;56,02;59,85;63,61;63,61;61,32;59,51;62,03;64,3;59,66;60,22;61,93;59,83;55,48;56,49;58,44;58,93;59,49;60,02;60,68;61,77;62,93;63,65;66,74;73,01;71,86;65,31;63,65;62,26;63,48;71,21;71,62;72,55;72;70,75;68,75;69,06;66,32;68,9;71,95;69,91;75,33;80,22;76,05;78,76;;;;;;;; 7;NYSE:BAC;;;;;24,64;28,47;29,08;28,54;30,58;26,6;29,42;30,68;27,05;29,17;31,27;33,43;35,22;32,83;29,37;21,23;24,05;24,61;23,75;24,88;25,74;24,09;24,08;28,16;30,31;29,96;35,79;38,69;40,53;42,92;41,23;37,96;41,75;42,45;47,85;44,47;44,49;46,14;44,2;41,22;36,14;37,2;31,13;33,71;33,61;30,2;36,04;37,85;33,12;35,48;34,3;28,6;29,04;27,79;28,69;32;28,67;26,7;26,34;30,49;33,67;34,01;34,52;37,52;37,01;39,99;39,77;40,31;40,7;39,68;41,82;47,04;43,95;46,3;46,1;41,73;39,88;44,08;47,32;47,27;50,42;51,59;53,45;53,24;55;54,03;49,81;48,75;53,46;;0;0;0;0;0;0;0 8;NASDAQ:ANSS;;;;;142,94;164,35;177,26;187,45;195,8;179,5;208,11;203,12;206,01;221,36;220,15;250,7;257,41;274,33;258,81;232,47;261,83;286,7;291,73;310,6;339,01;327,23;311,23;338,06;363,8;367,94;346,11;339,56;365,66;335,99;347,06;369,63;365,36;340,45;376,44;391,48;401,12;340,01;324,19;317,65;279,93;260,36;239,29;279,21;248,3;221,7;221,16;254,3;241,59;266,36;303,61;332,8;314,17;323,59;330,27;342,1;318,87;297,4;278,26;293,36;362,88;327,83;334,17;347,48;324,88;317,45;321,5;313,63;309,02;318,63;320,41;350,51;337,33;350,5;333,25;316,56;321,88;332,61;351,22;351,22;351,22;351,22;351,22;0;0;0;0;0;0;;;;;;;; 9;NASDAQ:AMD;;;;;18,46;24,41;23,53;26,36;27,63;27,41;31,2;30,45;30,9;28,99;33,93;38,73;45,86;47;47,46;45,48;52,39;53,63;52,61;77,43;90,82;81,99;74,7;92,66;91,71;87,66;86,39;78,5;81,62;80,81;93,93;108,63;110,72;102,9;125,23;158,37;143,9;114,25;123,34;109,34;89,84;101,86;76,47;96,78;84,87;63,36;60,06;77,63;64,77;75,15;78,58;98,01;89,69;118,21;113,91;114,4;105,72;103,27;98,5;121,16;147,41;167,69;192,53;183,34;158,38;166,9;162,21;144,48;136,94;164,08;144,07;142,06;120,79;115,95;99,86;102,74;97,35;114,63;141,9;176,31;162,32;161,79;256,12;219,76;214,16;246,27;198,62;203,43;354,49;;;;;;;; 10;NASDAQ:NVDA;;;;;33,38;35,94;38,57;45,57;45,25;33,87;41,54;42,18;41,04;43,52;50,26;52,31;58,83;59,11;69,11;65,9;73,07;88,06;94,98;106,15;133,75;135,31;125,81;134,01;130,55;132,37;138,42;133,48;150,1;162,65;200,03;197,5;223,85;207,16;258,27;326,76;294,11;244,86;243,85;272,86;195,33;186,72;151,59;184,41;150,94;121,39;134,97;169,23;146,14;195,37;232,16;277,77;289,1;378,34;423,02;467,29;493,55;447,82;407,8;467,7;495,22;61,53;79,11;90,36;86,4;109,63;123,54;117,02;108;121,44;132,76;138,63;134,29;120,07;124,92;108,38;108,92;137,38;157,99;177,87;170,78;186,58;202,49;179,92;186,5;185,61;182,48;174,4;199,57;;;;;;;; 11;NASDAQ:ADBE;;;;;226,24;247,82;262,5;272,17;289,25;270,9;300,97;298,86;282,45;276,25;277,93;302,75;329,81;351,14;360,28;318,24;353,64;389,68;435,31;444,32;513,39;490,43;444,94;478,47;500,12;470;469,57;475,37;508,34;495,91;585,64;618,75;663,7;575,72;640,2;669,85;567,06;534,3;467,68;455,62;407,29;416,48;366,06;411,09;373,44;275,2;318,5;344,93;336,53;370,34;323,95;385,37;374,15;417,79;488,99;546,17;559,34;521,13;532,06;611,01;596,6;617,78;560,28;502,09;462,83;444,76;555,54;551,65;571,04;517,78;478,08;516,2;444,68;437,45;438,56;383,53;374,98;403,4;386,88;357,69;345,63;352,75;340,31;322,85;349,99;293,38;260,88;243,08;246,1;;;;;;;; 12;NASDAQ:MSFT;;;;;101,57;104,43;112,03;119,02;130,6;123,68;135,68;136,27;136,04;139,03;143,37;149,55;157,7;170,23;172,79;157,71;179,21;182,83;203,51;205,01;225,53;210,33;202,33;214,07;222,42;239,65;236,94;235,77;252,18;247,4;270,9;284,82;301,88;281,92;329,37;330,59;336,32;310,98;298,79;308,31;284,47;271,87;256,83;278,01;261,47;232,9;232,13;255,14;239,82;247,81;249,42;288,3;305,56;328,39;340,54;335,92;327,76;321,8;338,11;378,91;376,04;397,58;413,64;424,57;389,33;415,13;446,95;418,35;409,44;430,3;406,35;430,98;421,5;415,06;396,99;375,39;395,26;461,97;497,41;533,5;505,12;517,95;517,81;486,74;483,62;423,37;398,55;370,17;407,78;;;;;;;; 13;NYSE:SPCE;;;;;10;10,05;10,12;10,19;10,23;10,34;10,4;10,47;10,34;10,7;9,41;7,44;11,55;17,15;25,98;14,78;17,62;17,52;16,34;22,45;17,9;19,23;17,66;26,61;23,73;53,79;38,14;30,63;22,15;28,88;46;31,87;27,11;25,3;19,55;16;13,38;9,2;9,68;9,88;7,89;7,01;6,02;7,4;5,91;4,71;4,62;5,09;3,48;5,52;5,74;4,05;3,57;3,46;3,88;4,28;2,52;1,77;1,48;2,23;2,45;1,78;1,74;1,43;0,87;0,86;8,43;7,11;6,16;6,1;6,57;7,02;5,88;4,76;3,8;3,03;2,89;3,12;2,73;3,8;3,09;3,86;3,94;3,79;3,21;2,68;2,6;2,43;2,38;;;;;;;; 14;NASDAQ:MRNA;;;;;15,27;16,6;22,6;20,59;26,03;20,78;14,73;13,1;14,88;15,92;16,75;19,76;19,56;20,51;29,88;29,95;45,99;62,18;64,21;74,1;64,89;70,75;67,11;152,74;104,47;157,48;157,4;130,95;175,67;184,66;234,98;346,61;376,69;384,86;337,17;352,43;253,98;169,33;153,6;172,26;142,08;145,33;142,85;161,51;132,27;118,25;150,33;175,91;179,62;176,06;138,81;153,58;133,4;127,71;121,5;117,66;113,07;103,31;75,96;77,7;99,45;101,05;92,24;105,6;110,31;142,55;118,75;119,22;72,94;66,83;54,36;44,26;41,58;39,42;30,96;28,35;28,54;27,05;27,59;29,56;24,19;25,83;27,16;24,16;29,49;42,55;52,85;50,8;45,94;;0;0;0;0;0;0;0 15;NYSE:SQ;;;;;56,09;71,35;81,24;76,32;72,82;61,95;73,2;80,41;61,13;61,95;61,43;66,88;62,56;74,69;80,67;52,38;65,14;82,72;104,94;129,85;159,56;162,55;155,23;210,96;217,64;221,94;241;227,05;244,82;221,95;243,8;272,38;268,07;239,84;255,04;208,33;161,51;122,29;127,5;135,6;105,86;87,51;61,46;77,81;68,91;54,99;60,07;67,77;62,84;81,72;76,73;68,65;60,22;60,39;66,57;80,53;57,65;43,19;40,25;63,43;77,35;65,01;79,47;81,46;73;64,08;64,49;61,88;64,17;67,13;72,32;92,78;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;;;;;;;; 16;NASDAQ:NFLX;;;;;267,66;339,5;358,1;366,96;370,54;343,28;374,6;322,99;289,29;267,62;287,41;309,99;323,57;345,09;381,05;375,5;419,85;425,92;455,04;488,88;529,56;500,03;484,12;490,7;540,73;539,04;550,64;521,66;513,47;499,08;528,21;515,15;569,19;610,34;681,17;641,9;602,44;427,14;394,52;374,59;199,46;197,44;174,87;226,21;223,56;235,44;291,88;305,53;294,88;353,86;322,13;345,48;324,12;395,23;440,49;438,97;433,68;380,33;411,69;473,97;486,88;564,11;602,92;614,31;550,64;641,62;674,88;628,35;675,32;709,27;756,03;897,74;250,42;976,76;980,56;932,53;1Ê131,72;1Ê218,98;1Ê339,13;1Ê159,40;1Ê214,11;1Ê198,92;1Ê118,86;109,13;93,76;82,76;97,09;96,15;93,61;;;;;;;; 17;NYSE:NIO;;;;;6,37;7,88;9,57;5,21;4,85;3,05;2,6;3,47;2,6;1,56;1,45;2,44;4,02;3,78;4,11;2,78;3,41;4,26;7,72;11,94;19,03;21,22;33,32;50,53;48,74;56,99;49,76;38,98;39,84;42,34;53,2;45,85;39,31;35,63;40,84;39,13;31,68;24,51;22,84;21,05;17,5;17,39;21,72;20,18;19,91;15,77;9,67;12,78;9,75;12,07;9,39;10,51;7,81;7,53;9,69;15,3;10,27;8,79;7,3;7,27;9,07;5,62;5,75;4,64;4,72;5,39;4,16;4,44;4,15;6,68;5,1;4,4;403,84;4,32;4,63;3,81;4,05;3,52;3,43;4,87;6,58;7,62;7,25;5,18;5,1;4,52;4,72;6,03;6,39;;;;;;;; 18;NYSE:BRK.B;;;;;204,18;205,54;201,3;205;216,71;197,42;214,62;205,43;200,9;208,02;212,58;220,33;226,5;224,43;217,63;182,83;187,36;183,84;178,51;195,78;218,04;212,94;204,31;228,91;231,87;229,32;249,21;255,47;274,95;289,84;277,92;278,14;285,77;272,94;286,24;276,69;299;313,02;321,45;352,91;318,19;315,98;273,02;295,86;280,8;267,02;295,09;318,6;308,9;311,52;305,18;308,77;330,17;321,08;341;351,96;360,2;348,08;341,33;360;356,66;383,74;409,4;420,2;396,73;414,4;406,8;438,5;476,83;460,26;450,92;477,33;85,35;468,67;513,83;532,58;533,25;502,81;485,77;471,88;501,14;502,74;477,54;508,55;502,65;487,29;480,17;479,2;473,6;;;;;;;; 19;NASDAQ:PLUG;;;;;1,24;1,37;1,79;2,35;2,49;2,56;2,24;2,21;2,14;2,63;2,65;3,8;3,16;3,87;4,36;3,54;4,18;4,28;8,21;7,71;12,98;13,41;15,47;26,39;33,91;63,85;52,46;35,84;28,51;30,89;34,19;26,62;26,06;25,54;41,65;39,85;28,23;21,87;25,29;28,61;21,7;18,48;16,57;21,24;28,04;21,01;15,98;15,96;12,37;17,02;14,87;11,72;8,83;8,32;10,39;13,12;8,46;6,83;5,89;4,04;4,5;4,45;3,53;3,44;2,31;3,33;2,33;2,47;1,75;2,26;1,96;2,3;2,13;1,86;1,61;1,35;0,87;0,82;1,49;1,5;1,48;2,33;2,69;1,92;1,97;2,08;1,81;2,26;3,13;;;;;;;; 20;NYSE:MA;;;;;188,65;211,13;224,77;239,05;254,24;251,49;266,77;272,27;280,11;271,57;276,81;286,47;298,59;315,94;306,74;241,56;274,97;301,4;295,7;308,53;358,19;338,17;289,97;336,51;356,94;321,56;362,9;356,05;382,06;359,79;365,09;375,26;346,23;347,68;334,05;314,92;359,32;386,38;360,82;357,38;359,04;357,87;315,48;350,54;329,35;286,77;328,18;356,4;347,73;370,6;355,29;363,41;379,86;365,02;393,3;394,28;412,64;395,85;376,35;413,83;426,51;449,23;474,76;478,4;451,2;447,07;441,16;463,71;482,12;493,8;499,59;531,36;219,39;555,43;576,31;548,12;548,06;581,22;561,94;566,47;591,87;568,81;551,99;543,97;570,88;555,37;521;499,66;502,92;;;;;;;; 21;NYSE:MCD;;;;;177,57;178,78;183,84;188,39;197,57;198,27;206,3;210,72;217,13;214,71;196,7;195,18;197,61;213,97;202,55;165,35;187,56;187,41;184,47;194,28;213,52;219,49;212,56;217,44;214,58;207,93;208,25;224,14;236,08;233,24;230,99;240,1;237,46;241,11;250,58;244,6;268,07;259,45;244,77;247,28;246,64;252,21;246,88;264,23;252,28;230,74;272,66;272,79;263,53;267,4;263,91;279,61;297,58;285,11;298,41;293,2;281,15;257,75;262,17;281,84;296,51;292,72;292,28;280,22;273,04;258,89;254,84;265,4;285,52;304,51;292,11;292,44;62,26;288,7;308,33;312,37;319,65;312,68;292,17;300,07;315,76;303,89;298,43;303,57;305,63;318,53;334,82;310,79;293,59;;;;;;;; 22;NASDAQ:UAL;;;;;83,73;87,27;87,81;80,87;88,86;77,65;88,45;91,91;83,15;88,41;90,84;91,63;88,09;74,8;61,26;31,55;29,58;29,46;34,61;31,38;36;34,75;33,78;45,05;43,25;39,94;53,31;57,54;54,4;59,67;52,29;46,07;46,51;47,57;48,05;42,26;43,78;42,88;44,4;46,36;50,19;47,63;35,42;37,69;35,01;32,53;43,08;44,17;37,7;48,96;51,96;44,25;44,41;47,47;54,87;54,31;49,81;41,62;35,01;39,4;41,26;41,38;45,49;47,35;51,46;52,99;48,66;45,42;43,87;57,06;78,26;97,44;43,95;105,84;93,81;69,05;68,82;81,23;79,63;88,31;104,68;96,5;94,04;101,12;111,82;107,35;103,21;92,07;90;;;;;;;; 23;NASDAQ:ZM;;;;;;;;;72,47;79,73;86,86;95,51;92,46;76,2;69,89;68,93;68,04;76,3;113,11;146,12;135,17;204,15;253,54;253,91;325,1;470,11;453;478,36;337,32;381,93;409,66;321,29;319,57;327,72;387,03;378,96;289,5;261,5;278,94;211,41;183,91;182,08;132,6;117,23;104,79;107,45;107,97;105,39;80,4;73,59;83,44;75,43;67,74;75;74,59;73,84;61,68;67,13;67,88;73,35;71,03;70,11;59,98;67,83;71,91;64,61;70,73;64,73;61,1;61,34;59,19;60,4;68,83;69,74;74,74;83,11;337,33;86,94;73,7;73,77;77,54;81,27;77,98;74,05;81,94;82,5;87,23;84,94;86,29;92,87;72,72;80,39;97,15;;;;;;;; 24;NYSE:BABA;;;;;137,07;168,49;183,03;180,89;185,57;149,26;175,05;173,11;172,41;167,23;176,67;196,31;212,1;206,59;210,98;194,48;202,67;206,57;215,7;251,02;287,03;293,98;310,84;263,36;232,73;264,69;241,69;226,73;230,95;219,48;226,78;200,09;166,99;148,05;170,17;127,53;118,79;125,79;105,19;108,8;101,21;96,05;113,68;90,34;95,41;79,99;63,58;87,56;88,09;110,2;87,79;102,18;84,16;79,55;83,35;102,16;92,9;86,53;82,54;74,88;77,51;72,17;74,03;73,37;74,85;78,34;72;78,85;82,27;106,12;97,98;85,95;120,79;98,84;132,51;132,23;119,43;114,75;113,41;120,63;138,55;178,73;170,43;164,26;146,58;168,39;142,56;125,46;131,88;;;;;;;; 25;NASDAQ:Z;;;;;31,58;35,09;41,8;35,31;33,4;43,02;47,58;49,96;32,99;29,82;32,57;39,86;45,94;46,21;54,4;36,02;43,96;58,22;57,61;68,39;85,76;101,59;89,16;107,81;129,8;137,05;167;129,64;130,12;113,56;122,22;107,52;95,77;88,14;97,15;54,27;63,85;50,48;57,52;49,29;40,96;39,9;31,75;35,28;33,46;28,61;30,86;37,98;32,21;44,21;42;44,47;43,92;45,61;50,26;54,16;52,16;45,64;36,25;40,94;57,86;56,84;56,15;48,22;42,57;40,95;46,39;48,7;54,01;63,85;60,09;83,7;134,29;82,22;76,66;68,56;67,33;68,36;70,05;79,55;81,81;77,05;74,98;73,53;68,22;62,52;43,54;41,38;44,4;;;;;;;; 26;NYSE:O;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66,09;69,3;67,38;68,22;68,26;73,67;68,28;58,2;62,27;63,07;63,43;67,83;63,95;63,32;61,49;59,69;59,3;61,03;56,26;49,06;47,39;53,84;57,6;54,8;52,14;53,46;53,54;53,06;52,82;57,43;62,28;63,42;59,37;56,69;444,68;54,64;57,03;58,01;57,86;56,58;57,61;56,13;57,74;60,79;57,98;57,43;56,37;60,53;67,56;61,18;64,24;;0;0;0;0;0;0;0 27;NYSE:TWTR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38,69;49,14;39,6;37,39;40,89;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;;;;;;;; 28;AMS:IWDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78,97;81,87;85,02;88,18;90,69;89,58;90,67;95,19;95,39;95,67;96,37;97,55;105,7;5,88;108,18;105,45;97,13;93,33;98,8;100,15;104,94;104,83;107,22;111,79;110,97;111,53;113,44;113,83;108,06;117,06;;;;;;;; 29;NASDAQ:QCOM;;;;;;49,52;53,39;57,81;86,13;66,82;77,52;73,16;75,12;76,28;80,44;82,45;88,23;85,31;80,56;67,65;78,67;79,73;91,21;105,61;119,1;117,68;123,97;147,17;152,34;161,58;139,49;132,59;138,8;133,94;142,93;148,86;146,69;128,98;134,81;180,56;182,87;175,76;171,99;152,82;145,27;143,22;127,74;147,43;137,08;114,84;117,66;126,49;109,94;133,21;123,53;127,58;115,84;113,41;119,04;132,17;114,53;111,1;108,99;129,05;144,63;148,51;157,79;171,72;165,85;204,05;199,18;180,95;163,24;170,05;162,77;163,03;41,58;172,93;157,17;153,61;148,46;146,63;159,26;146,76;158,78;166,36;180,9;168,04;171,05;152,62;141,03;128,78;179,58;;;;;;;; 30;NYSE:TSM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;172,33;165,8;160,49;173,67;190,54;194,4;197,49;209,32;180,53;166;166,69;194,84;226,49;241,62;228,39;279,29;300,43;287,68;303,89;341,36;369,11;337,95;396,06;;;;;;;; 31;INDEXNASDAQ:NDX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;182,06;172,93;171,39;180,14;182,75;200,06;203,04;207,27;201,23;178,2;172,83;189,34;192,41;203,25;198,7;203,66;222,92;218,45;215,21;217,11;211,46;200,38;227,52;;;;;;;; 32;AMS:VUSA;;;;;;44,75;46,63;48,32;49,67;47,2;49,71;51,41;50,55;51,82;51,55;53,4;54,41;55,51;51,43;45,5;50,49;52,1;51,84;52,1;55,66;54,5;54;57,23;57,66;59,07;61,42;64,31;65,96;65,19;68,67;70,48;72,91;71,18;75,44;77,22;79,99;75,58;74,06;78,41;74,42;73;68,54;76,33;75,14;70,83;74,34;72,83;67,72;70,6;71,27;71,19;70,68;74,2;77,11;78,79;79,22;77,47;74,88;79,21;82,04;85,4;89,17;91,45;90,19;91,16;96,89;95,41;96,93;97,52;100,1;109,43;108,03;111,45;107,33;97,32;92,25;97,84;99,78;105,84;104,94;107,45;112,42;111,42;111,06;112,04;111,26;105,86;115,85;;;;;;;; 33;CURRENCY:XAUEUR;;;;;;1154,29;1154,23;1152,01;1144,42;1168,96;1240,94;1276,17;1386,45;1351,13;1356,9;1328,81;1353,15;1430,87;1428,82;1427,49;1539,87;1559,63;1585,08;1675,56;1648,28;1608,99;1612,81;1489,35;1554,28;1518,47;1431,73;1455,77;1470,42;1559,47;1492,99;1529,29;1535,71;1517,31;1542,29;1565,28;1608,2;1599,65;1701,19;1750,71;1797,74;1711,91;1723,83;1722,97;1702,05;1695,66;1652,48;1699,28;1703,4;1774,86;1727,07;1817,14;1805,17;1836,93;1759,5;1787,55;1789,34;1748,36;1875,78;1870,47;1868,7;1885,9;1892,3;2070,6;2142,49;2145,24;2170,81;2260,99;2264,02;2366,64;2521,93;2504,58;2535,07;2700,15;2752,12;2886,94;2902,84;2901,27;2803,54;2881,8;2951,1;3288,04;3469,48;3665,33;3676,67;4089,85;4454,86;4039,4;3940,1;;;;;;;; 34;CURRENCY:USDEUR;;;;;;0,87;0,88;0,89;0,89;0,89;0,88;0,9;0,91;0,92;0,9;0,91;0,89;0,9;0,91;0,91;0,91;0,9;0,89;0,85;0,84;0,85;0,86;0,84;0,82;0,82;0,83;0,85;0,83;0,82;0,84;0,84;0,85;0,86;0,87;0,88;0,88;0,89;0,89;0,9;0,95;0,93;0,95;0,98;1;1,02;1,01;0,96;0,93;0,92;0,95;0,92;0,91;0,94;0,92;0,91;0,92;0,94;0,95;0,92;0,9;0,93;0,93;0,93;0,94;0,92;0,93;0,92;0,9;0,9;0,92;0,95;0,97;0,96;0,96;0,92;0,88;0,88;0,85;0,88;0,86;0,85;0,86;0,86;0,85;0,84;0,85;0,86;0,85;;;;;;;; ======================================================================================== FICHEIRO: dados_csv/extrato-revolut.csv Tamanho: 59378 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2019-10-13T20:45:52.089581Z,,CASH TOP-UP,,,USD 10,USD,1.1090 2019-10-15T15:04:56.402300Z,GOOGL,BUY - MARKET,0.00808315,USD 1237.14,USD 10,USD,1.1041 2019-10-16T16:40:49.118522Z,GOOGL,SELL - MARKET,0.00808315,USD 1244.56,USD 10.05,USD,1.1083 2019-10-16T16:42:15.845933Z,AMZN,BUY - MARKET,0.0056605,USD 1775.46,USD 10.05,USD,1.1083 2020-01-22T06:14:35.117802Z,,CASH TOP-UP,,,USD 150,USD,1.1087 2020-01-22T14:35:09.489834Z,AAPL,BUY - MARKET,0.47175745,USD 317.96,USD 150,USD,1.1087 2020-01-27T19:03:34.378166Z,,CASH TOP-UP,,,USD 100,USD,1.1016 2020-01-27T19:03:59.925033Z,AAPL,BUY - MARKET,0.32237266,USD 310.20,USD 100,USD,1.1017 2020-01-27T19:06:24.636699Z,,CASH TOP-UP,,,USD 100,USD,1.1017 2020-01-27T19:06:44.350393Z,AAPL,BUY - MARKET,0.32203007,USD 310.53,USD 100,USD,1.1016 2020-02-04T18:52:14.721865Z,,CASH TOP-UP,,,USD 100,USD,1.1043 2020-02-04T18:53:01.732348Z,ADBE,BUY - MARKET,0.27270991,USD 366.69,USD 100,USD,1.1044 2020-02-06T16:55:04.812084Z,,CASH TOP-UP,,,USD 100,USD,1.0977 2020-02-06T16:55:36.979717Z,TSLA,BUY - MARKET,0.12870012,USD 777,USD 100,USD,1.0977 2020-02-10T17:27:50.154414Z,AMZN,SELL - MARKET,0.0056605,USD 2121.72,USD 12,USD,1.0918 2020-02-12T17:19:39.458866Z,,CASH WITHDRAWAL,,,USD -12,USD,1.0883 2020-02-14T06:27:43.976551Z,AAPL,DIVIDEND,,,USD 0.73,USD,1.0841 2020-02-14T16:15:09.890489Z,,CASH TOP-UP,,,USD 23.44,USD,1.0844 2020-02-19T15:25:37.972712Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:27:08.446046Z,TSLA,BUY - MARKET,0.13183279,USD 933,USD 124.07,USD,1.0788 2020-02-19T15:31:20.268338Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:32:09.673339Z,MA,BUY - MARKET,0.28609409,USD 346.04,USD 100.07,USD,1.0787 2020-02-25T15:34:40.463966Z,,CASH TOP-UP,,,USD 100,USD,1.0852 2020-02-25T15:35:27.862543Z,MA,BUY - MARKET,0.31256977,USD 313.53,USD 99.08,USD,1.0854 2020-02-27T15:58:29.203288Z,,CASH TOP-UP,,,USD 100,USD,1.0989 2020-02-27T15:59:44.008442Z,AMZN,BUY - MARKET,0.05144915,USD 1924.23,USD 100.09,USD,1.0988 2020-02-29T23:14:40.446417Z,,CUSTODY FEE,,,USD -0.01,USD,1.1085 2020-03-10T08:36:25.622472Z,,CASH TOP-UP,,,USD 100,USD,1.1392 2020-03-10T08:43:28.760520Z,,CASH TOP-UP,,,USD 100,USD,1.1385 2020-03-16T15:06:33.044184Z,AAPL,BUY - MARKET,0.39257252,USD 254.73,USD 100,USD,1.1116 2020-03-19T14:18:51.824712Z,AMZN,BUY - MARKET,0.05281643,USD 1893.35,USD 100,USD,1.0791 2020-03-25T19:00:13.188887Z,,CASH TOP-UP,,,USD 100,USD,1.0870 2020-03-25T19:00:56.745398Z,TSLA,BUY - MARKET,0.18182479,USD 549.98,USD 100,USD,1.0875 2020-03-31T23:13:57.154290Z,,CUSTODY FEE,,,USD -0.01,USD,1.1030 2020-04-13T13:44:26.856924Z,AMZN,SELL - MARKET,0.0581643,USD 2068.97,USD 120.33,USD,1.0908 2020-04-14T13:46:27.827041Z,AMZN,SELL - MARKET,0.04610128,USD 2222.06,USD 102.43,USD,1.0963 2020-04-14T13:49:54.123864Z,TSLA,SELL - MARKET,0.18182479,USD 734.50,USD 133.54,USD,1.0962 2020-04-14T13:57:12.990070Z,NFLX,BUY - MARKET,0.25100401,USD 398.40,USD 101.09,USD,1.0962 2020-04-15T13:35:34.237135Z,TSLA,BUY - MARKET,0.13523381,USD 739.46,USD 101.08,USD,1.0879 2020-04-16T13:50:19.111529Z,NFLX,BUY - MARKET,0.22745365,USD 439.65,USD 101.08,USD,1.0879 2020-04-16T15:14:00.808432Z,,CASH TOP-UP,,,USD 150,USD,1.0846 2020-04-16T15:14:35.050777Z,AMZN,BUY - MARKET,0.08295313,USD 2411,USD 201.08,USD,1.0845 2020-04-23T14:28:19.106924Z,,CASH TOP-UP,,,USD 65,USD,1.0835 2020-04-27T13:48:51.812918Z,,CASH TOP-UP,,,USD 150,USD,1.0849 2020-04-27T13:49:44.983233Z,GOOGL,BUY - MARKET,0.15638072,USD 1278.93,USD 201.08,USD,1.0850 2020-04-29T13:25:29.598577Z,,CASH TOP-UP,,,USD 60,USD,1.0862 2020-04-30T15:20:09.164358Z,TSLA,SELL - MARKET,0.13523381,USD 841.36,USD 112.69,USD,1.0945 2020-04-30T23:18:53.565423Z,,CUSTODY FEE,,,USD -0.01,USD,1.0945 2020-05-01T15:48:15.829872Z,TSLA,BUY - MARKET,0.21263626,USD 705.43,USD 151.09,USD,1.1000 2020-05-01T15:48:47.039832Z,,CASH TOP-UP,,,USD 70,USD,1.1000 2020-05-01T15:49:20.695234Z,AMZN,BUY - MARKET,0.04362354,USD 2292.34,USD 101.09,USD,1.1002 2020-05-05T15:31:50.521509Z,AAPL,SELL - MARKET,0.39257252,USD 298.65,USD 117.23,USD,1.0845 2020-05-06T19:08:08.304224Z,TSLA,SELL - MARKET,0.21263626,USD 785.52,USD 167.02,USD,1.0807 2020-05-07T13:31:53.906481Z,MCD,BUY - MARKET,1.11594688,USD 179.22,USD 200,USD,1.0787 2020-05-11T04:29:40.915073Z,MA,DIVIDEND,,,USD 0.20,USD,1.0849 2020-05-11T15:45:23.256201Z,GOOGL,SELL - MARKET,0.15638072,USD 1397.42,USD 217.44,USD,1.0812 2020-05-11T15:57:35.550473Z,AMD,BUY - MARKET,1.80733779,USD 55.33,USD 101.08,USD,1.0815 2020-05-12T16:07:48.403062Z,NFLX,SELL - MARKET,0.25100401,USD 443.18,USD 110.15,USD,1.0866 2020-05-12T19:51:54.916962Z,MA,BUY - MARKET,0.36659579,USD 272.78,USD 101.08,USD,1.0852 2020-05-14T13:39:16.072650Z,GOOGL,BUY - MARKET,0.14908017,USD 1341.56,USD 201.07,USD,1.0794 2020-05-15T06:45:31.771097Z,AAPL,DIVIDEND,,,USD 0.78,USD,1.0803 2020-05-15T14:21:14.417945Z,,CASH TOP-UP,,,USD 200,USD,1.0834 2020-05-15T14:21:43.642288Z,XYZ,BUY - MARKET,2.54097319,USD 78.71,USD 201.08,USD,1.0834 2020-05-20T15:35:46.301014Z,MA,SELL - MARKET,0.36659579,USD 300.47,USD 109.05,USD,1.0994 2020-05-20T15:42:40.689961Z,NVDA,BUY - MARKET,0.34223706,USD 359.40,USD 124.09,USD,1.0989 2020-05-21T11:09:05.866676Z,,CASH TOP-UP,,,USD 200,USD,1.0991 2020-05-21T13:33:35.686825Z,KO,BUY - MARKET,4.34023991,USD 45.85,USD 200.09,USD,1.0984 2020-05-27T15:15:48.029062Z,,CASH TOP-UP,,,USD 101,USD,1.0978 2020-05-27T15:15:56.832046Z,ANSS,BUY - MARKET,0.38406882,USD 260.37,USD 101.09,USD,1.0979 2020-05-28T14:46:13.432873Z,MCD,SELL - MARKET,1.11594688,USD 188.74,USD 209.51,USD,1.1054 2020-05-28T14:46:46.563846Z,QCOM,BUY - MARKET,2.4789291,USD 80.68,USD 201.10,USD,1.1055 2020-05-29T16:04:45.366029Z,XYZ,SELL - MARKET,2.54097319,USD 81.15,USD 205.08,USD,1.1105 2020-05-29T16:07:02.985866Z,MSFT,BUY - MARKET,1.15486141,USD 181.84,USD 211.11,USD,1.1104 2020-05-29T19:26:29.477576Z,ADBE,SELL - MARKET,0.27270991,USD 385.61,USD 104.05,USD,1.1095 2020-05-31T23:19:05.143061Z,,CUSTODY FEE,,,USD -0.02,USD,1.1117 2020-06-01T13:02:55.670900Z,,CASH TOP-UP,,,USD 100,USD,1.1111 2020-06-01T13:42:34.671146Z,UAL,BUY - MARKET,6.8212824,USD 29.32,USD 201.11,USD,1.1117 2020-06-01T16:16:43.298913Z,TSLA,SELL - MARKET,0.12870012,USD 879.56,USD 112.08,USD,1.1131 2020-06-03T14:08:52.405659Z,ANSS,SELL - MARKET,0.38406882,USD 290.47,USD 111.55,USD,1.1224 2020-06-03T14:09:18.216215Z,UAL,BUY - MARKET,7.12250712,USD 31.59,USD 225,USD,1.1218 2020-06-03T15:40:53.775341Z,GOOGL,SELL - MARKET,0.14908017,USD 1435.47,USD 213.99,USD,1.1248 2020-06-03T15:41:39.067184Z,UAL,BUY - MARKET,6.44484412,USD 33.36,USD 216.12,USD,1.1248 2020-06-03T22:53:07.567360Z,,CASH TOP-UP,,,USD 96.40,USD,1.1233 2020-06-04T13:38:22.083446Z,UAL,BUY - MARKET,2.69444444,USD 36,USD 98.12,USD,1.1261 2020-06-04T14:52:37.932806Z,,CASH TOP-UP,,,USD 105.53,USD,1.1334 2020-06-04T14:53:08.914462Z,UAL,BUY - MARKET,2.78884462,USD 37.65,USD 106.13,USD,1.1334 2020-06-04T15:23:45.056331Z,,CASH TOP-UP,,,USD 200,USD,1.1330 2020-06-04T15:24:10.360661Z,UAL,BUY - MARKET,5.20231213,USD 38.06,USD 199.13,USD,1.1330 2020-06-05T13:04:26.828036Z,,CASH TOP-UP,,,USD 113.81,USD,1.1302 2020-06-05T14:18:00.799519Z,UAL,BUY - MARKET,2.4672489,USD 45.80,USD 114.12,USD,1.1297 2020-06-05T17:28:26.976376Z,QCOM,SELL - MARKET,2.4789291,USD 89.12,USD 220.91,USD,1.1289 2020-06-05T17:31:09.772451Z,UAL,BUY - MARKET,4.8456164,USD 44.37,USD 215,USD,1.1287 2020-06-08T14:15:52.005116Z,,CASH TOP-UP,,,USD 102.63,USD,1.1304 2020-06-08T14:16:33.413999Z,ANSS,BUY - MARKET,0.35145678,USD 284.53,USD 100,USD,1.1303 2020-06-08T14:17:24.882389Z,KO,SELL - MARKET,4.34023991,USD 49.70,USD 215.70,USD,1.1304 2020-06-08T14:23:38.760448Z,UAL,BUY - MARKET,4.86896252,USD 46.17,USD 224.80,USD,1.1309 2020-06-09T07:06:15.520922Z,,CASH TOP-UP,,,USD 100,USD,1.1277 2020-06-09T13:51:25.021186Z,UAL,BUY - MARKET,2.22121486,USD 44.12,USD 99.13,USD,1.1346 2020-06-09T14:17:33.110755Z,AMZN,SELL - MARKET,0.04362354,USD 2545.19,USD 109.89,USD,1.1345 2020-06-10T13:37:56.248650Z,UAL,BUY - MARKET,2.43486729,USD 41.07,USD 101.13,USD,1.1373 2020-06-10T13:43:11.542460Z,AAPL,SELL - MARKET,1.11616018,USD 350.18,USD 389.71,USD,1.1369 2020-06-10T13:48:41.773677Z,ANSS,BUY - MARKET,1.03831377,USD 288.93,USD 301.13,USD,1.1366 2020-06-10T14:04:33.156206Z,AMZN,SELL - MARKET,0.08295313,USD 2663.79,USD 219.83,USD,1.1366 2020-06-11T13:37:59.512320Z,TSLA,BUY - MARKET,0.30035742,USD 998.81,USD 301.13,USD,1.1367 2020-06-15T09:43:07.163997Z,,CASH TOP-UP,,,USD 150,USD,1.1250 2020-06-15T14:01:51.523075Z,AAPL,BUY - MARKET,0.44628246,USD 336.11,USD 151.12,USD,1.1280 2020-06-16T21:53:42.937926Z,,CASH TOP-UP,,,USD 97.58,USD,1.1262 2020-06-18T14:35:42.938104Z,UAL,SELL - MARKET,6.8212824,USD 40.04,USD 271.98,USD,1.1212 2020-06-18T14:37:42.274505Z,,CASH TOP-UP,,,USD 192.53,USD,1.1217 2020-06-19T13:52:12.947282Z,MSFT,SELL - MARKET,1.15486141,USD 199.15,USD 228.85,USD,1.1231 2020-06-19T13:53:37.856769Z,GOOGL,BUY - MARKET,0.20775767,USD 1443.99,USD 301.12,USD,1.1231 2020-06-19T14:05:29.762422Z,QCOM,BUY - MARKET,3.3463469,USD 89.65,USD 301.12,USD,1.1226 2020-06-22T13:37:24.868355Z,AAPL,BUY - MARKET,0.56580287,USD 353.48,USD 201.12,USD,1.1228 2020-06-26T06:44:11.028578Z,QCOM,DIVIDEND,,,USD 1.37,USD,1.1215 2020-06-29T04:54:02.365153Z,NVDA,DIVIDEND,,,USD 0.04,USD,1.1243 2020-06-30T18:19:47.514819Z,TSLA,SELL - MARKET,0.13183279,USD 1075.23,USD 141.74,USD,1.1236 2020-06-30T23:13:30.727834Z,,CUSTODY FEE,,,USD -0.03,USD,1.1237 2020-07-01T14:14:41.076966Z,UAL,SELL - MARKET,7.12250712,USD 37.39,USD 266.29,USD,1.1263 2020-07-01T14:24:40.305583Z,TSLA,SELL - MARKET,0.30035742,USD 1118.93,USD 336.06,USD,1.1266 2020-07-01T14:32:04.179320Z,NVDA,SELL - MARKET,0.34223706,USD 382.40,USD 130.86,USD,1.1275 2020-07-01T14:36:38.192960Z,NFLX,SELL - MARKET,0.22745365,USD 464.23,USD 105.58,USD,1.1268 2020-07-01T14:45:25.307546Z,KO,BUY - MARKET,6.61229887,USD 45.37,USD 300,USD,1.1269 2020-07-06T14:03:06.514648Z,AAPL,SELL - MARKET,0.44628246,USD 373.62,USD 166.73,USD,1.1327 2020-07-07T15:08:56.815724Z,UAL,BUY - MARKET,6.00781015,USD 33.29,USD 200,USD,1.1289 2020-07-07T15:09:28.099732Z,TSLA,BUY - MARKET,0.35837412,USD 1395.19,USD 500,USD,1.1289 2020-07-09T13:55:29.714774Z,ZM,BUY - MARKET,0.55248618,USD 271.50,USD 150,USD,1.1329 2020-07-09T17:10:13.780489Z,AMD,SELL - MARKET,1.80733779,USD 56.31,USD 101.76,USD,1.1295 2020-07-10T14:52:58.381420Z,AMZN,BUY - MARKET,0.03145999,USD 3178.64,USD 100,USD,1.1327 2020-07-10T19:29:46.857555Z,TSLA,SELL - MARKET,0.35837412,USD 1534.51,USD 549.91,USD,1.1304 2020-07-13T13:35:28.048770Z,AAPL,SELL - MARKET,0.56580287,USD 390.38,USD 220.87,USD,1.1352 2020-07-13T13:35:47.111924Z,TSLA,BUY - MARKET,0.17648096,USD 1699.90,USD 300,USD,1.1351 2020-07-13T13:35:52.230844Z,AMZN,BUY - MARKET,0.09185548,USD 3266,USD 300,USD,1.1350 2020-07-13T14:51:54.087827Z,MA,SELL - MARKET,0.31256977,USD 296.73,USD 92.74,USD,1.1368 2020-07-14T13:31:59.854077Z,AAPL,BUY - MARKET,0.65824117,USD 379.80,USD 250,USD,1.1369 2020-07-15T13:34:09.322645Z,UAL,SELL - MARKET,6.44484412,USD 34.06,USD 219.50,USD,1.1453 2020-07-15T13:35:04.961261Z,UAL,SELL - MARKET,6.00781015,USD 34.21,USD 205.52,USD,1.1450 2020-07-15T13:36:54.903151Z,AAPL,BUY - MARKET,0.5079494,USD 393.74,USD 200,USD,1.1450 2020-07-15T13:37:08.648684Z,TSLA,BUY - MARKET,0.13297872,USD 1504,USD 200,USD,1.1447 2020-07-17T10:21:42.253727Z,,CASH WITHDRAWAL,,,USD -16,USD,1.1414 2020-07-20T15:28:03.617896Z,GOOGL,SELL - MARKET,0.20775767,USD 1553.01,USD 322.63,USD,1.1444 2020-07-20T15:28:23.429522Z,UAL,BUY - MARKET,9.17150718,USD 32.71,USD 300,USD,1.1443 2020-07-21T13:52:52.140017Z,KO,SELL - MARKET,6.61229887,USD 47.62,USD 314.86,USD,1.1450 2020-07-21T14:53:45.843776Z,AAPL,BUY - MARKET,0.76413652,USD 392.60,USD 300,USD,1.1482 2020-07-23T16:16:56.135853Z,UAL,SELL - MARKET,9.17150718,USD 33.58,USD 307.96,USD,1.1618 2020-07-23T16:17:12.192300Z,AMZN,BUY - MARKET,0.09914274,USD 3025.94,USD 300,USD,1.1619 2020-07-24T13:37:52.361330Z,AMD,BUY - MARKET,1.05263157,USD 66.50,USD 70,USD,1.1611 2020-07-24T15:46:13.810803Z,AMD,SELL - MARKET,1.05263157,USD 68.80,USD 72.41,USD,1.1637 2020-07-24T15:50:14.518607Z,ZM,BUY - MARKET,0.28389503,USD 246.57,USD 70,USD,1.1635 2020-07-25T21:25:27.926085Z,,CASH TOP-UP,,,USD 150,USD,1.1714 2020-07-27T13:40:19.675494Z,TSLA,BUY - MARKET,0.10470034,USD 1432.66,USD 150,USD,1.1746 2020-07-30T13:37:41.742329Z,QCOM,SELL - MARKET,3.3463469,USD 102.67,USD 343.55,USD,1.1800 2020-07-30T13:44:03.123846Z,GOOGL,BUY - MARKET,0.19926934,USD 1505.50,USD 300,USD,1.1804 2020-07-30T16:32:20.847339Z,ANSS,SELL - MARKET,0.35145678,USD 309.60,USD 108.80,USD,1.1801 2020-07-30T16:35:39.859799Z,MSFT,BUY - MARKET,0.73800738,USD 203.25,USD 150,USD,1.1802 2020-07-31T15:21:05.501725Z,AAPL,SELL - MARKET,0.65824117,USD 411.70,USD 270.98,USD,1.1839 2020-07-31T15:23:47.598730Z,GOOGL,BUY - MARKET,0.16989812,USD 1471.47,USD 250,USD,1.1840 2020-07-31T23:43:53.566513Z,,CUSTODY FEE,,,USD -0.03,USD,1.1837 2020-08-03T13:46:32.153897Z,AAPL,SELL - MARKET,1.27208592,USD 444.06,USD 564.86,USD,1.1709 2020-08-03T14:00:31.581377Z,TSLA,BUY - MARKET,0.2030663,USD 1477.35,USD 300,USD,1.1731 2020-08-03T18:28:17.331649Z,ANSS,SELL - MARKET,1.03831377,USD 315.57,USD 327.64,USD,1.1755 2020-08-04T20:41:16.072701Z,,CASH WITHDRAWAL,,,USD -16.50,USD,1.1799 2020-08-05T13:32:48.539437Z,ANSS,BUY - MARKET,0.95910994,USD 312.79,USD 300,USD,1.1881 2020-08-05T13:36:03.481722Z,AMD,BUY - MARKET,1.18990956,USD 84.04,USD 100,USD,1.1891 2020-08-06T09:23:31.359439Z,,CASH TOP-UP,,,USD 300,USD,1.1850 2020-08-06T14:00:31.092775Z,AAPL,BUY - MARKET,0.22504782,USD 444.35,USD 100,USD,1.1859 2020-08-10T04:51:32.749766Z,MA,DIVIDEND,,,USD 0.20,USD,1.1794 2020-08-10T14:52:42.356948Z,UAL,SELL - MARKET,2.6944444,USD 36.55,USD 98.47,USD,1.1769 2020-08-10T14:54:34.374914Z,AMD,BUY - MARKET,1.23701138,USD 80.84,USD 100,USD,1.1768 2020-08-10T14:57:30.636414Z,ANSS,BUY - MARKET,0.32998944,USD 303.04,USD 100,USD,1.1767 2020-08-13T13:31:33.235267Z,TSLA,SELL - MARKET,0.10470034,USD 1607.54,USD 168.30,USD,1.1839 2020-08-13T14:32:36.305371Z,TSLA,SELL - MARKET,0.2030663,USD 1632.37,USD 331.46,USD,1.1859 2020-08-13T14:36:28.249846Z,ZM,BUY - MARKET,0.40695071,USD 245.73,USD 100,USD,1.1851 2020-08-14T06:42:26.713153Z,AAPL,DIVIDEND,,,USD 0.15,USD,1.1819 2020-08-14T13:33:39.022612Z,TSLA,SELL - MARKET,0.1397872,USD 1661.02,USD 232.17,USD,1.1826 2020-08-14T14:12:17.671752Z,XYZ,BUY - MARKET,0.7033338,USD 142.18,USD 100,USD,1.1830 2020-08-17T13:33:39.120706Z,TSLA,BUY - MARKET,0.05902769,USD 1694.12,USD 100,USD,1.1863 2020-08-17T14:36:39.947800Z,TSLA,BUY - MARKET,0.0561394,USD 1781.28,USD 100,USD,1.1883 2020-08-17T16:28:45.503089Z,XYZ,BUY - MARKET,0.66613375,USD 150.12,USD 100,USD,1.1860 2020-08-18T13:40:16.844239Z,TSLA,SELL - MARKET,0.05902769,USD 1883.01,USD 111.14,USD,1.1962 2020-08-18T13:46:26.654Z,ZM,SELL - MARKET,0.40695071,USD 270.87,USD 110.22,USD,1.1962 2020-08-18T14:20:31.458481Z,TSLA,SELL - MARKET,0.17599953,USD 1878.58,USD 330.61,USD,1.1934 2020-08-18T16:27:49.232388Z,UAL,BUY - MARKET,2.9620853,USD 33.76,USD 100,USD,1.1937 2020-08-19T16:01:34.832909Z,AMZN,SELL - MARKET,0.09914274,USD 3306.04,USD 327.75,USD,1.1899 2020-08-19T16:19:13.539922Z,NVDA,BUY - MARKET,0.10171698,USD 491.56,USD 50,USD,1.1872 2020-08-19T16:27:25.319575Z,MA,SELL - MARKET,0.28609409,USD 331.39,USD 94.80,USD,1.1877 2020-08-20T15:13:31.608194Z,TSLA,SELL - MARKET,0.04981235,USD 1966.58,USD 97.95,USD,1.1848 2020-08-20T15:17:03.912150Z,XYZ,SELL - MARKET,0.7033338,USD 156.27,USD 109.90,USD,1.1847 2020-08-20T15:35:58.284968Z,TSLA,BUY - MARKET,0.05034207,USD 1986.41,USD 100,USD,1.1856 2020-08-20T19:11:21.856894Z,TSLA,BUY - MARKET,0.04959308,USD 2016.41,USD 100,USD,1.1860 2020-08-21T13:46:22.168804Z,AAPL,BUY - MARKET,0.41413869,USD 482.93,USD 200,USD,1.1767 2020-08-21T13:46:40.645696Z,TSLA,BUY - MARKET,0.09623805,USD 2078.18,USD 200,USD,1.1765 2020-08-21T16:26:59.511866Z,ZM,SELL - MARKET,0.83638121,USD 290.27,USD 242.76,USD,1.1768 2020-08-21T16:30:38.287214Z,TSLA,BUY - MARKET,0.09596054,USD 2084.19,USD 200,USD,1.1770 2020-08-24T16:07:10.297884Z,UAL,SELL - MARKET,2.9620853,USD 36.19,USD 107.19,USD,1.1805 2020-08-24T16:08:07.511680Z,TSLA,BUY - MARKET,0.09782821,USD 2044.40,USD 200,USD,1.1805 2020-08-25T14:44:00.531640Z,BABA,BUY - MARKET,0.17636684,USD 283.50,USD 50,USD,1.1826 2020-08-25T15:15:44.630812Z,GOOGL,SELL - MARKET,0.16989812,USD 1605.20,USD 272.70,USD,1.1828 2020-08-26T15:07:42.730768Z,ZM,BUY - MARKET,0.1661792,USD 300.88,USD 50,USD,1.1821 2020-08-26T15:42:29.143351Z,BABA,BUY - MARKET,0.17246731,USD 289.91,USD 50,USD,1.1825 2020-08-27T13:56:12.492183Z,MSFT,SELL - MARKET,0.73800738,USD 229.08,USD 169.05,USD,1.1807 2020-08-27T13:57:57.647626Z,UAL,SELL - MARKET,2.78884462,USD 37.49,USD 104.54,USD,1.1803 2020-08-27T14:08:52.657497Z,UAL,SELL - MARKET,5.20231213,USD 36.73,USD 191.07,USD,1.1782 2020-08-27T14:47:04.731766Z,ANSS,SELL - MARKET,0.32998944,USD 331.65,USD 109.43,USD,1.1786 2020-08-27T15:52:39.194814Z,TSLA,BUY - MARKET,0.08780286,USD 2277.83,USD 200,USD,1.1825 2020-08-27T15:59:47.914287Z,TSLA,SELL - MARKET,0.09782821,USD 2272.96,USD 222.35,USD,1.1826 2020-08-27T16:02:06.770299Z,TSLA,BUY - MARKET,0.21983819,USD 2274.40,USD 500,USD,1.1822 2020-08-27T16:40:42.718746Z,TSLA,BUY - MARKET,0.22686231,USD 2203.98,USD 500,USD,1.1825 2020-08-27T17:15:43.206363Z,AAPL,BUY - MARKET,0.40120361,USD 498.50,USD 200,USD,1.1814 2020-08-28T14:57:20.303825Z,TSLA,SELL - MARKET,0.05034207,USD 2272.06,USD 114.37,USD,1.1911 2020-08-28T15:25:39.775903Z,UAL,SELL - MARKET,2.43486729,USD 37.02,USD 90.13,USD,1.1899 2020-08-28T15:30:21.083145Z,NVDA,BUY - MARKET,0.09644131,USD 518.45,USD 50,USD,1.1902 2020-08-31T00:22:15.681429Z,,CASH WITHDRAWAL,,,USD -16.66,USD,1.1915 2020-08-31T08:24:29.814099Z,AAPL,STOCK SPLIT,3.12117036,,USD 0,USD,1.1899 2020-08-31T08:27:18.193687Z,TSLA,STOCK SPLIT,3.10518012,,USD 0,USD,1.1898 2020-08-31T14:23:19.225150Z,TSLA,SELL - MARKET,0.48119025,USD 463.12,USD 222.84,USD,1.1941 2020-08-31T14:25:12.090849Z,TSLA,BUY - MARKET,1.07529194,USD 464.99,USD 500,USD,1.1939 2020-08-31T14:34:07.507538Z,AAPL,SELL - MARKET,0.90019128,USD 128.26,USD 115.45,USD,1.1945 2020-08-31T14:36:41.781166Z,TSLA,SELL - MARKET,0.4798027,USD 465.17,USD 223.18,USD,1.1950 2020-08-31T14:58:49.683011Z,AMD,SELL - MARKET,1.23701138,USD 89.87,USD 111.16,USD,1.1965 2020-08-31T15:00:12.913839Z,AMZN,SELL - MARKET,0.03145999,USD 3492.37,USD 109.86,USD,1.1961 2020-08-31T15:10:00.501852Z,TSLA,BUY - MARKET,0.41160732,USD 485.90,USD 200,USD,1.1951 2020-08-31T15:56:12.322382Z,TSLA,SELL - MARKET,1.13431155,USD 483.77,USD 548.73,USD,1.1955 2020-08-31T19:02:14.692076Z,TSLA,SELL - MARKET,0.2479654,USD 495.19,USD 122.78,USD,1.1935 2020-08-31T19:06:47.005425Z,TSLA,BUY - MARKET,1.00952996,USD 495.28,USD 500,USD,1.1938 2020-08-31T23:54:32.172792Z,,CUSTODY FEE,,,USD -0.02,USD,1.1940 2020-09-01T13:31:35.939299Z,ZM,BUY - MARKET,0.23466466,USD 426.14,USD 100,USD,1.1988 2020-09-01T13:31:46.997999Z,TSLA,BUY - MARKET,1.0119409,USD 494.10,USD 500,USD,1.1988 2020-09-01T13:47:37.140689Z,XYZ,SELL - MARKET,0.66613375,USD 166.08,USD 110.62,USD,1.1977 2020-09-01T13:53:42.126313Z,ZM,BUY - MARKET,0.44881288,USD 445.62,USD 200,USD,1.1969 2020-09-01T13:59:53.248673Z,ZM,SELL - MARKET,0.1661792,USD 453.67,USD 75.38,USD,1.1977 2020-09-01T14:07:15.473203Z,ZM,BUY - MARKET,0.42154073,USD 474.45,USD 200,USD,1.1952 2020-09-01T18:05:30.665718Z,GOOGL,SELL - MARKET,0.19926934,USD 1655.45,USD 329.86,USD,1.1917 2020-09-01T18:07:04.483988Z,ANSS,SELL - MARKET,0.95910994,USD 344.33,USD 330.23,USD,1.1919 2020-09-01T18:13:20.177621Z,NIO,BUY - MARKET,10.07556675,USD 19.85,USD 200,USD,1.1921 2020-09-02T13:33:53.638044Z,NIO,BUY - MARKET,10,USD 20.74,USD 207.40,USD,1.1832 2020-09-02T13:45:31.065500Z,NVDA,SELL - MARKET,0.19815829,USD 577.22,USD 114.37,USD,1.1839 2020-09-02T14:00:41.420342Z,TSLA,BUY - MARKET,0.84973166,USD 447.20,USD 380,USD,1.1834 2020-09-02T14:58:26.424459Z,,CASH TOP-UP,,,USD 200,USD,1.1844 2020-09-04T06:57:55.602815Z,,CASH WITHDRAWAL,,,USD -200,USD,1.1841 2020-09-04T07:21:47.180268Z,,CASH TOP-UP,,,USD 250,USD,1.1845 2020-09-04T07:22:00.765905Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1846 2020-09-10T06:43:18.012788Z,,CASH TOP-UP,,,USD 250,USD,1.1832 2020-09-10T06:43:39.697815Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1832 2020-09-11T07:08:09.301110Z,MSFT,DIVIDEND,,,USD 0.32,USD,1.1840 2020-09-15T14:37:48.200676Z,TSLA,SELL - MARKET,0.65498179,USD 438.20,USD 286.99,USD,1.1850 2020-09-15T14:54:20.817595Z,UAL,SELL - MARKET,2.22121486,USD 37.07,USD 82.33,USD,1.1857 2020-09-17T12:25:07.952921Z,,CASH WITHDRAWAL,,,USD -370.20,USD,1.1805 2020-09-22T13:33:29.786892Z,ZM,SELL - MARKET,0.23466466,USD 469.01,USD 110.05,USD,1.1759 2020-09-22T15:55:51.449872Z,ZM,SELL - MARKET,0.44881288,USD 488.20,USD 219.10,USD,1.1706 2020-09-23T14:38:22.109173Z,ZM,SELL - MARKET,0.42154073,USD 520,USD 219.19,USD,1.1668 2020-09-24T07:30:01.867812Z,,CASH WITHDRAWAL,,,USD -329.15,USD,1.1653 2020-09-25T05:34:43.533083Z,NVDA,DIVIDEND,,,USD 0.03,USD,1.1674 2020-09-25T07:08:24.483137Z,,CASH WITHDRAWAL,,,USD -219.22,USD,1.1668 2020-09-28T15:41:23.188756Z,BABA,SELL - MARKET,0.34883415,USD 275.69,USD 96.16,USD,1.1662 2020-09-29T15:58:04.990015Z,AMD,SELL - MARKET,1.18990956,USD 81.35,USD 96.79,USD,1.1721 2020-09-30T13:41:16.788426Z,NIO,SELL - MARKET,10.07556675,USD 22.13,USD 222.96,USD,1.1695 2020-09-30T23:05:22.729899Z,,CUSTODY FEE,,,USD -0.03,USD,1.1730 2020-10-01T08:39:07.068215Z,,CASH WITHDRAWAL,,,USD -16.40,USD,1.1728 2020-10-01T19:43:49.909598Z,TSLA,SELL - MARKET,0.60709082,USD 448.45,USD 272.23,USD,1.1745 2020-10-02T18:46:35.354198Z,,CASH WITHDRAWAL,,,USD -399.48,USD,1.1719 2020-10-06T13:45:20.572814Z,UAL,SELL - MARKET,2.4672489,USD 36.78,USD 90.74,USD,1.1797 2020-10-06T19:05:39.180375Z,,CASH WITHDRAWAL,,,USD -272.23,USD,1.1754 2020-10-08T14:41:22.813140Z,UAL,SELL - MARKET,4.8456164,USD 37.49,USD 181.65,USD,1.1744 2020-10-08T14:45:00.269291Z,UAL,SELL - MARKET,4.86896256,USD 37.41,USD 182.14,USD,1.1743 2020-10-09T18:26:13.289084Z,AAPL,SELL - MARKET,2.02064706,USD 116.32,USD 235.02,USD,1.1828 2020-10-12T17:56:05.845122Z,AAPL,SELL - MARKET,1.24072214,USD 124.33,USD 154.25,USD,1.1810 2020-10-14T13:30:16.262543Z,NIO,SELL - LIMIT,10,USD 24,USD 239.98,USD,1.1762 2020-10-14T15:26:47.927855Z,TSLA,SELL - MARKET,0.98969047,USD 462.20,USD 457.41,USD,1.1763 2020-10-15T12:02:19.535807Z,,CASH WITHDRAWAL,,,USD -400,USD,1.1708 2020-10-22T09:23:25.613263Z,,CASH WITHDRAWAL,,,USD -680,USD,1.1842 2020-10-22T19:06:30.184890Z,,CASH WITHDRAWAL,,,USD -461.19,USD,1.1819 2020-10-30T16:49:56.657758Z,,CASH TOP-UP,,,USD 230,USD,1.1655 2020-10-30T18:55:13.772909Z,,CASH WITHDRAWAL,,,USD -230,USD,1.1650 2020-11-01T00:12:15.461073Z,,CUSTODY FEE,,,USD -0.01,USD,1.1764 2020-11-02T23:50:23.731454Z,,CASH TOP-UP,,,USD 0.01,USD,1.1643 2020-11-13T17:32:40.396936Z,TSLA,SELL - MARKET,1.09919095,USD 404.95,USD 445.10,USD,1.1829 2020-11-13T17:33:09.255036Z,AMZN,SELL - MARKET,0.09185548,USD 3115.11,USD 286.12,USD,1.1829 2020-11-17T08:14:31.505714Z,,CASH WITHDRAWAL,,,USD -731.22,USD,1.1861 2020-11-26T10:29:43.997425Z,,CASH TOP-UP,,,USD 64.15,USD,1.1908 2020-11-30T14:07:20.231291Z,,CASH TOP-UP,,,USD 600,USD,1.1997 2020-11-30T14:13:04.510383Z,,CASH WITHDRAWAL,,,USD -664.15,USD,1.1995 2020-11-30T23:42:00.247197Z,,CUSTODY FEE,,,USD -0.01,USD,1.1938 2020-12-01T23:01:04.658915Z,,CASH TOP-UP,,,USD 0.01,USD,1.2075 2020-12-03T16:01:52.681026Z,TSLA,SELL - MARKET,1.51430624,USD 587.30,USD 889.32,USD,1.2162 2020-12-03T20:02:02.615104Z,,CASH TOP-UP,,,USD 283.13,USD,1.2146 2020-12-07T09:33:26.482581Z,,CASH TOP-UP,,,USD 245.04,USD,1.2091 2020-12-07T10:19:04.708279Z,,CASH WITHDRAWAL,,,USD -1417.49,USD,1.2098 2020-12-08T20:25:49.896141Z,,CASH TOP-UP,,,USD 600,USD,1.2104 2020-12-08T20:26:38.575792Z,MRNA,BUY - MARKET,3,USD 167.84,USD 503.52,USD,1.2104 2020-12-10T08:24:28.915801Z,,CASH TOP-UP,,,USD 1045.98,USD,1.2095 2020-12-10T14:30:02.653115Z,AMD,BUY - LIMIT,4,USD 89.55,USD 358.20,USD,1.2110 2020-12-10T14:30:13.150135Z,TSLA,BUY - LIMIT,1,USD 573.85,USD 573.85,USD,1.2112 2020-12-10T14:47:14.048156Z,MRNA,BUY - MARKET,1,USD 155.44,USD 155.44,USD,1.2139 2020-12-14T08:42:02.044895Z,,CASH TOP-UP,,,USD 873.84,USD,1.2148 2020-12-14T14:48:21.225847Z,TSLA,BUY - MARKET,1.39009052,USD 617.42,USD 858.27,USD,1.2161 2020-12-14T14:56:33.643638Z,NIO,BUY - MARKET,1,USD 39.90,USD 39.90,USD,1.2163 2020-12-15T14:33:22.241704Z,TSLA,SELL - MARKET,1.42113728,USD 640.27,USD 909.88,USD,1.2156 2020-12-15T14:50:30.838195Z,ANSS,BUY - MARKET,1,USD 345.66,USD 345.66,USD,1.2159 2020-12-15T18:04:07.650518Z,MRNA,BUY - LIMIT,4,USD 145,USD 580,USD,1.2161 2020-12-17T08:40:21.201412Z,,CASH TOP-UP,,,USD 1011.96,USD,1.2241 2020-12-17T14:30:06.433198Z,AAPL,BUY - LIMIT,3,USD 128.98,USD 386.94,USD,1.2249 2020-12-17T14:44:55.714193Z,TSLA,BUY - LIMIT,1,USD 620,USD 620,USD,1.2253 2020-12-17T20:44:47.556398Z,TSLA,SELL - LIMIT,1,USD 650,USD 649.98,USD,1.2263 2020-12-17T20:47:30.660341Z,AAPL,BUY - LIMIT,5,USD 128.63,USD 643.15,USD,1.2263 2020-12-21T13:26:44.115395Z,,CASH TOP-UP,,,USD 934.75,USD,1.2192 2020-12-21T15:25:16.971865Z,AMD,BUY - LIMIT,3,USD 92,USD 276,USD,1.2219 2020-12-22T14:30:05.457349Z,TSLA,BUY - LIMIT,1,USD 647.31,USD 647.31,USD,1.2225 2020-12-23T08:20:49.417315Z,,CASH TOP-UP,,,USD 440.80,USD,1.2179 2020-12-23T10:08:57.914132Z,,CASH TOP-UP,,,USD 1218.96,USD,1.2194 2020-12-23T14:30:12.260390Z,AAPL,BUY - LIMIT,4,USD 132.17,USD 528.68,USD,1.2199 2020-12-23T14:32:40.448977Z,TSLA,BUY - LIMIT,1,USD 630,USD 630,USD,1.2217 2020-12-23T15:56:56.184999Z,AMZN,BUY - MARKET,0.15645779,USD 3195.75,USD 500,USD,1.2185 2020-12-24T15:56:44.818105Z,,CASH TOP-UP,,,USD 14.23,USD,1.2184 2020-12-30T19:41:15.069854Z,TSLA,SELL - LIMIT,2,USD 695,USD 1389.96,USD,1.2289 2020-12-31T12:20:23.184470Z,,CASH TOP-UP,,,USD 500,USD,1.2276 2020-12-31T12:24:43.742Z,,CASH WITHDRAWAL,,,USD -64.98,USD,1.2273 2020-12-31T14:31:39.601626Z,NIO,BUY - LIMIT,10,USD 48.50,USD 485,USD,1.2279 2020-12-31T17:17:42.145519Z,TSLA,BUY - MARKET,1,USD 716.49,USD 716.49,USD,1.2232 2021-01-01T01:29:50.870336Z,,CUSTODY FEE,,,USD -0.04,USD,1.2219 2021-01-04T16:07:56.289208Z,AAPL,BUY - LIMIT,1,USD 130,USD 130,USD,1.2275 2021-01-06T16:21:50.650163Z,TSLA,BUY - MARKET,0.71085433,USD 769.37,USD 546.91,USD,1.2280 2021-01-07T15:55:24.088592Z,TSLA,SELL - LIMIT,2,USD 800,USD 1599.95,USD,1.2262 2021-01-07T16:23:46.257213Z,TSLA,BUY - MARKET,1,USD 805.56,USD 805.56,USD,1.2275 2021-01-08T01:26:54.692376Z,,CASH TOP-UP,,,USD 549.96,USD,1.2246 2021-01-08T09:16:01.965750Z,,CASH WITHDRAWAL,,,USD -71.85,USD,1.2234 2021-01-08T14:34:59.679144Z,TSLA,BUY - MARKET,0.28914567,USD 845.97,USD 244.61,USD,1.2280 2021-01-08T15:22:16.713016Z,TSLA,BUY - MARKET,1,USD 869.32,USD 869.32,USD,1.2229 2021-01-11T15:11:20.833428Z,NIO,BUY - MARKET,2,USD 64.89,USD 129.78,USD,1.2147 2021-01-13T08:40:39.001823Z,,CASH TOP-UP,,,USD 576.16,USD,1.2198 2021-01-13T14:36:16.142906Z,PLUG,BUY - MARKET,8,USD 69.31,USD 554.48,USD,1.2167 2021-01-14T15:14:44.924095Z,TSLA,SELL - LIMIT,1,USD 860,USD 859.97,USD,1.2118 2021-01-14T18:07:30.816970Z,PLUG,SELL - MARKET,8,USD 64.35,USD 514.78,USD,1.2167 2021-01-14T18:07:52.552385Z,MRNA,BUY - MARKET,4,USD 129.08,USD 516.32,USD,1.2168 2021-01-15T15:13:10.226921Z,NIO,BUY - MARKET,15,USD 57.38,USD 860.70,USD,1.2094 2021-01-20T14:30:56.453166Z,NIO,SELL - LIMIT,11,USD 60,USD 659.98,USD,1.2101 2021-01-22T16:33:20.961547Z,TSLA,BUY - MARKET,0.84141694,USD 831.93,USD 700,USD,1.2179 2021-01-25T15:03:48.621618Z,TSLA,SELL - LIMIT,1,USD 900,USD 899.97,USD,1.2129 2021-01-25T15:46:48.750569Z,AAPL,SELL - MARKET,5,USD 144.30,USD 721.47,USD,1.2129 2021-01-25T15:58:40.136461Z,TSLA,BUY - LIMIT,1,USD 870,USD 870,USD,1.2130 2021-01-25T16:04:44.895297Z,AAPL,BUY - LIMIT,5,USD 140,USD 700,USD,1.2129 2021-01-25T18:05:09.838791Z,NIO,BUY - LIMIT,1,USD 59.62,USD 59.62,USD,1.2148 2021-01-27T15:07:02.285287Z,,CASH TOP-UP,,,USD 136.83,USD,1.2080 2021-01-27T15:20:25.147014Z,,CASH TOP-UP,,,USD 470.71,USD,1.2077 2021-01-27T15:43:15.633441Z,AAPL,BUY - MARKET,2,USD 143.31,USD 286.62,USD,1.2091 2021-01-27T15:48:10.015296Z,MRNA,BUY - LIMIT,2,USD 158.09,USD 316.18,USD,1.2094 2021-01-28T07:27:07.598501Z,,CASH TOP-UP,,,USD 1373.27,USD,1.2089 2021-01-28T17:28:28.927848Z,MRNA,BUY - MARKET,3,USD 165.86,USD 497.58,USD,1.2126 2021-01-29T14:30:47.770020Z,MRNA,SELL - LIMIT,6,USD 174,USD 1043.97,USD,1.2153 2021-01-29T14:51:33.499884Z,TSLA,BUY - MARKET,1,USD 840.99,USD 840.99,USD,1.2148 2021-01-29T15:16:26.525884Z,MRNA,BUY - LIMIT,6,USD 177.35,USD 1064.10,USD,1.2147 2021-02-01T04:30:09.384615Z,,CUSTODY FEE,,,USD -0.09,USD,1.2133 2021-02-01T18:09:50.812968Z,,CASH TOP-UP,,,USD 196.46,USD,1.2067 2021-02-01T18:10:12.917721Z,MRNA,BUY - MARKET,1,USD 156.50,USD 156.50,USD,1.2067 2021-02-02T15:02:02.882495Z,ANSS,SELL - MARKET,1,USD 375.59,USD 375.57,USD,1.2033 2021-02-02T15:37:15.304627Z,TSLA,SELL - MARKET,0.71085433,USD 872.04,USD 619.87,USD,1.2029 2021-02-02T15:56:12.366798Z,AAPL,BUY - MARKET,4,USD 135.67,USD 542.68,USD,1.2029 2021-02-03T17:43:36.485615Z,AMZN,SELL - MARKET,0.15645779,USD 3399.26,USD 531.82,USD,1.2031 2021-02-04T17:57:10.745295Z,MRNA,SELL - MARKET,6,USD 172,USD 1031.97,USD,1.1965 2021-02-04T18:01:38.009039Z,,CASH WITHDRAWAL,,,USD -32.26,USD,1.1962 2021-02-05T17:10:07.082216Z,PYPL,BUY - MARKET,3,USD 267.18,USD 801.54,USD,1.2040 2021-02-08T14:56:37.080784Z,MRNA,SELL - LIMIT,6,USD 185,USD 1109.97,USD,1.2061 2021-02-08T15:09:42.308233Z,PYPL,BUY - MARKET,3,USD 280.95,USD 842.85,USD,1.2061 2021-02-08T15:15:57.131010Z,AMZN,BUY - MARKET,0.25,USD 3323.72,USD 830.93,USD,1.2060 2021-02-09T19:58:40.343296Z,NIO,SELL - MARKET,15,USD 62.66,USD 939.87,USD,1.2121 2021-02-09T20:00:27.291440Z,MRNA,BUY - MARKET,3,USD 178.82,USD 536.46,USD,1.2121 2021-02-09T21:20:29.683577Z,,CASH WITHDRAWAL,,,USD -500,USD,1.2121 2021-02-10T14:43:53.048254Z,TSLA,BUY - MARKET,0.69581812,USD 835.75,USD 581.53,USD,1.2135 2021-02-11T15:53:16.248489Z,PYPL,SELL - LIMIT,3,USD 300.01,USD 900,USD,1.2140 2021-02-11T19:21:16.355706Z,PYPL,BUY - LIMIT,3,USD 285,USD 855,USD,1.2133 2021-02-12T07:09:53.382539Z,AAPL,DIVIDEND,,,USD 3.31,USD,1.2126 2021-02-12T15:12:50.744899Z,AMZN,SELL - MARKET,0.25,USD 3250.16,USD 812.51,USD,1.2097 2021-02-12T15:13:55.508641Z,PYPL,BUY - MARKET,2.8,USD 292.47,USD 818.92,USD,1.2098 2021-02-19T18:01:22.470148Z,,CASH WITHDRAWAL,,,USD -41.90,USD,1.2129 2021-03-01T02:07:33.445438Z,,CUSTODY FEE,,,USD -0.08,USD,1.2090 2021-03-02T21:51:18.062393Z,,CASH TOP-UP,,,USD 0.08,USD,1.2091 2021-03-12T14:45:17.576033Z,,CASH TOP-UP,,,USD 178.93,USD,1.1937 2021-03-12T14:45:57.397742Z,NIO,BUY - LIMIT,4,USD 44.30,USD 177.20,USD,1.1933 2021-04-01T07:49:55.154005Z,,CUSTODY FEE,,,USD -0.97,USD,1.1737 2021-04-15T16:45:21.353857Z,AMD,SELL - MARKET,7,USD 83.06,USD 581.42,USD,1.1976 2021-04-19T14:24:42.527100Z,TSLA,BUY - MARKET,0.78607363,USD 699.68,USD 550,USD,1.2032 2021-05-01T08:17:07.806729Z,,CUSTODY FEE,,,USD -1.07,USD,1.2142 2021-05-03T19:47:37.874160Z,MRNA,SELL - MARKET,9,USD 186.87,USD 1681.81,USD,1.2067 2021-05-04T14:18:13.245358Z,GOOGL,BUY - MARKET,0.09823182,USD 2290.50,USD 225,USD,1.2027 2021-05-04T17:03:55.276186Z,MRNA,BUY - MARKET,4,USD 175.47,USD 701.88,USD,1.2021 2021-05-04T17:06:43.250543Z,ANSS,BUY - MARKET,2,USD 350.09,USD 700.18,USD,1.2023 2021-05-04T17:07:18.273114Z,AMZN,BUY - MARKET,0.02585158,USD 3288,USD 85,USD,1.2023 2021-05-14T04:54:27.999346Z,AAPL,DIVIDEND,,,USD 3.55,USD,1.2089 2021-05-24T15:55:44.146809Z,,CASH TOP-UP,,,USD 50,USD,1.2213 2021-05-24T15:56:03.617327Z,SPCE,BUY - MARKET,2,USD 24.93,USD 49.86,USD,1.2212 2021-05-27T15:57:09.986850Z,SPCE,SELL - MARKET,2,USD 28.02,USD 56.03,USD,1.2198 2021-05-27T16:51:08.235670Z,,CASH TOP-UP,,,USD 50,USD,1.2193 2021-05-27T16:52:28.014919Z,,CASH TOP-UP,,,USD 10,USD,1.2195 2021-05-27T16:52:47.221525Z,SPCE,BUY - MARKET,4,USD 28.53,USD 114.12,USD,1.2194 2021-05-27T19:11:54.661834Z,MRNA,SELL - MARKET,4,USD 177.05,USD 708.19,USD,1.2200 2021-05-27T19:12:45.582300Z,SPCE,BUY - LIMIT,23,USD 30.62,USD 704.26,USD,1.2199 2021-06-01T04:34:31.145849Z,,CUSTODY FEE,,,USD -1.03,USD,1.2229 2021-06-07T15:22:20.528310Z,SPCE,SELL - MARKET,27,USD 33.85,USD 913.97,USD,1.2198 2021-06-07T19:32:00.085384Z,NIO,BUY - MARKET,10,USD 43.72,USD 437.20,USD,1.2198 2021-06-08T14:19:53.290150Z,SPCE,BUY - MARKET,12,USD 37.36,USD 448.31,USD,1.2188 2021-06-25T13:30:46.699710Z,SPCE,SELL - LIMIT,12,USD 47.73,USD 572.75,USD,1.1969 2021-06-28T15:36:38.638872Z,NIO,SELL - LIMIT,14,USD 49,USD 685.99,USD,1.1932 2021-07-01T07:07:29.237955Z,,CUSTODY FEE,,,USD -1.02,USD,1.1855 2021-07-01T15:10:49.364022Z,NIO,BUY - LIMIT,10,USD 52,USD 520,USD,1.1869 2021-07-06T14:13:29.561384Z,AMZN,SELL - MARKET,0.02585158,USD 3621.44,USD 93.61,USD,1.1841 2021-07-06T14:13:42.195388Z,GOOGL,SELL - MARKET,0.09823182,USD 2521.08,USD 247.64,USD,1.1841 2021-07-06T15:42:06.615634Z,GOOGL,BUY - MARKET,0.21915668,USD 2509.62,USD 550,USD,1.1830 2021-07-07T13:40:07.363142Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1807 2021-07-08T15:28:51.781770Z,SPCE,SELL - LIMIT,12,USD 50,USD 599.99,USD,1.1848 2021-07-09T14:51:56.656892Z,AAPL,SELL - LIMIT,4,USD 145.04,USD 580.17,USD,1.1875 2021-07-12T13:40:10.104714Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1858 2021-07-14T19:19:12.332908Z,AAPL,SELL - MARKET,4,USD 149.16,USD 596.63,USD,1.1838 2021-07-14T20:06:27.095455Z,,CASH WITHDRAWAL,,,USD -63.73,USD,1.1839 2021-07-15T14:52:57.411248Z,MRNA,BUY - MARKET,1,USD 255.80,USD 255.80,USD,1.1817 2021-07-16T13:30:15.150905Z,SPCE,BUY - LIMIT,24,USD 32.56,USD 781.44,USD,1.1811 2021-07-16T14:00:06.695873Z,MRNA,SELL - LIMIT,1,USD 285,USD 284.99,USD,1.1804 2021-07-16T15:51:31.477893Z,AAPL,BUY - LIMIT,3,USD 147.31,USD 441.92,USD,1.1813 2021-07-23T16:05:00.019087Z,PYPL,SELL - MARKET,3,USD 308.81,USD 926.42,USD,1.1764 2021-07-23T16:05:29.193871Z,MRNA,BUY - MARKET,2,USD 335.27,USD 670.54,USD,1.1765 2021-07-27T06:51:45.976639Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1793 2021-08-01T05:41:21.067616Z,,CUSTODY FEE,,,USD -1.12,USD,1.1999 2021-08-03T18:07:55.781076Z,MRNA,SELL - LIMIT,2,USD 370,USD 739.99,USD,1.1866 2021-08-03T18:10:06.118513Z,AMZN,BUY - MARKET,0.22221761,USD 3375.07,USD 750,USD,1.1866 2021-08-09T14:53:34.032557Z,GOOGL,SELL - MARKET,0.21915668,USD 2716.87,USD 595.41,USD,1.1751 2021-08-09T14:54:08.334621Z,MRNA,BUY - MARKET,1,USD 450.93,USD 450.93,USD,1.1752 2021-08-13T04:42:24.271612Z,AAPL,DIVIDEND,,,USD 2.62,USD,1.1742 2021-08-16T13:39:48.653719Z,AAPL,SELL - LIMIT,4,USD 150,USD 599.99,USD,1.1785 2021-08-19T13:30:23.348630Z,AAPL,BUY - LIMIT,5,USD 144.93,USD 724.65,USD,1.1697 2021-09-01T07:40:38.748966Z,,CUSTODY FEE,,,USD -1.15,USD,1.1800 2021-09-07T13:41:12.356305Z,AAPL,SELL - LIMIT,5,USD 155.05,USD 775.24,USD,1.1862 2021-09-10T16:13:16.888876Z,AAPL,BUY - MARKET,5,USD 149.97,USD 749.85,USD,1.1823 2021-09-17T14:05:43.934832Z,TSLA,SELL - MARKET,0.78607363,USD 758.73,USD 596.41,USD,1.1758 2021-09-17T14:06:29.208538Z,AAPL,BUY - MARKET,4,USD 146.83,USD 587.32,USD,1.1758 2021-10-01T03:10:46.826293Z,,CUSTODY FEE,,,USD -1.11,USD,1.1580 2021-10-01T08:38:11.538983Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1582 2021-10-19T15:35:49.113762Z,ANSS,SELL - MARKET,2,USD 364.67,USD 729.33,USD,1.1638 2021-10-19T15:36:40.367755Z,GOOGL,BUY - MARKET,0.25686385,USD 2859.18,USD 734.42,USD,1.1640 2021-10-21T14:37:31.105249Z,TSLA,SELL - MARKET,0.84141694,USD 895.48,USD 753.46,USD,1.1640 2021-10-25T13:30:27.810820Z,TSLA,SELL - LIMIT,1,USD 951.50,USD 951.49,USD,1.1614 2021-10-25T14:12:51.623985Z,TSLA,SELL - MARKET,0.98496385,USD 956.01,USD 941.63,USD,1.1613 2021-10-25T14:30:51.121969Z,TSLA,SELL - MARKET,0.99999994,USD 974.91,USD 974.90,USD,1.1615 2021-10-25T14:35:27.184763Z,,CASH WITHDRAWAL,,,USD -78.27,USD,1.1616 2021-10-25T16:30:55.577488Z,TSLA,SELL - MARKET,1,USD 992.83,USD 992.81,USD,1.1610 2021-10-26T13:33:01.736631Z,TSLA,BUY - MARKET,1,USD 1044.49,USD 1044.49,USD,1.1609 2021-10-26T13:45:33.604150Z,AAPL,BUY - MARKET,4,USD 150.48,USD 601.92,USD,1.1611 2021-10-27T16:17:31.917375Z,AAPL,BUY - MARKET,10,USD 149.25,USD 1492.49,USD,1.1603 2021-10-29T10:53:14.177467Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1652 2021-11-01T14:50:45.336203Z,TSLA,SELL - LIMIT,1,USD 1150,USD 1149.98,USD,1.1583 2021-11-01T20:36:56.194415Z,,CASH WITHDRAWAL,,,USD -100,USD,1.1609 2021-11-04T01:13:01.959445Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.1613 2021-11-04T03:17:16.783359Z,,CUSTODY FEE,,,USD -1.07,USD,1.1603 2021-11-04T06:29:23.316411Z,,CASH TOP-UP,,,USD 2000,USD,1.1586 2021-11-04T14:10:12.273414Z,NIO,SELL - MARKET,13,USD 43.54,USD 566.02,USD,1.1553 2021-11-04T14:22:38.394300Z,KO,BUY - MARKET,10,USD 56.29,USD 562.89,USD,1.1552 2021-11-04T14:23:41.524349Z,BAC,BUY - MARKET,10,USD 47.49,USD 474.89,USD,1.1551 2021-11-09T16:46:11.784013Z,TSLA,BUY - MARKET,1,USD 1065.78,USD 1065.78,USD,1.1586 2021-11-09T16:52:01.682293Z,SPCE,SELL - LIMIT,24,USD 20.99,USD 503.77,USD,1.1588 2021-11-10T15:33:05.030639Z,TSLA,BUY - MARKET,1,USD 1073.50,USD 1073.50,USD,1.1521 2021-11-17T07:09:11.457335Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1305 2021-11-18T19:06:58.592793Z,AAPL,SELL - LIMIT,2,USD 158,USD 315.99,USD,1.1372 2021-11-19T14:33:40.386692Z,AMZN,SELL - MARKET,0.22221761,USD 3734.13,USD 829.78,USD,1.1315 2021-11-19T16:55:21.098116Z,AAPL,SELL - LIMIT,5,USD 160,USD 799.99,USD,1.1318 2021-11-19T19:20:55.700535Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1292 2021-11-22T10:38:55.919887Z,,CASH WITHDRAWAL,,,USD -153.20,USD,1.1287 2021-11-22T14:38:56.905968Z,PYPL,SELL - MARKET,3,USD 191.85,USD 575.54,USD,1.1242 2021-11-22T14:40:07.462187Z,AAPL,BUY - MARKET,10,USD 163.08,USD 1630.79,USD,1.1243 2021-11-22T14:40:36.826246Z,TSLA,BUY - MARKET,0.5,USD 1181.76,USD 590.88,USD,1.1244 2021-11-22T17:28:58.134841Z,MRNA,BUY - LIMIT,1,USD 287.97,USD 287.97,USD,1.1255 2021-11-26T14:30:44.164387Z,MRNA,SELL - LIMIT,1,USD 320,USD 319.99,USD,1.1289 2021-11-26T15:11:21.748088Z,AAPL,BUY - LIMIT,2,USD 158.17,USD 316.34,USD,1.1300 2021-11-26T17:15:02.710330Z,MRNA,SELL - MARKET,1,USD 327.96,USD 327.95,USD,1.1300 2021-11-26T17:19:19.840447Z,AMZN,BUY - MARKET,0.09497631,USD 3527.09,USD 334.99,USD,1.1297 2021-11-30T20:55:44.227431Z,AAPL,SELL - LIMIT,7,USD 165,USD 1154.98,USD,1.1337 2021-12-01T16:17:49.426751Z,AAPL,SELL - LIMIT,15,USD 170,USD 2549.98,USD,1.1331 2021-12-02T06:08:45.125392Z,,CUSTODY FEE,,,USD -1.07,USD,1.1325 2021-12-02T09:09:32.353819Z,,CASH WITHDRAWAL,,,USD -300,USD,1.1325 2021-12-02T09:09:59.218758Z,,CASH TOP-UP,,,USD 100,USD,1.1324 2021-12-02T14:30:31.195638Z,AAPL,BUY - LIMIT,7,USD 158.72,USD 1111.04,USD,1.1345 2021-12-02T14:48:54.578317Z,AAPL,BUY - MARKET,3,USD 160.89,USD 482.67,USD,1.1349 2021-12-02T17:17:29.448590Z,AMZN,BUY - MARKET,0.08667514,USD 3461.20,USD 300,USD,1.1310 2021-12-02T17:22:47.526948Z,AAPL,BUY - MARKET,9,USD 163.26,USD 1469.33,USD,1.1307 2021-12-03T15:52:09.743899Z,SPCE,SELL - MARKET,12,USD 14.32,USD 171.84,USD,1.1280 2021-12-06T15:14:43.715974Z,AAPL,SELL - MARKET,4,USD 167.09,USD 668.35,USD,1.1290 2021-12-06T15:23:37.271485Z,,CASH TOP-UP,,,USD 50,USD,1.1293 2021-12-06T15:24:23.771651Z,TSLA,BUY - LIMIT,1,USD 992.90,USD 992.90,USD,1.1291 2021-12-10T20:40:03.360809Z,AAPL,SELL - MARKET,5,USD 178.17,USD 890.85,USD,1.1316 2021-12-10T20:46:05.031639Z,,CASH WITHDRAWAL,,,USD -26.65,USD,1.1319 2021-12-13T14:31:24.268753Z,AAPL,SELL - LIMIT,7,USD 181,USD 1266.98,USD,1.1294 2021-12-13T17:18:39.928392Z,AAPL,BUY - MARKET,4,USD 178.20,USD 712.80,USD,1.1302 2021-12-14T07:45:33.061233Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1279 2021-12-14T19:27:37.943686Z,TSLA,BUY - MARKET,0.5,USD 943.68,USD 471.84,USD,1.1264 2021-12-14T19:27:59.893606Z,AAPL,BUY - MARKET,4,USD 174.17,USD 696.68,USD,1.1264 2021-12-17T08:05:11.817525Z,KO,DIVIDEND,,,USD 3.57,USD,1.1323 2021-12-21T22:24:23.051009Z,,CASH TOP-UP,,,USD 550,USD,1.1288 2021-12-25T17:04:42.634707Z,,CASH TOP-UP,,,USD 100,USD,1.1315 2021-12-27T16:07:19.048883Z,TSLA,SELL - MARKET,0.5,USD 1102.70,USD 551.34,USD,1.1327 2021-12-28T15:52:44.354571Z,AMZN,BUY - MARKET,0.05822687,USD 3434.84,USD 200,USD,1.1295 2022-01-03T15:04:47.514435Z,TSLA,SELL - MARKET,1,USD 1153.59,USD 1153.57,USD,1.1309 2022-01-03T17:21:55.035249Z,ANSS,BUY - MARKET,2,USD 393.43,USD 786.86,USD,1.1288 2022-01-03T20:22:20.865769Z,TSLA,SELL - MARKET,0.5,USD 1194.86,USD 597.42,USD,1.1302 2022-01-04T05:38:05.560396Z,BAC,DIVIDEND,,,USD 1.78,USD,1.1307 2022-01-04T10:52:06.498921Z,,CUSTODY FEE,,,USD -1.16,USD,1.1303 2022-01-06T14:54:57.808284Z,TSLA,BUY - LIMIT,1,USD 1050,USD 1050,USD,1.1330 2022-01-11T14:44:35.020133Z,AAPL,BUY - LIMIT,6,USD 171,USD 1026,USD,1.1324 2022-02-02T13:11:56.907881Z,,CUSTODY FEE,,,USD -1.22,USD,1.1324 2022-02-02T14:35:03.638282Z,PYPL,SELL - MARKET,2.8,USD 136.33,USD 381.71,USD,1.1317 2022-02-02T14:38:16.310927Z,GOOGL,BUY - MARKET,0.1370781,USD 3006.68,USD 412.15,USD,1.1318 2022-02-15T05:59:54.545870Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1320 2022-02-17T19:14:51.499522Z,KO,SELL - LIMIT,10,USD 62,USD 619.99,USD,1.1365 2022-02-18T14:43:59.084299Z,TSLA,BUY - MARKET,0.5,USD 863.86,USD 431.93,USD,1.1344 2022-02-18T16:23:53.036317Z,O,BUY - MARKET,2,USD 67.03,USD 134.06,USD,1.1336 2022-02-28T12:59:53.335490Z,,CASH TOP-UP,,,USD 250,USD,1.1198 2022-02-28T14:38:21.778362Z,KO,BUY - MARKET,2,USD 61.93,USD 123.86,USD,1.1225 2022-03-02T06:56:23.623381Z,,CUSTODY FEE,,,USD -1.16,USD,1.1104 2022-03-02T16:10:30.245886Z,MSFT,BUY - MARKET,0.62199751,USD 297.67,USD 185.15,USD,1.1092 2022-03-16T05:35:16.177499Z,O,DIVIDEND,,,USD 0.42,USD,1.0978 2022-03-22T15:06:09.673524Z,TSLA,SELL - MARKET,0.5,USD 942.18,USD 471.08,USD,1.1033 2022-03-25T09:15:31.379423Z,,CASH WITHDRAWAL,,,USD -257.83,USD,1.1004 2022-03-28T04:32:31.012802Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0955 2022-04-02T04:06:59.837476Z,,CUSTODY FEE,,,USD -1.24,USD,1.1051 2022-04-04T04:35:23.159499Z,KO,DIVIDEND,,,USD 0.75,USD,1.1051 2022-04-13T19:27:21.376535Z,AAPL,BUY - MARKET,1,USD 170.66,USD 170.66,USD,1.0892 2022-04-14T11:17:15.965883Z,,CASH TOP-UP,,,USD 200,USD,1.0905 2022-04-14T13:30:19.229173Z,TWTR,BUY - LIMIT,4,USD 48.42,USD 193.68,USD,1.0829 2022-04-19T05:08:35.489675Z,O,DIVIDEND,,,USD 0.42,USD,1.0772 2022-04-19T13:30:44.030267Z,TWTR,BUY - LIMIT,1,USD 47.24,USD 47.24,USD,1.0798 2022-04-20T17:05:03.527689Z,O,SELL - LIMIT,2,USD 75,USD 149.99,USD,1.0848 2022-04-22T13:56:13.446949Z,O,BUY - LIMIT,2,USD 74,USD 148,USD,1.0817 2022-05-03T04:22:39.919354Z,,CUSTODY FEE,,,USD -1.11,USD,1.0519 2022-05-16T05:21:24.813176Z,O,DIVIDEND,,,USD 0.42,USD,1.0410 2022-05-16T05:26:42.889192Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0407 2022-05-20T08:17:11.587079Z,,CASH TOP-UP,,,USD 150,USD,1.0562 2022-05-20T13:30:08.229515Z,AAPL,BUY - LIMIT,1,USD 139.02,USD 139.02,USD,1.0564 2022-06-02T05:19:39.349765Z,,CUSTODY FEE,,,USD -1.05,USD,1.0657 2022-06-06T05:21:09.168520Z,AMZN,STOCK SPLIT,4.55768808,,USD 0,USD,1.0738 2022-06-07T15:18:23.292832Z,,CASH TOP-UP,,,USD 10,USD,1.0702 2022-06-07T15:19:02.548830Z,AMZN,BUY - MARKET,0.2024336,USD 122.26,USD 24.75,USD,1.0700 2022-06-10T04:51:36.764084Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0635 2022-06-16T04:24:09.940734Z,O,DIVIDEND,,,USD 0.42,USD,1.0441 2022-06-27T04:21:07.933377Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0571 2022-07-02T10:16:19.663439Z,,CUSTODY FEE,,,USD -0.96,USD,1.0432 2022-07-05T04:30:14.263191Z,KO,DIVIDEND,,,USD 0.75,USD,1.0442 2022-07-18T04:23:43.057183Z,O,DIVIDEND,,,USD 0.42,USD,1.0105 2022-07-18T05:13:29.606545Z,GOOGL,STOCK SPLIT,7.48489705,,USD 0,USD,1.0100 2022-07-21T16:32:01.558198Z,AAPL,SELL - LIMIT,1,USD 155.04,USD 155.02,USD,1.0194 2022-07-29T15:15:54.355733Z,,CASH TOP-UP,,,USD 150,USD,1.0209 2022-08-02T14:00:10.449611Z,,CUSTODY FEE,,,USD -1.13,USD,1.0210 2022-08-16T06:38:59.962142Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0171 2022-08-16T06:48:27.180503Z,O,DIVIDEND,,,USD 0.42,USD,1.0165 2022-08-25T08:29:28.839969Z,TSLA,STOCK SPLIT,6,,USD 0,USD,0.9997 2022-09-03T11:43:40.762285Z,,CUSTODY FEE,,,USD -1.08,USD,0.9961 2022-09-12T05:35:58.495990Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0096 2022-09-14T14:19:49.128161Z,AAPL,BUY - LIMIT,2,USD 155.78,USD 311.56,USD,0.9982 2022-09-16T05:17:20.255485Z,O,DIVIDEND,,,USD 0.42,USD,0.9995 2022-10-03T04:32:31.694830Z,BAC,DIVIDEND,,,USD 1.87,USD,0.9807 2022-10-04T04:31:18.366499Z,,CUSTODY FEE,,,USD -1,USD,0.9841 2022-10-04T06:15:22.053724Z,KO,DIVIDEND,,,USD 0.75,USD,0.9861 2022-10-05T14:17:47.799690Z,TWTR,SELL - MARKET,5,USD 50.93,USD 254.64,USD,0.9852 2022-10-17T04:30:26.662073Z,O,DIVIDEND,,,USD 0.42,USD,0.9748 2022-11-02T09:58:08.362246Z,,CUSTODY FEE,,,USD -1,USD,0.9906 2022-11-11T10:43:43.775454Z,AAPL,DIVIDEND,,,USD 7.04,USD,1.0271 2022-11-16T06:44:25.085056Z,O,DIVIDEND,,,USD 0.42,USD,1.0383 2022-12-02T06:58:53.260720Z,,CUSTODY FEE,,,USD -0.97,USD,1.0532 2022-12-09T07:49:09.937455Z,MSFT,DIVIDEND,,,USD 0.36,USD,1.0582 2022-12-16T06:53:22.378091Z,KO,DIVIDEND,,,USD 0.75,USD,1.0667 2022-12-16T06:58:57.301385Z,O,DIVIDEND,,,USD 0.42,USD,1.0662 2022-12-20T14:35:52.087523Z,AAPL,BUY - LIMIT,2,USD 130,USD 260,USD,1.0620 2023-01-03T05:33:54.622583Z,BAC,DIVIDEND,,,USD 1.87,USD,1.0672 2023-01-04T09:51:33.829102Z,,CUSTODY FEE,,,USD -0.84,USD,1.0625 2023-01-17T05:40:19.551093Z,O,DIVIDEND,,,USD 0.35,USD,1.0831 2023-01-23T16:49:31.990Z,AAPL,SELL - LIMIT,2,USD 143,USD 285.98,USD,1.0868 2023-01-23T16:50:31.944Z,TSLA,BUY - MARKET,2,USD 141.48,USD 282.96,USD,1.0866 2023-01-26T14:30:02.502Z,TSLA,SELL - LIMIT,2,USD 159.99,USD 319.96,USD,1.0901 2023-01-30T15:28:04.951Z,AAPL,BUY - MARKET,2,USD 143.94,USD 287.88,USD,1.0889 2023-02-01T04:47:19.689616Z,,CUSTODY FEE,,,USD -0.95,USD,1.0871 2023-02-16T07:10:29.099680Z,O,DIVIDEND,,,USD 0.35,USD,1.0707 2023-02-17T07:05:43.640146Z,AAPL,DIVIDEND,,,USD 6.12,USD,1.0641 2023-03-01T11:12:23.865134Z,,CASH TOP-UP,,,USD 250,USD,1.0669 2023-03-01T14:45:06.338Z,BRK.B,BUY - LIMIT,1,USD 303.16,USD 303.16,USD,1.0685 2023-03-02T08:37:29.518195Z,,CUSTODY FEE,,,USD -1,USD,1.0636 2023-03-13T05:01:07.362448Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0731 2023-03-16T05:53:51.457497Z,O,DIVIDEND,,,USD 0.36,USD,1.0618 2023-03-22T14:28:40.213Z,AAPL,SELL - LIMIT,2,USD 160,USD 319.98,USD,1.0794 2023-04-03T04:34:36.432266Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0809 2023-04-04T07:43:19.011071Z,KO,DIVIDEND,,,USD 0.64,USD,1.0919 2023-04-04T10:05:57.474134Z,,CUSTODY FEE,,,USD -1.08,USD,1.0941 2023-04-17T05:14:59.411865Z,O,DIVIDEND,,,USD 0.36,USD,1.1000 2023-05-02T16:58:09.717081Z,,CUSTODY FEE,,,USD -1.07,USD,1.1010 2023-05-05T13:33:41.989Z,AAPL,SELL - LIMIT,2,USD 172,USD 343.98,USD,1.0998 2023-05-08T16:49:22.657920Z,,CASH TOP-UP,,,USD 150,USD,1.1037 2023-05-08T16:50:05.075Z,TSLA,BUY - MARKET,1,USD 171.76,USD 171.76,USD,1.1037 2023-05-16T05:28:06.065980Z,O,DIVIDEND,,,USD 0.36,USD,1.0890 2023-05-19T06:32:05.730565Z,AAPL,DIVIDEND,,,USD 5.71,USD,1.0800 2023-05-23T13:45:40.451Z,TSLA,SELL - LIMIT,1,USD 190,USD 189.98,USD,1.0783 2023-05-23T13:53:42.530Z,AAPL,BUY - MARKET,1,USD 172.79,USD 172.79,USD,1.0783 2023-05-25T13:41:55.501Z,MSFT,SELL - MARKET,0.62199751,USD 321.63,USD 200.03,USD,1.0722 2023-05-26T14:28:00.905Z,TSLA,BUY - MARKET,1,USD 190.12,USD 190.12,USD,1.0743 2023-06-02T08:57:47.333209Z,,CUSTODY FEE,,,USD -1.13,USD,1.0788 2023-06-02T13:30:02.757Z,TSLA,SELL - LIMIT,1,USD 210,USD 209.98,USD,1.0779 2023-06-05T11:24:00.663315Z,,CASH TOP-UP,,,USD 100,USD,1.0703 2023-06-06T07:53:30.801799Z,,CASH WITHDRAWAL,,,USD -200,USD,1.0725 2023-06-06T15:58:37.683Z,AAPL,BUY - MARKET,4,USD 178.62,USD 714.50,USD,1.0706 2023-06-09T06:10:29.033529Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0787 2023-06-14T15:52:32.276Z,BRK.B,SELL - LIMIT,1,USD 340,USD 339.98,USD,1.0868 2023-06-14T16:30:12.174Z,TSLA,BUY - MARKET,1,USD 258,USD 258,USD,1.0872 2023-06-15T13:53:37.361Z,AAPL,SELL - LIMIT,19,USD 185.01,USD 3515.15,USD,1.0909 2023-06-15T14:32:54.586Z,BRK.B,BUY - MARKET,4,USD 338.24,USD 1352.95,USD,1.0927 2023-06-16T04:49:46.803865Z,O,DIVIDEND,,,USD 0.36,USD,1.0954 2023-06-20T17:34:39.166Z,TSLA,BUY - MARKET,2,USD 271.03,USD 542.06,USD,1.0929 2023-06-30T15:35:47.990Z,AAPL,BUY - MARKET,4,USD 192.45,USD 769.79,USD,1.0928 2023-07-03T04:42:47.064493Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0929 2023-07-04T06:14:58.867435Z,,CUSTODY FEE,,,USD -1.19,USD,1.0914 2023-07-05T04:38:30.594392Z,KO,DIVIDEND,,,USD 0.64,USD,1.0888 2023-07-17T04:29:28.019975Z,O,DIVIDEND,,,USD 0.36,USD,1.1239 2023-07-19T13:58:34.924Z,TSLA,BUY - MARKET,3,USD 296.58,USD 889.74,USD,1.1228 2023-08-02T09:34:03.883636Z,,CUSTODY FEE,,,USD -1.31,USD,1.0994 2023-08-16T04:35:04.390352Z,O,DIVIDEND,,,USD 0.36,USD,1.0928 2023-08-18T04:57:05.333405Z,AAPL,DIVIDEND,,,USD 4.03,USD,1.0901 2023-09-02T03:13:46.440774Z,,CUSTODY FEE,,,USD -1.27,USD,1.0790 2023-09-09T08:05:14.452584Z,,TRANSFER FROM REVOLUT BANK UAB TO REVOLUT SECURITIES EUROPE UAB,,,USD 117.44,USD,1.0719 2023-09-09T09:34:24.443702Z,GOOGL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,7.878839,,USD 0,USD,1.0719 2023-09-09T09:34:24.561658Z,O,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:24.660297Z,TSLA,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,15,,USD 0,USD,1.0719 2023-09-09T09:34:24.767410Z,BAC,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,10,,USD 0,USD,1.0719 2023-09-09T09:34:24.873457Z,BRK.B,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,4,,USD 0,USD,1.0719 2023-09-09T09:34:24.979123Z,KO,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.079904Z,ANSS,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.189128Z,AMZN,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,5,,USD 0,USD,1.0719 2023-09-09T09:34:25.292873Z,AAPL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,24,,USD 0,USD,1.0719 2023-09-13T15:07:29.260651Z,,CASH TOP-UP,,,USD 11.76,USD,1.0756 2023-09-13T15:08:11.622299Z,,CASH TOP-UP,,,USD 400,USD,1.0757 2023-09-13T15:09:28.691Z,AAPL,BUY - LIMIT,3,USD 175.02,USD 525.05,USD,1.0757 2023-09-18T10:59:47.342077Z,O,DIVIDEND,,,USD 0.36,USD,1.0686 2023-10-01T07:39:16.220080Z,,CUSTODY FEE,,,USD -1.25,USD,1.0595 2023-10-02T11:08:11.013935Z,BAC,DIVIDEND,,,USD 1.68,USD,1.0550 2023-10-03T12:35:09.127138Z,KO,DIVIDEND,,,USD 0.78,USD,1.0488 2023-10-16T13:27:58.306547Z,O,DIVIDEND,,,USD 0.43,USD,1.0557 2023-11-02T07:47:24.136368Z,,CUSTODY FEE,,,USD -1.17,USD,1.0617 2023-11-16T12:42:39.810501Z,O,DIVIDEND,,,USD 0.43,USD,1.0863 2023-11-16T14:31:16.694Z,AAPL,SELL - LIMIT,6,USD 190,USD 1139.98,USD,1.0885 2023-11-17T18:26:36.033179Z,AAPL,DIVIDEND,,,USD 5.51,USD,1.0913 2023-12-01T10:05:46.401211Z,,CUSTODY FEE,,,USD -1.19,USD,1.0922 2023-12-13T13:32:17.638Z,AAPL,SELL - LIMIT,7,USD 196,USD 1371.98,USD,1.0814 2023-12-14T11:33:48.192861Z,,CASH WITHDRAWAL,,,USD -490,USD,1.0942 2023-12-14T11:42:42.236702Z,,CASH WITHDRAWAL,,,USD -540,USD,1.0945 2023-12-14T11:44:57.481825Z,,CASH TOP-UP,,,EUR 493.36,EUR,1.0000 2023-12-14T11:46:14.224594Z,,CASH TOP-UP,,,EUR 22.55,EUR,1.0000 2023-12-14T11:46:28.633Z,EUNL,BUY - MARKET,6,EUR 81.89,EUR 491.33,EUR,1.0000 2023-12-14T11:46:58.960291Z,,CASH WITHDRAWAL,,,EUR -22.55,EUR,1.0000 2023-12-18T14:35:49.692078Z,O,DIVIDEND,,,USD 0.43,USD,1.0945 2023-12-18T14:42:19.088Z,AAPL,BUY - LIMIT,2,USD 195,USD 390,USD,1.0946 2023-12-18T16:03:32.089281Z,KO,DIVIDEND,,,USD 0.78,USD,1.0937 2023-12-22T14:53:30.293Z,ANSS,SELL - MARKET,2,USD 334.81,USD 669.60,USD,1.1060 2023-12-22T14:55:28Z,AAPL,BUY - MARKET,3,USD 195.24,USD 585.73,USD,1.1059 2023-12-29T17:03:07.509Z,AAPL,BUY - MARKET,3,USD 192.32,USD 576.95,USD,1.1082 2024-01-01T07:00:29.342845Z,,CUSTODY FEE,,,USD -1.18,USD,1.1060 2024-01-01T07:00:29.400142Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-01-03T17:20:49.193495Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0927 2024-01-08T09:32:34.413Z,AAPL,BUY - LIMIT,3,USD 180,USD 540,USD,1.0945 2024-01-16T12:06:46.872915Z,O,DIVIDEND,,,USD 0.43,USD,1.0909 2024-01-25T14:32:03.923Z,BRK.B,SELL - LIMIT,4,USD 380,USD 1519.98,USD,1.0876 2024-01-25T14:46:38.746Z,TSLA,SELL - MARKET,3,USD 187.76,USD 563.25,USD,1.0875 2024-01-25T14:53:37.441Z,NVDA,BUY - MARKET,3,USD 621.78,USD 1865.35,USD,1.0876 2024-01-29T15:13:05.633327Z,,CASH WITHDRAWAL,,,USD -288.99,USD,1.0829 2024-01-31T16:53:08.153Z,TSLA,SELL - LIMIT,3,USD 190,USD 569.98,USD,1.0877 2024-01-31T17:17:42.114Z,MSFT,BUY - MARKET,1,USD 402.58,USD 402.58,USD,1.0869 2024-02-01T03:25:42.443177Z,,CUSTODY FEE,,,USD -1.10,USD,1.0837 2024-02-01T03:25:42.504846Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-02-02T18:27:54.549Z,AMZN,SELL - MARKET,5,USD 171.96,USD 859.78,USD,1.0804 2024-02-02T18:28:56.258Z,NVDA,BUY - MARKET,1,USD 659.78,USD 659.78,USD,1.0805 2024-02-02T18:42:33.310Z,AAPL,BUY - MARKET,1,USD 186.01,USD 186.01,USD,1.0809 2024-02-05T19:01:24.403Z,TSLA,SELL - MARKET,3,USD 181.48,USD 544.43,USD,1.0765 2024-02-05T19:13:49.716Z,NVDA,BUY - MARKET,1,USD 688.87,USD 688.87,USD,1.0765 2024-02-09T18:38:36.240Z,NVDA,SELL - LIMIT,3,USD 720,USD 2159.97,USD,1.0809 2024-02-09T19:04:23.041Z,TSLA,SELL - MARKET,4,USD 192.78,USD 771.11,USD,1.0811 2024-02-13T14:35:34.549398Z,,CASH WITHDRAWAL,,,USD -755.30,USD,1.0737 2024-02-16T15:48:11.314342Z,O,DIVIDEND,,,USD 0.43,USD,1.0796 2024-02-16T17:20:34.309565Z,AAPL,DIVIDEND,,,USD 5.30,USD,1.0789 2024-02-21T21:25:57.106Z,NVDA,BUY - LIMIT,3,USD 679,USD 2037,USD,1.0838 2024-03-01T09:08:46.556Z,TSLA,SELL - LIMIT,2,USD 201.22,USD 402.43,USD,1.0834 2024-03-05T17:02:20.128Z,BRK.B,BUY - LIMIT,1,USD 400,USD 400,USD,1.0882 2024-03-11T09:45:10.733671Z,,CASH TOP-UP,,,USD 1091.80,USD,1.0964 2024-03-11T09:45:57.889Z,NVDA,BUY - LIMIT,1,USD 889.33,USD 889.33,USD,1.0964 2024-03-11T14:04:39.233521Z,,CASH TOP-UP,,,USD 126.74,USD,1.0941 2024-03-15T12:28:23.824579Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0914 2024-03-18T13:44:16.977280Z,O,DIVIDEND,,,USD 0.43,USD,1.0912 2024-03-28T12:59:32.090109Z,NVDA,DIVIDEND,,,USD 0.17,USD,1.0831 2024-04-01T14:18:52.459Z,AAPL,BUY - LIMIT,3,USD 170,USD 510,USD,1.0768 2024-04-02T17:32:27.807174Z,KO,DIVIDEND,,,USD 0.82,USD,1.0788 2024-04-02T17:50:08.293837Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0789 2024-04-12T13:53:08.110Z,GOOGL,SELL - LIMIT,5,USD 160,USD 799.98,USD,1.0659 2024-04-16T11:57:48.211880Z,O,DIVIDEND,,,USD 0.43,USD,1.0668 2024-04-22T13:42:17.982936Z,,CASH WITHDRAWAL,,,USD -720,USD,1.0653 2024-04-22T13:43:26.153902Z,,CASH TOP-UP,,,EUR 675.75,EUR,1.0000 2024-04-22T13:44:05.671Z,EUNL,BUY - MARKET,7,EUR 88.42,EUR 618.93,EUR,1.0000 2024-04-26T13:30:00.940Z,GOOGL,SELL - MARKET,2.878839,USD 174.33,USD 501.85,USD,1.0733 2024-04-30T14:37:07.030880Z,,CASH WITHDRAWAL,,,USD -398.79,USD,1.0728 2024-05-16T08:51:27.652167Z,O,DIVIDEND,,,USD 0.43,USD,1.0895 2024-05-17T10:26:14.210180Z,AAPL,DIVIDEND,,,USD 6.16,USD,1.0867 2024-05-20T13:54:41.117Z,NVDA,SELL - LIMIT,1,USD 950,USD 949.98,USD,1.0889 2024-05-22T21:14:39.325Z,NVDA,SELL - LIMIT,5,USD 1000,USD 4999.85,USD,1.0847 2024-05-28T15:44:41.483Z,NVDA,BUY - MARKET,3,USD 1120.59,USD 3361.77,USD,1.0899 2024-06-05T10:11:57.724Z,KO,SELL - LIMIT,2,USD 63.92,USD 127.83,USD,1.0890 2024-06-06T12:20:06.768Z,NVDA,BUY - LIMIT,2,USD 1249.18,USD 2498.35,USD,1.0907 2024-06-10T12:35:45.964651Z,NVDA,STOCK SPLIT,45,,USD 0,USD,1.0778 2024-06-11T14:16:51.891Z,AAPL,SELL - LIMIT,6,USD 200,USD 1199.96,USD,1.0748 2024-06-12T13:53:20.883Z,AAPL,BUY - MARKET,7,USD 213.95,USD 1497.64,USD,1.0856 2024-06-14T10:17:31.111265Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0709 2024-06-17T10:18:03.287961Z,O,DIVIDEND,,,USD 0.44,USD,1.0728 2024-06-17T18:01:31.892Z,MSFT,SELL - LIMIT,1,USD 450,USD 449.98,USD,1.0750 2024-06-20T15:19:16.531Z,AAPL,BUY - LIMIT,2,USD 210,USD 420,USD,1.0741 2024-07-01T11:01:29.101517Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.0772 2024-07-01T12:19:36.098603Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0768 2024-07-02T15:09:31.105Z,AAPL,SELL - LIMIT,9,USD 220,USD 1979.93,USD,1.0762 2024-07-03T14:43:34.756Z,TSLA,BUY - MARKET,2,USD 247.92,USD 495.85,USD,1.0825 2024-07-11T12:30:08.457Z,BAC,SELL - LIMIT,10,USD 42,USD 419.98,USD,1.0899 2024-07-11T13:25:05.444Z,TSM,BUY - LIMIT,10,USD 193.86,USD 1938.61,USD,1.0915 2024-07-16T08:59:29.967862Z,O,DIVIDEND,,,USD 0.44,USD,1.0923 2024-07-17T14:40:33.756Z,O,SELL - MARKET,2,USD 57.17,USD 114.32,USD,1.0957 2024-07-23T14:02:29.334480Z,,CASH TOP-UP,,,EUR 800,EUR,1.0000 2024-07-23T14:03:16.459Z,EXXT,BUY - MARKET,4.84403203,EUR 177.28,EUR 858.75,EUR,1.0000 2024-07-30T13:34:15.782Z,BRK.B,SELL - LIMIT,1,USD 440,USD 439.98,USD,1.0832 2024-08-01T21:50:35.835874Z,,CASH TOP-UP,,,USD 1077.48,USD,1.0809 2024-08-01T21:51:25.637Z,AAPL,BUY - LIMIT,5,USD 218.85,USD 1094.25,USD,1.0809 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,2,USD 204.90,USD 409.80,USD,1.0966 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,1,USD 204.90,USD 204.90,USD,1.0966 2024-08-16T15:20:28.266341Z,AAPL,DIVIDEND,,,USD 6.59,USD,1.1011 2024-08-29T11:33:30.727Z,AAPL,SELL - LIMIT,5,USD 230,USD 1149.96,USD,1.1113 2024-09-05T08:59:30.602Z,TSLA,SELL - LIMIT,2,USD 225.22,USD 450.43,USD,1.1118 2024-10-04T10:47:03.807610Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.1053 2024-10-10T08:38:54.394212Z,TSM,DIVIDEND,,,USD 4.93,USD,1.0958 2024-10-11T14:46:49.313Z,TSM,SELL - MARKET,10,USD 189.81,USD 1898.01,USD,1.0965 2024-10-17T10:50:43.300Z,NVDA,SELL - LIMIT,10,USD 140,USD 1399.95,USD,1.0885 2024-11-06T15:32:35.795880Z,,CASH TOP-UP,,,USD 34.98,USD,1.0750 2024-11-06T15:32:48.038Z,AAPL,BUY - MARKET,21,USD 225.81,USD 4741.95,USD,1.0750 2024-11-06T15:33:20.894832Z,,CASH WITHDRAWAL,,,USD -34.98,USD,1.0748 2024-11-15T10:57:21.547072Z,AAPL,DIVIDEND,,,USD 9.99,USD,1.0596 2024-11-25T15:51:08.045065Z,,CASH TOP-UP,,,USD 1004,USD,1.0525 2024-11-25T15:51:44.437Z,NVDA,BUY - MARKET,8,USD 137.70,USD 1101.58,USD,1.0526 2024-11-26T14:35:15.260Z,AAPL,SELL - LIMIT,9,USD 235,USD 2114.93,USD,1.0517 2024-11-29T12:41:10.527444Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.0574 2024-12-18T15:56:03.404813Z,EXXT,DIVIDEND,,,EUR 0.51,EUR,1.0000 2024-12-18T18:45:05.272532Z,,CASH TOP-UP,,,USD 2006.76,USD,1.0513 2024-12-18T18:45:59.510540Z,,CASH WITHDRAWAL,,,USD -2240.70,USD,1.0514 2024-12-18T18:47:39.084460Z,,CASH TOP-UP,,,EUR 2133.85,EUR,1.0000 2024-12-18T18:49:15.187Z,EXXT,BUY - LIMIT,10,EUR 203.80,EUR 2038,EUR,1.0000 2024-12-19T08:40:07.479915Z,,CASH TOP-UP,,,USD 0.02,USD,1.0415 2024-12-30T10:55:50.865219Z,NVDA,DIVIDEND,,,USD 0.41,USD,1.0464 2025-01-06T14:49:38.005Z,NVDA,SELL - LIMIT,20,USD 150,USD 2999.91,USD,1.0408 2025-01-07T09:50:04.477942Z,,CASH WITHDRAWAL,,,USD -3000,USD,1.0449 2025-01-07T15:54:48.223347Z,,CASH TOP-UP,,,USD 3001.30,USD,1.0396 2025-01-07T15:56:07.411Z,NVDA,BUY - LIMIT,21,USD 142.77,USD 2998.17,USD,1.0396 2025-01-28T08:48:36.329627Z,,CASH TOP-UP,,,USD 245,USD,1.0451 2025-01-28T09:07:04.086Z,NVDA,BUY - LIMIT,2,USD 123.58,USD 247.17,USD,1.0449 2025-02-14T20:37:33.255111Z,AAPL,DIVIDEND,,,USD 8.08,USD,1.0521 2025-03-19T15:56:49.384716Z,EXXT,DIVIDEND,,,EUR 1.67,EUR,1.0000 2025-04-03T15:56:21.046251Z,NVDA,DIVIDEND,,,USD 0.43,USD,1.1083 2025-05-16T18:36:19.943256Z,AAPL,DIVIDEND,,,USD 8.40,USD,1.1172 2025-05-28T20:38:28.721Z,NVDA,SELL - LIMIT,20,USD 140,USD 2799.99,USD,1.1318 2025-05-29T22:34:38.868352Z,,CASH WITHDRAWAL,,,USD -2818.20,USD,1.1398 2025-06-18T14:58:51.657905Z,EXXT,DIVIDEND,,,EUR 3.70,EUR,1.0000 2025-07-02T11:16:20.772081Z,,CASH TOP-UP,,,USD 2000,USD,1.1797 2025-07-03T14:46:34.490Z,NVDA,BUY - LIMIT,12,USD 159.89,USD 1918.68,USD,1.1784 2025-07-10T07:34:53.882147Z,NVDA,DIVIDEND,,,USD 0.26,USD,1.1761 2025-08-08T15:39:25.511Z,AAPL,SELL - LIMIT,3,USD 225,USD 674.99,USD,1.1692 2025-08-14T23:12:20.834326Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1674 2025-08-20T17:26:50.819936Z,,CASH WITHDRAWAL,,,USD -764.31,USD,1.1692 2025-10-02T19:05:09.782319Z,NVDA,DIVIDEND,,,USD 0.37,USD,1.1750 2025-10-16T08:44:53.616001Z,,CASH TOP-UP,,,USD 1502.57,USD,1.1685 2025-10-16T08:47:26.528Z,NVDA,BUY - LIMIT,8,USD 181.79,USD 1454.35,USD,1.1686 2025-11-11T15:34:00.722Z,AAPL,SELL - MARKET,5,USD 273.91,USD 1369.52,USD,1.1626 2025-11-11T16:59:52.307677Z,,CASH TOP-UP,,,USD 500,USD,1.1619 2025-11-11T18:05:47.274Z,NVDA,BUY - LIMIT,9,USD 193.60,USD 1742.36,USD,1.1619 2025-11-11T18:06:31.280523Z,,CASH WITHDRAWAL,,,USD -175,USD,1.1618 2025-11-13T21:09:36.155137Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1658 ======================================================================================== FICHEIRO: dados_csv/filipe/extrato-revolut.csv Tamanho: 17561 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2020-09-04T06:59:00.729503Z,,CASH TOP-UP,,,USD 250,USD,1.1839 2020-09-04T07:23:21.719355Z,,CASH TOP-UP,,,USD 250,USD,1.1845 2020-09-04T13:30:50.412089Z,AAPL,BUY - MARKET,2.08333333,USD 120,USD 250,USD,1.1811 2020-09-04T13:31:24.844921Z,TSLA,BUY - MARKET,0.60709082,USD 411.80,USD 250,USD,1.1809 2020-09-10T06:45:04.953968Z,,CASH TOP-UP,,,USD 250,USD,1.1834 2020-09-10T13:31:20.802910Z,TSLA,BUY - MARKET,0.65498179,USD 381.69,USD 250,USD,1.1896 2020-09-24T07:34:08.996392Z,,CASH TOP-UP,,,USD 329.15,USD,1.1657 2020-09-24T13:30:43.242667Z,TSLA,BUY - MARKET,0.89772262,USD 366.65,USD 329.15,USD,1.1651 2020-09-24T18:21:14.916812Z,TSLA,SELL - MARKET,0.89772262,USD 391.49,USD 351.43,USD,1.1679 2020-09-24T18:23:04.012520Z,ZM,BUY - MARKET,0.74879082,USD 469.33,USD 351.43,USD,1.1677 2020-09-25T07:24:45.526328Z,,CASH TOP-UP,,,USD 219.22,USD,1.1679 2020-09-25T07:28:29.757600Z,,CASH WITHDRAWAL,,,USD -219.22,USD,1.1687 2020-09-30T23:52:35.122704Z,,CUSTODY FEE,,,USD -0.01,USD,1.1727 2020-10-02T18:47:58.639012Z,,CASH TOP-UP,,,USD 0.01,USD,1.1718 2020-10-02T18:48:18.615660Z,,CASH TOP-UP,,,USD 415.88,USD,1.1718 2020-10-02T18:49:38.635966Z,TSLA,BUY - MARKET,0.98969047,USD 419.03,USD 415.88,USD,1.1717 2020-10-12T17:58:35.238834Z,AAPL,SELL - MARKET,1.17523455,USD 124.41,USD 145.02,USD,1.1811 2020-10-13T16:19:26.919939Z,Z,BUY - LIMIT,1,USD 100,USD 101.17,USD,1.1736 2020-10-13T18:36:26.239154Z,ZM,SELL - MARKET,0.74879082,USD 512.17,USD 382.32,USD,1.1746 2020-10-15T12:03:01.014983Z,,CASH TOP-UP,,,USD 400,USD,1.1708 2020-10-15T18:11:52.039017Z,ANSS,BUY - MARKET,1,USD 350.37,USD 351.53,USD,1.1699 2020-10-15T18:12:50.686186Z,TSLA,BUY - MARKET,1,USD 447.03,USD 448.19,USD,1.1699 2020-10-22T19:08:13.614097Z,,CASH TOP-UP,,,USD 499.59,USD,1.1821 2020-10-22T19:09:34.905452Z,NIO,BUY - MARKET,19.00692924,USD 27.42,USD 521.17,USD,1.1819 2020-10-29T18:55:00.260065Z,NIO,SELL - MARKET,19.00692924,USD 31.80,USD 604.41,USD,1.1676 2020-10-30T18:56:29.039455Z,,CASH TOP-UP,,,USD 230,USD,1.1650 2020-10-30T18:56:51.641601Z,NIO,BUY - MARKET,19,USD 30.59,USD 581.21,USD,1.1650 2020-10-30T18:57:57.787675Z,AAPL,BUY - MARKET,2.37198781,USD 108.31,USD 258.07,USD,1.1650 2020-10-31T23:47:17.741658Z,,CUSTODY FEE,,,USD -0.02,USD,1.1764 2020-11-03T15:53:12.856984Z,NIO,SELL - LIMIT,19,USD 34.50,USD 654.32,USD,1.1732 2020-11-04T18:55:00.333905Z,NIO,BUY - MARKET,17.55848346,USD 37.19,USD 654.17,USD,1.1722 2020-11-05T20:22:09.458491Z,NIO,SELL - MARKET,17.55848346,USD 41.52,USD 727.82,USD,1.1832 2020-11-06T14:34:58.811794Z,Z,SELL - LIMIT,1,USD 116,USD 114.81,USD,1.1881 2020-11-06T18:59:27.241831Z,NIO,BUY - LIMIT,20,USD 41.18,USD 824.77,USD,1.1885 2020-11-12T18:51:45.536988Z,NIO,SELL - MARKET,20,USD 49.06,USD 979.99,USD,1.1811 2020-11-12T20:28:48.899248Z,ZM,BUY - MARKET,1,USD 434.26,USD 435.44,USD,1.1806 2020-11-13T07:29:21.306371Z,AAPL,DIVIDEND,,,USD 0.57,USD,1.1809 2020-11-13T16:00:28.844792Z,NIO,BUY - LIMIT,12,USD 45,USD 541.18,USD,1.1825 2020-11-17T08:15:59.644143Z,,CASH TOP-UP,,,USD 731.22,USD,1.1865 2020-11-17T14:30:26.648440Z,NIO,BUY - LIMIT,15,USD 47.60,USD 715.18,USD,1.1881 2020-11-18T20:12:07.728932Z,TSLA,SELL - MARKET,1.84973166,USD 493.13,USD 910.95,USD,1.1869 2020-11-18T20:19:35.527950Z,AAPL,BUY - MARKET,4,USD 119.46,USD 479.02,USD,1.1869 2020-11-23T18:57:03.219942Z,ZM,SELL - MARKET,1,USD 428.78,USD 428.76,USD,1.1844 2020-11-23T19:06:24.107144Z,MRNA,BUY - MARKET,8,USD 101.20,USD 809.60,USD,1.1846 2020-11-23T19:55:40.733Z,NIO,SELL - LIMIT,27,USD 55,USD 1484.96,USD,1.1844 2020-11-23T20:30:29.564774Z,AAPL,BUY - MARKET,4,USD 114.01,USD 457.22,USD,1.1846 2020-11-24T18:51:56.018454Z,NIO,BUY - MARKET,20,USD 53.06,USD 1062.38,USD,1.1883 2020-11-27T15:27:23.105927Z,MRNA,SELL - LIMIT,8,USD 125,USD 998.78,USD,1.1948 2020-11-30T14:15:54.164131Z,,CASH TOP-UP,,,USD 664.15,USD,1.1995 2020-11-30T14:30:49.626140Z,AAPL,BUY - LIMIT,2,USD 116.83,USD 234.84,USD,1.2000 2020-11-30T14:33:41.605018Z,MRNA,BUY - LIMIT,10,USD 145.90,USD 1460.19,USD,1.1999 2020-12-01T00:30:11.291111Z,,CUSTODY FEE,,,USD -0.03,USD,1.1944 2020-12-07T10:23:47.307513Z,,CASH TOP-UP,,,USD 1426.49,USD,1.2111 2020-12-07T14:30:14.146234Z,MRNA,BUY - LIMIT,3,USD 155,USD 466.21,USD,1.2140 2020-12-07T14:30:16.651365Z,AMD,BUY - LIMIT,4,USD 95,USD 381.21,USD,1.2140 2020-12-07T14:37:45.448906Z,NIO,BUY - MARKET,8,USD 43.88,USD 352.25,USD,1.2151 2020-12-07T14:48:29.177623Z,,CASH TOP-UP,,,USD 11.90,USD,1.2160 2020-12-07T14:52:21.891107Z,AAPL,BUY - LIMIT,2,USD 124.20,USD 249.61,USD,1.2160 2020-12-08T20:31:41.166482Z,ANSS,SELL - MARKET,1,USD 339.69,USD 338.47,USD,1.2103 2020-12-08T20:41:46.607512Z,AMD,SELL - MARKET,4,USD 92.80,USD 369.97,USD,1.2106 2020-12-10T07:20:47.264099Z,,CASH WITHDRAWAL,,,USD -719.84,USD,1.2099 2020-12-10T20:40:18.560804Z,TSLA,SELL - MARKET,1.40203142,USD 624.15,USD 873.84,USD,1.2144 2020-12-14T07:43:28.816492Z,,CASH WITHDRAWAL,,,USD -873.84,USD,1.2154 2020-12-15T18:55:28.066297Z,AAPL,SELL - MARKET,8,USD 126.65,USD 1011.96,USD,1.2156 2020-12-17T07:54:05.445923Z,,CASH WITHDRAWAL,,,USD -1011.96,USD,1.2239 2020-12-17T18:55:02.049985Z,AAPL,SELL - MARKET,7.28008659,USD 128.57,USD 934.75,USD,1.2266 2020-12-21T13:20:36.584594Z,,CASH WITHDRAWAL,,,USD -934.75,USD,1.2181 2020-12-21T19:56:52.327716Z,NIO,SELL - MARKET,9,USD 48.98,USD 440.80,USD,1.2250 2020-12-23T07:28:05.324423Z,,CASH WITHDRAWAL,,,USD -440.80,USD,1.2194 2020-12-31T23:45:30.563583Z,,CUSTODY FEE,,,USD -0.02,USD,1.2219 2021-01-06T14:38:58.419778Z,NIO,SELL - LIMIT,10,USD 55,USD 549.98,USD,1.2310 2021-01-08T01:23:25.271933Z,,CASH WITHDRAWAL,,,USD -549.96,USD,1.2243 2021-01-11T19:10:30.338236Z,NIO,SELL - MARKET,9,USD 64.02,USD 576.16,USD,1.2172 2021-01-13T07:46:17.357323Z,,CASH WITHDRAWAL,,,USD -576.16,USD,1.2219 2021-01-21T19:55:57.688286Z,MRNA,SELL - MARKET,4,USD 134.71,USD 538.82,USD,1.2161 2021-01-25T08:21:04.979177Z,,CASH WITHDRAWAL,,,USD -538.82,USD,1.2174 2021-01-26T19:19:16.914055Z,MRNA,SELL - MARKET,9,USD 152.59,USD 1373.27,USD,1.2165 2021-01-28T07:22:05.590731Z,,CASH WITHDRAWAL,,,USD -1373.27,USD,1.2092 2023-11-24T17:03:57.734783Z,,CASH TOP-UP,,,EUR 504.50,EUR,1.0000 2023-11-24T17:15:33.304Z,EUNL,BUY - MARKET,6.396602,EUR 78.87,EUR 504.50,EUR,1.0000 2023-12-01T08:42:05.534265Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2023-12-14T11:34:52.147494Z,,CASH TOP-UP,,,EUR 0.05,EUR,1.0000 2023-12-14T16:36:50.068587Z,,CASH TOP-UP,,,USD 489.94,USD,1.1019 2023-12-14T16:40:51.905Z,AAPL,BUY - MARKET,2.46591654,USD 198.19,USD 489.94,USD,1.1019 2023-12-22T13:27:28.076800Z,,CASH TOP-UP,,,USD 879,USD,1.1040 2023-12-22T17:20:12.958Z,AAPL,BUY - LIMIT,2,USD 194,USD 388,USD,1.1031 2023-12-26T14:30:08.353Z,AAPL,BUY - MARKET,2.52985537,USD 193.60,USD 491,USD,1.1043 2024-01-01T06:23:42.708819Z,,CUSTODY FEE,,,USD -0.13,USD,1.1060 2024-01-01T06:23:42.760294Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-01-02T19:59:58.107632Z,,CASH TOP-UP,,,USD 0.13,USD,1.0967 2024-01-02T20:01:20.502425Z,,CASH TOP-UP,,,USD 543,USD,1.0968 2024-01-08T09:32:34.413Z,AAPL,BUY - LIMIT,3,USD 180,USD 541.37,USD,1.0945 2024-01-25T15:07:15.293590Z,,CASH TOP-UP,,,EUR 0.05,EUR,1.0000 2024-01-25T20:42:52.086873Z,,CASH TOP-UP,,,EUR 200.69,EUR,1.0000 2024-01-26T07:00:11.166Z,EUNL,BUY - MARKET,2.37003708,EUR 84.68,EUR 200.69,EUR,1.0000 2024-01-31T12:52:00.509845Z,,CASH TOP-UP,,,USD 288.99,USD,1.0857 2024-01-31T14:30:00.714Z,MSFT,BUY - MARKET,0.71112093,USD 407.16,USD 290.63,USD,1.0886 2024-02-01T08:56:45.345127Z,,CUSTODY FEE,,,USD -0.21,USD,1.0810 2024-02-01T08:56:45.413690Z,,CUSTODY FEE,,,EUR -0.07,EUR,1.0000 2024-02-13T14:38:08.488487Z,,CASH TOP-UP,,,USD 0.22,USD,1.0738 2024-02-13T14:40:17.841298Z,,CASH TOP-UP,,,USD 755.08,USD,1.0736 2024-02-13T14:40:38.679Z,NVDA,BUY - MARKET,1.06123369,USD 709.74,USD 755.09,USD,1.0736 2024-02-16T19:52:41.455422Z,AAPL,DIVIDEND,,,USD 2.03,USD,1.0804 2024-03-04T14:22:20.905847Z,,CASH TOP-UP,,,EUR 0.07,EUR,1.0000 2024-03-04T14:23:11.695860Z,,CASH TOP-UP,,,USD 499.93,USD,1.0871 2024-03-04T14:23:32.332134Z,,CASH TOP-UP,,,USD 38.14,USD,1.0872 2024-03-04T14:55:06.012Z,AAPL,BUY - LIMIT,3,USD 175,USD 525,USD,1.0884 2024-03-04T17:52:28.294Z,AAPL,BUY - MARKET,0.0803971,USD 174.26,USD 15.09,USD,1.0881 2024-03-15T13:18:50.186954Z,MSFT,DIVIDEND,,,USD 0.45,USD,1.0916 2024-03-22T09:33:28.387261Z,,CASH TOP-UP,,,EUR 802.91,EUR,1.0000 2024-03-22T09:35:02.359240Z,,CASH WITHDRAWAL,,,EUR -802.91,EUR,1.0000 2024-03-22T09:36:34.905427Z,,CASH TOP-UP,,,USD 866.85,USD,1.0841 2024-03-22T13:30:03.044Z,AAPL,BUY - MARKET,5.05272356,USD 171.65,USD 867.30,USD,1.0844 2024-03-28T13:14:54.322150Z,NVDA,DIVIDEND,,,USD 0.03,USD,1.0832 2024-04-30T18:58:29.511144Z,,CASH TOP-UP,,,USD 398.79,USD,1.0701 2024-04-30T21:53:59.511625Z,,CASH WITHDRAWAL,,,USD -398.80,USD,1.0692 2024-04-30T21:54:43.619956Z,,CASH TOP-UP,,,EUR 373.01,EUR,1.0000 2024-05-02T06:00:16.615Z,EUNL,BUY - MARKET,4.18924079,EUR 89.04,EUR 373.01,EUR,1.0000 2024-05-17T10:53:20.444540Z,AAPL,DIVIDEND,,,USD 3.85,USD,1.0861 2024-05-22T21:14:39.648Z,NVDA,SELL - LIMIT,1,USD 1000,USD 999.96,USD,1.0847 2024-06-06T21:07:57.606092Z,,CASH WITHDRAWAL,,,USD -1000,USD,1.0915 2024-06-10T12:45:20.997537Z,NVDA,STOCK SPLIT,0.55110321,,USD 0,USD,1.0774 2024-06-11T15:45:44.606498Z,,CASH TOP-UP,,,USD 510.70,USD,1.0753 2024-06-11T15:46:11.821Z,AAPL,BUY - MARKET,2.51985895,USD 204.19,USD 514.53,USD,1.0754 2024-06-14T10:33:01.853533Z,MSFT,DIVIDEND,,,USD 0.45,USD,1.0711 2024-06-20T12:29:51.031136Z,,CASH TOP-UP,,,USD 855.76,USD,1.0747 2024-06-20T12:33:04.082900Z,,CASH TOP-UP,,,EUR 0.39,EUR,1.0000 2024-06-20T13:30:18.215Z,NVDA,BUY - MARKET,6.12891911,USD 139.70,USD 856.21,USD,1.0747 2024-06-21T14:34:27.483597Z,,CASH TOP-UP,,,EUR 1300,EUR,1.0000 2024-06-21T14:38:20.081676Z,,CASH WITHDRAWAL,,,EUR -1300.39,EUR,1.0000 2024-06-21T14:38:56.144330Z,,CASH TOP-UP,,,EUR 1300.39,EUR,1.0000 2024-06-21T14:45:00.298869Z,,CASH WITHDRAWAL,,,EUR -1200.39,EUR,1.0000 2024-06-21T15:13:03.410460Z,,CASH WITHDRAWAL,,,EUR -100,EUR,1.0000 2024-06-21T15:14:11.098313Z,,CASH TOP-UP,,,USD 1300.39,USD,1.0709 2024-06-21T15:15:59.315Z,RIVN,BUY - MARKET,4.46376811,USD 10.35,USD 47.27,USD,1.0708 2024-06-24T14:03:36.788Z,NVDA,BUY - MARKET,10.13228499,USD 123.37,USD 1253.12,USD,1.0767 2024-06-25T19:28:23.934655Z,,CASH TOP-UP,,,EUR 70.80,EUR,1.0000 2024-06-26T06:00:38.873Z,EUNL,BUY - MARKET,0.73362482,EUR 95.14,EUR 70.80,EUR,1.0000 2024-07-10T15:23:26.567689Z,,CASH TOP-UP,,,EUR 550,EUR,1.0000 2024-07-10T15:23:28.152Z,EUNL,BUY - MARKET,5.71561028,EUR 95.99,EUR 550,EUR,1.0000 2024-07-15T07:00:47.240466Z,,CASH TOP-UP,,,EUR 4125,EUR,1.0000 2024-07-15T07:04:43.399Z,EUNL,BUY - MARKET,42.71029686,EUR 96.34,EUR 4125,EUR,1.0000 2024-07-15T07:58:13.494235Z,,CASH TOP-UP,,,EUR 5500,EUR,1.0000 2024-07-17T06:48:24.137Z,EXXT,BUY - MARKET,12,EUR 180.60,EUR 2172.62,EUR,1.0000 2024-07-18T23:08:19.546857Z,,CASH WITHDRAWAL,,,EUR -1500,EUR,1.0000 2024-07-18T23:08:45.728004Z,,CASH TOP-UP,,,USD 1500,USD,1.0922 2024-07-19T17:22:56.157Z,EXXT,BUY - LIMIT,5,EUR 174,EUR 872.18,EUR,1.0000 2024-07-22T10:03:28.017672Z,,CASH TOP-UP,,,EUR 117.07,EUR,1.0000 2024-07-22T10:59:38.965Z,EXXT,BUY - MARKET,6.07934523,EUR 175.94,EUR 1072.27,EUR,1.0000 2024-07-22T13:30:01.410Z,RIVN,BUY - MARKET,0.51790957,USD 17.03,USD 9.91,USD,1.0903 2024-07-24T14:01:21.718Z,,CASH TOP-UP,,,USD 750.06,USD,1.0879 2024-07-24T14:44:00.063Z,AAPL,BUY - LIMIT,6,USD 220,USD 1320,USD,1.0882 2024-07-25T13:58:18.968Z,NVDA,BUY - LIMIT,6,USD 110,USD 661.65,USD,1.0856 2024-08-01T18:45:39.482Z,RIVN,BUY - LIMIT,5,USD 15,USD 76.08,USD,1.0803 2024-08-02T10:03:50.184733Z,,CASH TOP-UP,,,USD 1500,USD,1.0840 2024-08-02T11:09:33.988193Z,,CASH TOP-UP,,,USD 97.92,USD,1.0844 2024-08-02T13:30:04.412Z,AAPL,BUY - MARKET,6.88368697,USD 219.15,USD 1512.33,USD,1.0912 2024-08-02T13:30:07.004Z,RIVN,BUY - MARKET,6.65955983,USD 14.54,USD 97.91,USD,1.0911 2024-08-02T19:13:53.883371Z,,CASH TOP-UP,,,USD 6.42,USD,1.0934 2024-08-02T19:14:06.918Z,RIVN,BUY - MARKET,0.36335623,USD 14.67,USD 6.42,USD,1.0934 2024-08-05T13:30:00.026Z,RIVN,BUY - LIMIT,13,USD 12.96,USD 169.57,USD,1.1015 2024-08-16T15:17:34.058952Z,AAPL,DIVIDEND,,,USD 7.12,USD,1.1013 2024-09-12T13:30:01.579Z,AAPL,BUY - MARKET,0.0344176,USD 222.27,USD 7.65,USD,1.1060 2024-09-13T10:09:30.437957Z,MSFT,DIVIDEND,,,USD 0.45,USD,1.1112 2024-10-04T11:06:38.613263Z,NVDA,DIVIDEND,,,USD 0.19,USD,1.1052 2024-10-17T10:50:43.300Z,NVDA,SELL - LIMIT,22,USD 140,USD 3079.90,USD,1.0885 2024-10-28T13:20:19.490825Z,,CASH WITHDRAWAL,,,USD -3080.54,USD,1.0838 2024-10-28T13:22:04.259575Z,,CASH TOP-UP,,,USD 3080.54,USD,1.0837 2024-11-06T11:36:43.272005Z,,CASH WITHDRAWAL,,,USD -3080.54,USD,1.0741 2024-11-15T10:51:18.882155Z,AAPL,DIVIDEND,,,USD 7.13,USD,1.0596 2024-11-19T21:10:34.073573Z,,CASH TOP-UP,,,EUR 1000.93,EUR,1.0000 2024-11-19T21:16:04.015409Z,,CASH WITHDRAWAL,,,USD -7.13,USD,1.0617 2024-11-19T21:22:13.152382Z,,CASH TOP-UP,,,EUR 2913.11,EUR,1.0000 2024-11-20T07:00:23.409Z,VUSA,BUY - MARKET,36.80546152,EUR 106.34,EUR 3914.04,EUR,1.0000 2024-11-22T10:18:57.120815Z,,CASH TOP-UP,,,USD 2076.27,USD,1.0422 2024-11-22T14:30:10.466Z,NVDA,BUY - MARKET,14.19916358,USD 145.86,USD 2076.26,USD,1.0433 2024-12-09T15:22:26.481Z,RIVN,SELL - MARKET,30.00459374,USD 14.63,USD 437.89,USD,1.0597 2024-12-10T15:18:23.058Z,MSFT,SELL - MARKET,0.71112093,USD 449.40,USD 318.51,USD,1.0529 2024-12-13T13:07:55.553427Z,MSFT,DIVIDEND,,,USD 0.50,USD,1.0539 2024-12-13T13:10:24.438650Z,,CASH WITHDRAWAL,,,USD -756.41,USD,1.0540 2024-12-17T13:13:41.278239Z,,CASH TOP-UP,,,USD 756.47,USD,1.0518 2024-12-17T14:30:09.042Z,NVDA,BUY - MARKET,5.8574199,USD 128.91,USD 756.97,USD,1.0526 2024-12-18T15:56:07.657064Z,EXXT,DIVIDEND,,,EUR 2.45,EUR,1.0000 2024-12-20T08:53:47.568825Z,,CASH TOP-UP,,,EUR 1000,EUR,1.0000 2024-12-20T08:55:41.144Z,VUSA,BUY - MARKET,9.41762804,EUR 106.44,EUR 1002.45,EUR,1.0000 2024-12-30T11:13:13.047080Z,NVDA,DIVIDEND,,,USD 0.13,USD,1.0463 2024-12-31T16:37:09.382630Z,VUSA,DIVIDEND,,,EUR 10.77,EUR,1.0000 2025-01-02T08:26:47.227963Z,,CASH WITHDRAWAL,,,USD -0.13,USD,1.0379 2025-01-02T08:27:04.695292Z,,CASH WITHDRAWAL,,,EUR -10.77,EUR,1.0000 2025-01-22T20:26:44.223967Z,,CASH TOP-UP,,,USD 841,USD,1.0442 2025-01-22T20:49:21.147Z,AAPL,BUY - MARKET,3.76830361,USD 223.18,USD 841,USD,1.0436 2025-01-30T18:51:53.611617Z,,CASH TOP-UP,,,USD 510.77,USD,1.0445 2025-01-30T18:52:55.951777Z,,CASH TOP-UP,,,USD 8,USD,1.0446 2025-01-30T18:53:43.860Z,NVDA,BUY - MARKET,4.32358593,USD 119.69,USD 518.77,USD,1.0445 2025-02-14T20:34:14.179261Z,AAPL,DIVIDEND,,,USD 7.93,USD,1.0521 2025-02-24T12:57:16.960888Z,,CASH WITHDRAWAL,,,USD -7.93,USD,1.0488 2025-02-25T07:54:24.798945Z,,CASH TOP-UP,,,EUR 1700,EUR,1.0000 2025-02-25T08:04:16.746Z,EXXT,BUY - MARKET,8.58499141,EUR 198.02,EUR 1700,EUR,1.0000 2025-03-07T21:56:26.746370Z,,CASH TOP-UP,,,EUR 1800,EUR,1.0000 2025-03-10T07:09:05.065Z,EXXT,BUY - MARKET,9.9562493,EUR 180.34,EUR 1800,EUR,1.0000 2025-03-17T14:53:56.276880Z,,CASH TOP-UP,,,EUR 809.79,EUR,1.0000 2025-03-17T14:54:43.632Z,VUSA,BUY - MARKET,8.21071355,EUR 98.38,EUR 809.79,EUR,1.0000 2025-03-19T15:57:20.906797Z,EXXT,DIVIDEND,,,EUR 4.69,EUR,1.0000 2025-03-31T13:35:22.737068Z,,CASH TOP-UP,,,EUR 850.28,EUR,1.0000 2025-03-31T13:35:49.950Z,EXXT,BUY - MARKET,5.03515901,EUR 169.80,EUR 854.97,EUR,1.0000 2025-04-03T16:28:39.241991Z,NVDA,DIVIDEND,,,USD 0.21,USD,1.1066 2025-04-10T16:57:00.357808Z,VUSA,DIVIDEND,,,EUR 15.74,EUR,1.0000 2025-04-11T01:03:23.685545Z,,CASH WITHDRAWAL,,,EUR -15.74,EUR,1.0000 2025-04-11T01:03:38.016522Z,,CASH WITHDRAWAL,,,USD -0.21,USD,1.1326 2025-04-28T11:43:36.485Z,AAPL,SELL - LIMIT,6,USD 210,USD 1256.80,USD,1.1366 2025-05-01T16:19:41.043934Z,,CASH WITHDRAWAL,,,USD -1256.80,USD,1.1305 2025-05-05T21:46:31.246939Z,,CASH TOP-UP,,,USD 1265.50,USD,1.1341 2025-05-16T18:31:25.227508Z,AAPL,DIVIDEND,,,USD 6.92,USD,1.1172 2025-06-16T15:11:22.017Z,NVDA,SELL - LIMIT,9,USD 146,USD 1312.84,USD,1.1614 2025-06-18T14:59:15.822789Z,EXXT,DIVIDEND,,,EUR 11.63,EUR,1.0000 2025-06-19T06:17:45.118728Z,,CASH WITHDRAWAL,,,EUR -11.63,EUR,1.0000 2025-06-19T14:25:19.692788Z,,CASH WITHDRAWAL,,,USD -1474.11,USD,1.1500 2025-07-09T12:24:12.220532Z,VUSA,DIVIDEND,,,EUR 14.42,EUR,1.0000 2025-07-10T08:16:38.327181Z,NVDA,DIVIDEND,,,USD 0.21,USD,1.1755 2025-07-25T16:14:30.658497Z,,CASH WITHDRAWAL,,,USD -0.21,USD,1.1753 2025-07-25T16:15:18.340Z,AAPL,BUY - MARKET,5.17526109,USD 214.48,USD 1111.15,USD,1.1751 2025-07-25T16:18:04.910320Z,,CASH WITHDRAWAL,,,EUR -14.42,EUR,1.0000 2025-07-25T16:19:37.782025Z,,CASH TOP-UP,,,USD 1478.65,USD,1.1750 2025-07-25T16:19:38.539Z,GOOGL,BUY - MARKET,7.64474569,USD 193.27,USD 1478.65,USD,1.1750 2025-07-25T16:20:51.847436Z,,CASH TOP-UP,,,EUR 1032.78,EUR,1.0000 2025-07-25T16:20:54.709Z,EXXT,BUY - MARKET,5.3399234,EUR 193.22,EUR 1032.78,EUR,1.0000 2025-08-14T23:05:38.545180Z,AAPL,DIVIDEND,,,USD 8.07,USD,1.1677 2025-08-29T19:22:45.487940Z,,CASH WITHDRAWAL,,,USD -8.07,USD,1.1726 2025-09-15T14:26:50.602733Z,GOOGL,DIVIDEND,,,USD 1.36,USD,1.1778 2025-10-01T13:37:38.687481Z,,CASH WITHDRAWAL,,,USD -1.36,USD,1.1785 2025-10-02T20:11:01.878991Z,NVDA,DIVIDEND,,,USD 0.14,USD,1.1747 2025-10-03T17:03:55.879717Z,VUSA,DIVIDEND,,,EUR 13.94,EUR,1.0000 2025-10-03T17:05:28.310537Z,,CASH WITHDRAWAL,,,USD -0.14,USD,1.1766 2025-10-06T16:20:24.426444Z,,CASH WITHDRAWAL,,,EUR -13.94,EUR,1.0000 2025-10-24T11:59:42.247101Z,,CASH TOP-UP,,,EUR 937.20,EUR,1.0000 2025-10-24T12:05:53.567199Z,,CASH WITHDRAWAL,,,EUR -937.20,EUR,1.0000 2025-11-09T13:33:45.679788Z,,CASH TOP-UP,,,USD 1011.67,USD,1.1610 2025-11-10T14:30:42.949Z,NVDA,BUY - MARKET,5.18210256,USD 195,USD 1011.66,USD,1.1591 2025-11-13T21:03:12.016246Z,AAPL,DIVIDEND,,,USD 8.07,USD,1.1658 2025-12-04T21:00:36.955089Z,,CASH WITHDRAWAL,,,USD -8.08,USD,1.1670 ======================================================================================== FICHEIRO: dados_csv/filipe/lucro-mensal.json Tamanho: 43267 bytes ======================================================================================== { "ok": true, "user": "filipe", "moeda": "EUR", "compatibilidade": true, "totalmeses": 71, "investimentoinicial": 33002.77, "series": [ { "mes": "2020-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-02-29", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 0, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 0, "precofonte": "stooq" }, { "mes": "2020-09", "ganhos": 18.4, "dividendos": 0, "taxas": 0.01, "net": 18.39, "deltarealizado": 18.4, "deltanaorealizado": 0, "realizadoacumulado": 18.4, "naorealizadofimmes": 0, "fimmesusado": "2020-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 915.97, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 915.97, "precofonte": "stooq" }, { "mes": "2020-10", "ganhos": 104.6, "dividendos": 0, "taxas": 0.02, "net": 104.58, "deltarealizado": 104.6, "deltanaorealizado": 0, "realizadoacumulado": 123, "naorealizadofimmes": 0, "fimmesusado": "2020-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 2232.59, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 2232.59, "precofonte": "stooq" }, { "mes": "2020-11", "ganhos": 804.33, "dividendos": 0.48, "taxas": 0, "net": 804.81, "deltarealizado": 804.33, "deltanaorealizado": 0, "realizadoacumulado": 927.33, "naorealizadofimmes": 0, "fimmesusado": "2020-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3402.56, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3402.56, "precofonte": "stooq" }, { "mes": "2020-12", "ganhos": 211.01, "dividendos": 0, "taxas": 0.04, "net": 210.97, "deltarealizado": 211.01, "deltanaorealizado": 0, "realizadoacumulado": 1138.34, "naorealizadofimmes": 0, "fimmesusado": "2020-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 1320.56, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 1320.56, "precofonte": "stooq" }, { "mes": "2021-01", "ganhos": 41.78, "dividendos": 0, "taxas": 0, "net": 41.78, "deltarealizado": 41.78, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2021-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2021-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2022-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2022-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -1178.46, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -1178.46, "precofonte": "stooq" }, { "mes": "2023-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": -673.96, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": -673.96, "precofonte": "stooq" }, { "mes": "2023-12", "ganhos": 0, "dividendos": 0, "taxas": 0.05, "net": -0.05, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2023-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 566.92, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 566.92, "precofonte": "stooq" }, { "mes": "2024-01", "ganhos": 0, "dividendos": 0, "taxas": 0.17, "net": -0.17, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 1529.03, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 1529.03, "precofonte": "stooq" }, { "mes": "2024-02", "ganhos": 0, "dividendos": 1.88, "taxas": 0.26, "net": 1.61, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-02-29", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 2232.55, "saldocaixafimmes": -0.07, "valorcarteira": -0.07, "investimentoinicial": 2232.55, "precofonte": "stooq" }, { "mes": "2024-03", "ganhos": 0, "dividendos": 0.44, "taxas": 0, "net": 0.44, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3527.18, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 3527.18, "precofonte": "stooq" }, { "mes": "2024-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1180.12, "naorealizadofimmes": 0, "fimmesusado": "2024-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3899.87, "saldocaixafimmes": 373.01, "valorcarteira": 373.01, "investimentoinicial": 3899.87, "precofonte": "stooq" }, { "mes": "2024-05", "ganhos": 259.13, "dividendos": 3.54, "taxas": 0, "net": 262.68, "deltarealizado": 259.13, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 3899.87, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 3899.87, "precofonte": "stooq" }, { "mes": "2024-06", "ganhos": 0, "dividendos": 0.42, "taxas": 0, "net": 0.42, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 5540.01, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5540.01, "precofonte": "stooq" }, { "mes": "2024-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 16394.91, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 16394.91, "precofonte": "stooq" }, { "mes": "2024-08", "ganhos": 0, "dividendos": 6.47, "taxas": 0, "net": 6.47, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 17874.85, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 17874.85, "precofonte": "stooq" }, { "mes": "2024-09", "ganhos": 0, "dividendos": 0.4, "taxas": 0, "net": 0.4, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1439.26, "naorealizadofimmes": 0, "fimmesusado": "2024-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 17874.85, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 17874.85, "precofonte": "stooq" }, { "mes": "2024-10", "ganhos": 291.41, "dividendos": 0.17, "taxas": 0, "net": 291.58, "deltarealizado": 291.41, "deltanaorealizado": 0, "realizadoacumulado": 1730.66, "naorealizadofimmes": 0, "fimmesusado": "2024-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 17875.11, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 17875.11, "precofonte": "stooq" }, { "mes": "2024-11", "ganhos": 0, "dividendos": 6.73, "taxas": 0, "net": 6.73, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1730.66, "naorealizadofimmes": 0, "fimmesusado": "2024-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 20906.61, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 20906.61, "precofonte": "stooq" }, { "mes": "2024-12", "ganhos": 75.54, "dividendos": 13.82, "taxas": 0, "net": 89.36, "deltarealizado": 75.54, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 21908.17, "saldocaixafimmes": 10.77, "valorcarteira": 10.77, "investimentoinicial": 21908.17, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 23199.35, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 23199.35, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 7.54, "taxas": 0, "net": 7.54, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 24891.78, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 24891.78, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 4.69, "taxas": 0, "net": 4.69, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1806.2, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 28351.85, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 28351.85, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": -107.26, "dividendos": 15.93, "taxas": 0, "net": -91.33, "deltarealizado": -107.26, "deltanaorealizado": 0, "realizadoacumulado": 1698.94, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 28335.93, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 28335.93, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 0, "dividendos": 6.19, "taxas": 0, "net": 6.19, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1698.94, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 28340.07, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 28340.07, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 56.26, "dividendos": 11.63, "taxas": 0, "net": 67.89, "deltarealizado": 56.26, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 27046.61, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 27046.61, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 14.6, "taxas": 0, "net": 14.6, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 31223.21, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 31223.21, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 0, "dividendos": 6.91, "taxas": 0, "net": 6.91, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 31216.33, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 31216.33, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 1.15, "taxas": 0, "net": 1.15, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 31216.33, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 31216.33, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 14.06, "taxas": 0, "net": 14.06, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 32138.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 32138.32, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 0, "dividendos": 6.92, "taxas": 0, "net": 6.92, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 1755.21, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 33009.7, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 33009.7, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 6647.07, "dividendos": 0, "taxas": 0, "net": 6647.07, "deltarealizado": 0, "deltanaorealizado": 6647.07, "realizadoacumulado": 1755.21, "naorealizadofimmes": 6647.07, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 41529.28, "investimentoacumulado": 33002.77, "saldocaixafimmes": 0, "valorcarteira": 41529.28, "investimentoinicial": 33002.77, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 16:00:50", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: dados_csv/filipe/movimentos-caixa.csv Tamanho: 8762 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2020-09-04,Depósito,250,USD,CASH TOP-UP,1.1839 2,2020-09-04,Depósito,250,USD,CASH TOP-UP,1.1845 3,2020-09-10,Depósito,250,USD,CASH TOP-UP,1.1834 4,2020-09-24,Depósito,329.15,USD,CASH TOP-UP,1.1657 5,2020-09-25,Depósito,219.22,USD,CASH TOP-UP,1.1679 6,2020-09-25,Levantamento,-219.22,USD,CASH WITHDRAWAL,1.1687 7,2020-09-30,Outros,-0.01,USD,CUSTODY FEE,1.1727 8,2020-10-02,Depósito,0.01,USD,CASH TOP-UP,1.1718 9,2020-10-02,Depósito,415.88,USD,CASH TOP-UP,1.1718 10,2020-10-15,Depósito,400,USD,CASH TOP-UP,1.1708 11,2020-10-22,Depósito,499.59,USD,CASH TOP-UP,1.1821 12,2020-10-30,Depósito,230,USD,CASH TOP-UP,1.165 13,2020-10-31,Outros,-0.02,USD,CUSTODY FEE,1.1764 14,2020-11-13,Dividendo,0.57,USD,AAPL DIVIDEND,1.1809 15,2020-11-17,Depósito,731.22,USD,CASH TOP-UP,1.1865 16,2020-11-30,Depósito,664.15,USD,CASH TOP-UP,1.1995 17,2020-12-01,Outros,-0.03,USD,CUSTODY FEE,1.1944 18,2020-12-07,Depósito,1426.49,USD,CASH TOP-UP,1.2111 19,2020-12-07,Depósito,11.9,USD,CASH TOP-UP,1.216 20,2020-12-10,Levantamento,-719.84,USD,CASH WITHDRAWAL,1.2099 21,2020-12-14,Levantamento,-873.84,USD,CASH WITHDRAWAL,1.2154 22,2020-12-17,Levantamento,-1011.96,USD,CASH WITHDRAWAL,1.2239 23,2020-12-21,Levantamento,-934.75,USD,CASH WITHDRAWAL,1.2181 24,2020-12-23,Levantamento,-440.8,USD,CASH WITHDRAWAL,1.2194 25,2020-12-31,Outros,-0.02,USD,CUSTODY FEE,1.2219 26,2021-01-08,Levantamento,-549.96,USD,CASH WITHDRAWAL,1.2243 27,2021-01-13,Levantamento,-576.16,USD,CASH WITHDRAWAL,1.2219 28,2021-01-25,Levantamento,-538.82,USD,CASH WITHDRAWAL,1.2174 29,2021-01-28,Levantamento,-1373.27,USD,CASH WITHDRAWAL,1.2092 30,2023-11-24,Depósito,504.5,EUR,CASH TOP-UP,1 31,2023-12-01,Outros,-0.05,EUR,CUSTODY FEE,1 32,2023-12-14,Depósito,0.05,EUR,CASH TOP-UP,1 33,2023-12-14,Depósito,489.94,USD,CASH TOP-UP,1.1019 34,2023-12-22,Depósito,879,USD,CASH TOP-UP,1.104 35,2024-01-01,Outros,-0.13,USD,CUSTODY FEE,1.106 36,2024-01-01,Outros,-0.05,EUR,CUSTODY FEE,1 37,2024-01-02,Depósito,0.13,USD,CASH TOP-UP,1.0967 38,2024-01-02,Depósito,543,USD,CASH TOP-UP,1.0968 39,2024-01-25,Depósito,0.05,EUR,CASH TOP-UP,1 40,2024-01-25,Depósito,200.69,EUR,CASH TOP-UP,1 41,2024-01-31,Depósito,288.99,USD,CASH TOP-UP,1.0857 42,2024-02-01,Outros,-0.21,USD,CUSTODY FEE,1.081 43,2024-02-01,Outros,-0.07,EUR,CUSTODY FEE,1 44,2024-02-13,Depósito,0.22,USD,CASH TOP-UP,1.0738 45,2024-02-13,Depósito,755.08,USD,CASH TOP-UP,1.0736 46,2024-02-16,Dividendo,2.03,USD,AAPL DIVIDEND,1.0804 47,2024-03-04,Depósito,0.07,EUR,CASH TOP-UP,1 48,2024-03-04,Depósito,499.93,USD,CASH TOP-UP,1.0871 49,2024-03-04,Depósito,38.14,USD,CASH TOP-UP,1.0872 50,2024-03-15,Dividendo,0.45,USD,MSFT DIVIDEND,1.0916 51,2024-03-22,Depósito,802.91,EUR,CASH TOP-UP,1 52,2024-03-22,Levantamento,-802.91,EUR,CASH WITHDRAWAL,1 53,2024-03-22,Depósito,866.85,USD,CASH TOP-UP,1.0841 54,2024-03-28,Dividendo,0.03,USD,NVDA DIVIDEND,1.0832 55,2024-04-30,Depósito,398.79,USD,CASH TOP-UP,1.0701 56,2024-04-30,Levantamento,-398.8,USD,CASH WITHDRAWAL,1.0692 57,2024-04-30,Depósito,373.01,EUR,CASH TOP-UP,1 58,2024-05-17,Dividendo,3.85,USD,AAPL DIVIDEND,1.0861 59,2024-06-06,Levantamento,-1000,USD,CASH WITHDRAWAL,1.0915 60,2024-06-11,Depósito,510.7,USD,CASH TOP-UP,1.0753 61,2024-06-14,Dividendo,0.45,USD,MSFT DIVIDEND,1.0711 62,2024-06-20,Depósito,855.76,USD,CASH TOP-UP,1.0747 63,2024-06-20,Depósito,0.39,EUR,CASH TOP-UP,1 64,2024-06-21,Depósito,1300,EUR,CASH TOP-UP,1 65,2024-06-21,Levantamento,-1300.39,EUR,CASH WITHDRAWAL,1 66,2024-06-21,Depósito,1300.39,EUR,CASH TOP-UP,1 67,2024-06-21,Levantamento,-1200.39,EUR,CASH WITHDRAWAL,1 68,2024-06-21,Levantamento,-100,EUR,CASH WITHDRAWAL,1 69,2024-06-21,Depósito,1300.39,USD,CASH TOP-UP,1.0709 70,2024-06-25,Depósito,70.8,EUR,CASH TOP-UP,1 71,2024-07-10,Depósito,550,EUR,CASH TOP-UP,1 72,2024-07-15,Depósito,4125,EUR,CASH TOP-UP,1 73,2024-07-15,Depósito,5500,EUR,CASH TOP-UP,1 74,2024-07-18,Levantamento,-1500,EUR,CASH WITHDRAWAL,1 75,2024-07-18,Depósito,1500,USD,CASH TOP-UP,1.0922 76,2024-07-22,Depósito,117.07,EUR,CASH TOP-UP,1 77,2024-07-24,Depósito,750.06,USD,CASH TOP-UP,1.0879 78,2024-08-02,Depósito,1500,USD,CASH TOP-UP,1.084 79,2024-08-02,Depósito,97.92,USD,CASH TOP-UP,1.0844 80,2024-08-02,Depósito,6.42,USD,CASH TOP-UP,1.0934 81,2024-08-16,Dividendo,7.12,USD,AAPL DIVIDEND,1.1013 82,2024-09-13,Dividendo,0.45,USD,MSFT DIVIDEND,1.1112 83,2024-10-04,Dividendo,0.19,USD,NVDA DIVIDEND,1.1052 84,2024-10-28,Levantamento,-3080.54,USD,CASH WITHDRAWAL,1.0838 85,2024-10-28,Depósito,3080.54,USD,CASH TOP-UP,1.0837 86,2024-11-06,Levantamento,-3080.54,USD,CASH WITHDRAWAL,1.0741 87,2024-11-15,Dividendo,7.13,USD,AAPL DIVIDEND,1.0596 88,2024-11-19,Depósito,1000.93,EUR,CASH TOP-UP,1 89,2024-11-19,Levantamento,-7.13,USD,CASH WITHDRAWAL,1.0617 90,2024-11-19,Depósito,2913.11,EUR,CASH TOP-UP,1 91,2024-11-22,Depósito,2076.27,USD,CASH TOP-UP,1.0422 92,2024-12-13,Dividendo,0.5,USD,MSFT DIVIDEND,1.0539 93,2024-12-13,Levantamento,-756.41,USD,CASH WITHDRAWAL,1.054 94,2024-12-17,Depósito,756.47,USD,CASH TOP-UP,1.0518 95,2024-12-18,Dividendo,2.45,EUR,EXXT DIVIDEND,1 96,2024-12-20,Depósito,1000,EUR,CASH TOP-UP,1 97,2024-12-30,Dividendo,0.13,USD,NVDA DIVIDEND,1.0463 98,2024-12-31,Dividendo,10.77,EUR,VUSA DIVIDEND,1 99,2025-01-02,Levantamento,-0.13,USD,CASH WITHDRAWAL,1.0379 100,2025-01-02,Levantamento,-10.77,EUR,CASH WITHDRAWAL,1 101,2025-01-22,Depósito,841,USD,CASH TOP-UP,1.0442 102,2025-01-30,Depósito,510.77,USD,CASH TOP-UP,1.0445 103,2025-01-30,Depósito,8,USD,CASH TOP-UP,1.0446 104,2025-02-14,Dividendo,7.93,USD,AAPL DIVIDEND,1.0521 105,2025-02-24,Levantamento,-7.93,USD,CASH WITHDRAWAL,1.0488 106,2025-02-25,Depósito,1700,EUR,CASH TOP-UP,1 107,2025-03-07,Depósito,1800,EUR,CASH TOP-UP,1 108,2025-03-17,Depósito,809.79,EUR,CASH TOP-UP,1 109,2025-03-19,Dividendo,4.69,EUR,EXXT DIVIDEND,1 110,2025-03-31,Depósito,850.28,EUR,CASH TOP-UP,1 111,2025-04-03,Dividendo,0.21,USD,NVDA DIVIDEND,1.1066 112,2025-04-10,Dividendo,15.74,EUR,VUSA DIVIDEND,1 113,2025-04-11,Levantamento,-15.74,EUR,CASH WITHDRAWAL,1 114,2025-04-11,Levantamento,-0.21,USD,CASH WITHDRAWAL,1.1326 115,2025-05-01,Levantamento,-1256.8,USD,CASH WITHDRAWAL,1.1305 116,2025-05-05,Depósito,1265.5,USD,CASH TOP-UP,1.1341 117,2025-05-16,Dividendo,6.92,USD,AAPL DIVIDEND,1.1172 118,2025-06-18,Dividendo,11.63,EUR,EXXT DIVIDEND,1 119,2025-06-19,Levantamento,-11.63,EUR,CASH WITHDRAWAL,1 120,2025-06-19,Levantamento,-1474.11,USD,CASH WITHDRAWAL,1.15 121,2025-07-09,Dividendo,14.42,EUR,VUSA DIVIDEND,1 122,2025-07-10,Dividendo,0.21,USD,NVDA DIVIDEND,1.1755 123,2025-07-25,Levantamento,-0.21,USD,CASH WITHDRAWAL,1.1753 124,2025-07-25,Levantamento,-14.42,EUR,CASH WITHDRAWAL,1 125,2025-07-25,Depósito,1478.65,USD,CASH TOP-UP,1.175 126,2025-07-25,Depósito,1032.78,EUR,CASH TOP-UP,1 127,2025-08-14,Dividendo,8.07,USD,AAPL DIVIDEND,1.1677 128,2025-08-29,Levantamento,-8.07,USD,CASH WITHDRAWAL,1.1726 129,2025-09-15,Dividendo,1.36,USD,GOOGL DIVIDEND,1.1778 130,2025-10-01,Levantamento,-1.36,USD,CASH WITHDRAWAL,1.1785 131,2025-10-02,Dividendo,0.14,USD,NVDA DIVIDEND,1.1747 132,2025-10-03,Dividendo,13.94,EUR,VUSA DIVIDEND,1 133,2025-10-03,Levantamento,-0.14,USD,CASH WITHDRAWAL,1.1766 134,2025-10-06,Levantamento,-13.94,EUR,CASH WITHDRAWAL,1 135,2025-10-24,Depósito,937.2,EUR,CASH TOP-UP,1 136,2025-10-24,Levantamento,-937.2,EUR,CASH WITHDRAWAL,1 137,2025-11-09,Depósito,1011.67,USD,CASH TOP-UP,1.161 138,2025-11-13,Dividendo,8.07,USD,AAPL DIVIDEND,1.1658 139,2025-12-04,Levantamento,-8.08,USD,CASH WITHDRAWAL,1.167 140,2025-07-27,Depósito,1900,EUR,CASH TOP-UP,1 141,2025-10-24,Depósito,937.2,EUR,CASH TOP-UP,1 142,2025-12-15,Dividendo,1.36,USD,GOOGL DIVIDEND, 143,2025-12-17,Dividendo,2.45,EUR,EXXT DIVIDEND,1 144,2025-12-22,Levantamento,-2.45,EUR,CASH WITHDRAWAL,1 145,2025-12-22,Levantamento,-1.36,USD,CASH WITHDRAWAL, 146,2025-12-26,Dividendo,0.18,USD,NVDA DIVIDEND, 147,2025-12-31,Levantamento,-0.18,USD,CASH WITHDRAWAL, 148,2026-01-05,Dividendo,13.87,EUR,VUSA DIVIDEND,1 149,2026-01-13,Levantamento,-13.87,EUR,CASH WITHDRAWAL,1 150,2026-02-12,Dividendo,8.07,USD,AAPL DIVIDEND, 151,2026-02-20,Levantamento,-8.07,USD,CASH WITHDRAWAL, 152,2026-03-16,Dividendo,1.36,USD,GOOGL DIVIDEND, 153,2026-03-19,Dividendo,4.9,EUR,EXXT DIVIDEND,1 154,2026-03-23,Levantamento,-1.36,USD,CASH WITHDRAWAL, 155,2026-03-23,Levantamento,4.9,EUR,CASH WITHDRAWAL,1 156,2026-04-01,Dividendo,0.18,USD,NVDA DIVIDEND, 157,2026-04-07,Dividendo,15.53,EUR,VUSA DIVIDEND,1 158,2026-04-13,Levantamento,-15.53,EUR,CASH WITHDRAWAL,1 159,2026-04-13,Levantamento,-0.18,USD,CASH WITHDRAWAL, 160,2026-05-01,Depósito,2021,USD,CASH TOP-UP, 161,2026-04-14,Dividendo,8.37,USD,AAPL DIVIDEND, 162,2026-04-19,Depósito,800.43,USD,CASH TOP-UP, 163,2026-04-19,Depósito,125.62,USD,CASH TOP-UP, ======================================================================================== FICHEIRO: dados_csv/filipe/transacoes-acoes.csv Tamanho: 7267 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2020-09-04","2020-12-17","AAPL","0.908098","0.00","108.97","116.60","1.1811","1.2266","USD" "2","2020-09-04","2020-12-10","TSLA","1.821273","0.00","250.00","250.57","1.1809","1.2144","USD" "3","2020-09-10","2020-11-18","TSLA","1.964946","0.00","250.00","341.61","1.1896","1.1869","USD" "4","2020-09-24","2020-09-24","TSLA","2.693169","0.00","329.15","351.43","1.1651","1.1679","USD" "5","2020-09-24","2020-10-13","ZM","0.748791","0.00","351.43","382.32","1.1677","1.1746","USD" "6","2020-10-02","2020-11-18","TSLA","14.84535","0.00","415.88","569.34","1.1717","1.1869","USD" "7","2020-09-04","2020-10-12","AAPL","1.175235","0.00","141.03","145.02","1.1811","1.1811","USD" "8","2020-10-13","2020-11-06","Z","1.000000","0.00","101.17","114.81","1.1736","1.1881","USD" "9","2020-10-15","2020-12-08","ANSS","1.000000","0.00","351.53","338.47","1.1699","1.2103","USD" "10","2020-10-15","2020-12-10","TSLA","3","0.00","448.19","623.27","1.1699","1.2144","USD" "11","2020-10-22","2020-10-29","NIO","19.006929","0.00","521.17","604.41","1.1819","1.1676","USD" "12","2020-10-30","2020-11-03","NIO","19.000000","0.00","581.21","654.32","1.1650","1.1732","USD" "13","2020-10-30","2020-12-17","AAPL","2.371988","0.00","258.07","304.56","1.1650","1.2266","USD" "14","2020-11-04","2020-11-05","NIO","17.558483","0.00","654.17","727.82","1.1722","1.1832","USD" "15","2020-11-06","2020-11-12","NIO","20.000000","0.00","824.77","979.99","1.1885","1.1811","USD" "16","2020-11-12","2020-11-23","ZM","1.000000","0.00","435.44","428.76","1.1806","1.1844","USD" "17","2020-11-13","2020-11-23","NIO","12.000000","0.00","541.18","659.98","1.1825","1.1844","USD" "18","2020-11-17","2020-11-23","NIO","15.000000","0.00","715.18","824.98","1.1881","1.1844","USD" "20","2020-11-18","2020-12-15","AAPL","4.000000","0.00","479.02","505.98","1.1869","1.2156","USD" "21","2020-11-23","2020-11-27","MRNA","8.000000","0.00","809.60","998.78","1.1846","1.1948","USD" "23","2020-11-30","2020-12-17","AAPL","2.000000","0.00","234.84","256.79","1.2000","1.2266","USD" "24","2020-11-30","2021-01-26","MRNA","10.000000","0.00","1460.19","1373.27","1.1999","1.2165","USD" "25","2020-12-07","2021-01-21","MRNA","3.000000","0.00","466.21","538.82","1.2140","1.2161","USD" "26","2020-12-07","2020-12-08","AMD","4.000000","0.00","381.21","369.97","1.2140","1.2106","USD" "27","2020-12-07","2020-12-21","NIO","8.000000","0.00","352.25","391.82","1.2151","1.2250","USD" "31","2020-11-24","2020-12-21","NIO","1","0.00","53.12","48.98","1.1883","1.2250","USD" "32","2020-11-24","2021-01-06","NIO","10.000000","0.00","531.19","549.98","1.1883","1.2310","USD" "35","2023-11-24","","AMS:IWDA","6.396602","","504.50","","1.0000","","EUR" "36","2023-12-14","","AAPL","2.465917","","489.94","","1.1019","","USD" "37","2023-12-26","","AAPL","2.529855","","491.00","","1.1043","","USD" "38","2024-01-08","","AAPL","3.000000","","541.37","","1.0945","","USD" "39","2024-01-26","","AMS:IWDA","2.370037","","200.69","","1.0000","","EUR" "40","2024-01-31","2024-12-10","MSFT","0.711121","0.00","290.63","318.51","1.0886","1.0529","USD" "41","2024-02-13","","NVDA","0.61234","","43.57","","1.0736","","USD" "42","2024-03-04","","AAPL","0.080397","","15.09","","1.0881","","USD" "43","2024-03-22","","AAPL","5.052724","","867.30","","1.0844","","USD" "44","2024-05-02","","AMS:IWDA","4.189241","","373.01","","1.0000","","EUR" "45","2024-02-13","2024-05-22","NVDA","7","0.00","711.52","999.96","1.0736","1.0847","USD" "46","2024-06-11","","AAPL","2.519859","","514.53","","1.0754","","USD" "47","2024-06-20","2024-10-17","NVDA","6","0.00","838.21","839.97","1.0747","1.0885","USD" "48","2024-06-21","2024-12-09","RIVN","4.463768","0.00","47.27","65.14","1.0708","1.0597","USD" "49","2024-06-24","2024-10-17","NVDA","10","0.00","1236.76","1399.96","1.0767","1.0885","USD" "50","2024-06-26","","AMS:IWDA","0.733625","","70.80","","1.0000","","EUR" "51","2024-07-10","","AMS:IWDA","5.715610","","550.00","","1.0000","","EUR" "52","2024-07-15","","AMS:IWDA","42.710297","","4125.00","","1.0000","","EUR" "53","2024-07-17","","INDEXNASDAQ:NDX","12.000000","","2172.62","","1.0000","","EUR" "54","2024-07-19","","INDEXNASDAQ:NDX","5.000000","","872.18","","1.0000","","EUR" "55","2024-07-22","","INDEXNASDAQ:NDX","6.079345","","1072.27","","1.0000","","EUR" "56","2024-07-22","2024-12-09","RIVN","0.517910","0.00","9.91","7.56","1.0903","1.0597","USD" "57","2024-07-24","2025-04-28","AAPL","6.000000","0.00","1320.00","1256.80","1.0882","1.1366","USD" "58","2024-07-25","2024-10-17","NVDA","6","0.00","661.65","839.97","1.0856","1.0885","USD" "59","2024-08-01","2024-12-09","RIVN","5.000000","0.00","76.08","72.97","1.0803","1.0597","USD" "60","2024-08-02","","AAPL","6.883687","","1512.33","","1.0912","","USD" "61","2024-08-02","2024-12-09","RIVN","6.659560","0.00","97.91","97.19","1.0911","1.0597","USD" "62","2024-08-02","2024-12-09","RIVN","0.363356","0.00","6.42","5.30","1.0934","1.0597","USD" "63","2024-08-05","2024-12-09","RIVN","13.000000","0.00","169.57","189.73","1.1015","1.0597","USD" "64","2024-09-12","","AAPL","0.034418","","7.65","","1.1060","","USD" "66","2024-11-20","","VUSA","36.805462","","3914.04","","1.0000","","EUR" "67","2024-11-22","","NVDA","14.199164","","2076.26","","1.0433","","USD" "69","2024-12-17","2025-06-16","NVDA","5","0.00","646.96","729.36","1.0526","1.1614","USD" "70","2024-12-20","","VUSA","9.417628","","1002.45","","1.0000","","EUR" "71","2025-01-22","","AAPL","3.768304","","841.00","","1.0436","","USD" "72","2025-01-30","2025-06-16","NVDA","4","0.00","479.95","583.48","1.0445","1.1614","USD" "73","2025-02-25","","INDEXNASDAQ:NDX","8.584991","","1700.00","","1.0000","","EUR" "74","2025-03-10","","INDEXNASDAQ:NDX","9.956249","","1800.00","","1.0000","","EUR" "75","2025-03-17","","VUSA","8.210714","","809.79","","1.0000","","EUR" "76","2025-03-31","","INDEXNASDAQ:NDX","5.035159","","854.97","","1.0000","","EUR" "78","2025-07-25","","AAPL","5.175261","","1111.15","","1.1751","","USD" "79","2025-07-25","","GOOGL","7.644746","","1478.65","","1.1750","","USD" "80","2025-07-25","","INDEXNASDAQ:NDX","5.339923","","1032.78","","1.0000","","EUR" "81","2025-11-10","","NVDA","5.182103","","1011.66","","1.1591","","USD" "79","2020-11-24","2021-01-11","NIO","9","0","478.07","576.16","1.1883","1.2172","USD" "79","2024-06-20","","NVDA","0.128919","","18","","1.0767","","USD" "80","2024-06-24","","NVDA","0.132285","","16.36","","1.0747","","USD" "80","2024-12-17","","NVDA","0.857420","","110.01","","1.0526","","USD" "81","2025-01-30","","NVDA","0.323586","","38.82","","1.0445","","USD" "81","2020-11-23","2020-12-15","AAPL","4","0","457.22","505.98","1.1846","1.2156","USD" "82","2020-02-07","2020-12-17","AAPL","2","0","249.61","256.80","1.2160","1.2266","USD" "79","2023-12-22","","AAPL","2","","388","","1.1031","","USD" "80","2024-03-04","","AAPL","3","","525","","1.0884","","USD" "81","2025-07-25","","XAU","0.651188","27.81","1900","","1","","EUR" "82","2025-10-24","","XAU","0.26215","9.28","937.20","","1","","EUR" "83","2026-05-01","","NVDA","10.0358243","1.17","2020.98","","","","USD" "84","2026-05-19","","GOOGL","2.35240591","1.16","934.43","","","","USD" ======================================================================================== FICHEIRO: dados_csv/historico-ativos.csv Tamanho: 3416 bytes ======================================================================================== Período,EURUSD,AAPL,TSLA,NVDA,GOOGL ,1.1643,280.68,450.20,183.45,317.62 2018/12/31,0.8760,39.44,22.19,33.38, 2019/01/31,0.8850,41.61,20.47,35.94, 2019/02/28,0.8920,43.29,21.33,38.57, 2019/03/31,0.9000,47.81,19.28,45.57, 2019/04/30,0.9200,50.17,15.91,45.25, 2019/05/31,0.9500,43.77,12.34,33.87, 2019/06/30,0.9700,50.39,15.14,41.54, 2019/07/31,0.9750,53.26,16.11,42.18, 2019/08/31,0.9600,51.43,15.00,41.04, 2019/09/30,0.9200,55.99,16.06,43.52, 2019/10/31,0.8800,62.19,20.99,50.26, 2019/11/30,0.8800,66.04,22.32,52.31, 2019/12/31,0.8500,73.41,27.89,58.83, 2020/01/31,0.8800,77.38,43.37,59.11, 2020/02/29,0.8600,74.70,49.57,69.11, 2020/03/31,0.8500,63.57,34.93,65.90, 2020/04/30,0.8600,73.45,52.13,73.07, 2020/05/31,0.8600,80.46,59.87,88.06, 2020/06/30,0.8600,91.20,71.99,94.98, 2020/07/31,0.8600,106.26,95.38,106.15, 2020/08/31,0.8600,129.04,166.11,133.75, 2020/09/30,0.8300,115.81,143.00,135.31, 2020/10/31,0.8300,108.77,133.50,125.81, 2020/11/30,0.8300,119.05,189.20,134.01, 2020/12/31,0.8300,132.69,235.22,130.55, 2021/01/31,0.8200,134.14,279.94,132.37, 2021/02/28,0.8400,127.79,239.48,138.42, 2021/03/31,0.8400,122.15,222.64,133.48, 2021/04/30,0.8300,131.46,236.48,150.10, 2021/05/31,0.8200,124.28,207.97,162.65, 2021/06/30,0.8500,136.96,226.57,200.03, 2021/07/31,0.8600,145.52,236.56,197.50, 2021/08/31,0.8500,151.83,245.24,223.85, 2021/09/30,0.8600,141.50,258.49,207.16, 2021/10/31,0.8800,148.96,402.86,258.27, 2021/11/30,0.8800,165.30,381.59,326.76, 2021/12/31,0.8800,177.57,352.26,294.11, 2022/01/31,0.8800,174.78,312.24,244.86, 2022/02/28,0.8900,165.12,290.14,243.85, 2022/03/31,0.9200,174.61,359.20,272.86, 2022/04/30,0.9400,157.96,300.98,195.33, 2022/05/31,0.9500,148.84,252.75,186.72, 2022/06/30,0.9600,136.72,224.47,151.59, 2022/07/31,0.9700,161.51,297.28,184.41, 2022/08/31,0.9800,157.22,275.61,150.94, 2022/09/30,0.9700,138.20,265.25,121.39, 2022/10/31,0.9700,153.34,227.54,134.97, 2022/11/30,0.9800,148.03,194.70,169.23, 2022/12/30,0.9900,129.93,123.18,146.14, 2023/01/31,1.0000,144.29,173.22,195.37, 2023/02/28,1.0100,147.41,205.71,232.16, 2023/03/31,1.0800,164.90,207.46,277.77, 2023/04/30,1.1000,169.59,161.83,289.10, 2023/05/31,1.0800,177.25,203.93,378.34, 2023/06/30,1.0900,193.97,261.77,423.02, 2023/07/31,1.1100,196.45,267.43,467.29, 2023/08/31,1.0900,187.87,258.08,493.55, 2023/09/30,1.0600,173.75,251.60,447.82, 2023/10/31,1.0600,170.77,200.84,407.80, 2023/11/30,1.0900,189.95,240.08,467.70, 2023/12/31,1.1000,192.53,248.48,495.22, 2024/01/31,1.0800,184.40,187.29,61.53, 2024/02/29,1.0800,180.75,201.88,79.11, 2024/03/31,1.0800,170.03,175.22,90.36, 2024/04/30,1.0700,170.33,183.28,86.40, 2024/05/31,1.0800,192.25,178.08,109.63, 2024/06/27,1.0700,210.62,197.88,123.54, 2024/07/30,1.0900,222.08,232.07,117.02, 2024/08/31,1.1100,222.77,210.60,108.00, 2024/09/30,1.1100,233.00,261.63,121.44, 2024/10/31,1.0900,225.91,249.85,132.76, 2024/11/30,1.0800,239.59,357.09,134.29, 2024/12/31,1.0500,250.42,403.84,120.07, 2025/01/31,1.0800,236.00,292.98,124.92, 2025/02/28,1.0900,241.84,259.16,108.38, 2025/03/31,1.0900,222.13,282.16,108.92, 2025/04/30,1.1000,212.50,342.69,137.38, 2025/05/31,1.1200,201.70,317.66,157.99, 2025/06/30,1.1300,205.17,308.27,177.87, 2025/07/31,1.1400,207.57,329.36,170.78, 2025/08/31,1.1500,229.72,444.72,186.58, 2025/09/30,1.1600,254.63,456.56,202.49, 2025/10/31,1.1600,270.37,430.14,179.92, 2025/11/30,1.1600,283.10,454.48,183.38, 2025/12/31,1.1643,280.68,450.20,183.45,317.62 ======================================================================================== FICHEIRO: dados_csv/historico-cambio-date.txt Tamanho: 10 bytes ======================================================================================== 2026-06-19 ======================================================================================== FICHEIRO: dados_csv/historico-cambio.json Tamanho: 44530 bytes ======================================================================================== { "2019-10-01": 1.0898, "2019-10-02": 1.0925, "2019-10-03": 1.0951, "2019-10-04": 1.0979, "2019-10-07": 1.0993, "2019-10-08": 1.0986, "2019-10-09": 1.0981, "2019-10-10": 1.103, "2019-10-11": 1.1043, "2019-10-14": 1.1031, "2019-10-15": 1.1007, "2019-10-16": 1.1025, "2019-10-17": 1.1113, "2019-10-18": 1.1144, "2019-10-21": 1.1173, "2019-10-22": 1.113, "2019-10-23": 1.1123, "2019-10-24": 1.1128, "2019-10-25": 1.1107, "2019-10-28": 1.1087, "2019-10-29": 1.1095, "2019-10-30": 1.1106, "2019-10-31": 1.1154, "2019-11-01": 1.1139, "2019-11-04": 1.1158, "2019-11-05": 1.1109, "2019-11-06": 1.109, "2019-11-07": 1.1077, "2019-11-08": 1.1034, "2019-11-11": 1.1041, "2019-11-12": 1.1015, "2019-11-13": 1.1006, "2019-11-14": 1.0997, "2019-11-15": 1.1034, "2019-11-18": 1.1061, "2019-11-19": 1.1077, "2019-11-20": 1.1059, "2019-11-21": 1.1091, "2019-11-22": 1.1058, "2019-11-25": 1.1008, "2019-11-26": 1.102, "2019-11-27": 1.1009, "2019-11-28": 1.1005, "2019-11-29": 1.0982, "2019-12-02": 1.1023, "2019-12-03": 1.1071, "2019-12-04": 1.1081, "2019-12-05": 1.1094, "2019-12-06": 1.1094, "2019-12-09": 1.1075, "2019-12-10": 1.1077, "2019-12-11": 1.1075, "2019-12-12": 1.1137, "2019-12-13": 1.1174, "2019-12-16": 1.1146, "2019-12-17": 1.1162, "2019-12-18": 1.1115, "2019-12-19": 1.1117, "2019-12-20": 1.1097, "2019-12-23": 1.1075, "2019-12-24": 1.108, "2019-12-27": 1.1153, "2019-12-30": 1.1189, "2019-12-31": 1.1234, "2020-01-02": 1.1193, "2020-01-03": 1.1147, "2020-01-06": 1.1194, "2020-01-07": 1.1172, "2020-01-08": 1.1115, "2020-01-09": 1.111, "2020-01-10": 1.1091, "2020-01-13": 1.1126, "2020-01-14": 1.1115, "2020-01-15": 1.1142, "2020-01-16": 1.1169, "2020-01-17": 1.1108, "2020-01-20": 1.1085, "2020-01-21": 1.1115, "2020-01-22": 1.1088, "2020-01-23": 1.1091, "2020-01-24": 1.1035, "2020-01-27": 1.1025, "2020-01-28": 1.1005, "2020-01-29": 1.1001, "2020-01-30": 1.1029, "2020-01-31": 1.1052, "2020-02-03": 1.1066, "2020-02-04": 1.1048, "2020-02-05": 1.1023, "2020-02-06": 1.1003, "2020-02-07": 1.0969, "2020-02-10": 1.0951, "2020-02-11": 1.0901, "2020-02-12": 1.0914, "2020-02-13": 1.0867, "2020-02-14": 1.0842, "2020-02-17": 1.0835, "2020-02-18": 1.0816, "2020-02-19": 1.08, "2020-02-20": 1.079, "2020-02-21": 1.0801, "2020-02-24": 1.0818, "2020-02-25": 1.084, "2020-02-26": 1.0875, "2020-02-27": 1.0964, "2020-02-28": 1.0977, "2020-03-02": 1.1122, "2020-03-03": 1.1117, "2020-03-04": 1.1125, "2020-03-05": 1.1187, "2020-03-06": 1.1336, "2020-03-09": 1.1456, "2020-03-10": 1.139, "2020-03-11": 1.1336, "2020-03-12": 1.124, "2020-03-13": 1.1104, "2020-03-16": 1.1157, "2020-03-17": 1.0982, "2020-03-18": 1.0934, "2020-03-19": 1.0801, "2020-03-20": 1.0707, "2020-03-23": 1.0783, "2020-03-24": 1.0843, "2020-03-25": 1.0827, "2020-03-26": 1.0981, "2020-03-27": 1.0977, "2020-03-30": 1.1034, "2020-03-31": 1.0956, "2020-04-01": 1.0936, "2020-04-02": 1.0906, "2020-04-03": 1.0785, "2020-04-06": 1.0791, "2020-04-07": 1.0885, "2020-04-08": 1.0871, "2020-04-09": 1.0867, "2020-04-14": 1.0963, "2020-04-15": 1.0903, "2020-04-16": 1.0888, "2020-04-17": 1.086, "2020-04-20": 1.086, "2020-04-21": 1.0837, "2020-04-22": 1.0867, "2020-04-23": 1.0772, "2020-04-24": 1.08, "2020-04-27": 1.0852, "2020-04-28": 1.0877, "2020-04-29": 1.0842, "2020-04-30": 1.0876, "2020-05-04": 1.0942, "2020-05-05": 1.0843, "2020-05-06": 1.0807, "2020-05-07": 1.0783, "2020-05-08": 1.0843, "2020-05-11": 1.0824, "2020-05-12": 1.0858, "2020-05-13": 1.0875, "2020-05-14": 1.0792, "2020-05-15": 1.0798, "2020-05-18": 1.0832, "2020-05-19": 1.095, "2020-05-20": 1.0958, "2020-05-21": 1.1, "2020-05-22": 1.0904, "2020-05-25": 1.091, "2020-05-26": 1.0975, "2020-05-27": 1.0991, "2020-05-28": 1.1016, "2020-05-29": 1.1136, "2020-06-01": 1.1116, "2020-06-02": 1.1174, "2020-06-03": 1.1194, "2020-06-04": 1.125, "2020-06-05": 1.133, "2020-06-08": 1.1285, "2020-06-09": 1.1294, "2020-06-10": 1.1375, "2020-06-11": 1.1348, "2020-06-12": 1.1304, "2020-06-15": 1.1253, "2020-06-16": 1.1308, "2020-06-17": 1.1232, "2020-06-18": 1.1222, "2020-06-19": 1.121, "2020-06-22": 1.1213, "2020-06-23": 1.1318, "2020-06-24": 1.128, "2020-06-25": 1.12, "2020-06-26": 1.1213, "2020-06-29": 1.1284, "2020-06-30": 1.1198, "2020-07-01": 1.12, "2020-07-02": 1.1286, "2020-07-03": 1.1224, "2020-07-06": 1.1325, "2020-07-07": 1.129, "2020-07-08": 1.1286, "2020-07-09": 1.1342, "2020-07-10": 1.1276, "2020-07-13": 1.1329, "2020-07-14": 1.1375, "2020-07-15": 1.1444, "2020-07-16": 1.1414, "2020-07-17": 1.1428, "2020-07-20": 1.1448, "2020-07-21": 1.1443, "2020-07-22": 1.1578, "2020-07-23": 1.1569, "2020-07-24": 1.1608, "2020-07-27": 1.176, "2020-07-28": 1.1717, "2020-07-29": 1.1725, "2020-07-30": 1.1743, "2020-07-31": 1.1848, "2020-08-03": 1.1726, "2020-08-04": 1.1765, "2020-08-05": 1.1854, "2020-08-06": 1.1843, "2020-08-07": 1.1817, "2020-08-10": 1.1763, "2020-08-11": 1.1783, "2020-08-12": 1.1771, "2020-08-13": 1.1833, "2020-08-14": 1.1813, "2020-08-17": 1.1853, "2020-08-18": 1.1906, "2020-08-19": 1.1933, "2020-08-20": 1.185, "2020-08-21": 1.1769, "2020-08-24": 1.1847, "2020-08-25": 1.1814, "2020-08-26": 1.1789, "2020-08-27": 1.1806, "2020-08-28": 1.1915, "2020-08-31": 1.194, "2020-09-01": 1.1987, "2020-09-02": 1.1861, "2020-09-03": 1.1813, "2020-09-04": 1.1842, "2020-09-07": 1.1824, "2020-09-08": 1.1785, "2020-09-09": 1.1773, "2020-09-10": 1.1849, "2020-09-11": 1.1854, "2020-09-14": 1.1876, "2020-09-15": 1.1892, "2020-09-16": 1.1869, "2020-09-17": 1.1797, "2020-09-18": 1.1833, "2020-09-21": 1.1787, "2020-09-22": 1.174, "2020-09-23": 1.1692, "2020-09-24": 1.1645, "2020-09-25": 1.1634, "2020-09-28": 1.167, "2020-09-29": 1.1702, "2020-09-30": 1.1708, "2020-10-01": 1.1752, "2020-10-02": 1.173, "2020-10-05": 1.1768, "2020-10-06": 1.1795, "2020-10-07": 1.177, "2020-10-08": 1.1765, "2020-10-09": 1.1795, "2020-10-12": 1.1799, "2020-10-13": 1.1787, "2020-10-14": 1.175, "2020-10-15": 1.1698, "2020-10-16": 1.1741, "2020-10-19": 1.1785, "2020-10-20": 1.181, "2020-10-21": 1.1852, "2020-10-22": 1.1821, "2020-10-23": 1.1856, "2020-10-26": 1.1819, "2020-10-27": 1.1832, "2020-10-28": 1.1727, "2020-10-29": 1.1704, "2020-10-30": 1.1698, "2020-11-02": 1.1652, "2020-11-03": 1.1702, "2020-11-04": 1.1721, "2020-11-05": 1.1855, "2020-11-06": 1.187, "2020-11-09": 1.1883, "2020-11-10": 1.1808, "2020-11-11": 1.1766, "2020-11-12": 1.1791, "2020-11-13": 1.1815, "2020-11-16": 1.183, "2020-11-17": 1.1882, "2020-11-18": 1.1868, "2020-11-19": 1.1832, "2020-11-20": 1.1863, "2020-11-23": 1.1901, "2020-11-24": 1.1865, "2020-11-25": 1.189, "2020-11-26": 1.19, "2020-11-27": 1.1922, "2020-11-30": 1.198, "2020-12-01": 1.1968, "2020-12-02": 1.2066, "2020-12-03": 1.2151, "2020-12-04": 1.2159, "2020-12-07": 1.2128, "2020-12-08": 1.2114, "2020-12-09": 1.2109, "2020-12-10": 1.2115, "2020-12-11": 1.2127, "2020-12-14": 1.2162, "2020-12-15": 1.214, "2020-12-16": 1.2189, "2020-12-17": 1.2246, "2020-12-18": 1.2259, "2020-12-21": 1.2173, "2020-12-22": 1.2239, "2020-12-23": 1.2166, "2020-12-24": 1.2193, "2020-12-28": 1.2219, "2020-12-29": 1.2259, "2020-12-30": 1.2281, "2020-12-31": 1.2271, "2021-01-04": 1.2296, "2021-01-05": 1.2271, "2021-01-06": 1.2338, "2021-01-07": 1.2276, "2021-01-08": 1.225, "2021-01-11": 1.2163, "2021-01-12": 1.2161, "2021-01-13": 1.2166, "2021-01-14": 1.2124, "2021-01-15": 1.2123, "2021-01-18": 1.2064, "2021-01-19": 1.2132, "2021-01-20": 1.2101, "2021-01-21": 1.2158, "2021-01-22": 1.2158, "2021-01-25": 1.2152, "2021-01-26": 1.2143, "2021-01-27": 1.2114, "2021-01-28": 1.2091, "2021-01-29": 1.2136, "2021-02-01": 1.2084, "2021-02-02": 1.2044, "2021-02-03": 1.2017, "2021-02-04": 1.1996, "2021-02-05": 1.1983, "2021-02-08": 1.2025, "2021-02-09": 1.2104, "2021-02-10": 1.2127, "2021-02-11": 1.2147, "2021-02-12": 1.2108, "2021-02-15": 1.2129, "2021-02-16": 1.2143, "2021-02-17": 1.206, "2021-02-18": 1.2084, "2021-02-19": 1.2139, "2021-02-22": 1.2133, "2021-02-23": 1.2143, "2021-02-24": 1.2146, "2021-02-25": 1.2225, "2021-02-26": 1.2121, "2021-03-01": 1.2053, "2021-03-02": 1.2028, "2021-03-03": 1.2048, "2021-03-04": 1.2034, "2021-03-05": 1.1938, "2021-03-08": 1.1866, "2021-03-09": 1.1894, "2021-03-10": 1.1892, "2021-03-11": 1.1969, "2021-03-12": 1.1933, "2021-03-15": 1.192, "2021-03-16": 1.1926, "2021-03-17": 1.1907, "2021-03-18": 1.1912, "2021-03-19": 1.1891, "2021-03-22": 1.1926, "2021-03-23": 1.1883, "2021-03-24": 1.1825, "2021-03-25": 1.1802, "2021-03-26": 1.1782, "2021-03-29": 1.1784, "2021-03-30": 1.1741, "2021-03-31": 1.1725, "2021-04-01": 1.1746, "2021-04-06": 1.1812, "2021-04-07": 1.1884, "2021-04-08": 1.1873, "2021-04-09": 1.1888, "2021-04-12": 1.1904, "2021-04-13": 1.1896, "2021-04-14": 1.1964, "2021-04-15": 1.197, "2021-04-16": 1.1986, "2021-04-19": 1.2035, "2021-04-20": 1.2051, "2021-04-21": 1.2007, "2021-04-22": 1.2046, "2021-04-23": 1.2066, "2021-04-26": 1.2085, "2021-04-27": 1.2088, "2021-04-28": 1.207, "2021-04-29": 1.2129, "2021-04-30": 1.2082, "2021-05-03": 1.2044, "2021-05-04": 1.2021, "2021-05-05": 1.2005, "2021-05-06": 1.206, "2021-05-07": 1.2059, "2021-05-10": 1.2169, "2021-05-11": 1.217, "2021-05-12": 1.2118, "2021-05-13": 1.2081, "2021-05-14": 1.2123, "2021-05-17": 1.2143, "2021-05-18": 1.2222, "2021-05-19": 1.2212, "2021-05-20": 1.2203, "2021-05-21": 1.2188, "2021-05-24": 1.2212, "2021-05-25": 1.2264, "2021-05-26": 1.2229, "2021-05-27": 1.2198, "2021-05-28": 1.2142, "2021-05-31": 1.2201, "2021-06-01": 1.2225, "2021-06-02": 1.2186, "2021-06-03": 1.2187, "2021-06-04": 1.2117, "2021-06-07": 1.2162, "2021-06-08": 1.2182, "2021-06-09": 1.2195, "2021-06-10": 1.2174, "2021-06-11": 1.2125, "2021-06-14": 1.2112, "2021-06-15": 1.2108, "2021-06-16": 1.2124, "2021-06-17": 1.1937, "2021-06-18": 1.1898, "2021-06-21": 1.1891, "2021-06-22": 1.1894, "2021-06-23": 1.1951, "2021-06-24": 1.1936, "2021-06-25": 1.195, "2021-06-28": 1.191, "2021-06-29": 1.1888, "2021-06-30": 1.1884, "2021-07-01": 1.1884, "2021-07-02": 1.1823, "2021-07-05": 1.1866, "2021-07-06": 1.1838, "2021-07-07": 1.1831, "2021-07-08": 1.1838, "2021-07-09": 1.1858, "2021-07-12": 1.1852, "2021-07-13": 1.1844, "2021-07-14": 1.1812, "2021-07-15": 1.1809, "2021-07-16": 1.1802, "2021-07-19": 1.1766, "2021-07-20": 1.1775, "2021-07-21": 1.1772, "2021-07-22": 1.1775, "2021-07-23": 1.1767, "2021-07-26": 1.1787, "2021-07-27": 1.181, "2021-07-28": 1.1807, "2021-07-29": 1.1873, "2021-07-30": 1.1891, "2021-08-02": 1.1886, "2021-08-03": 1.1885, "2021-08-04": 1.1861, "2021-08-05": 1.185, "2021-08-06": 1.1807, "2021-08-09": 1.1761, "2021-08-10": 1.1722, "2021-08-11": 1.1718, "2021-08-12": 1.1739, "2021-08-13": 1.1765, "2021-08-16": 1.1772, "2021-08-17": 1.1767, "2021-08-18": 1.1723, "2021-08-19": 1.1696, "2021-08-20": 1.1671, "2021-08-23": 1.1718, "2021-08-24": 1.174, "2021-08-25": 1.1736, "2021-08-26": 1.1767, "2021-08-27": 1.1761, "2021-08-30": 1.1801, "2021-08-31": 1.1834, "2021-09-01": 1.1817, "2021-09-02": 1.1846, "2021-09-03": 1.1872, "2021-09-06": 1.1864, "2021-09-07": 1.186, "2021-09-08": 1.1827, "2021-09-09": 1.1838, "2021-09-10": 1.1841, "2021-09-13": 1.178, "2021-09-14": 1.1814, "2021-09-15": 1.1824, "2021-09-16": 1.1763, "2021-09-17": 1.178, "2021-09-20": 1.1711, "2021-09-21": 1.1738, "2021-09-22": 1.1729, "2021-09-23": 1.1715, "2021-09-24": 1.1719, "2021-09-27": 1.1698, "2021-09-28": 1.1678, "2021-09-29": 1.1654, "2021-09-30": 1.1579, "2021-10-01": 1.16, "2021-10-04": 1.1636, "2021-10-05": 1.1602, "2021-10-06": 1.1542, "2021-10-07": 1.1562, "2021-10-08": 1.1569, "2021-10-11": 1.1574, "2021-10-12": 1.1555, "2021-10-13": 1.1562, "2021-10-14": 1.1602, "2021-10-15": 1.1602, "2021-10-18": 1.1604, "2021-10-19": 1.1655, "2021-10-20": 1.1623, "2021-10-21": 1.1637, "2021-10-22": 1.163, "2021-10-25": 1.1603, "2021-10-26": 1.1618, "2021-10-27": 1.1617, "2021-10-28": 1.1593, "2021-10-29": 1.1645, "2021-11-01": 1.1578, "2021-11-02": 1.1603, "2021-11-03": 1.1578, "2021-11-04": 1.1569, "2021-11-05": 1.1519, "2021-11-08": 1.1579, "2021-11-09": 1.1577, "2021-11-10": 1.1558, "2021-11-11": 1.146, "2021-11-12": 1.1448, "2021-11-15": 1.1444, "2021-11-16": 1.1368, "2021-11-17": 1.1316, "2021-11-18": 1.1345, "2021-11-19": 1.1271, "2021-11-22": 1.1278, "2021-11-23": 1.1259, "2021-11-24": 1.1206, "2021-11-25": 1.1223, "2021-11-26": 1.1291, "2021-11-29": 1.1276, "2021-11-30": 1.1363, "2021-12-01": 1.1314, "2021-12-02": 1.1339, "2021-12-03": 1.1291, "2021-12-06": 1.1287, "2021-12-07": 1.1256, "2021-12-08": 1.1299, "2021-12-09": 1.1311, "2021-12-10": 1.1273, "2021-12-13": 1.1278, "2021-12-14": 1.1309, "2021-12-15": 1.1262, "2021-12-16": 1.1336, "2021-12-17": 1.133, "2021-12-20": 1.1273, "2021-12-21": 1.1295, "2021-12-22": 1.1301, "2021-12-23": 1.131, "2021-12-24": 1.1317, "2021-12-27": 1.1312, "2021-12-28": 1.1331, "2021-12-29": 1.1303, "2021-12-30": 1.1334, "2021-12-31": 1.1326, "2022-01-03": 1.1355, "2022-01-04": 1.1279, "2022-01-05": 1.1319, "2022-01-06": 1.1315, "2022-01-07": 1.1298, "2022-01-10": 1.1318, "2022-01-11": 1.1336, "2022-01-12": 1.137, "2022-01-13": 1.1463, "2022-01-14": 1.1447, "2022-01-17": 1.1403, "2022-01-18": 1.1367, "2022-01-19": 1.1345, "2022-01-20": 1.1338, "2022-01-21": 1.1348, "2022-01-24": 1.1304, "2022-01-25": 1.1268, "2022-01-26": 1.1277, "2022-01-27": 1.116, "2022-01-28": 1.1138, "2022-01-31": 1.1156, "2022-02-01": 1.126, "2022-02-02": 1.1323, "2022-02-03": 1.1286, "2022-02-04": 1.1464, "2022-02-07": 1.1447, "2022-02-08": 1.1408, "2022-02-09": 1.1435, "2022-02-10": 1.1439, "2022-02-11": 1.1417, "2022-02-14": 1.1316, "2022-02-15": 1.1345, "2022-02-16": 1.1372, "2022-02-17": 1.137, "2022-02-18": 1.1354, "2022-02-21": 1.1338, "2022-02-22": 1.1342, "2022-02-23": 1.1344, "2022-02-24": 1.1163, "2022-02-25": 1.1216, "2022-02-28": 1.1199, "2022-03-01": 1.1162, "2022-03-02": 1.1106, "2022-03-03": 1.1076, "2022-03-04": 1.0929, "2022-03-07": 1.0895, "2022-03-08": 1.0892, "2022-03-09": 1.0993, "2022-03-10": 1.1084, "2022-03-11": 1.099, "2022-03-14": 1.096, "2022-03-15": 1.0991, "2022-03-16": 1.0994, "2022-03-17": 1.1051, "2022-03-18": 1.1008, "2022-03-21": 1.1038, "2022-03-22": 1.1024, "2022-03-23": 1.0985, "2022-03-24": 1.0978, "2022-03-25": 1.1002, "2022-03-28": 1.0966, "2022-03-29": 1.1085, "2022-03-30": 1.1126, "2022-03-31": 1.1101, "2022-04-01": 1.1052, "2022-04-04": 1.1005, "2022-04-05": 1.0969, "2022-04-06": 1.0923, "2022-04-07": 1.0916, "2022-04-08": 1.0861, "2022-04-11": 1.09, "2022-04-12": 1.0861, "2022-04-13": 1.0826, "2022-04-14": 1.0878, "2022-04-19": 1.0803, "2022-04-20": 1.083, "2022-04-21": 1.0887, "2022-04-22": 1.0817, "2022-04-25": 1.0746, "2022-04-26": 1.0674, "2022-04-27": 1.0583, "2022-04-28": 1.0485, "2022-04-29": 1.054, "2022-05-02": 1.0524, "2022-05-03": 1.0556, "2022-05-04": 1.0531, "2022-05-05": 1.0568, "2022-05-06": 1.057, "2022-05-09": 1.0559, "2022-05-10": 1.0554, "2022-05-11": 1.0553, "2022-05-12": 1.0408, "2022-05-13": 1.0385, "2022-05-16": 1.0422, "2022-05-17": 1.0541, "2022-05-18": 1.0523, "2022-05-19": 1.0525, "2022-05-20": 1.0577, "2022-05-23": 1.0659, "2022-05-24": 1.072, "2022-05-25": 1.0656, "2022-05-26": 1.0697, "2022-05-27": 1.0722, "2022-05-30": 1.0764, "2022-05-31": 1.0713, "2022-06-01": 1.0712, "2022-06-02": 1.0692, "2022-06-03": 1.073, "2022-06-06": 1.0726, "2022-06-07": 1.0662, "2022-06-08": 1.0739, "2022-06-09": 1.0743, "2022-06-10": 1.0578, "2022-06-13": 1.0455, "2022-06-14": 1.0452, "2022-06-15": 1.0431, "2022-06-16": 1.04, "2022-06-17": 1.0486, "2022-06-20": 1.0517, "2022-06-21": 1.055, "2022-06-22": 1.0521, "2022-06-23": 1.0493, "2022-06-24": 1.0524, "2022-06-27": 1.0572, "2022-06-28": 1.0561, "2022-06-29": 1.0517, "2022-06-30": 1.0387, "2022-07-01": 1.0425, "2022-07-04": 1.0455, "2022-07-05": 1.029, "2022-07-06": 1.0177, "2022-07-07": 1.018, "2022-07-08": 1.0163, "2022-07-11": 1.0098, "2022-07-12": 1.0042, "2022-07-13": 1.0067, "2022-07-14": 1.0005, "2022-07-15": 1.0059, "2022-07-18": 1.0131, "2022-07-19": 1.0245, "2022-07-20": 1.0199, "2022-07-21": 1.0199, "2022-07-22": 1.019, "2022-07-25": 1.0236, "2022-07-26": 1.0124, "2022-07-27": 1.0152, "2022-07-28": 1.0122, "2022-07-29": 1.0198, "2022-08-01": 1.0233, "2022-08-02": 1.0224, "2022-08-03": 1.0194, "2022-08-04": 1.0181, "2022-08-05": 1.0233, "2022-08-08": 1.0199, "2022-08-09": 1.0234, "2022-08-10": 1.0252, "2022-08-11": 1.0338, "2022-08-12": 1.0285, "2022-08-15": 1.0195, "2022-08-16": 1.0131, "2022-08-17": 1.0164, "2022-08-18": 1.0178, "2022-08-19": 1.0054, "2022-08-22": 1.0001, "2022-08-23": 0.9927, "2022-08-24": 0.9934, "2022-08-25": 0.997, "2022-08-26": 1.0007, "2022-08-29": 0.9986, "2022-08-30": 1.0034, "2022-08-31": 1, "2022-09-01": 1.0004, "2022-09-02": 0.9993, "2022-09-05": 0.992, "2022-09-06": 0.9928, "2022-09-07": 0.9885, "2022-09-08": 1.0009, "2022-09-09": 1.0049, "2022-09-12": 1.0155, "2022-09-13": 1.0175, "2022-09-14": 0.999, "2022-09-15": 0.9992, "2022-09-16": 0.9954, "2022-09-19": 0.999, "2022-09-20": 0.9986, "2022-09-21": 0.9906, "2022-09-22": 0.9884, "2022-09-23": 0.9754, "2022-09-26": 0.9646, "2022-09-27": 0.9644, "2022-09-28": 0.9565, "2022-09-29": 0.9706, "2022-09-30": 0.9748, "2022-10-03": 0.9764, "2022-10-04": 0.9891, "2022-10-05": 0.9915, "2022-10-06": 0.986, "2022-10-07": 0.9797, "2022-10-10": 0.9697, "2022-10-11": 0.9723, "2022-10-12": 0.9706, "2022-10-13": 0.9739, "2022-10-14": 0.9717, "2022-10-17": 0.9739, "2022-10-18": 0.9835, "2022-10-19": 0.9778, "2022-10-20": 0.9811, "2022-10-21": 0.973, "2022-10-24": 0.9851, "2022-10-25": 0.9861, "2022-10-26": 1.0023, "2022-10-27": 1.0037, "2022-10-28": 0.9951, "2022-10-31": 0.9914, "2022-11-01": 0.9947, "2022-11-02": 0.9908, "2022-11-03": 0.9753, "2022-11-04": 0.9872, "2022-11-07": 0.9993, "2022-11-08": 0.9996, "2022-11-09": 1.0039, "2022-11-10": 0.9954, "2022-11-11": 1.0308, "2022-11-14": 1.0319, "2022-11-15": 1.0404, "2022-11-16": 1.0412, "2022-11-17": 1.0319, "2022-11-18": 1.0366, "2022-11-21": 1.0246, "2022-11-22": 1.0274, "2022-11-23": 1.0325, "2022-11-24": 1.0413, "2022-11-25": 1.0375, "2022-11-28": 1.0463, "2022-11-29": 1.0366, "2022-11-30": 1.0376, "2022-12-01": 1.0454, "2022-12-02": 1.0538, "2022-12-05": 1.0587, "2022-12-06": 1.0516, "2022-12-07": 1.0529, "2022-12-08": 1.0519, "2022-12-09": 1.0559, "2022-12-12": 1.0562, "2022-12-13": 1.0545, "2022-12-14": 1.0649, "2022-12-15": 1.0621, "2022-12-16": 1.0619, "2022-12-19": 1.0598, "2022-12-20": 1.0599, "2022-12-21": 1.0636, "2022-12-22": 1.0633, "2022-12-23": 1.0622, "2022-12-27": 1.0624, "2022-12-28": 1.064, "2022-12-29": 1.0649, "2022-12-30": 1.0666, "2023-01-02": 1.0683, "2023-01-03": 1.0545, "2023-01-04": 1.0599, "2023-01-05": 1.0601, "2023-01-06": 1.05, "2023-01-09": 1.0696, "2023-01-10": 1.0723, "2023-01-11": 1.0747, "2023-01-12": 1.0772, "2023-01-13": 1.0814, "2023-01-16": 1.0812, "2023-01-17": 1.0843, "2023-01-18": 1.0839, "2023-01-19": 1.0815, "2023-01-20": 1.0826, "2023-01-23": 1.0871, "2023-01-24": 1.0858, "2023-01-25": 1.0878, "2023-01-26": 1.0895, "2023-01-27": 1.0865, "2023-01-30": 1.0903, "2023-01-31": 1.0833, "2023-02-01": 1.0894, "2023-02-02": 1.0988, "2023-02-03": 1.0937, "2023-02-06": 1.0776, "2023-02-07": 1.07, "2023-02-08": 1.0735, "2023-02-09": 1.0771, "2023-02-10": 1.069, "2023-02-13": 1.0686, "2023-02-14": 1.0759, "2023-02-15": 1.07, "2023-02-16": 1.07, "2023-02-17": 1.0625, "2023-02-20": 1.0674, "2023-02-21": 1.0664, "2023-02-22": 1.0644, "2023-02-23": 1.0616, "2023-02-24": 1.057, "2023-02-27": 1.0554, "2023-02-28": 1.0619, "2023-03-01": 1.0684, "2023-03-02": 1.0605, "2023-03-03": 1.0615, "2023-03-06": 1.0646, "2023-03-07": 1.0665, "2023-03-08": 1.0545, "2023-03-09": 1.0554, "2023-03-10": 1.0586, "2023-03-13": 1.0706, "2023-03-14": 1.0737, "2023-03-15": 1.0549, "2023-03-16": 1.0595, "2023-03-17": 1.0623, "2023-03-20": 1.0717, "2023-03-21": 1.0776, "2023-03-22": 1.0785, "2023-03-23": 1.0879, "2023-03-24": 1.0745, "2023-03-27": 1.0773, "2023-03-28": 1.0841, "2023-03-29": 1.0847, "2023-03-30": 1.0886, "2023-03-31": 1.0875, "2023-04-03": 1.087, "2023-04-04": 1.0901, "2023-04-05": 1.094, "2023-04-06": 1.0915, "2023-04-11": 1.0905, "2023-04-12": 1.0922, "2023-04-13": 1.1015, "2023-04-14": 1.1057, "2023-04-17": 1.0981, "2023-04-18": 1.0972, "2023-04-19": 1.0933, "2023-04-20": 1.0944, "2023-04-21": 1.0978, "2023-04-24": 1.1002, "2023-04-25": 1.1022, "2023-04-26": 1.1039, "2023-04-27": 1.1042, "2023-04-28": 1.0981, "2023-05-02": 1.0965, "2023-05-03": 1.1043, "2023-05-04": 1.1074, "2023-05-05": 1.1014, "2023-05-08": 1.1037, "2023-05-09": 1.0959, "2023-05-10": 1.095, "2023-05-11": 1.093, "2023-05-12": 1.0892, "2023-05-15": 1.0876, "2023-05-16": 1.0881, "2023-05-17": 1.0829, "2023-05-18": 1.0813, "2023-05-19": 1.0808, "2023-05-22": 1.0822, "2023-05-23": 1.0779, "2023-05-24": 1.0785, "2023-05-25": 1.0735, "2023-05-26": 1.0751, "2023-05-29": 1.0715, "2023-05-30": 1.0744, "2023-05-31": 1.0683, "2023-06-01": 1.0697, "2023-06-02": 1.0763, "2023-06-05": 1.069, "2023-06-06": 1.0683, "2023-06-07": 1.0717, "2023-06-08": 1.0737, "2023-06-09": 1.078, "2023-06-12": 1.0765, "2023-06-13": 1.0793, "2023-06-14": 1.0809, "2023-06-15": 1.0819, "2023-06-16": 1.0966, "2023-06-19": 1.0922, "2023-06-20": 1.0933, "2023-06-21": 1.0923, "2023-06-22": 1.0985, "2023-06-23": 1.0884, "2023-06-26": 1.0918, "2023-06-27": 1.0951, "2023-06-28": 1.0938, "2023-06-29": 1.0938, "2023-06-30": 1.0866, "2023-07-03": 1.0899, "2023-07-04": 1.0895, "2023-07-05": 1.0879, "2023-07-06": 1.0899, "2023-07-07": 1.0888, "2023-07-10": 1.0956, "2023-07-11": 1.0989, "2023-07-12": 1.1022, "2023-07-13": 1.1182, "2023-07-14": 1.1221, "2023-07-17": 1.123, "2023-07-18": 1.1255, "2023-07-19": 1.1222, "2023-07-20": 1.1197, "2023-07-21": 1.1123, "2023-07-24": 1.1096, "2023-07-25": 1.1051, "2023-07-26": 1.1059, "2023-07-27": 1.1125, "2023-07-28": 1.101, "2023-07-31": 1.1023, "2023-08-01": 1.097, "2023-08-02": 1.0985, "2023-08-03": 1.0932, "2023-08-04": 1.0946, "2023-08-07": 1.0984, "2023-08-08": 1.0944, "2023-08-09": 1.0968, "2023-08-10": 1.1019, "2023-08-11": 1.1004, "2023-08-14": 1.093, "2023-08-15": 1.0926, "2023-08-16": 1.0916, "2023-08-17": 1.09, "2023-08-18": 1.0867, "2023-08-21": 1.0908, "2023-08-22": 1.0887, "2023-08-23": 1.0805, "2023-08-24": 1.084, "2023-08-25": 1.0808, "2023-08-28": 1.0808, "2023-08-29": 1.0803, "2023-08-30": 1.0886, "2023-08-31": 1.0868, "2023-09-01": 1.0844, "2023-09-04": 1.0801, "2023-09-05": 1.0731, "2023-09-06": 1.0745, "2023-09-07": 1.071, "2023-09-08": 1.0704, "2023-09-11": 1.0724, "2023-09-12": 1.0713, "2023-09-13": 1.0733, "2023-09-14": 1.073, "2023-09-15": 1.0658, "2023-09-18": 1.0663, "2023-09-19": 1.0713, "2023-09-20": 1.0702, "2023-09-21": 1.0635, "2023-09-22": 1.0647, "2023-09-25": 1.0633, "2023-09-26": 1.0605, "2023-09-27": 1.0536, "2023-09-28": 1.0539, "2023-09-29": 1.0594, "2023-10-02": 1.053, "2023-10-03": 1.0469, "2023-10-04": 1.0497, "2023-10-05": 1.0526, "2023-10-06": 1.0563, "2023-10-09": 1.0531, "2023-10-10": 1.0582, "2023-10-11": 1.0604, "2023-10-12": 1.0619, "2023-10-13": 1.0524, "2023-10-16": 1.0538, "2023-10-17": 1.0569, "2023-10-18": 1.0565, "2023-10-19": 1.0558, "2023-10-20": 1.0591, "2023-10-23": 1.0597, "2023-10-24": 1.0632, "2023-10-25": 1.0576, "2023-10-26": 1.054, "2023-10-27": 1.0541, "2023-10-30": 1.0605, "2023-10-31": 1.0619, "2023-11-01": 1.0537, "2023-11-02": 1.0661, "2023-11-03": 1.0702, "2023-11-06": 1.0741, "2023-11-07": 1.0686, "2023-11-08": 1.0671, "2023-11-09": 1.0691, "2023-11-10": 1.0683, "2023-11-13": 1.067, "2023-11-14": 1.0724, "2023-11-15": 1.0868, "2023-11-16": 1.0849, "2023-11-17": 1.0872, "2023-11-20": 1.0928, "2023-11-21": 1.0955, "2023-11-22": 1.0911, "2023-11-23": 1.09, "2023-11-24": 1.0916, "2023-11-27": 1.0951, "2023-11-28": 1.0949, "2023-11-29": 1.0985, "2023-11-30": 1.0931, "2023-12-01": 1.0875, "2023-12-04": 1.0868, "2023-12-05": 1.0817, "2023-12-06": 1.0778, "2023-12-07": 1.0771, "2023-12-08": 1.0777, "2023-12-11": 1.0757, "2023-12-12": 1.0804, "2023-12-13": 1.0787, "2023-12-14": 1.0919, "2023-12-15": 1.0946, "2023-12-18": 1.0918, "2023-12-19": 1.0962, "2023-12-20": 1.0944, "2023-12-21": 1.0983, "2023-12-22": 1.1023, "2023-12-27": 1.1065, "2023-12-28": 1.1114, "2023-12-29": 1.105, "2024-01-02": 1.0956, "2024-01-03": 1.0919, "2024-01-04": 1.0953, "2024-01-05": 1.0921, "2024-01-08": 1.0946, "2024-01-09": 1.094, "2024-01-10": 1.0946, "2024-01-11": 1.0987, "2024-01-12": 1.0942, "2024-01-15": 1.0945, "2024-01-16": 1.0882, "2024-01-17": 1.0877, "2024-01-18": 1.0875, "2024-01-19": 1.0887, "2024-01-22": 1.089, "2024-01-23": 1.0872, "2024-01-24": 1.0905, "2024-01-25": 1.0893, "2024-01-26": 1.0871, "2024-01-29": 1.0823, "2024-01-30": 1.0846, "2024-01-31": 1.0837, "2024-02-01": 1.0814, "2024-02-02": 1.0883, "2024-02-05": 1.0746, "2024-02-06": 1.0743, "2024-02-07": 1.0776, "2024-02-08": 1.0758, "2024-02-09": 1.0772, "2024-02-12": 1.0773, "2024-02-13": 1.0793, "2024-02-14": 1.0713, "2024-02-15": 1.0743, "2024-02-16": 1.0768, "2024-02-19": 1.0776, "2024-02-20": 1.0802, "2024-02-21": 1.0809, "2024-02-22": 1.0844, "2024-02-23": 1.0834, "2024-02-26": 1.0852, "2024-02-27": 1.0856, "2024-02-28": 1.0808, "2024-02-29": 1.0826, "2024-03-01": 1.0813, "2024-03-04": 1.0846, "2024-03-05": 1.0849, "2024-03-06": 1.0874, "2024-03-07": 1.0895, "2024-03-08": 1.0932, "2024-03-11": 1.0926, "2024-03-12": 1.0916, "2024-03-13": 1.0939, "2024-03-14": 1.0925, "2024-03-15": 1.0892, "2024-03-18": 1.0892, "2024-03-19": 1.0854, "2024-03-20": 1.0844, "2024-03-21": 1.0907, "2024-03-22": 1.0823, "2024-03-25": 1.0835, "2024-03-26": 1.0855, "2024-03-27": 1.0816, "2024-03-28": 1.0811, "2024-04-02": 1.0749, "2024-04-03": 1.0783, "2024-04-04": 1.0852, "2024-04-05": 1.0841, "2024-04-08": 1.0823, "2024-04-09": 1.0867, "2024-04-10": 1.086, "2024-04-11": 1.0729, "2024-04-12": 1.0652, "2024-04-15": 1.0656, "2024-04-16": 1.0637, "2024-04-17": 1.0638, "2024-04-18": 1.0679, "2024-04-19": 1.0653, "2024-04-22": 1.0632, "2024-04-23": 1.0674, "2024-04-24": 1.0686, "2024-04-25": 1.072, "2024-04-26": 1.0714, "2024-04-29": 1.072, "2024-04-30": 1.0718, "2024-05-02": 1.0698, "2024-05-03": 1.0744, "2024-05-06": 1.0776, "2024-05-07": 1.0766, "2024-05-08": 1.0743, "2024-05-09": 1.0732, "2024-05-10": 1.0779, "2024-05-13": 1.0795, "2024-05-14": 1.0796, "2024-05-15": 1.0832, "2024-05-16": 1.0866, "2024-05-17": 1.0844, "2024-05-20": 1.0861, "2024-05-21": 1.0864, "2024-05-22": 1.083, "2024-05-23": 1.0854, "2024-05-24": 1.084, "2024-05-27": 1.0843, "2024-05-28": 1.0882, "2024-05-29": 1.0857, "2024-05-30": 1.0815, "2024-05-31": 1.0852, "2024-06-03": 1.0842, "2024-06-04": 1.0865, "2024-06-05": 1.0872, "2024-06-06": 1.0865, "2024-06-07": 1.0898, "2024-06-10": 1.0756, "2024-06-11": 1.073, "2024-06-12": 1.0765, "2024-06-13": 1.0784, "2024-06-14": 1.0686, "2024-06-17": 1.0712, "2024-06-18": 1.0715, "2024-06-19": 1.0749, "2024-06-20": 1.0719, "2024-06-21": 1.0688, "2024-06-24": 1.073, "2024-06-25": 1.0714, "2024-06-26": 1.0689, "2024-06-27": 1.0696, "2024-06-28": 1.0705, "2024-07-01": 1.0745, "2024-07-02": 1.0729, "2024-07-03": 1.0758, "2024-07-04": 1.08, "2024-07-05": 1.0824, "2024-07-08": 1.0835, "2024-07-09": 1.0814, "2024-07-10": 1.0825, "2024-07-11": 1.0855, "2024-07-12": 1.089, "2024-07-15": 1.0907, "2024-07-16": 1.0902, "2024-07-17": 1.0934, "2024-07-18": 1.093, "2024-07-19": 1.089, "2024-07-22": 1.0888, "2024-07-23": 1.086, "2024-07-24": 1.0848, "2024-07-25": 1.0851, "2024-07-26": 1.086, "2024-07-29": 1.0817, "2024-07-30": 1.0824, "2024-07-31": 1.0828, "2024-08-01": 1.0789, "2024-08-02": 1.0835, "2024-08-05": 1.0966, "2024-08-06": 1.0915, "2024-08-07": 1.0922, "2024-08-08": 1.093, "2024-08-09": 1.0917, "2024-08-12": 1.0925, "2024-08-13": 1.0931, "2024-08-14": 1.1019, "2024-08-15": 1.1011, "2024-08-16": 1.0994, "2024-08-19": 1.1041, "2024-08-20": 1.1084, "2024-08-21": 1.1116, "2024-08-22": 1.1135, "2024-08-23": 1.1121, "2024-08-26": 1.1163, "2024-08-27": 1.1162, "2024-08-28": 1.1117, "2024-08-29": 1.1088, "2024-08-30": 1.1087, "2024-09-02": 1.1061, "2024-09-03": 1.1035, "2024-09-04": 1.105, "2024-09-05": 1.1097, "2024-09-06": 1.1103, "2024-09-09": 1.1043, "2024-09-10": 1.1031, "2024-09-11": 1.1043, "2024-09-12": 1.1016, "2024-09-13": 1.1081, "2024-09-16": 1.1126, "2024-09-17": 1.1139, "2024-09-18": 1.1124, "2024-09-19": 1.1156, "2024-09-20": 1.1166, "2024-09-23": 1.1119, "2024-09-24": 1.1133, "2024-09-25": 1.1194, "2024-09-26": 1.1155, "2024-09-27": 1.1158, "2024-09-30": 1.1196, "2024-10-01": 1.1086, "2024-10-02": 1.1071, "2024-10-03": 1.1039, "2024-10-04": 1.1029, "2024-10-07": 1.0982, "2024-10-08": 1.0982, "2024-10-09": 1.0957, "2024-10-10": 1.0932, "2024-10-11": 1.0938, "2024-10-14": 1.0915, "2024-10-15": 1.0903, "2024-10-16": 1.0897, "2024-10-17": 1.0866, "2024-10-18": 1.0847, "2024-10-21": 1.0853, "2024-10-22": 1.0821, "2024-10-23": 1.0767, "2024-10-24": 1.0801, "2024-10-25": 1.0825, "2024-10-28": 1.0818, "2024-10-29": 1.0774, "2024-10-30": 1.0815, "2024-10-31": 1.0882, "2024-11-01": 1.0885, "2024-11-04": 1.0904, "2024-11-05": 1.0897, "2024-11-06": 1.0695, "2024-11-07": 1.0785, "2024-11-08": 1.0772, "2024-11-11": 1.0651, "2024-11-12": 1.0617, "2024-11-13": 1.0629, "2024-11-14": 1.0533, "2024-11-15": 1.0583, "2024-11-18": 1.0552, "2024-11-19": 1.0578, "2024-11-20": 1.0562, "2024-11-21": 1.0526, "2024-11-22": 1.0412, "2024-11-25": 1.0495, "2024-11-26": 1.0522, "2024-11-27": 1.0531, "2024-11-28": 1.0542, "2024-11-29": 1.0562, "2024-12-02": 1.0507, "2024-12-03": 1.0512, "2024-12-04": 1.0492, "2024-12-05": 1.054, "2024-12-06": 1.0581, "2024-12-09": 1.0568, "2024-12-10": 1.0527, "2024-12-11": 1.0507, "2024-12-12": 1.0491, "2024-12-13": 1.0518, "2024-12-16": 1.0498, "2024-12-17": 1.0497, "2024-12-18": 1.0496, "2024-12-19": 1.0395, "2024-12-20": 1.039, "2024-12-23": 1.0393, "2024-12-24": 1.0395, "2024-12-27": 1.0435, "2024-12-30": 1.0444, "2024-12-31": 1.0389, "2025-01-02": 1.0321, "2025-01-03": 1.0299, "2025-01-06": 1.0426, "2025-01-07": 1.0393, "2025-01-08": 1.0286, "2025-01-09": 1.0305, "2025-01-10": 1.0304, "2025-01-13": 1.0198, "2025-01-14": 1.0245, "2025-01-15": 1.03, "2025-01-16": 1.0272, "2025-01-17": 1.0298, "2025-01-20": 1.0316, "2025-01-21": 1.0357, "2025-01-22": 1.0443, "2025-01-23": 1.0404, "2025-01-24": 1.0472, "2025-01-27": 1.053, "2025-01-28": 1.0421, "2025-01-29": 1.0396, "2025-01-30": 1.0403, "2025-01-31": 1.0393, "2025-02-03": 1.0274, "2025-02-04": 1.0335, "2025-02-05": 1.0422, "2025-02-06": 1.036, "2025-02-07": 1.0377, "2025-02-10": 1.032, "2025-02-11": 1.0324, "2025-02-12": 1.037, "2025-02-13": 1.039, "2025-02-14": 1.0478, "2025-02-17": 1.0473, "2025-02-18": 1.0447, "2025-02-19": 1.0434, "2025-02-20": 1.0443, "2025-02-21": 1.0465, "2025-02-24": 1.0466, "2025-02-25": 1.0497, "2025-02-26": 1.0487, "2025-02-27": 1.0477, "2025-02-28": 1.0411, "2025-03-03": 1.0465, "2025-03-04": 1.0557, "2025-03-05": 1.0694, "2025-03-06": 1.0796, "2025-03-07": 1.0857, "2025-03-10": 1.0845, "2025-03-11": 1.0912, "2025-03-12": 1.0886, "2025-03-13": 1.083, "2025-03-14": 1.0889, "2025-03-17": 1.0903, "2025-03-18": 1.0918, "2025-03-19": 1.0897, "2025-03-20": 1.0833, "2025-03-21": 1.0827, "2025-03-24": 1.0824, "2025-03-25": 1.0825, "2025-03-26": 1.0788, "2025-03-27": 1.0785, "2025-03-28": 1.0797, "2025-03-31": 1.0815, "2025-04-01": 1.0788, "2025-04-02": 1.0803, "2025-04-03": 1.1097, "2025-04-04": 1.1057, "2025-04-07": 1.0967, "2025-04-08": 1.095, "2025-04-09": 1.1045, "2025-04-10": 1.1082, "2025-04-11": 1.1346, "2025-04-14": 1.1377, "2025-04-15": 1.1324, "2025-04-16": 1.1355, "2025-04-17": 1.136, "2025-04-22": 1.1476, "2025-04-23": 1.1415, "2025-04-24": 1.1376, "2025-04-25": 1.1357, "2025-04-28": 1.1358, "2025-04-29": 1.1373, "2025-04-30": 1.1373, "2025-05-02": 1.1343, "2025-05-05": 1.1343, "2025-05-06": 1.1325, "2025-05-07": 1.136, "2025-05-08": 1.1297, "2025-05-09": 1.1252, "2025-05-12": 1.1106, "2025-05-13": 1.1112, "2025-05-14": 1.1214, "2025-05-15": 1.1185, "2025-05-16": 1.1194, "2025-05-19": 1.1262, "2025-05-20": 1.1241, "2025-05-21": 1.1321, "2025-05-22": 1.1309, "2025-05-23": 1.1301, "2025-05-26": 1.1381, "2025-05-27": 1.1356, "2025-05-28": 1.1317, "2025-05-29": 1.1281, "2025-05-30": 1.1339, "2025-06-02": 1.1419, "2025-06-03": 1.1386, "2025-06-04": 1.1384, "2025-06-05": 1.1423, "2025-06-06": 1.1411, "2025-06-09": 1.141, "2025-06-10": 1.1429, "2025-06-11": 1.1433, "2025-06-12": 1.1594, "2025-06-13": 1.1512, "2025-06-16": 1.1574, "2025-06-17": 1.1568, "2025-06-18": 1.1508, "2025-06-19": 1.1478, "2025-06-20": 1.1515, "2025-06-23": 1.1472, "2025-06-24": 1.1607, "2025-06-25": 1.1598, "2025-06-26": 1.1695, "2025-06-27": 1.1704, "2025-06-30": 1.172, "2025-07-01": 1.181, "2025-07-02": 1.1755, "2025-07-03": 1.1782, "2025-07-04": 1.1767, "2025-07-07": 1.1728, "2025-07-08": 1.1718, "2025-07-09": 1.1698, "2025-07-10": 1.1709, "2025-07-11": 1.1683, "2025-07-14": 1.169, "2025-07-15": 1.1665, "2025-07-16": 1.1602, "2025-07-17": 1.1579, "2025-07-18": 1.165, "2025-07-21": 1.1667, "2025-07-22": 1.1699, "2025-07-23": 1.1726, "2025-07-24": 1.1756, "2025-07-25": 1.1724, "2025-07-28": 1.1654, "2025-07-29": 1.1533, "2025-07-30": 1.1527, "2025-07-31": 1.1446, "2025-08-01": 1.1404, "2025-08-04": 1.1565, "2025-08-05": 1.1546, "2025-08-06": 1.1604, "2025-08-07": 1.1643, "2025-08-08": 1.1648, "2025-08-11": 1.1622, "2025-08-12": 1.1606, "2025-08-13": 1.1711, "2025-08-14": 1.169, "2025-08-15": 1.1688, "2025-08-18": 1.1673, "2025-08-19": 1.1682, "2025-08-20": 1.1651, "2025-08-21": 1.1639, "2025-08-22": 1.1608, "2025-08-25": 1.1697, "2025-08-26": 1.1656, "2025-08-27": 1.1593, "2025-08-28": 1.1676, "2025-08-29": 1.1658, "2025-09-01": 1.1715, "2025-09-02": 1.1646, "2025-09-03": 1.1653, "2025-09-04": 1.1647, "2025-09-05": 1.1697, "2025-09-08": 1.1728, "2025-09-09": 1.1744, "2025-09-10": 1.1707, "2025-09-11": 1.1685, "2025-09-12": 1.1718, "2025-09-15": 1.1766, "2025-09-16": 1.1807, "2025-09-17": 1.1837, "2025-09-18": 1.1818, "2025-09-19": 1.1736, "2025-09-22": 1.1781, "2025-09-23": 1.1793, "2025-09-24": 1.1756, "2025-09-25": 1.1739, "2025-09-26": 1.1672, "2025-09-29": 1.1723, "2025-09-30": 1.1741, "2025-10-01": 1.1724, "2025-10-02": 1.1754, "2025-10-03": 1.1734, "2025-10-06": 1.1678, "2025-10-07": 1.1666, "2025-10-08": 1.1627, "2025-10-09": 1.1611, "2025-10-10": 1.1568, "2025-10-13": 1.1569, "2025-10-14": 1.1553, "2025-10-15": 1.1622, "2025-10-16": 1.1649, "2025-10-17": 1.1681, "2025-10-20": 1.1655, "2025-10-21": 1.1607, "2025-10-22": 1.1587, "2025-10-23": 1.1593, "2025-10-24": 1.1612, "2025-10-27": 1.164, "2025-10-28": 1.163, "2025-10-29": 1.1636, "2025-10-30": 1.155, "2025-10-31": 1.1554, "2025-11-03": 1.1514, "2025-11-04": 1.1491, "2025-11-05": 1.1492, "2025-11-06": 1.1533, "2025-11-07": 1.1561, "2025-11-10": 1.1571, "2025-11-11": 1.1575, "2025-11-12": 1.1576, "2025-11-13": 1.1619, "2025-11-14": 1.1648, "2025-11-17": 1.1593, "2025-11-18": 1.159, "2025-11-19": 1.1583, "2025-11-20": 1.1514, "2025-11-21": 1.152, "2025-11-24": 1.1544, "2025-11-25": 1.1551, "2025-11-26": 1.1577, "2025-11-27": 1.1586, "2025-11-28": 1.1566, "2025-12-01": 1.1646, "2025-12-02": 1.1614, "2025-12-03": 1.1668, "2025-12-04": 1.1666, "2025-12-05": 1.1645, "2025-12-08": 1.1655, "2025-12-09": 1.1637, "2025-12-10": 1.1634, "2025-12-11": 1.1714, "2025-12-12": 1.1731, "2025-12-15": 1.1753, "2025-12-16": 1.1776, "2025-12-17": 1.1722, "2025-12-18": 1.1719, "2025-12-19": 1.1712, "2025-12-22": 1.1745, "2025-12-23": 1.1786, "2025-12-24": 1.1787, "2025-12-29": 1.1766, "2025-12-30": 1.1757, "2025-12-31": 1.175, "2026-01-02": 1.1721, "2026-01-05": 1.1664, "2026-01-06": 1.1707, "2026-01-07": 1.1684, "2026-01-08": 1.1675, "2026-01-09": 1.1642, "2026-01-12": 1.1692, "2026-01-13": 1.1654, "2026-01-14": 1.1651, "2026-01-15": 1.1624, "2026-01-16": 1.1617, "2026-01-19": 1.1631, "2026-01-20": 1.1728, "2026-01-21": 1.1739, "2026-01-22": 1.1706, "2026-01-23": 1.1742, "2026-01-26": 1.1836, "2026-01-27": 1.1929, "2026-01-28": 1.1974, "2026-01-29": 1.1968, "2026-01-30": 1.1919, "2026-02-02": 1.184, "2026-02-03": 1.1801, "2026-02-04": 1.182, "2026-02-05": 1.1798, "2026-02-06": 1.1794, "2026-02-09": 1.1886, "2026-02-10": 1.1894, "2026-02-11": 1.19, "2026-02-12": 1.1874, "2026-02-13": 1.1862, "2026-02-16": 1.1855, "2026-02-17": 1.1826, "2026-02-18": 1.1845, "2026-02-19": 1.1753, "2026-02-20": 1.1767, "2026-02-23": 1.1784, "2026-02-24": 1.1777, "2026-02-25": 1.1784, "2026-02-26": 1.1814, "2026-02-27": 1.1805, "2026-03-02": 1.1698, "2026-03-03": 1.1606, "2026-03-04": 1.1649, "2026-03-05": 1.1618, "2026-03-06": 1.1561, "2026-03-09": 1.1555, "2026-03-10": 1.1641, "2026-03-11": 1.1581, "2026-03-12": 1.1547, "2026-03-13": 1.1476, "2026-03-16": 1.1478, "2026-03-17": 1.1531, "2026-03-18": 1.15, "2026-03-19": 1.1489, "2026-03-20": 1.1555, "2026-03-23": 1.1596, "2026-03-24": 1.1572, "2026-03-25": 1.1592, "2026-03-26": 1.1539, "2026-03-27": 1.1517, "2026-03-30": 1.1484, "2026-03-31": 1.1498, "2026-04-01": 1.1605, "2026-04-02": 1.1525, "2026-04-07": 1.1557, "2026-04-08": 1.1706, "2026-04-09": 1.1685, "2026-04-10": 1.1711, "2026-04-13": 1.1684, "2026-04-14": 1.1793, "2026-04-15": 1.178, "2026-04-16": 1.1782, "2026-04-17": 1.1797, "2026-04-20": 1.176, "2026-04-21": 1.1767, "2026-04-22": 1.1733, "2026-04-23": 1.1694, "2026-04-24": 1.1712, "2026-04-27": 1.1749, "2026-04-28": 1.168, "2026-04-29": 1.1706, "2026-04-30": 1.1702, "2026-05-04": 1.17, "2026-05-05": 1.1686, "2026-05-06": 1.1762, "2026-05-07": 1.177, "2026-05-08": 1.1761, "2026-05-11": 1.1765, "2026-05-12": 1.1738, "2026-05-13": 1.1715, "2026-05-14": 1.1702, "2026-05-15": 1.1628, "2026-05-18": 1.1648, "2026-05-19": 1.162, "2026-05-20": 1.16, "2026-05-21": 1.1599, "2026-05-22": 1.1595, "2026-05-25": 1.1643, "2026-05-26": 1.1634, "2026-05-27": 1.1637, "2026-05-28": 1.1617, "2026-05-29": 1.1644, "2026-06-01": 1.1646, "2026-06-02": 1.1649, "2026-06-03": 1.1614, "2026-06-04": 1.164, "2026-06-05": 1.164, "2026-06-08": 1.154, "2026-06-09": 1.1573, "2026-06-10": 1.1539, "2026-06-11": 1.1537, "2026-06-12": 1.1567, "2026-06-15": 1.1607, "2026-06-16": 1.1594, "2026-06-17": 1.1591, "2026-06-18": 1.1461, "2026-06-19": 1.15 } ======================================================================================== FICHEIRO: dados_csv/historico-precos-mensal.json Tamanho: 99027 bytes ======================================================================================== { "meta": { "user": "tiago", "todos": false, "encerradas": false, "mindatacompra": "2019-10-15", "minmesguardado": "2019-10", "debugtickersamostra": [ "AAPL", "NVDA" ], "fontes_prioridade_default": [ "stooq", "twelvedata", "eodhd", "perplexity", "manual" ], "ttlcachesegundos": 2592000, "forcar": false, "stats": { "totaltickers": 34, "atualizados": 0, "ignoradossemmapa": 0, "semdados": 0, "erros": 0, "porfonte": { "stooq": 0, "twelvedata": 0, "eodhd": 0, "perplexity": 0, "manual": 0 } }, "timestamp": "2026-05-02 21:48:17" }, "ativos": { "AAPL": { "stooq": "aapl.us", "moeda": "USD", "mensal": { "2018-12": 39.44, "2019-01": 41.61, "2019-02": 43.29, "2019-03": 47.81, "2019-04": 50.17, "2019-05": 43.77, "2019-06": 50.39, "2019-07": 53.26, "2019-08": 51.43, "2019-09": 55.99, "2019-10": 62.19, "2019-11": 66.04, "2019-12": 73.41, "2020-01": 77.38, "2020-02": 74.7, "2020-03": 63.57, "2020-04": 73.45, "2020-05": 80.46, "2020-06": 91.2, "2020-07": 106.26, "2020-08": 129.04, "2020-09": 115.81, "2020-10": 108.77, "2020-11": 119.05, "2020-12": 132.69, "2021-01": 134.14, "2021-02": 127.79, "2021-03": 122.15, "2021-04": 131.46, "2021-05": 124.28, "2021-06": 136.96, "2021-07": 145.52, "2021-08": 151.83, "2021-09": 141.5, "2021-10": 148.96, "2021-11": 165.3, "2021-12": 177.57, "2022-01": 174.78, "2022-02": 165.12, "2022-03": 174.61, "2022-04": 157.96, "2022-05": 148.84, "2022-06": 136.72, "2022-07": 161.51, "2022-08": 157.22, "2022-09": 138.2, "2022-10": 153.34, "2022-11": 148.03, "2022-12": 129.93, "2023-01": 144.29, "2023-02": 147.41, "2023-03": 164.9, "2023-04": 169.59, "2023-05": 177.25, "2023-06": 193.97, "2023-07": 196.45, "2023-08": 187.87, "2023-09": 173.75, "2023-10": 170.77, "2023-11": 189.95, "2023-12": 192.53, "2024-01": 184.4, "2024-02": 180.75, "2024-03": 170.03, "2024-04": 170.33, "2024-05": 192.25, "2024-06": 210.62, "2024-07": 222.08, "2024-08": 222.77, "2024-09": 233, "2024-10": 225.91, "2024-11": 239.59, "2024-12": 250.42, "2025-01": 236, "2025-02": 241.84, "2025-03": 222.13, "2025-04": 212.5, "2025-05": 201.7, "2025-06": 205.17, "2025-07": 207.57, "2025-08": 229.72, "2025-09": 254.63, "2025-10": 270.37, "2025-11": 283.1, "2025-12": 271.86, "2026-01": 270.01, "2026-02": 264.72, "2026-03": 253.79, "2026-04": 271.35 } }, "ADBE": { "stooq": "adbe.us", "moeda": "USD", "mensal": { "2018-12": 226.24, "2019-01": 247.82, "2019-02": 262.5, "2019-03": 272.17, "2019-04": 289.25, "2019-05": 270.9, "2019-06": 300.97, "2019-07": 298.86, "2019-08": 282.45, "2019-09": 276.25, "2019-10": 277.93, "2019-11": 302.75, "2019-12": 329.81, "2020-01": 351.14, "2020-02": 360.28, "2020-03": 318.24, "2020-04": 353.64, "2020-05": 389.68, "2020-06": 435.31, "2020-07": 444.32, "2020-08": 513.39, "2020-09": 490.43, "2020-10": 444.94, "2020-11": 478.47, "2020-12": 500.12, "2021-01": 470, "2021-02": 469.57, "2021-03": 475.37, "2021-04": 508.34, "2021-05": 495.91, "2021-06": 585.64, "2021-07": 618.75, "2021-08": 663.7, "2021-09": 575.72, "2021-10": 640.2, "2021-11": 669.85, "2021-12": 567.06, "2022-01": 534.3, "2022-02": 467.68, "2022-03": 455.62, "2022-04": 407.29, "2022-05": 416.48, "2022-06": 366.06, "2022-07": 411.09, "2022-08": 373.44, "2022-09": 275.2, "2022-10": 318.5, "2022-11": 344.93, "2022-12": 336.53, "2023-01": 370.34, "2023-02": 323.95, "2023-03": 385.37, "2023-04": 374.15, "2023-05": 417.79, "2023-06": 488.99, "2023-07": 546.17, "2023-08": 559.34, "2023-09": 521.13, "2023-10": 532.06, "2023-11": 611.01, "2023-12": 596.6, "2024-01": 617.78, "2024-02": 560.28, "2024-03": 502.09, "2024-04": 462.83, "2024-05": 444.76, "2024-06": 555.54, "2024-07": 551.65, "2024-08": 571.04, "2024-09": 517.78, "2024-10": 478.08, "2024-11": 516.2, "2024-12": 444.68, "2025-01": 437.45, "2025-02": 438.56, "2025-03": 383.53, "2025-04": 374.98, "2025-05": 403.4, "2025-06": 386.88, "2025-07": 357.69, "2025-08": 345.63, "2025-09": 352.75, "2025-10": 340.31, "2025-11": 322.85, "2025-12": 349.99, "2026-01": 293.38, "2026-02": 260.88, "2026-03": 243.08, "2026-04": 246.1 } }, "AMD": { "stooq": "amd.us", "moeda": "USD", "mensal": { "2018-12": 18.46, "2019-01": 24.41, "2019-02": 23.53, "2019-03": 26.36, "2019-04": 27.63, "2019-05": 27.41, "2019-06": 31.2, "2019-07": 30.45, "2019-08": 30.9, "2019-09": 28.99, "2019-10": 33.93, "2019-11": 38.73, "2019-12": 45.86, "2020-01": 47, "2020-02": 47.46, "2020-03": 45.48, "2020-04": 52.39, "2020-05": 53.63, "2020-06": 52.61, "2020-07": 77.43, "2020-08": 90.82, "2020-09": 81.99, "2020-10": 74.7, "2020-11": 92.66, "2020-12": 91.71, "2021-01": 87.66, "2021-02": 86.39, "2021-03": 78.5, "2021-04": 81.62, "2021-05": 80.81, "2021-06": 93.93, "2021-07": 108.63, "2021-08": 110.72, "2021-09": 102.9, "2021-10": 125.23, "2021-11": 158.37, "2021-12": 143.9, "2022-01": 114.25, "2022-02": 123.34, "2022-03": 109.34, "2022-04": 89.84, "2022-05": 101.86, "2022-06": 76.47, "2022-07": 96.78, "2022-08": 84.87, "2022-09": 63.36, "2022-10": 60.06, "2022-11": 77.63, "2022-12": 64.77, "2023-01": 75.15, "2023-02": 78.58, "2023-03": 98.01, "2023-04": 89.69, "2023-05": 118.21, "2023-06": 113.91, "2023-07": 114.4, "2023-08": 105.72, "2023-09": 103.27, "2023-10": 98.5, "2023-11": 121.16, "2023-12": 147.41, "2024-01": 167.69, "2024-02": 192.53, "2024-03": 183.34, "2024-04": 158.38, "2024-05": 166.9, "2024-06": 162.21, "2024-07": 144.48, "2024-08": 136.94, "2024-09": 164.08, "2024-10": 144.07, "2024-11": 142.06, "2024-12": 120.79, "2025-01": 115.95, "2025-02": 99.86, "2025-03": 102.74, "2025-04": 97.35, "2025-05": 114.63, "2025-06": 141.9, "2025-07": 176.31, "2025-08": 162.32, "2025-09": 161.79, "2025-10": 256.12, "2025-11": 219.76, "2025-12": 214.16, "2026-01": 246.27, "2026-02": 198.62, "2026-03": 203.43, "2026-04": 354.49 } }, "AMZN": { "stooq": "amzn.us", "moeda": "USD", "mensal": { "2018-12": 75.1, "2019-01": 85.94, "2019-02": 81.99, "2019-03": 90.71, "2019-04": 96.33, "2019-05": 88.75, "2019-06": 96.11, "2019-07": 93.34, "2019-08": 89.49, "2019-09": 86.8, "2019-10": 88.83, "2019-11": 89.08, "2019-12": 92.39, "2020-01": 100.44, "2020-02": 97.7, "2020-03": 97.49, "2020-04": 123.7, "2020-05": 123.55, "2020-06": 137.94, "2020-07": 158.23, "2020-08": 172.55, "2020-09": 157.44, "2020-10": 150.22, "2020-11": 158.4, "2020-12": 162.85, "2021-01": 167.14, "2021-02": 157.31, "2021-03": 154.7, "2021-04": 173.37, "2021-05": 160.93, "2021-06": 172.01, "2021-07": 166.57, "2021-08": 173.54, "2021-09": 164.25, "2021-10": 165.91, "2021-11": 175.35, "2021-12": 166.72, "2022-01": 135.3, "2022-02": 153.56, "2022-03": 163, "2022-04": 124.5, "2022-05": 120.21, "2022-06": 106.21, "2022-07": 135.39, "2022-08": 126.77, "2022-09": 113, "2022-10": 102.44, "2022-11": 96.54, "2022-12": 84, "2023-01": 103.13, "2023-02": 94.23, "2023-03": 103.29, "2023-04": 102.05, "2023-05": 120.58, "2023-06": 130.36, "2023-07": 133.68, "2023-08": 138.01, "2023-09": 129.46, "2023-10": 133.09, "2023-11": 146.09, "2023-12": 151.94, "2024-01": 155.2, "2024-02": 176.76, "2024-03": 180.97, "2024-04": 175, "2024-05": 176.44, "2024-06": 193.25, "2024-07": 186.98, "2024-08": 176.25, "2024-09": 186.33, "2024-10": 186.4, "2024-11": 210.71, "2024-12": 219.39, "2025-01": 237.68, "2025-02": 212.28, "2025-03": 190.26, "2025-04": 184.42, "2025-05": 206.65, "2025-06": 219.39, "2025-07": 234.11, "2025-08": 225.34, "2025-09": 219.57, "2025-10": 244.22, "2025-11": 233.88, "2025-12": 230.82, "2026-01": 242.96, "2026-02": 208.39, "2026-03": 208.27, "2026-04": 265.06 } }, "ANSS": { "stooq": "anss.us", "moeda": "USD", "mensal": { "2018-12": 142.94, "2019-01": 164.35, "2019-02": 177.26, "2019-03": 187.45, "2019-04": 195.8, "2019-05": 179.5, "2019-06": 208.11, "2019-07": 203.12, "2019-08": 206.01, "2019-09": 221.36, "2019-10": 220.15, "2019-11": 250.7, "2019-12": 257.41, "2020-01": 274.33, "2020-02": 258.81, "2020-03": 232.47, "2020-04": 261.83, "2020-05": 286.7, "2020-06": 291.73, "2020-07": 310.6, "2020-08": 339.01, "2020-09": 327.23, "2020-10": 311.23, "2020-11": 338.06, "2020-12": 363.8, "2021-01": 367.94, "2021-02": 346.11, "2021-03": 339.56, "2021-04": 365.66, "2021-05": 335.99, "2021-06": 347.06, "2021-07": 369.63, "2021-08": 365.36, "2021-09": 340.45, "2021-10": 376.44, "2021-11": 391.48, "2021-12": 401.12, "2022-01": 340.01, "2022-02": 324.19, "2022-03": 317.65, "2022-04": 279.93, "2022-05": 260.36, "2022-06": 239.29, "2022-07": 279.21, "2022-08": 248.3, "2022-09": 221.7, "2022-10": 221.16, "2022-11": 254.3, "2022-12": 241.59, "2023-01": 266.36, "2023-02": 303.61, "2023-03": 332.8, "2023-04": 314.17, "2023-05": 323.59, "2023-06": 330.27, "2023-07": 342.1, "2023-08": 318.87, "2023-09": 297.4, "2023-10": 278.26, "2023-11": 293.36, "2023-12": 362.88, "2024-01": 327.83, "2024-02": 334.17, "2024-03": 347.48, "2024-04": 324.88, "2024-05": 317.45, "2024-06": 321.5, "2024-07": 313.63, "2024-08": 309.02, "2024-09": 318.63, "2024-10": 320.41, "2024-11": 350.51, "2024-12": 337.33, "2025-01": 350.5, "2025-02": 333.25, "2025-03": 316.56, "2025-04": 321.88, "2025-05": 332.61, "2025-06": 351.22, "2025-07": 351.22, "2025-08": 351.22, "2025-09": 351.22, "2025-10": 351.22, "2025-11": 0, "2025-12": 0, "2026-01": 0, "2026-02": 0, "2026-03": 0, "2026-04": 0 } }, "BABA": { "stooq": "baba.us", "moeda": "USD", "mensal": { "2018-12": 137.07, "2019-01": 168.49, "2019-02": 183.03, "2019-03": 180.89, "2019-04": 185.57, "2019-05": 149.26, "2019-06": 175.05, "2019-07": 173.11, "2019-08": 172.41, "2019-09": 167.23, "2019-10": 176.67, "2019-11": 196.31, "2019-12": 212.1, "2020-01": 206.59, "2020-02": 210.98, "2020-03": 194.48, "2020-04": 202.67, "2020-05": 206.57, "2020-06": 215.7, "2020-07": 251.02, "2020-08": 287.03, "2020-09": 293.98, "2020-10": 310.84, "2020-11": 263.36, "2020-12": 232.73, "2021-01": 264.69, "2021-02": 241.69, "2021-03": 226.73, "2021-04": 230.95, "2021-05": 219.48, "2021-06": 226.78, "2021-07": 200.09, "2021-08": 166.99, "2021-09": 148.05, "2021-10": 170.17, "2021-11": 127.53, "2021-12": 118.79, "2022-01": 125.79, "2022-02": 105.19, "2022-03": 108.8, "2022-04": 101.21, "2022-05": 96.05, "2022-06": 113.68, "2022-07": 90.34, "2022-08": 95.41, "2022-09": 79.99, "2022-10": 63.58, "2022-11": 87.56, "2022-12": 88.09, "2023-01": 110.2, "2023-02": 87.79, "2023-03": 102.18, "2023-04": 84.16, "2023-05": 79.55, "2023-06": 83.35, "2023-07": 102.16, "2023-08": 92.9, "2023-09": 86.53, "2023-10": 82.54, "2023-11": 74.88, "2023-12": 77.51, "2024-01": 72.17, "2024-02": 74.03, "2024-03": 73.37, "2024-04": 74.85, "2024-05": 78.34, "2024-06": 72, "2024-07": 78.85, "2024-08": 82.27, "2024-09": 106.12, "2024-10": 97.98, "2024-11": 85.95, "2024-12": 120.79, "2025-01": 98.84, "2025-02": 132.51, "2025-03": 132.23, "2025-04": 119.43, "2025-05": 114.75, "2025-06": 113.41, "2025-07": 120.63, "2025-08": 138.55, "2025-09": 178.73, "2025-10": 170.43, "2025-11": 164.26, "2025-12": 146.58, "2026-01": 168.39, "2026-02": 142.56, "2026-03": 125.46, "2026-04": 131.88 } }, "BAC": { "stooq": "bac.us", "moeda": "USD", "mensal": { "2018-12": 24.64, "2019-01": 28.47, "2019-02": 29.08, "2019-03": 28.54, "2019-04": 30.58, "2019-05": 26.6, "2019-06": 29.42, "2019-07": 30.68, "2019-08": 27.05, "2019-09": 29.17, "2019-10": 31.27, "2019-11": 33.43, "2019-12": 35.22, "2020-01": 32.83, "2020-02": 29.37, "2020-03": 21.23, "2020-04": 24.05, "2020-05": 24.61, "2020-06": 23.75, "2020-07": 24.88, "2020-08": 25.74, "2020-09": 24.09, "2020-10": 24.08, "2020-11": 28.16, "2020-12": 30.31, "2021-01": 29.96, "2021-02": 35.79, "2021-03": 38.69, "2021-04": 40.53, "2021-05": 42.92, "2021-06": 41.23, "2021-07": 37.96, "2021-08": 41.75, "2021-09": 42.45, "2021-10": 47.85, "2021-11": 44.47, "2021-12": 44.49, "2022-01": 46.14, "2022-02": 44.2, "2022-03": 41.22, "2022-04": 36.14, "2022-05": 37.2, "2022-06": 31.13, "2022-07": 33.71, "2022-08": 33.61, "2022-09": 30.2, "2022-10": 36.04, "2022-11": 37.85, "2022-12": 33.12, "2023-01": 35.48, "2023-02": 34.3, "2023-03": 28.6, "2023-04": 29.04, "2023-05": 27.79, "2023-06": 28.69, "2023-07": 32, "2023-08": 28.67, "2023-09": 26.7, "2023-10": 26.34, "2023-11": 30.49, "2023-12": 33.67, "2024-01": 34.01, "2024-02": 34.52, "2024-03": 37.52, "2024-04": 37.01, "2024-05": 39.99, "2024-06": 39.77, "2024-07": 40.31, "2024-08": 40.7, "2024-09": 39.68, "2024-10": 41.82, "2024-11": 47.04, "2024-12": 43.95, "2025-01": 46.3, "2025-02": 46.1, "2025-03": 41.73, "2025-04": 39.88, "2025-05": 44.08, "2025-06": 47.32, "2025-07": 47.27, "2025-08": 50.42, "2025-09": 51.59, "2025-10": 53.45, "2025-11": 53.24, "2025-12": 55, "2026-01": 54.03, "2026-02": 49.81, "2026-03": 48.75, "2026-04": 53.46 } }, "BRKB": { "stooq": "brk-b.us", "moeda": "USD", "mensal": { "2018-12": 204.18, "2019-01": 205.54, "2019-02": 201.3, "2019-03": 205, "2019-04": 216.71, "2019-05": 197.42, "2019-06": 214.62, "2019-07": 205.43, "2019-08": 200.9, "2019-09": 208.02, "2019-10": 212.58, "2019-11": 220.33, "2019-12": 226.5, "2020-01": 224.43, "2020-02": 217.63, "2020-03": 182.83, "2020-04": 187.36, "2020-05": 183.84, "2020-06": 178.51, "2020-07": 195.78, "2020-08": 218.04, "2020-09": 212.94, "2020-10": 204.31, "2020-11": 228.91, "2020-12": 231.87, "2021-01": 229.32, "2021-02": 249.21, "2021-03": 255.47, "2021-04": 274.95, "2021-05": 289.84, "2021-06": 277.92, "2021-07": 278.14, "2021-08": 285.77, "2021-09": 272.94, "2021-10": 286.24, "2021-11": 276.69, "2021-12": 299, "2022-01": 313.02, "2022-02": 321.45, "2022-03": 352.91, "2022-04": 318.19, "2022-05": 315.98, "2022-06": 273.02, "2022-07": 295.86, "2022-08": 280.8, "2022-09": 267.02, "2022-10": 295.09, "2022-11": 318.6, "2022-12": 308.9, "2023-01": 311.52, "2023-02": 305.18, "2023-03": 308.77, "2023-04": 330.17, "2023-05": 321.08, "2023-06": 341, "2023-07": 351.96, "2023-08": 360.2, "2023-09": 348.08, "2023-10": 341.33, "2023-11": 360, "2023-12": 356.66, "2024-01": 383.74, "2024-02": 409.4, "2024-03": 420.2, "2024-04": 396.73, "2024-05": 414.4, "2024-06": 406.8, "2024-07": 438.5, "2024-08": 476.83, "2024-09": 460.26, "2024-10": 450.92, "2024-11": 477.33, "2024-12": 85.35, "2025-01": 468.67, "2025-02": 513.83, "2025-03": 532.58, "2025-04": 533.25, "2025-05": 502.81, "2025-06": 485.77, "2025-07": 471.88, "2025-08": 501.14, "2025-09": 502.74, "2025-10": 477.54, "2025-11": 508.55, "2025-12": 502.65, "2026-01": 487.29, "2026-02": 480.17, "2026-03": 479.2, "2026-04": 473.6 } }, "GOOGL": { "stooq": "googl.us", "moeda": "USD", "mensal": { "2018-12": 52.25, "2019-01": 56.29, "2019-02": 56.33, "2019-03": 59.95, "2019-04": 59.95, "2019-05": 55.33, "2019-06": 55, "2019-07": 60.91, "2019-08": 58.48, "2019-09": 61.06, "2019-10": 62.94, "2019-11": 64.44, "2019-12": 66.97, "2020-01": 71.64, "2020-02": 69.32, "2020-03": 58.1, "2020-04": 67.34, "2020-05": 71.74, "2020-06": 70.9, "2020-07": 74.4, "2020-08": 81.48, "2020-09": 73.28, "2020-10": 81.22, "2020-11": 87.72, "2020-12": 87.63, "2021-01": 94.65, "2021-02": 103.48, "2021-03": 103.13, "2021-04": 117.68, "2021-05": 119.06, "2021-06": 122.09, "2021-07": 134.85, "2021-08": 144.7, "2021-09": 133.68, "2021-10": 143.5, "2021-11": 141.9, "2021-12": 144.85, "2022-01": 135.3, "2022-02": 135.06, "2022-03": 139.07, "2022-04": 116.58, "2022-05": 113.76, "2022-06": 108.96, "2022-07": 114.86, "2022-08": 108.22, "2022-09": 95.65, "2022-10": 94.51, "2022-11": 100.99, "2022-12": 88.23, "2023-01": 98.84, "2023-02": 90.06, "2023-03": 103.73, "2023-04": 107.2, "2023-05": 122.87, "2023-06": 119.7, "2023-07": 132.72, "2023-08": 136.17, "2023-09": 134.17, "2023-10": 124.08, "2023-11": 132.53, "2023-12": 139.69, "2024-01": 140.1, "2024-02": 138.46, "2024-03": 155.49, "2024-04": 162.78, "2024-05": 172.5, "2024-06": 182.15, "2024-07": 171.54, "2024-08": 157.36, "2024-09": 165.85, "2024-10": 171.11, "2024-11": 171.49, "2024-12": 189.3, "2025-01": 204.02, "2025-02": 170.28, "2025-03": 154.64, "2025-04": 158.8, "2025-05": 169.03, "2025-06": 176.23, "2025-07": 191.9, "2025-08": 211.35, "2025-09": 243.1, "2025-10": 281.19, "2025-11": 314.89, "2025-12": 313, "2026-01": 343.69, "2026-02": 306.52, "2026-03": 287.56, "2026-04": 384.8 } }, "IWDA": { "stooq": "eunl.de", "moeda": "EUR", "mensal": { "2023-11": 78.97, "2023-12": 81.87, "2024-01": 85.02, "2024-02": 88.18, "2024-03": 90.69, "2024-04": 89.58, "2024-05": 90.67, "2024-06": 95.19, "2024-07": 95.39, "2024-08": 95.67, "2024-09": 96.37, "2024-10": 97.55, "2024-11": 105.7, "2024-12": 5.88, "2025-01": 108.18, "2025-02": 105.45, "2025-03": 97.13, "2025-04": 93.33, "2025-05": 98.8, "2025-06": 100.15, "2025-07": 104.94, "2025-08": 104.83, "2025-09": 107.22, "2025-10": 111.79, "2025-11": 110.97, "2025-12": 111.53, "2026-01": 113.44, "2026-02": 113.83, "2026-03": 108.06, "2026-04": 117.06 } }, "KO": { "stooq": "ko.us", "moeda": "USD", "mensal": { "2018-12": 47.35, "2019-01": 48.13, "2019-02": 45.34, "2019-03": 46.72, "2019-04": 49.06, "2019-05": 49.13, "2019-06": 51.6, "2019-07": 52.63, "2019-08": 55.3, "2019-09": 54.44, "2019-10": 54.43, "2019-11": 53.75, "2019-12": 55.35, "2020-01": 58.4, "2020-02": 55.92, "2020-03": 44.25, "2020-04": 45.89, "2020-05": 46.99, "2020-06": 44.68, "2020-07": 47.24, "2020-08": 49.53, "2020-09": 49.37, "2020-10": 48.62, "2020-11": 51.6, "2020-12": 54.84, "2021-01": 48.48, "2021-02": 49.9, "2021-03": 52.71, "2021-04": 53.98, "2021-05": 55.28, "2021-06": 54.11, "2021-07": 56.88, "2021-08": 56.31, "2021-09": 52.47, "2021-10": 56.17, "2021-11": 52.45, "2021-12": 59.21, "2022-01": 61.01, "2022-02": 62.24, "2022-03": 62, "2022-04": 63.44, "2022-05": 63.38, "2022-06": 62.91, "2022-07": 64.52, "2022-08": 61.71, "2022-09": 56.02, "2022-10": 59.85, "2022-11": 63.61, "2022-12": 63.61, "2023-01": 61.32, "2023-02": 59.51, "2023-03": 62.03, "2023-04": 64.3, "2023-05": 59.66, "2023-06": 60.22, "2023-07": 61.93, "2023-08": 59.83, "2023-09": 55.48, "2023-10": 56.49, "2023-11": 58.44, "2023-12": 58.93, "2024-01": 59.49, "2024-02": 60.02, "2024-03": 60.68, "2024-04": 61.77, "2024-05": 62.93, "2024-06": 63.65, "2024-07": 66.74, "2024-08": 73.01, "2024-09": 71.86, "2024-10": 65.31, "2024-11": 63.65, "2024-12": 62.26, "2025-01": 63.48, "2025-02": 71.21, "2025-03": 71.62, "2025-04": 72.55, "2025-05": 72, "2025-06": 70.75, "2025-07": 68.75, "2025-08": 69.06, "2025-09": 66.32, "2025-10": 68.9, "2025-11": 71.95, "2025-12": 69.91, "2026-01": 75.33, "2026-02": 80.22, "2026-03": 76.05, "2026-04": 78.76 } }, "MA": { "stooq": "ma.us", "moeda": "USD", "mensal": { "2018-12": 188.65, "2019-01": 211.13, "2019-02": 224.77, "2019-03": 239.05, "2019-04": 254.24, "2019-05": 251.49, "2019-06": 266.77, "2019-07": 272.27, "2019-08": 280.11, "2019-09": 271.57, "2019-10": 276.81, "2019-11": 286.47, "2019-12": 298.59, "2020-01": 315.94, "2020-02": 306.74, "2020-03": 241.56, "2020-04": 274.97, "2020-05": 301.4, "2020-06": 295.7, "2020-07": 308.53, "2020-08": 358.19, "2020-09": 338.17, "2020-10": 289.97, "2020-11": 336.51, "2020-12": 356.94, "2021-01": 321.56, "2021-02": 362.9, "2021-03": 356.05, "2021-04": 382.06, "2021-05": 359.79, "2021-06": 365.09, "2021-07": 375.26, "2021-08": 346.23, "2021-09": 347.68, "2021-10": 334.05, "2021-11": 314.92, "2021-12": 359.32, "2022-01": 386.38, "2022-02": 360.82, "2022-03": 357.38, "2022-04": 359.04, "2022-05": 357.87, "2022-06": 315.48, "2022-07": 350.54, "2022-08": 329.35, "2022-09": 286.77, "2022-10": 328.18, "2022-11": 356.4, "2022-12": 347.73, "2023-01": 370.6, "2023-02": 355.29, "2023-03": 363.41, "2023-04": 379.86, "2023-05": 365.02, "2023-06": 393.3, "2023-07": 394.28, "2023-08": 412.64, "2023-09": 395.85, "2023-10": 376.35, "2023-11": 413.83, "2023-12": 426.51, "2024-01": 449.23, "2024-02": 474.76, "2024-03": 478.4, "2024-04": 451.2, "2024-05": 447.07, "2024-06": 441.16, "2024-07": 463.71, "2024-08": 482.12, "2024-09": 493.8, "2024-10": 499.59, "2024-11": 531.36, "2024-12": 219.39, "2025-01": 555.43, "2025-02": 576.31, "2025-03": 548.12, "2025-04": 548.06, "2025-05": 581.22, "2025-06": 561.94, "2025-07": 566.47, "2025-08": 591.87, "2025-09": 568.81, "2025-10": 551.99, "2025-11": 543.97, "2025-12": 570.88, "2026-01": 555.37, "2026-02": 521, "2026-03": 499.66, "2026-04": 502.92 } }, "MCD": { "stooq": "mcd.us", "moeda": "USD", "mensal": { "2018-12": 177.57, "2019-01": 178.78, "2019-02": 183.84, "2019-03": 188.39, "2019-04": 197.57, "2019-05": 198.27, "2019-06": 206.3, "2019-07": 210.72, "2019-08": 217.13, "2019-09": 214.71, "2019-10": 196.7, "2019-11": 195.18, "2019-12": 197.61, "2020-01": 213.97, "2020-02": 202.55, "2020-03": 165.35, "2020-04": 187.56, "2020-05": 187.41, "2020-06": 184.47, "2020-07": 194.28, "2020-08": 213.52, "2020-09": 219.49, "2020-10": 212.56, "2020-11": 217.44, "2020-12": 214.58, "2021-01": 207.93, "2021-02": 208.25, "2021-03": 224.14, "2021-04": 236.08, "2021-05": 233.24, "2021-06": 230.99, "2021-07": 240.1, "2021-08": 237.46, "2021-09": 241.11, "2021-10": 250.58, "2021-11": 244.6, "2021-12": 268.07, "2022-01": 259.45, "2022-02": 244.77, "2022-03": 247.28, "2022-04": 246.64, "2022-05": 252.21, "2022-06": 246.88, "2022-07": 264.23, "2022-08": 252.28, "2022-09": 230.74, "2022-10": 272.66, "2022-11": 272.79, "2022-12": 263.53, "2023-01": 267.4, "2023-02": 263.91, "2023-03": 279.61, "2023-04": 297.58, "2023-05": 285.11, "2023-06": 298.41, "2023-07": 293.2, "2023-08": 281.15, "2023-09": 257.75, "2023-10": 262.17, "2023-11": 281.84, "2023-12": 296.51, "2024-01": 292.72, "2024-02": 292.28, "2024-03": 280.22, "2024-04": 273.04, "2024-05": 258.89, "2024-06": 254.84, "2024-07": 265.4, "2024-08": 285.52, "2024-09": 304.51, "2024-10": 292.11, "2024-11": 292.44, "2024-12": 62.26, "2025-01": 288.7, "2025-02": 308.33, "2025-03": 312.37, "2025-04": 319.65, "2025-05": 312.68, "2025-06": 292.17, "2025-07": 300.07, "2025-08": 315.76, "2025-09": 303.89, "2025-10": 298.43, "2025-11": 303.57, "2025-12": 305.63, "2026-01": 318.53, "2026-02": 334.82, "2026-03": 310.79, "2026-04": 293.59 } }, "MRNA": { "stooq": "mrna.us", "moeda": "USD", "mensal": { "2018-12": 15.27, "2019-01": 16.6, "2019-02": 22.6, "2019-03": 20.59, "2019-04": 26.03, "2019-05": 20.78, "2019-06": 14.73, "2019-07": 13.1, "2019-08": 14.88, "2019-09": 15.92, "2019-10": 16.75, "2019-11": 19.76, "2019-12": 19.56, "2020-01": 20.51, "2020-02": 29.88, "2020-03": 29.95, "2020-04": 45.99, "2020-05": 62.18, "2020-06": 64.21, "2020-07": 74.1, "2020-08": 64.89, "2020-09": 70.75, "2020-10": 67.11, "2020-11": 152.74, "2020-12": 104.47, "2021-01": 157.48, "2021-02": 157.4, "2021-03": 130.95, "2021-04": 175.67, "2021-05": 184.66, "2021-06": 234.98, "2021-07": 346.61, "2021-08": 376.69, "2021-09": 384.86, "2021-10": 337.17, "2021-11": 352.43, "2021-12": 253.98, "2022-01": 169.33, "2022-02": 153.6, "2022-03": 172.26, "2022-04": 142.08, "2022-05": 145.33, "2022-06": 142.85, "2022-07": 161.51, "2022-08": 132.27, "2022-09": 118.25, "2022-10": 150.33, "2022-11": 175.91, "2022-12": 179.62, "2023-01": 176.06, "2023-02": 138.81, "2023-03": 153.58, "2023-04": 133.4, "2023-05": 127.71, "2023-06": 121.5, "2023-07": 117.66, "2023-08": 113.07, "2023-09": 103.31, "2023-10": 75.96, "2023-11": 77.7, "2023-12": 99.45, "2024-01": 101.05, "2024-02": 92.24, "2024-03": 105.6, "2024-04": 110.31, "2024-05": 142.55, "2024-06": 118.75, "2024-07": 119.22, "2024-08": 72.94, "2024-09": 66.83, "2024-10": 54.36, "2024-11": 44.26, "2024-12": 41.58, "2025-01": 39.42, "2025-02": 30.96, "2025-03": 28.35, "2025-04": 28.54, "2025-05": 27.05, "2025-06": 27.59, "2025-07": 29.56, "2025-08": 24.19, "2025-09": 25.83, "2025-10": 27.16, "2025-11": 24.16, "2025-12": 29.49, "2026-01": 42.55, "2026-02": 52.85, "2026-03": 50.8, "2026-04": 45.94 } }, "MSFT": { "stooq": "msft.us", "moeda": "USD", "mensal": { "2018-12": 101.57, "2019-01": 104.43, "2019-02": 112.03, "2019-03": 119.02, "2019-04": 130.6, "2019-05": 123.68, "2019-06": 135.68, "2019-07": 136.27, "2019-08": 136.04, "2019-09": 139.03, "2019-10": 143.37, "2019-11": 149.55, "2019-12": 157.7, "2020-01": 170.23, "2020-02": 172.79, "2020-03": 157.71, "2020-04": 179.21, "2020-05": 182.83, "2020-06": 203.51, "2020-07": 205.01, "2020-08": 225.53, "2020-09": 210.33, "2020-10": 202.33, "2020-11": 214.07, "2020-12": 222.42, "2021-01": 239.65, "2021-02": 236.94, "2021-03": 235.77, "2021-04": 252.18, "2021-05": 247.4, "2021-06": 270.9, "2021-07": 284.82, "2021-08": 301.88, "2021-09": 281.92, "2021-10": 329.37, "2021-11": 330.59, "2021-12": 336.32, "2022-01": 310.98, "2022-02": 298.79, "2022-03": 308.31, "2022-04": 284.47, "2022-05": 271.87, "2022-06": 256.83, "2022-07": 278.01, "2022-08": 261.47, "2022-09": 232.9, "2022-10": 232.13, "2022-11": 255.14, "2022-12": 239.82, "2023-01": 247.81, "2023-02": 249.42, "2023-03": 288.3, "2023-04": 305.56, "2023-05": 328.39, "2023-06": 340.54, "2023-07": 335.92, "2023-08": 327.76, "2023-09": 321.8, "2023-10": 338.11, "2023-11": 378.91, "2023-12": 376.04, "2024-01": 397.58, "2024-02": 413.64, "2024-03": 424.57, "2024-04": 389.33, "2024-05": 415.13, "2024-06": 446.95, "2024-07": 418.35, "2024-08": 409.44, "2024-09": 430.3, "2024-10": 406.35, "2024-11": 430.98, "2024-12": 421.5, "2025-01": 415.06, "2025-02": 396.99, "2025-03": 375.39, "2025-04": 395.26, "2025-05": 461.97, "2025-06": 497.41, "2025-07": 533.5, "2025-08": 505.12, "2025-09": 517.95, "2025-10": 517.81, "2025-11": 486.74, "2025-12": 483.62, "2026-01": 423.37, "2026-02": 398.55, "2026-03": 370.17, "2026-04": 407.78 } }, "NDXEX": { "stooq": "exxt.de", "moeda": "EUR", "mensal": { "2024-06": 182.06, "2024-07": 172.93, "2024-08": 171.39, "2024-09": 180.14, "2024-10": 182.75, "2024-11": 200.06, "2024-12": 203.04, "2025-01": 207.27, "2025-02": 201.23, "2025-03": 178.2, "2025-04": 172.83, "2025-05": 189.34, "2025-06": 192.41, "2025-07": 203.25, "2025-08": 198.7, "2025-09": 203.66, "2025-10": 222.92, "2025-11": 218.45, "2025-12": 215.21, "2026-01": 217.11, "2026-02": 211.46, "2026-03": 200.38, "2026-04": 227.52 } }, "NFLX": { "stooq": "nflx.us", "moeda": "USD", "mensal": { "2018-12": 267.66, "2019-01": 339.5, "2019-02": 358.1, "2019-03": 366.96, "2019-04": 370.54, "2019-05": 343.28, "2019-06": 374.6, "2019-07": 322.99, "2019-08": 289.29, "2019-09": 267.62, "2019-10": 287.41, "2019-11": 309.99, "2019-12": 323.57, "2020-01": 345.09, "2020-02": 381.05, "2020-03": 375.5, "2020-04": 419.85, "2020-05": 425.92, "2020-06": 455.04, "2020-07": 488.88, "2020-08": 529.56, "2020-09": 500.03, "2020-10": 484.12, "2020-11": 490.7, "2020-12": 540.73, "2021-01": 539.04, "2021-02": 550.64, "2021-03": 521.66, "2021-04": 513.47, "2021-05": 499.08, "2021-06": 528.21, "2021-07": 515.15, "2021-08": 569.19, "2021-09": 610.34, "2021-10": 681.17, "2021-11": 641.9, "2021-12": 602.44, "2022-01": 427.14, "2022-02": 394.52, "2022-03": 374.59, "2022-04": 199.46, "2022-05": 197.44, "2022-06": 174.87, "2022-07": 226.21, "2022-08": 223.56, "2022-09": 235.44, "2022-10": 291.88, "2022-11": 305.53, "2022-12": 294.88, "2023-01": 353.86, "2023-02": 322.13, "2023-03": 345.48, "2023-04": 324.12, "2023-05": 395.23, "2023-06": 440.49, "2023-07": 438.97, "2023-08": 433.68, "2023-09": 380.33, "2023-10": 411.69, "2023-11": 473.97, "2023-12": 486.88, "2024-01": 564.11, "2024-02": 602.92, "2024-03": 614.31, "2024-04": 550.64, "2024-05": 641.62, "2024-06": 674.88, "2024-07": 628.35, "2024-08": 675.32, "2024-09": 709.27, "2024-10": 756.03, "2024-11": 897.74, "2024-12": 250.42, "2025-01": 976.76, "2025-02": 980.56, "2025-03": 932.53, "2025-11": 109.13, "2025-12": 93.76, "2026-01": 82.76, "2026-02": 97.09, "2026-03": 96.15, "2026-04": 93.61 } }, "NIO": { "stooq": "nio.us", "moeda": "USD", "mensal": { "2018-12": 6.37, "2019-01": 7.88, "2019-02": 9.57, "2019-03": 5.21, "2019-04": 4.85, "2019-05": 3.05, "2019-06": 2.6, "2019-07": 3.47, "2019-08": 2.6, "2019-09": 1.56, "2019-10": 1.45, "2019-11": 2.44, "2019-12": 4.02, "2020-01": 3.78, "2020-02": 4.11, "2020-03": 2.78, "2020-04": 3.41, "2020-05": 4.26, "2020-06": 7.72, "2020-07": 11.94, "2020-08": 19.03, "2020-09": 21.22, "2020-10": 33.32, "2020-11": 50.53, "2020-12": 48.74, "2021-01": 56.99, "2021-02": 49.76, "2021-03": 38.98, "2021-04": 39.84, "2021-05": 42.34, "2021-06": 53.2, "2021-07": 45.85, "2021-08": 39.31, "2021-09": 35.63, "2021-10": 40.84, "2021-11": 39.13, "2021-12": 31.68, "2022-01": 24.51, "2022-02": 22.84, "2022-03": 21.05, "2022-04": 17.5, "2022-05": 17.39, "2022-06": 21.72, "2022-07": 20.18, "2022-08": 19.91, "2022-09": 15.77, "2022-10": 9.67, "2022-11": 12.78, "2022-12": 9.75, "2023-01": 12.07, "2023-02": 9.39, "2023-03": 10.51, "2023-04": 7.81, "2023-05": 7.53, "2023-06": 9.69, "2023-07": 15.3, "2023-08": 10.27, "2023-09": 8.79, "2023-10": 7.3, "2023-11": 7.27, "2023-12": 9.07, "2024-01": 5.62, "2024-02": 5.75, "2024-03": 4.64, "2024-04": 4.72, "2024-05": 5.39, "2024-06": 4.16, "2024-07": 4.44, "2024-08": 4.15, "2024-09": 6.68, "2024-10": 5.1, "2024-11": 4.4, "2024-12": 403.84, "2025-01": 4.32, "2025-02": 4.63, "2025-03": 3.81, "2025-04": 4.05, "2025-05": 3.52, "2025-06": 3.43, "2025-07": 4.87, "2025-08": 6.58, "2025-09": 7.62, "2025-10": 7.25, "2025-11": 5.18, "2025-12": 5.1, "2026-01": 4.52, "2026-02": 4.72, "2026-03": 6.03, "2026-04": 6.39 } }, "NVDA": { "stooq": "nvda.us", "moeda": "USD", "mensal": { "2018-12": 33.38, "2019-01": 35.94, "2019-02": 38.57, "2019-03": 45.57, "2019-04": 45.25, "2019-05": 33.87, "2019-06": 41.54, "2019-07": 42.18, "2019-08": 41.04, "2019-09": 43.52, "2019-10": 50.26, "2019-11": 52.31, "2019-12": 58.83, "2020-01": 59.11, "2020-02": 69.11, "2020-03": 65.9, "2020-04": 73.07, "2020-05": 88.06, "2020-06": 94.98, "2020-07": 106.15, "2020-08": 133.75, "2020-09": 135.31, "2020-10": 125.81, "2020-11": 134.01, "2020-12": 130.55, "2021-01": 132.37, "2021-02": 138.42, "2021-03": 133.48, "2021-04": 150.1, "2021-05": 162.65, "2021-06": 200.03, "2021-07": 197.5, "2021-08": 223.85, "2021-09": 207.16, "2021-10": 258.27, "2021-11": 326.76, "2021-12": 294.11, "2022-01": 244.86, "2022-02": 243.85, "2022-03": 272.86, "2022-04": 195.33, "2022-05": 186.72, "2022-06": 151.59, "2022-07": 184.41, "2022-08": 150.94, "2022-09": 121.39, "2022-10": 134.97, "2022-11": 169.23, "2022-12": 146.14, "2023-01": 195.37, "2023-02": 232.16, "2023-03": 277.77, "2023-04": 289.1, "2023-05": 378.34, "2023-06": 423.02, "2023-07": 467.29, "2023-08": 493.55, "2023-09": 447.82, "2023-10": 407.8, "2023-11": 467.7, "2023-12": 495.22, "2024-01": 61.53, "2024-02": 79.11, "2024-03": 90.36, "2024-04": 86.4, "2024-05": 109.63, "2024-06": 123.54, "2024-07": 117.02, "2024-08": 108, "2024-09": 121.44, "2024-10": 132.76, "2024-11": 138.63, "2024-12": 134.29, "2025-01": 120.07, "2025-02": 124.92, "2025-03": 108.38, "2025-04": 108.92, "2025-05": 137.38, "2025-06": 157.99, "2025-07": 177.87, "2025-08": 170.78, "2025-09": 186.58, "2025-10": 202.49, "2025-11": 179.92, "2025-12": 186.5, "2026-01": 185.61, "2026-02": 182.48, "2026-03": 174.4, "2026-04": 199.57 } }, "O": { "stooq": "o.us", "moeda": "USD", "mensal": { "2022-02": 66.09, "2022-03": 69.3, "2022-04": 67.38, "2022-05": 68.22, "2022-06": 68.26, "2022-07": 73.67, "2022-08": 68.28, "2022-09": 58.2, "2022-10": 62.27, "2022-11": 63.07, "2022-12": 63.43, "2023-01": 67.83, "2023-02": 63.95, "2023-03": 63.32, "2023-04": 61.49, "2023-05": 59.69, "2023-06": 59.3, "2023-07": 61.03, "2023-08": 56.26, "2023-09": 49.06, "2023-10": 47.39, "2023-11": 53.84, "2023-12": 57.6, "2024-01": 54.8, "2024-02": 52.14, "2024-03": 53.46, "2024-04": 53.54, "2024-05": 53.06, "2024-06": 52.82, "2024-07": 57.43, "2024-08": 62.28, "2024-09": 63.42, "2024-10": 59.37, "2024-11": 56.69, "2024-12": 444.68, "2025-01": 54.64, "2025-02": 57.03, "2025-03": 58.01, "2025-04": 57.86, "2025-05": 56.58, "2025-06": 57.61, "2025-07": 56.13, "2025-08": 57.74, "2025-09": 60.79, "2025-10": 57.98, "2025-11": 57.43, "2025-12": 56.37, "2026-01": 60.53, "2026-02": 67.56, "2026-03": 61.18, "2026-04": 64.24 } }, "PLUG": { "stooq": "plug.us", "moeda": "USD", "mensal": { "2018-12": 1.24, "2019-01": 1.37, "2019-02": 1.79, "2019-03": 2.35, "2019-04": 2.49, "2019-05": 2.56, "2019-06": 2.24, "2019-07": 2.21, "2019-08": 2.14, "2019-09": 2.63, "2019-10": 2.65, "2019-11": 3.8, "2019-12": 3.16, "2020-01": 3.87, "2020-02": 4.36, "2020-03": 3.54, "2020-04": 4.18, "2020-05": 4.28, "2020-06": 8.21, "2020-07": 7.71, "2020-08": 12.98, "2020-09": 13.41, "2020-10": 15.47, "2020-11": 26.39, "2020-12": 33.91, "2021-01": 63.85, "2021-02": 52.46, "2021-03": 35.84, "2021-04": 28.51, "2021-05": 30.89, "2021-06": 34.19, "2021-07": 26.62, "2021-08": 26.06, "2021-09": 25.54, "2021-10": 41.65, "2021-11": 39.85, "2021-12": 28.23, "2022-01": 21.87, "2022-02": 25.29, "2022-03": 28.61, "2022-04": 21.7, "2022-05": 18.48, "2022-06": 16.57, "2022-07": 21.24, "2022-08": 28.04, "2022-09": 21.01, "2022-10": 15.98, "2022-11": 15.96, "2022-12": 12.37, "2023-01": 17.02, "2023-02": 14.87, "2023-03": 11.72, "2023-04": 8.83, "2023-05": 8.32, "2023-06": 10.39, "2023-07": 13.12, "2023-08": 8.46, "2023-09": 6.83, "2023-10": 5.89, "2023-11": 4.04, "2023-12": 4.5, "2024-01": 4.45, "2024-02": 3.53, "2024-03": 3.44, "2024-04": 2.31, "2024-05": 3.33, "2024-06": 2.33, "2024-07": 2.47, "2024-08": 1.75, "2024-09": 2.26, "2024-10": 1.96, "2024-11": 2.3, "2024-12": 2.13, "2025-01": 1.86, "2025-02": 1.61, "2025-03": 1.35, "2025-04": 0.87, "2025-05": 0.82, "2025-06": 1.49, "2025-07": 1.5, "2025-08": 1.48, "2025-09": 2.33, "2025-10": 2.69, "2025-11": 1.92, "2025-12": 1.97, "2026-01": 2.08, "2026-02": 1.81, "2026-03": 2.26, "2026-04": 3.13 } }, "PYPL": { "stooq": "pypl.us", "moeda": "USD", "mensal": { "2018-12": 84.09, "2019-01": 88.76, "2019-02": 98.07, "2019-03": 105.55, "2019-04": 112.77, "2019-05": 109.75, "2019-06": 115.03, "2019-07": 110.4, "2019-08": 106.75, "2019-09": 103.59, "2019-10": 104.1, "2019-11": 106.21, "2019-12": 108.17, "2020-01": 113.89, "2020-02": 112.86, "2020-03": 95.74, "2020-04": 123, "2020-05": 154.53, "2020-06": 174.23, "2020-07": 196.07, "2020-08": 204.14, "2020-09": 197.03, "2020-10": 187.76, "2020-11": 214.12, "2020-12": 234.2, "2021-01": 241.85, "2021-02": 273.63, "2021-03": 242.84, "2021-04": 262.29, "2021-05": 259.27, "2021-06": 291.48, "2021-07": 270.99, "2021-08": 288.66, "2021-09": 260.21, "2021-10": 231.28, "2021-11": 184.89, "2021-12": 188.58, "2022-01": 171.94, "2022-02": 111.93, "2022-03": 115.65, "2022-04": 91.53, "2022-05": 85.21, "2022-06": 69.84, "2022-07": 88.57, "2022-08": 93.44, "2022-09": 86.07, "2022-10": 83.58, "2022-11": 78.41, "2022-12": 71.22, "2023-01": 81.49, "2023-02": 73.6, "2023-03": 75.94, "2023-04": 75.11, "2023-05": 61.99, "2023-06": 66.73, "2023-07": 75.82, "2023-08": 62.51, "2023-09": 58.56, "2023-10": 51.8, "2023-11": 57.61, "2023-12": 61.41, "2024-01": 61.35, "2024-02": 60.34, "2024-03": 65.03, "2024-04": 67.92, "2024-05": 62.99, "2024-06": 58.03, "2024-07": 65.78, "2024-08": 72, "2024-09": 78.03, "2024-10": 79.3, "2024-11": 86.53, "2024-12": 85.35, "2025-01": 88.58, "2025-02": 71.05, "2025-03": 65.25, "2025-04": 65.84, "2025-05": 70.93, "2025-06": 74.32, "2025-07": 68.76, "2025-08": 69.25, "2025-09": 67.06, "2025-10": 69.27, "2025-11": 62.58, "2025-12": 58.38, "2026-01": 52.33, "2026-02": 45.63, "2026-03": 45.23, "2026-04": 50.14 } }, "QCOM": { "stooq": "qcom.us", "moeda": "USD", "mensal": { "2019-01": 49.52, "2019-02": 53.39, "2019-03": 57.81, "2019-04": 86.13, "2019-05": 66.82, "2019-06": 77.52, "2019-07": 73.16, "2019-08": 75.12, "2019-09": 76.28, "2019-10": 80.44, "2019-11": 82.45, "2019-12": 88.23, "2020-01": 85.31, "2020-02": 80.56, "2020-03": 67.65, "2020-04": 78.67, "2020-05": 79.73, "2020-06": 91.21, "2020-07": 105.61, "2020-08": 119.1, "2020-09": 117.68, "2020-10": 123.97, "2020-11": 147.17, "2020-12": 152.34, "2021-01": 161.58, "2021-02": 139.49, "2021-03": 132.59, "2021-04": 138.8, "2021-05": 133.94, "2021-06": 142.93, "2021-07": 148.86, "2021-08": 146.69, "2021-09": 128.98, "2021-10": 134.81, "2021-11": 180.56, "2021-12": 182.87, "2022-01": 175.76, "2022-02": 171.99, "2022-03": 152.82, "2022-04": 145.27, "2022-05": 143.22, "2022-06": 127.74, "2022-07": 147.43, "2022-08": 137.08, "2022-09": 114.84, "2022-10": 117.66, "2022-11": 126.49, "2022-12": 109.94, "2023-01": 133.21, "2023-02": 123.53, "2023-03": 127.58, "2023-04": 115.84, "2023-05": 113.41, "2023-06": 119.04, "2023-07": 132.17, "2023-08": 114.53, "2023-09": 111.1, "2023-10": 108.99, "2023-11": 129.05, "2023-12": 144.63, "2024-01": 148.51, "2024-02": 157.79, "2024-03": 171.72, "2024-04": 165.85, "2024-05": 204.05, "2024-06": 199.18, "2024-07": 180.95, "2024-08": 163.24, "2024-09": 170.05, "2024-10": 162.77, "2024-11": 163.03, "2024-12": 41.58, "2025-01": 172.93, "2025-02": 157.17, "2025-03": 153.61, "2025-04": 148.46, "2025-05": 146.63, "2025-06": 159.26, "2025-07": 146.76, "2025-08": 158.78, "2025-09": 166.36, "2025-10": 180.9, "2025-11": 168.04, "2025-12": 171.05, "2026-01": 152.62, "2026-02": 141.03, "2026-03": 128.78, "2026-04": 179.58 } }, "SPCE": { "stooq": "spce.us", "moeda": "USD", "mensal": { "2018-12": 10, "2019-01": 10.05, "2019-02": 10.12, "2019-03": 10.19, "2019-04": 10.23, "2019-05": 10.34, "2019-06": 10.4, "2019-07": 10.47, "2019-08": 10.34, "2019-09": 10.7, "2019-10": 9.41, "2019-11": 7.44, "2019-12": 11.55, "2020-01": 17.15, "2020-02": 25.98, "2020-03": 14.78, "2020-04": 17.62, "2020-05": 17.52, "2020-06": 16.34, "2020-07": 22.45, "2020-08": 17.9, "2020-09": 19.23, "2020-10": 17.66, "2020-11": 26.61, "2020-12": 23.73, "2021-01": 53.79, "2021-02": 38.14, "2021-03": 30.63, "2021-04": 22.15, "2021-05": 28.88, "2021-06": 46, "2021-07": 31.87, "2021-08": 27.11, "2021-09": 25.3, "2021-10": 19.55, "2021-11": 16, "2021-12": 13.38, "2022-01": 9.2, "2022-02": 9.68, "2022-03": 9.88, "2022-04": 7.89, "2022-05": 7.01, "2022-06": 6.02, "2022-07": 7.4, "2022-08": 5.91, "2022-09": 4.71, "2022-10": 4.62, "2022-11": 5.09, "2022-12": 3.48, "2023-01": 5.52, "2023-02": 5.74, "2023-03": 4.05, "2023-04": 3.57, "2023-05": 3.46, "2023-06": 3.88, "2023-07": 4.28, "2023-08": 2.52, "2023-09": 1.77, "2023-10": 1.48, "2023-11": 2.23, "2023-12": 2.45, "2024-01": 1.78, "2024-02": 1.74, "2024-03": 1.43, "2024-04": 0.87, "2024-05": 0.86, "2024-06": 8.43, "2024-07": 7.11, "2024-08": 6.16, "2024-09": 6.1, "2024-10": 6.57, "2024-11": 7.02, "2024-12": 5.88, "2025-01": 4.76, "2025-02": 3.8, "2025-03": 3.03, "2025-04": 2.89, "2025-05": 3.12, "2025-06": 2.73, "2025-07": 3.8, "2025-08": 3.09, "2025-09": 3.86, "2025-10": 3.94, "2025-11": 3.79, "2025-12": 3.21, "2026-01": 2.68, "2026-02": 2.6, "2026-03": 2.43, "2026-04": 2.38 } }, "SQ": { "stooq": "sq.us", "moeda": "USD", "mensal": { "2018-12": 56.09, "2019-01": 71.35, "2019-02": 81.24, "2019-03": 76.32, "2019-04": 72.82, "2019-05": 61.95, "2019-06": 73.2, "2019-07": 80.41, "2019-08": 61.13, "2019-09": 61.95, "2019-10": 61.43, "2019-11": 66.88, "2019-12": 62.56, "2020-01": 74.69, "2020-02": 80.67, "2020-03": 52.38, "2020-04": 65.14, "2020-05": 82.72, "2020-06": 104.94, "2020-07": 129.85, "2020-08": 159.56, "2020-09": 162.55, "2020-10": 155.23, "2020-11": 210.96, "2020-12": 217.64, "2021-01": 221.94, "2021-02": 241, "2021-03": 227.05, "2021-04": 244.82, "2021-05": 221.95, "2021-06": 243.8, "2021-07": 272.38, "2021-08": 268.07, "2021-09": 239.84, "2021-10": 255.04, "2021-11": 208.33, "2021-12": 161.51, "2022-01": 122.29, "2022-02": 127.5, "2022-03": 135.6, "2022-04": 105.86, "2022-05": 87.51, "2022-06": 61.46, "2022-07": 77.81, "2022-08": 68.91, "2022-09": 54.99, "2022-10": 60.07, "2022-11": 67.77, "2022-12": 62.84, "2023-01": 81.72, "2023-02": 76.73, "2023-03": 68.65, "2023-04": 60.22, "2023-05": 60.39, "2023-06": 66.57, "2023-07": 80.53, "2023-08": 57.65, "2023-09": 43.19, "2023-10": 40.25, "2023-11": 63.43, "2023-12": 77.35, "2024-01": 65.01, "2024-02": 79.47, "2024-03": 81.46, "2024-04": 73, "2024-05": 64.08, "2024-06": 64.49, "2024-07": 61.88, "2024-08": 64.17, "2024-09": 67.13, "2024-10": 72.32, "2024-11": 92.78, "2024-12": 0, "2025-01": 0, "2025-02": 0, "2025-03": 0, "2025-04": 0, "2025-05": 0, "2025-06": 0, "2025-07": 0, "2025-08": 0, "2025-09": 0, "2025-10": 0, "2025-11": 0, "2025-12": 0, "2026-01": 0, "2026-02": 0, "2026-03": 0, "2026-04": 0 } }, "TSLA": { "stooq": "tsla.us", "moeda": "USD", "mensal": { "2018-12": 22.19, "2019-01": 20.47, "2019-02": 21.33, "2019-03": 19.28, "2019-04": 15.91, "2019-05": 12.34, "2019-06": 15.14, "2019-07": 16.11, "2019-08": 15, "2019-09": 16.06, "2019-10": 20.99, "2019-11": 22.32, "2019-12": 27.89, "2020-01": 43.37, "2020-02": 49.57, "2020-03": 34.93, "2020-04": 52.13, "2020-05": 59.87, "2020-06": 71.99, "2020-07": 95.38, "2020-08": 166.11, "2020-09": 143, "2020-10": 133.5, "2020-11": 189.2, "2020-12": 235.22, "2021-01": 279.94, "2021-02": 239.48, "2021-03": 222.64, "2021-04": 236.48, "2021-05": 207.97, "2021-06": 226.57, "2021-07": 236.56, "2021-08": 245.24, "2021-09": 258.49, "2021-10": 402.86, "2021-11": 381.59, "2021-12": 352.26, "2022-01": 312.24, "2022-02": 290.14, "2022-03": 359.2, "2022-04": 300.98, "2022-05": 252.75, "2022-06": 224.47, "2022-07": 297.28, "2022-08": 275.61, "2022-09": 265.25, "2022-10": 227.54, "2022-11": 194.7, "2022-12": 123.18, "2023-01": 173.22, "2023-02": 205.71, "2023-03": 207.46, "2023-04": 161.83, "2023-05": 203.93, "2023-06": 261.77, "2023-07": 267.43, "2023-08": 258.08, "2023-09": 251.6, "2023-10": 200.84, "2023-11": 240.08, "2023-12": 248.48, "2024-01": 187.29, "2024-02": 201.88, "2024-03": 175.22, "2024-04": 183.28, "2024-05": 178.08, "2024-06": 197.88, "2024-07": 232.07, "2024-08": 210.6, "2024-09": 261.63, "2024-10": 249.85, "2024-11": 357.09, "2024-12": 403.84, "2025-01": 404.6, "2025-02": 292.98, "2025-03": 259.16, "2025-04": 282.16, "2025-05": 342.69, "2025-06": 317.66, "2025-07": 308.27, "2025-08": 329.36, "2025-09": 444.72, "2025-10": 456.56, "2025-11": 430.14, "2025-12": 449.72, "2026-01": 421.81, "2026-02": 403.32, "2026-03": 371.75, "2026-04": 381.63 } }, "TSM": { "stooq": "tsm.us", "moeda": "USD", "mensal": { "2024-06": 172.33, "2024-07": 165.8, "2024-08": 160.49, "2024-09": 173.67, "2024-10": 190.54, "2024-11": 194.4, "2024-12": 197.49, "2025-01": 209.32, "2025-02": 180.53, "2025-03": 166, "2025-04": 166.69, "2025-05": 194.84, "2025-06": 226.49, "2025-07": 241.62, "2025-08": 228.39, "2025-09": 279.29, "2025-10": 300.43, "2025-11": 287.68, "2025-12": 303.89, "2026-01": 341.36, "2026-02": 369.11, "2026-03": 337.95, "2026-04": 396.06 } }, "TWTR": { "stooq": "twtr.us", "moeda": "USD", "mensal": { "2022-03": 38.69, "2022-04": 49.14, "2022-05": 39.6, "2022-06": 37.39, "2022-07": 40.89, "2022-08": 0, "2022-09": 0, "2022-10": 0, "2022-11": 0, "2022-12": 0, "2023-01": 0, "2023-02": 0, "2023-03": 0, "2023-04": 0, "2023-05": 0, "2023-06": 0, "2023-07": 0, "2023-08": 0, "2023-09": 0, "2023-10": 0, "2023-11": 0, "2023-12": 0, "2024-01": 0, "2024-02": 0, "2024-03": 0, "2024-04": 0, "2024-05": 0, "2024-06": 0, "2024-07": 0, "2024-08": 0, "2024-09": 0, "2024-10": 0, "2024-11": 0, "2024-12": 0, "2025-01": 0, "2025-02": 0, "2025-03": 0, "2025-04": 0, "2025-05": 0, "2025-06": 0, "2025-07": 0, "2025-08": 0, "2025-09": 0, "2025-10": 0, "2025-11": 0, "2025-12": 0, "2026-01": 0, "2026-02": 0, "2026-03": 0, "2026-04": 0 } }, "UAL": { "stooq": "ual.us", "moeda": "USD", "mensal": { "2018-12": 83.73, "2019-01": 87.27, "2019-02": 87.81, "2019-03": 80.87, "2019-04": 88.86, "2019-05": 77.65, "2019-06": 88.45, "2019-07": 91.91, "2019-08": 83.15, "2019-09": 88.41, "2019-10": 90.84, "2019-11": 91.63, "2019-12": 88.09, "2020-01": 74.8, "2020-02": 61.26, "2020-03": 31.55, "2020-04": 29.58, "2020-05": 29.46, "2020-06": 34.61, "2020-07": 31.38, "2020-08": 36, "2020-09": 34.75, "2020-10": 33.78, "2020-11": 45.05, "2020-12": 43.25, "2021-01": 39.94, "2021-02": 53.31, "2021-03": 57.54, "2021-04": 54.4, "2021-05": 59.67, "2021-06": 52.29, "2021-07": 46.07, "2021-08": 46.51, "2021-09": 47.57, "2021-10": 48.05, "2021-11": 42.26, "2021-12": 43.78, "2022-01": 42.88, "2022-02": 44.4, "2022-03": 46.36, "2022-04": 50.19, "2022-05": 47.63, "2022-06": 35.42, "2022-07": 37.69, "2022-08": 35.01, "2022-09": 32.53, "2022-10": 43.08, "2022-11": 44.17, "2022-12": 37.7, "2023-01": 48.96, "2023-02": 51.96, "2023-03": 44.25, "2023-04": 44.41, "2023-05": 47.47, "2023-06": 54.87, "2023-07": 54.31, "2023-08": 49.81, "2023-09": 41.62, "2023-10": 35.01, "2023-11": 39.4, "2023-12": 41.26, "2024-01": 41.38, "2024-02": 45.49, "2024-03": 47.35, "2024-04": 51.46, "2024-05": 52.99, "2024-06": 48.66, "2024-07": 45.42, "2024-08": 43.87, "2024-09": 57.06, "2024-10": 78.26, "2024-11": 97.44, "2024-12": 43.95, "2025-01": 105.84, "2025-02": 93.81, "2025-03": 69.05, "2025-04": 68.82, "2025-05": 81.23, "2025-06": 79.63, "2025-07": 88.31, "2025-08": 104.68, "2025-09": 96.5, "2025-10": 94.04, "2025-11": 101.12, "2025-12": 111.82, "2026-01": 107.35, "2026-02": 103.21, "2026-03": 92.07, "2026-04": 90 } }, "USDEUR": { "stooq": "usdeur", "moeda": "EUR", "mensal": { "2019-01": 0.87, "2019-02": 0.88, "2019-03": 0.89, "2019-04": 0.89, "2019-05": 0.89, "2019-06": 0.88, "2019-07": 0.9, "2019-08": 0.91, "2019-09": 0.92, "2019-10": 0.9, "2019-11": 0.91, "2019-12": 0.89, "2020-01": 0.9, "2020-02": 0.91, "2020-03": 0.91, "2020-04": 0.91, "2020-05": 0.9, "2020-06": 0.89, "2020-07": 0.85, "2020-08": 0.84, "2020-09": 0.85, "2020-10": 0.86, "2020-11": 0.84, "2020-12": 0.82, "2021-01": 0.82, "2021-02": 0.83, "2021-03": 0.85, "2021-04": 0.83, "2021-05": 0.82, "2021-06": 0.84, "2021-07": 0.84, "2021-08": 0.85, "2021-09": 0.86, "2021-10": 0.87, "2021-11": 0.88, "2021-12": 0.88, "2022-01": 0.89, "2022-02": 0.89, "2022-03": 0.9, "2022-04": 0.95, "2022-05": 0.93, "2022-06": 0.95, "2022-07": 0.98, "2022-08": 1, "2022-09": 1.02, "2022-10": 1.01, "2022-11": 0.96, "2022-12": 0.93, "2023-01": 0.92, "2023-02": 0.95, "2023-03": 0.92, "2023-04": 0.91, "2023-05": 0.94, "2023-06": 0.92, "2023-07": 0.91, "2023-08": 0.92, "2023-09": 0.94, "2023-10": 0.95, "2023-11": 0.92, "2023-12": 0.9, "2024-01": 0.93, "2024-02": 0.93, "2024-03": 0.93, "2024-04": 0.94, "2024-05": 0.92, "2024-06": 0.93, "2024-07": 0.92, "2024-08": 0.9, "2024-09": 0.9, "2024-10": 0.92, "2024-11": 0.95, "2024-12": 0.97, "2025-01": 0.96, "2025-02": 0.96, "2025-03": 0.92, "2025-04": 0.88, "2025-05": 0.88, "2025-06": 0.85, "2025-07": 0.88, "2025-08": 0.86, "2025-09": 0.85, "2025-10": 0.86, "2025-11": 0.86, "2025-12": 0.85, "2026-01": 0.84, "2026-02": 0.85, "2026-03": 0.86, "2026-04": 0.85 } }, "VUSA": { "stooq": "vusa.de", "moeda": "EUR", "mensal": { "2019-01": 44.75, "2019-02": 46.63, "2019-03": 48.32, "2019-04": 49.67, "2019-05": 47.2, "2019-06": 49.71, "2019-07": 51.41, "2019-08": 50.55, "2019-09": 51.82, "2019-10": 51.55, "2019-11": 53.4, "2019-12": 54.41, "2020-01": 55.51, "2020-02": 51.43, "2020-03": 45.5, "2020-04": 50.49, "2020-05": 52.1, "2020-06": 51.84, "2020-07": 52.1, "2020-08": 55.66, "2020-09": 54.5, "2020-10": 54, "2020-11": 57.23, "2020-12": 57.66, "2021-01": 59.07, "2021-02": 61.42, "2021-03": 64.31, "2021-04": 65.96, "2021-05": 65.19, "2021-06": 68.67, "2021-07": 70.48, "2021-08": 72.91, "2021-09": 71.18, "2021-10": 75.44, "2021-11": 77.22, "2021-12": 79.99, "2022-01": 75.58, "2022-02": 74.06, "2022-03": 78.41, "2022-04": 74.42, "2022-05": 73, "2022-06": 68.54, "2022-07": 76.33, "2022-08": 75.14, "2022-09": 70.83, "2022-10": 74.34, "2022-11": 72.83, "2022-12": 67.72, "2023-01": 70.6, "2023-02": 71.27, "2023-03": 71.19, "2023-04": 70.68, "2023-05": 74.2, "2023-06": 77.11, "2023-07": 78.79, "2023-08": 79.22, "2023-09": 77.47, "2023-10": 74.88, "2023-11": 79.21, "2023-12": 82.04, "2024-01": 85.4, "2024-02": 89.17, "2024-03": 91.45, "2024-04": 90.19, "2024-05": 91.16, "2024-06": 96.89, "2024-07": 95.41, "2024-08": 96.93, "2024-09": 97.52, "2024-10": 100.1, "2024-11": 109.43, "2024-12": 108.03, "2025-01": 111.45, "2025-02": 107.33, "2025-03": 97.32, "2025-04": 92.25, "2025-05": 97.84, "2025-06": 99.78, "2025-07": 105.84, "2025-08": 104.94, "2025-09": 107.45, "2025-10": 112.42, "2025-11": 111.42, "2025-12": 111.06, "2026-01": 112.04, "2026-02": 111.26, "2026-03": 105.86, "2026-04": 115.85 } }, "XAUEUR": { "stooq": "xaueur", "moeda": "EUR", "mensal": { "2019-01": 1154.29, "2019-02": 1154.23, "2019-03": 1152.01, "2019-04": 1144.42, "2019-05": 1168.96, "2019-06": 1240.94, "2019-07": 1276.17, "2019-08": 1386.45, "2019-09": 1351.13, "2019-10": 1356.9, "2019-11": 1328.81, "2019-12": 1353.15, "2020-01": 1430.87, "2020-02": 1428.82, "2020-03": 1427.49, "2020-04": 1539.87, "2020-05": 1559.63, "2020-06": 1585.08, "2020-07": 1675.56, "2020-08": 1648.28, "2020-09": 1608.99, "2020-10": 1612.81, "2020-11": 1489.35, "2020-12": 1554.28, "2021-01": 1518.47, "2021-02": 1431.73, "2021-03": 1455.77, "2021-04": 1470.42, "2021-05": 1559.47, "2021-06": 1492.99, "2021-07": 1529.29, "2021-08": 1535.71, "2021-09": 1517.31, "2021-10": 1542.29, "2021-11": 1565.28, "2021-12": 1608.2, "2022-01": 1599.65, "2022-02": 1701.19, "2022-03": 1750.71, "2022-04": 1797.74, "2022-05": 1711.91, "2022-06": 1723.83, "2022-07": 1722.97, "2022-08": 1702.05, "2022-09": 1695.66, "2022-10": 1652.48, "2022-11": 1699.28, "2022-12": 1703.4, "2023-01": 1774.86, "2023-02": 1727.07, "2023-03": 1817.14, "2023-04": 1805.17, "2023-05": 1836.93, "2023-06": 1759.5, "2023-07": 1787.55, "2023-08": 1789.34, "2023-09": 1748.36, "2023-10": 1875.78, "2023-11": 1870.47, "2023-12": 1868.7, "2024-01": 1885.9, "2024-02": 1892.3, "2024-03": 2070.6, "2024-04": 2142.49, "2024-05": 2145.24, "2024-06": 2170.81, "2024-07": 2260.99, "2024-08": 2264.02, "2024-09": 2366.64, "2024-10": 2521.93, "2024-11": 2504.58, "2024-12": 2535.07, "2025-01": 2700.15, "2025-02": 2752.12, "2025-03": 2886.94, "2025-04": 2902.84, "2025-05": 2901.27, "2025-06": 2803.54, "2025-07": 2881.8, "2025-08": 2951.1, "2025-09": 3288.04, "2025-10": 3469.48, "2025-11": 3665.33, "2025-12": 3676.67, "2026-01": 4089.85, "2026-02": 4454.86, "2026-03": 4039.4, "2026-04": 3940.1 } }, "Z": { "stooq": "z.us", "moeda": "USD", "mensal": { "2018-12": 31.58, "2019-01": 35.09, "2019-02": 41.8, "2019-03": 35.31, "2019-04": 33.4, "2019-05": 43.02, "2019-06": 47.58, "2019-07": 49.96, "2019-08": 32.99, "2019-09": 29.82, "2019-10": 32.57, "2019-11": 39.86, "2019-12": 45.94, "2020-01": 46.21, "2020-02": 54.4, "2020-03": 36.02, "2020-04": 43.96, "2020-05": 58.22, "2020-06": 57.61, "2020-07": 68.39, "2020-08": 85.76, "2020-09": 101.59, "2020-10": 89.16, "2020-11": 107.81, "2020-12": 129.8, "2021-01": 137.05, "2021-02": 167, "2021-03": 129.64, "2021-04": 130.12, "2021-05": 113.56, "2021-06": 122.22, "2021-07": 107.52, "2021-08": 95.77, "2021-09": 88.14, "2021-10": 97.15, "2021-11": 54.27, "2021-12": 63.85, "2022-01": 50.48, "2022-02": 57.52, "2022-03": 49.29, "2022-04": 40.96, "2022-05": 39.9, "2022-06": 31.75, "2022-07": 35.28, "2022-08": 33.46, "2022-09": 28.61, "2022-10": 30.86, "2022-11": 37.98, "2022-12": 32.21, "2023-01": 44.21, "2023-02": 42, "2023-03": 44.47, "2023-04": 43.92, "2023-05": 45.61, "2023-06": 50.26, "2023-07": 54.16, "2023-08": 52.16, "2023-09": 45.64, "2023-10": 36.25, "2023-11": 40.94, "2023-12": 57.86, "2024-01": 56.84, "2024-02": 56.15, "2024-03": 48.22, "2024-04": 42.57, "2024-05": 40.95, "2024-06": 46.39, "2024-07": 48.7, "2024-08": 54.01, "2024-09": 63.85, "2024-10": 60.09, "2024-11": 83.7, "2024-12": 134.29, "2025-01": 82.22, "2025-02": 76.66, "2025-03": 68.56, "2025-04": 67.33, "2025-05": 68.36, "2025-06": 70.05, "2025-07": 79.55, "2025-08": 81.81, "2025-09": 77.05, "2025-10": 74.98, "2025-11": 73.53, "2025-12": 68.22, "2026-01": 62.52, "2026-02": 43.54, "2026-03": 41.38, "2026-04": 44.4 } }, "ZM": { "stooq": "zm.us", "moeda": "USD", "mensal": { "2019-04": 72.47, "2019-05": 79.73, "2019-06": 86.86, "2019-07": 95.51, "2019-08": 92.46, "2019-09": 76.2, "2019-10": 69.89, "2019-11": 68.93, "2019-12": 68.04, "2020-01": 76.3, "2020-02": 113.11, "2020-03": 146.12, "2020-04": 135.17, "2020-05": 204.15, "2020-06": 253.54, "2020-07": 253.91, "2020-08": 325.1, "2020-09": 470.11, "2020-10": 453, "2020-11": 478.36, "2020-12": 337.32, "2021-01": 381.93, "2021-02": 409.66, "2021-03": 321.29, "2021-04": 319.57, "2021-05": 327.72, "2021-06": 387.03, "2021-07": 378.96, "2021-08": 289.5, "2021-09": 261.5, "2021-10": 278.94, "2021-11": 211.41, "2021-12": 183.91, "2022-01": 182.08, "2022-02": 132.6, "2022-03": 117.23, "2022-04": 104.79, "2022-05": 107.45, "2022-06": 107.97, "2022-07": 105.39, "2022-08": 80.4, "2022-09": 73.59, "2022-10": 83.44, "2022-11": 75.43, "2022-12": 67.74, "2023-01": 75, "2023-02": 74.59, "2023-03": 73.84, "2023-04": 61.68, "2023-05": 67.13, "2023-06": 67.88, "2023-07": 73.35, "2023-08": 71.03, "2023-09": 70.11, "2023-10": 59.98, "2023-11": 67.83, "2023-12": 71.91, "2024-01": 64.61, "2024-02": 70.73, "2024-03": 64.73, "2024-04": 61.1, "2024-05": 61.34, "2024-06": 59.19, "2024-07": 60.4, "2024-08": 68.83, "2024-09": 69.74, "2024-10": 74.74, "2024-11": 83.11, "2024-12": 337.33, "2025-01": 86.94, "2025-02": 73.7, "2025-03": 73.77, "2025-04": 77.54, "2025-05": 81.27, "2025-06": 77.98, "2025-07": 74.05, "2025-08": 81.94, "2025-09": 82.5, "2025-10": 87.23, "2025-11": 84.94, "2025-12": 86.29, "2026-01": 92.87, "2026-02": 72.72, "2026-03": 80.39, "2026-04": 97.15 } } } } ======================================================================================== FICHEIRO: dados_csv/maria/extrato-revolut.csv Tamanho: 1636 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2020-09-17T12:27:15.160488Z,,CASH TOP-UP,,,USD 371.31,USD,1.1805 2020-09-17T13:39:22.948143Z,ANSS,BUY - MARKET,1.19565287,USD 310.55,USD 371.31,USD,1.1802 2020-09-25T07:29:38.401058Z,,CASH TOP-UP,,,USD 219.22,USD,1.1685 2020-09-25T13:30:25.062959Z,AAPL,BUY - MARKET,2.02064706,USD 108.49,USD 219.22,USD,1.1637 2020-09-30T23:46:35.132687Z,,CUSTODY FEE,,,USD -0.01,USD,1.1726 2020-10-01T19:31:42.942068Z,ANSS,SELL - MARKET,1.19565287,USD 334.09,USD 399.44,USD,1.1747 2020-10-01T19:32:55.054485Z,GOOGL,BUY - MARKET,0.26943183,USD 1482.49,USD 399.43,USD,1.1747 2020-10-06T19:06:41.107980Z,,CASH TOP-UP,,,USD 272.23,USD,1.1748 2020-10-06T19:08:42.944338Z,AAPL,BUY - MARKET,2.41595669,USD 112.68,USD 272.23,USD,1.1743 2020-10-21T18:37:36.086402Z,GOOGL,SELL - MARKET,0.26943183,USD 1599.25,USD 429.69,USD,1.1870 2020-10-21T18:38:58.188987Z,ZM,BUY - MARKET,0.8230289,USD 520.65,USD 429.69,USD,1.1870 2020-10-31T23:41:36.606251Z,,CUSTODY FEE,,,USD -0.01,USD,1.1764 2020-11-05T19:44:48.031263Z,AAPL,SELL - MARKET,2.37198781,USD 119.23,USD 282.79,USD,1.1839 2020-11-13T07:13:25.304525Z,AAPL,DIVIDEND,,,USD 0.36,USD,1.1804 2020-12-01T00:24:05.293275Z,,CUSTODY FEE,,,USD -0.01,USD,1.1940 2020-12-03T19:58:58.314837Z,,CASH WITHDRAWAL,,,USD -283.13,USD,1.2145 2020-12-03T20:11:17.516495Z,AAPL,SELL - MARKET,2.06461594,USD 123.06,USD 254.05,USD,1.2148 2020-12-07T08:37:25.768991Z,,CASH WITHDRAWAL,,,USD -254.04,USD,1.2099 2020-12-08T20:45:32.828867Z,ZM,SELL - MARKET,0.8230289,USD 410.74,USD 338.03,USD,1.2105 2020-12-10T08:04:34.598480Z,,CASH WITHDRAWAL,,,USD -338.04,USD,1.2091 ======================================================================================== FICHEIRO: dados_csv/maria/lucro-mensal.json Tamanho: 38309 bytes ======================================================================================== { "ok": true, "user": "maria", "moeda": "EUR", "compatibilidade": true, "totalmeses": 64, "investimentoinicial": 11.2, "series": [ { "mes": "2020-09", "ganhos": 0, "dividendos": 0, "taxas": 0.01, "net": -0.01, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0, "naorealizadofimmes": 0, "fimmesusado": "2020-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 502.14, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 502.14, "precofonte": "stooq" }, { "mes": "2020-10", "ganhos": 47.39, "dividendos": 0, "taxas": 0.01, "net": 47.38, "deltarealizado": 47.39, "deltanaorealizado": 0, "realizadoacumulado": 47.39, "naorealizadofimmes": 0, "fimmesusado": "2020-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 733.87, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 733.87, "precofonte": "stooq" }, { "mes": "2020-11", "ganhos": 7.04, "dividendos": 0.3, "taxas": 0, "net": 7.34, "deltarealizado": 7.04, "deltanaorealizado": 0, "realizadoacumulado": 54.43, "naorealizadofimmes": 0, "fimmesusado": "2020-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 733.87, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 733.87, "precofonte": "stooq" }, { "mes": "2020-12", "ganhos": -62, "dividendos": 0, "taxas": 0.01, "net": -62.01, "deltarealizado": -62, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2020-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2021-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2021-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2022-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2022-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2023-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2023-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-02-29", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2024-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": -7.57, "naorealizadofimmes": 0, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 0, "investimentoacumulado": 11.2, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 11.2, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 16:23:59", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: dados_csv/maria/movimentos-caixa.csv Tamanho: 91 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2026-05-15,Depósito,2000,EUR,Depósito, ======================================================================================== FICHEIRO: dados_csv/maria/transacoes-acoes.csv Tamanho: 182 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "6","2026-05-15","","INDEXNASDAQ:NDX","8.19672131","0","2000","","","","EUR" ======================================================================================== FICHEIRO: dados_csv/movimentos-caixa.csv Tamanho: 17894 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2019-10-13,Depósito,10.00,USD,CASH TOP-UP,1.1090 2,2020-01-22,Depósito,150.00,USD,CASH TOP-UP,1.1087 3,2020-01-27,Depósito,100.00,USD,CASH TOP-UP,1.1016 4,2020-01-27,Depósito,100.00,USD,CASH TOP-UP,1.1017 5,2020-02-04,Depósito,100.00,USD,CASH TOP-UP,1.1043 6,2020-02-06,Depósito,100.00,USD,CASH TOP-UP,1.0977 7,2020-02-12,Levantamento,-12.00,USD,CASH WITHDRAWAL,1.0883 8,2020-02-14,Dividendo,0.73,USD,AAPL DIVIDEND,1.0841 9,2020-02-14,Depósito,23.44,USD,CASH TOP-UP,1.0844 10,2020-02-19,Depósito,100.00,USD,CASH TOP-UP,1.0786 11,2020-02-19,Depósito,100.00,USD,CASH TOP-UP,1.0786 12,2020-02-25,Depósito,100.00,USD,CASH TOP-UP,1.0852 13,2020-02-27,Depósito,100.00,USD,CASH TOP-UP,1.0989 14,2020-02-29,Outros,-0.01,USD,CUSTODY FEE,1.1085 15,2020-03-10,Depósito,100.00,USD,CASH TOP-UP,1.1392 16,2020-03-10,Depósito,100.00,USD,CASH TOP-UP,1.1385 17,2020-03-25,Depósito,100.00,USD,CASH TOP-UP,1.0870 18,2020-03-31,Outros,-0.01,USD,CUSTODY FEE,1.1030 19,2020-04-16,Depósito,150.00,USD,CASH TOP-UP,1.0846 20,2020-04-23,Depósito,65.00,USD,CASH TOP-UP,1.0835 21,2020-04-27,Depósito,150.00,USD,CASH TOP-UP,1.0849 22,2020-04-29,Depósito,60.00,USD,CASH TOP-UP,1.0862 23,2020-04-30,Outros,-0.01,USD,CUSTODY FEE,1.0945 24,2020-05-01,Depósito,70.00,USD,CASH TOP-UP,1.1000 25,2020-05-11,Dividendo,0.20,USD,MA DIVIDEND,1.0849 26,2020-05-15,Dividendo,0.78,USD,AAPL DIVIDEND,1.0803 27,2020-05-15,Depósito,200.00,USD,CASH TOP-UP,1.0834 28,2020-05-21,Depósito,200.00,USD,CASH TOP-UP,1.0991 29,2020-05-27,Depósito,101.00,USD,CASH TOP-UP,1.0978 30,2020-05-31,Outros,-0.02,USD,CUSTODY FEE,1.1117 31,2020-06-01,Depósito,100.00,USD,CASH TOP-UP,1.1111 32,2020-06-03,Depósito,96.40,USD,CASH TOP-UP,1.1233 33,2020-06-04,Depósito,105.53,USD,CASH TOP-UP,1.1334 34,2020-06-04,Depósito,200.00,USD,CASH TOP-UP,1.1330 35,2020-06-05,Depósito,113.81,USD,CASH TOP-UP,1.1302 36,2020-06-08,Depósito,102.63,USD,CASH TOP-UP,1.1304 37,2020-06-09,Depósito,100.00,USD,CASH TOP-UP,1.1277 38,2020-06-15,Depósito,150.00,USD,CASH TOP-UP,1.1250 39,2020-06-16,Depósito,97.58,USD,CASH TOP-UP,1.1262 40,2020-06-18,Depósito,192.53,USD,CASH TOP-UP,1.1217 41,2020-06-26,Dividendo,1.37,USD,QCOM DIVIDEND,1.1215 42,2020-06-29,Dividendo,0.04,USD,NVDA DIVIDEND,1.1243 43,2020-06-30,Outros,-0.03,USD,CUSTODY FEE,1.1237 44,2020-07-17,Levantamento,-16.00,USD,CASH WITHDRAWAL,1.1414 45,2020-07-25,Depósito,150.00,USD,CASH TOP-UP,1.1714 46,2020-07-31,Outros,-0.03,USD,CUSTODY FEE,1.1837 47,2020-08-04,Levantamento,-16.50,USD,CASH WITHDRAWAL,1.1799 48,2020-08-06,Depósito,300.00,USD,CASH TOP-UP,1.1850 49,2020-08-10,Dividendo,0.20,USD,MA DIVIDEND,1.1794 50,2020-08-14,Dividendo,0.15,USD,AAPL DIVIDEND,1.1819 51,2020-08-31,Levantamento,-16.66,USD,CASH WITHDRAWAL,1.1915 52,2020-08-31,Outros,-0.02,USD,CUSTODY FEE,1.1940 53,2020-09-02,Depósito,200.00,USD,CASH TOP-UP,1.1844 54,2020-09-04,Levantamento,-200.00,USD,CASH WITHDRAWAL,1.1841 55,2020-09-04,Depósito,250.00,USD,CASH TOP-UP,1.1845 56,2020-09-04,Levantamento,-250.00,USD,CASH WITHDRAWAL,1.1846 57,2020-09-10,Depósito,250.00,USD,CASH TOP-UP,1.1832 58,2020-09-10,Levantamento,-250.00,USD,CASH WITHDRAWAL,1.1832 59,2020-09-11,Dividendo,0.32,USD,MSFT DIVIDEND,1.1840 60,2020-09-17,Levantamento,-370.20,USD,CASH WITHDRAWAL,1.1805 61,2020-09-24,Levantamento,-329.15,USD,CASH WITHDRAWAL,1.1653 62,2020-09-25,Dividendo,0.03,USD,NVDA DIVIDEND,1.1674 63,2020-09-25,Levantamento,-219.22,USD,CASH WITHDRAWAL,1.1668 64,2020-09-30,Outros,-0.03,USD,CUSTODY FEE,1.1730 65,2020-10-01,Levantamento,-16.40,USD,CASH WITHDRAWAL,1.1728 66,2020-10-02,Levantamento,-399.48,USD,CASH WITHDRAWAL,1.1719 67,2020-10-06,Levantamento,-272.23,USD,CASH WITHDRAWAL,1.1754 68,2020-10-15,Levantamento,-400.00,USD,CASH WITHDRAWAL,1.1708 69,2020-10-22,Levantamento,-680.00,USD,CASH WITHDRAWAL,1.1842 70,2020-10-22,Levantamento,-461.19,USD,CASH WITHDRAWAL,1.1819 71,2020-10-30,Depósito,230.00,USD,CASH TOP-UP,1.1655 72,2020-10-30,Levantamento,-230.00,USD,CASH WITHDRAWAL,1.1650 73,2020-11-01,Outros,-0.01,USD,CUSTODY FEE,1.1764 74,2020-11-02,Depósito,0.01,USD,CASH TOP-UP,1.1643 75,2020-11-17,Levantamento,-731.22,USD,CASH WITHDRAWAL,1.1861 76,2020-11-26,Depósito,64.15,USD,CASH TOP-UP,1.1908 77,2020-11-30,Depósito,600.00,USD,CASH TOP-UP,1.1997 78,2020-11-30,Levantamento,-664.15,USD,CASH WITHDRAWAL,1.1995 79,2020-11-30,Outros,-0.01,USD,CUSTODY FEE,1.1938 80,2020-12-01,Depósito,0.01,USD,CASH TOP-UP,1.2075 81,2020-12-03,Depósito,283.13,USD,CASH TOP-UP,1.2146 82,2020-12-07,Depósito,245.04,USD,CASH TOP-UP,1.2091 83,2020-12-07,Levantamento,-1417.49,USD,CASH WITHDRAWAL,1.2098 84,2020-12-08,Depósito,600.00,USD,CASH TOP-UP,1.2104 85,2020-12-10,Depósito,1045.98,USD,CASH TOP-UP,1.2095 86,2020-12-14,Depósito,873.84,USD,CASH TOP-UP,1.2148 87,2020-12-17,Depósito,1011.96,USD,CASH TOP-UP,1.2241 88,2020-12-21,Depósito,934.75,USD,CASH TOP-UP,1.2192 89,2020-12-23,Depósito,440.80,USD,CASH TOP-UP,1.2179 90,2020-12-23,Depósito,1218.96,USD,CASH TOP-UP,1.2194 91,2020-12-24,Depósito,14.23,USD,CASH TOP-UP,1.2184 92,2020-12-31,Depósito,500.00,USD,CASH TOP-UP,1.2276 93,2020-12-31,Levantamento,-64.98,USD,CASH WITHDRAWAL,1.2273 94,2021-01-01,Outros,-0.04,USD,CUSTODY FEE,1.2219 95,2021-01-08,Depósito,549.96,USD,CASH TOP-UP,1.2246 96,2021-01-08,Levantamento,-71.85,USD,CASH WITHDRAWAL,1.2234 97,2021-01-13,Depósito,576.16,USD,CASH TOP-UP,1.2198 98,2021-01-27,Depósito,136.83,USD,CASH TOP-UP,1.2080 99,2021-01-27,Depósito,470.71,USD,CASH TOP-UP,1.2077 100,2021-01-28,Depósito,1373.27,USD,CASH TOP-UP,1.2089 101,2021-02-01,Outros,-0.09,USD,CUSTODY FEE,1.2133 102,2021-02-01,Depósito,196.46,USD,CASH TOP-UP,1.2067 103,2021-02-04,Levantamento,-32.26,USD,CASH WITHDRAWAL,1.1962 104,2021-02-09,Levantamento,-500.00,USD,CASH WITHDRAWAL,1.2121 105,2021-02-12,Dividendo,3.31,USD,AAPL DIVIDEND,1.2126 106,2021-02-19,Levantamento,-41.90,USD,CASH WITHDRAWAL,1.2129 107,2021-03-01,Outros,-0.08,USD,CUSTODY FEE,1.2090 108,2021-03-02,Depósito,0.08,USD,CASH TOP-UP,1.2091 109,2021-03-12,Depósito,178.93,USD,CASH TOP-UP,1.1937 110,2021-04-01,Outros,-0.97,USD,CUSTODY FEE,1.1737 111,2021-05-01,Outros,-1.07,USD,CUSTODY FEE,1.2142 112,2021-05-14,Dividendo,3.55,USD,AAPL DIVIDEND,1.2089 113,2021-05-24,Depósito,50.00,USD,CASH TOP-UP,1.2213 114,2021-05-27,Depósito,50.00,USD,CASH TOP-UP,1.2193 115,2021-05-27,Depósito,10.00,USD,CASH TOP-UP,1.2195 116,2021-06-01,Outros,-1.03,USD,CUSTODY FEE,1.2229 117,2021-07-01,Outros,-1.02,USD,CUSTODY FEE,1.1855 118,2021-07-14,Levantamento,-63.73,USD,CASH WITHDRAWAL,1.1839 119,2021-07-27,Levantamento,-250.00,USD,CASH WITHDRAWAL,1.1793 120,2021-08-01,Outros,-1.12,USD,CUSTODY FEE,1.1999 121,2021-08-13,Dividendo,2.62,USD,AAPL DIVIDEND,1.1742 122,2021-09-01,Outros,-1.15,USD,CUSTODY FEE,1.1800 123,2021-10-01,Outros,-1.11,USD,CUSTODY FEE,1.1580 124,2021-10-01,Levantamento,-50.00,USD,CASH WITHDRAWAL,1.1582 125,2021-10-25,Levantamento,-78.27,USD,CASH WITHDRAWAL,1.1616 126,2021-10-29,Levantamento,-50.00,USD,CASH WITHDRAWAL,1.1652 127,2021-11-01,Levantamento,-100.00,USD,CASH WITHDRAWAL,1.1609 128,2021-11-04,Levantamento,-2000.00,USD,CASH WITHDRAWAL,1.1613 129,2021-11-04,Outros,-1.07,USD,CUSTODY FEE,1.1603 130,2021-11-04,Depósito,2000.00,USD,CASH TOP-UP,1.1586 131,2021-11-17,Dividendo,6.17,USD,AAPL DIVIDEND,1.1305 132,2021-11-19,Levantamento,-150.00,USD,CASH WITHDRAWAL,1.1292 133,2021-11-22,Levantamento,-153.20,USD,CASH WITHDRAWAL,1.1287 134,2021-12-02,Outros,-1.07,USD,CUSTODY FEE,1.1325 135,2021-12-02,Levantamento,-300.00,USD,CASH WITHDRAWAL,1.1325 136,2021-12-02,Depósito,100.00,USD,CASH TOP-UP,1.1324 137,2021-12-06,Depósito,50.00,USD,CASH TOP-UP,1.1293 138,2021-12-10,Levantamento,-26.65,USD,CASH WITHDRAWAL,1.1319 139,2021-12-14,Levantamento,-150.00,USD,CASH WITHDRAWAL,1.1279 140,2021-12-17,Dividendo,3.57,USD,KO DIVIDEND,1.1323 141,2021-12-21,Depósito,550.00,USD,CASH TOP-UP,1.1288 142,2021-12-25,Depósito,100.00,USD,CASH TOP-UP,1.1315 143,2022-01-04,Dividendo,1.78,USD,BAC DIVIDEND,1.1307 144,2022-01-04,Outros,-1.16,USD,CUSTODY FEE,1.1303 145,2022-02-02,Outros,-1.22,USD,CUSTODY FEE,1.1324 146,2022-02-15,Dividendo,6.17,USD,AAPL DIVIDEND,1.1320 147,2022-02-28,Depósito,250.00,USD,CASH TOP-UP,1.1198 148,2022-03-02,Outros,-1.16,USD,CUSTODY FEE,1.1104 149,2022-03-16,Dividendo,0.42,USD,O DIVIDEND,1.0978 150,2022-03-25,Levantamento,-257.83,USD,CASH WITHDRAWAL,1.1004 151,2022-03-28,Dividendo,1.78,USD,BAC DIVIDEND,1.0955 152,2022-04-02,Outros,-1.24,USD,CUSTODY FEE,1.1051 153,2022-04-04,Dividendo,0.75,USD,KO DIVIDEND,1.1051 154,2022-04-14,Depósito,200.00,USD,CASH TOP-UP,1.0905 155,2022-04-19,Dividendo,0.42,USD,O DIVIDEND,1.0772 156,2022-05-03,Outros,-1.11,USD,CUSTODY FEE,1.0519 157,2022-05-16,Dividendo,0.42,USD,O DIVIDEND,1.0410 158,2022-05-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0407 159,2022-05-20,Depósito,150.00,USD,CASH TOP-UP,1.0562 160,2022-06-02,Outros,-1.05,USD,CUSTODY FEE,1.0657 161,2022-06-07,Depósito,10.00,USD,CASH TOP-UP,1.0702 162,2022-06-10,Dividendo,0.33,USD,MSFT DIVIDEND,1.0635 163,2022-06-16,Dividendo,0.42,USD,O DIVIDEND,1.0441 164,2022-06-27,Dividendo,1.78,USD,BAC DIVIDEND,1.0571 165,2022-07-02,Outros,-0.96,USD,CUSTODY FEE,1.0432 166,2022-07-05,Dividendo,0.75,USD,KO DIVIDEND,1.0442 167,2022-07-18,Dividendo,0.42,USD,O DIVIDEND,1.0105 168,2022-07-29,Depósito,150.00,USD,CASH TOP-UP,1.0209 169,2022-08-02,Outros,-1.13,USD,CUSTODY FEE,1.0210 170,2022-08-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0171 171,2022-08-16,Dividendo,0.42,USD,O DIVIDEND,1.0165 172,2022-09-03,Outros,-1.08,USD,CUSTODY FEE,0.9961 173,2022-09-12,Dividendo,0.33,USD,MSFT DIVIDEND,1.0096 174,2022-09-16,Dividendo,0.42,USD,O DIVIDEND,0.9995 175,2022-10-03,Dividendo,1.87,USD,BAC DIVIDEND,0.9807 176,2022-10-04,Outros,-1.00,USD,CUSTODY FEE,0.9841 177,2022-10-04,Dividendo,0.75,USD,KO DIVIDEND,0.9861 178,2022-10-17,Dividendo,0.42,USD,O DIVIDEND,0.9748 179,2022-11-02,Outros,-1.00,USD,CUSTODY FEE,0.9906 180,2022-11-11,Dividendo,7.04,USD,AAPL DIVIDEND,1.0271 181,2022-11-16,Dividendo,0.42,USD,O DIVIDEND,1.0383 182,2022-12-02,Outros,-0.97,USD,CUSTODY FEE,1.0532 183,2022-12-09,Dividendo,0.36,USD,MSFT DIVIDEND,1.0582 184,2022-12-16,Dividendo,0.75,USD,KO DIVIDEND,1.0667 185,2022-12-16,Dividendo,0.42,USD,O DIVIDEND,1.0662 186,2023-01-03,Dividendo,1.87,USD,BAC DIVIDEND,1.0672 187,2023-01-04,Outros,-0.84,USD,CUSTODY FEE,1.0625 188,2023-01-17,Dividendo,0.35,USD,O DIVIDEND,1.0831 189,2023-02-01,Outros,-0.95,USD,CUSTODY FEE,1.0871 190,2023-02-16,Dividendo,0.35,USD,O DIVIDEND,1.0707 191,2023-02-17,Dividendo,6.12,USD,AAPL DIVIDEND,1.0641 192,2023-03-01,Depósito,250.00,USD,CASH TOP-UP,1.0669 193,2023-03-02,Outros,-1.00,USD,CUSTODY FEE,1.0636 194,2023-03-13,Dividendo,0.29,USD,MSFT DIVIDEND,1.0731 195,2023-03-16,Dividendo,0.36,USD,O DIVIDEND,1.0618 196,2023-04-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0809 197,2023-04-04,Dividendo,0.64,USD,KO DIVIDEND,1.0919 198,2023-04-04,Outros,-1.08,USD,CUSTODY FEE,1.0941 199,2023-04-17,Dividendo,0.36,USD,O DIVIDEND,1.1000 200,2023-05-02,Outros,-1.07,USD,CUSTODY FEE,1.1010 201,2023-05-08,Depósito,150.00,USD,CASH TOP-UP,1.1037 202,2023-05-16,Dividendo,0.36,USD,O DIVIDEND,1.0890 203,2023-05-19,Dividendo,5.71,USD,AAPL DIVIDEND,1.0800 204,2023-06-02,Outros,-1.13,USD,CUSTODY FEE,1.0788 205,2023-06-05,Depósito,100.00,USD,CASH TOP-UP,1.0703 206,2023-06-06,Levantamento,-200.00,USD,CASH WITHDRAWAL,1.0725 207,2023-06-09,Dividendo,0.29,USD,MSFT DIVIDEND,1.0787 208,2023-06-16,Dividendo,0.36,USD,O DIVIDEND,1.0954 209,2023-07-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0929 210,2023-07-04,Outros,-1.19,USD,CUSTODY FEE,1.0914 211,2023-07-05,Dividendo,0.64,USD,KO DIVIDEND,1.0888 212,2023-07-17,Dividendo,0.36,USD,O DIVIDEND,1.1239 213,2023-08-02,Outros,-1.31,USD,CUSTODY FEE,1.0994 214,2023-08-16,Dividendo,0.36,USD,O DIVIDEND,1.0928 215,2023-08-18,Dividendo,4.03,USD,AAPL DIVIDEND,1.0901 216,2023-09-02,Outros,-1.27,USD,CUSTODY FEE,1.0790 217,2023-09-09,Outros,117.44,USD,TRANSFER FROM REVOLUT BANK UAB TO REVOLUT SECURITIES EUROPE UAB,1.0719 218,2023-09-13,Depósito,11.76,USD,CASH TOP-UP,1.0756 219,2023-09-13,Depósito,400.00,USD,CASH TOP-UP,1.0757 220,2023-09-18,Dividendo,0.36,USD,O DIVIDEND,1.0686 221,2023-10-01,Outros,-1.25,USD,CUSTODY FEE,1.0595 222,2023-10-02,Dividendo,1.68,USD,BAC DIVIDEND,1.0550 223,2023-10-03,Dividendo,0.78,USD,KO DIVIDEND,1.0488 224,2023-10-16,Dividendo,0.43,USD,O DIVIDEND,1.0557 225,2023-11-02,Outros,-1.17,USD,CUSTODY FEE,1.0617 226,2023-11-16,Dividendo,0.43,USD,O DIVIDEND,1.0863 227,2023-11-17,Dividendo,5.51,USD,AAPL DIVIDEND,1.0913 228,2023-12-01,Outros,-1.19,USD,CUSTODY FEE,1.0922 229,2023-12-14,Levantamento,-490.00,USD,CASH WITHDRAWAL,1.0942 230,2023-12-14,Levantamento,-540.00,USD,CASH WITHDRAWAL,1.0945 231,2023-12-14,Depósito,493.36,EUR,CASH TOP-UP,1.0000 232,2023-12-14,Depósito,22.55,EUR,CASH TOP-UP,1.0000 233,2023-12-14,Levantamento,-22.55,EUR,CASH WITHDRAWAL,1.0000 234,2023-12-18,Dividendo,0.43,USD,O DIVIDEND,1.0945 235,2023-12-18,Dividendo,0.78,USD,KO DIVIDEND,1.0937 236,2024-01-01,Outros,-1.18,USD,CUSTODY FEE,1.1060 237,2024-01-01,Outros,-0.05,EUR,CUSTODY FEE,1.0000 238,2024-01-03,Dividendo,2.04,USD,BAC DIVIDEND,1.0927 239,2024-01-16,Dividendo,0.43,USD,O DIVIDEND,1.0909 240,2024-01-29,Levantamento,-288.99,USD,CASH WITHDRAWAL,1.0829 241,2024-02-01,Outros,-1.10,USD,CUSTODY FEE,1.0837 242,2024-02-01,Outros,-0.05,EUR,CUSTODY FEE,1.0000 243,2024-02-13,Levantamento,-755.30,USD,CASH WITHDRAWAL,1.0737 244,2024-02-16,Dividendo,0.43,USD,O DIVIDEND,1.0796 245,2024-02-16,Dividendo,5.30,USD,AAPL DIVIDEND,1.0789 246,2024-03-11,Depósito,1091.80,USD,CASH TOP-UP,1.0964 247,2024-03-11,Depósito,126.74,USD,CASH TOP-UP,1.0941 248,2024-03-15,Dividendo,0.64,USD,MSFT DIVIDEND,1.0914 249,2024-03-18,Dividendo,0.43,USD,O DIVIDEND,1.0912 250,2024-03-28,Dividendo,0.17,USD,NVDA DIVIDEND,1.0831 251,2024-04-02,Dividendo,0.82,USD,KO DIVIDEND,1.0788 252,2024-04-02,Dividendo,2.04,USD,BAC DIVIDEND,1.0789 253,2024-04-16,Dividendo,0.43,USD,O DIVIDEND,1.0668 254,2024-04-22,Levantamento,-720.00,USD,CASH WITHDRAWAL,1.0653 255,2024-04-22,Depósito,675.75,EUR,CASH TOP-UP,1.0000 256,2024-04-30,Levantamento,-398.79,USD,CASH WITHDRAWAL,1.0728 257,2024-05-16,Dividendo,0.43,USD,O DIVIDEND,1.0895 258,2024-05-17,Dividendo,6.16,USD,AAPL DIVIDEND,1.0867 259,2024-06-14,Dividendo,0.64,USD,MSFT DIVIDEND,1.0709 260,2024-06-17,Dividendo,0.44,USD,O DIVIDEND,1.0728 261,2024-07-01,Dividendo,0.42,USD,NVDA DIVIDEND,1.0772 262,2024-07-01,Dividendo,2.04,USD,BAC DIVIDEND,1.0768 263,2024-07-16,Dividendo,0.44,USD,O DIVIDEND,1.0923 264,2024-07-23,Depósito,800.00,EUR,CASH TOP-UP,1.0000 265,2024-08-01,Depósito,1077.48,USD,CASH TOP-UP,1.0809 266,2024-08-16,Dividendo,6.59,USD,AAPL DIVIDEND,1.1011 267,2024-10-04,Dividendo,0.42,USD,NVDA DIVIDEND,1.1053 268,2024-10-10,Dividendo,4.93,USD,TSM DIVIDEND,1.0958 269,2024-11-06,Depósito,34.98,USD,CASH TOP-UP,1.0750 270,2024-11-06,Levantamento,-34.98,USD,CASH WITHDRAWAL,1.0748 271,2024-11-15,Dividendo,9.99,USD,AAPL DIVIDEND,1.0596 272,2024-11-25,Depósito,1004.00,USD,CASH TOP-UP,1.0525 273,2024-11-29,Levantamento,-2000.00,USD,CASH WITHDRAWAL,1.0574 274,2024-12-18,Dividendo,0.51,EUR,EXXT DIVIDEND,1.0000 275,2024-12-18,Depósito,2006.76,USD,CASH TOP-UP,1.0513 276,2024-12-18,Levantamento,-2240.70,USD,CASH WITHDRAWAL,1.0514 277,2024-12-18,Depósito,2133.85,EUR,CASH TOP-UP,1.0000 278,2024-12-19,Depósito,0.02,USD,CASH TOP-UP,1.0415 279,2024-12-30,Dividendo,0.41,USD,NVDA DIVIDEND,1.0464 280,2025-01-07,Levantamento,-3000.00,USD,CASH WITHDRAWAL,1.0449 281,2025-01-07,Depósito,3001.30,USD,CASH TOP-UP,1.0396 282,2025-01-28,Depósito,245.00,USD,CASH TOP-UP,1.0451 283,2025-02-14,Dividendo,8.08,USD,AAPL DIVIDEND,1.0521 284,2025-03-19,Dividendo,1.67,EUR,EXXT DIVIDEND,1.0000 285,2025-04-03,Dividendo,0.43,USD,NVDA DIVIDEND,1.1083 286,2025-05-16,Dividendo,8.40,USD,AAPL DIVIDEND,1.1172 287,2025-05-29,Levantamento,-2818.20,USD,CASH WITHDRAWAL,1.1398 288,2025-06-18,Dividendo,3.70,EUR,EXXT DIVIDEND,1.0000 289,2025-07-02,Depósito,2000.00,USD,CASH TOP-UP,1.1797 290,2025-07-10,Dividendo,0.26,USD,NVDA DIVIDEND,1.1761 291,2025-08-14,Dividendo,7.74,USD,AAPL DIVIDEND,1.1674 292,2025-08-20,Levantamento,-764.31,USD,CASH WITHDRAWAL,1.1692 293,2025-10-02,Dividendo,0.37,USD,NVDA DIVIDEND,1.1750 294,2025-10-16,Depósito,1502.57,USD,CASH TOP-UP,1.1685 295,2025-11-11,Depósito,500.00,USD,CASH TOP-UP,1.1619 296,2025-11-11,Levantamento,-175.00,USD,CASH WITHDRAWAL,1.1618 297,2025-11-13,Dividendo,7.74,USD,AAPL DIVIDEND,1.16584 270,2024-10-10,Dividendo,4.93,USD,TSM DIVIDEND,1.0958 271,2024-11-06,Depósito,34.98,USD,CASH TOP-UP,1.0750 272,2024-11-06,Levantamento,-34.98,USD,CASH WITHDRAWAL,1.0748 273,2024-11-15,Dividendo,9.99,USD,AAPL DIVIDEND,1.0596 274,2024-11-25,Depósito,1004.00,USD,CASH TOP-UP,1.0525 275,2024-11-29,Levantamento,-2000.00,USD,CASH WITHDRAWAL,1.0574 276,2024-12-18,Depósito,2006.76,USD,CASH TOP-UP,1.0513 277,2024-12-18,Levantamento,-2240.70,USD,CASH WITHDRAWAL,1.0514 278,2024-12-19,Depósito,0.02,USD,CASH TOP-UP,1.0415 279,2024-12-30,Dividendo,0.41,USD,NVDA DIVIDEND,1.0464 280,2025-01-07,Levantamento,-3000.00,USD,CASH WITHDRAWAL,1.0449 281,2025-01-07,Depósito,3001.30,USD,CASH TOP-UP,1.0396 282,2025-01-28,Depósito,245.00,USD,CASH TOP-UP,1.0451 283,2025-02-14,Dividendo,8.08,USD,AAPL DIVIDEND,1.0521 284,2025-04-03,Dividendo,0.43,USD,NVDA DIVIDEND,1.1083 285,2025-05-16,Dividendo,8.40,USD,AAPL DIVIDEND,1.1172 286,2025-05-29,Levantamento,-2818.20,USD,CASH WITHDRAWAL,1.1398 287,2025-07-02,Depósito,2000.00,USD,CASH TOP-UP,1.1797 288,2025-07-10,Dividendo,0.26,USD,NVDA DIVIDEND,1.1761 289,2025-08-14,Dividendo,7.74,USD,AAPL DIVIDEND,1.1674 290,2025-08-20,Levantamento,-764.31,USD,CASH WITHDRAWAL,1.1692 291,2025-10-02,Dividendo,0.37,USD,NVDA DIVIDEND,1.1750 292,2025-10-16,Depósito,1502.57,USD,CASH TOP-UP,1.1685 293,2025-11-11,Depósito,500.00,USD,CASH TOP-UP,1.1619 294,2025-11-11,Levantamento,-175.00,USD,CASH WITHDRAWAL,1.1618 295,2025-11-13,Dividendo,7.74,USD,AAPL DIVIDEND,1.1658 ======================================================================================== FICHEIRO: dados_csv/precos-atuais.json Tamanho: 2046 bytes ======================================================================================== { "precos": { "AAPL": { "preco": 291.079987, "moeda": "USD", "timestamp": "2026-06-14 00:15:13", "fonte": "twelve:AAPL", "prevclose": 295.63, "close": 295.63, "pctdia": -1.5391 }, "NVDA": { "preco": 205.13, "moeda": "USD", "timestamp": "2026-06-14 00:15:13", "fonte": "twelve:NVDA", "prevclose": 204.87, "close": 204.87, "pctdia": 0.1269 }, "GOOGL": { "preco": 359.67001, "moeda": "USD", "timestamp": "2026-06-14 00:15:13", "fonte": "twelve:GOOGL", "prevclose": 357.76999, "close": 357.76999, "pctdia": 0.5311 }, "VUSA": { "preco": 0, "moeda": "EUR", "timestamp": "2026-06-14 00:15:13", "fonte": "indisponivel", "prevclose": null, "close": null, "pctdia": null }, "IWDA": { "preco": 0, "moeda": "EUR", "timestamp": "2026-06-14 00:15:13", "fonte": "indisponivel", "prevclose": null, "close": null, "pctdia": null }, "NDXEX": { "preco": 0, "moeda": "EUR", "timestamp": "2026-06-14 00:15:13", "fonte": "indisponivel", "prevclose": null, "close": null, "pctdia": null }, "XAUEUR": { "preco": 0, "moeda": "EUR", "timestamp": "2026-06-14 00:15:13", "fonte": "indisponivel", "prevclose": null, "close": null, "pctdia": null } }, "cambio": { "EURUSD": 1.16, "USDEUR": 0.8621, "fonte": "calculos.php?acao=cambio_atual", "timestamp": "2026-06-14 00:15:13" }, "ultima_atualizacao": "2026-06-14 00:15:13" } ======================================================================================== FICHEIRO: dados_csv/prevclose-cache.json Tamanho: 3242 bytes ======================================================================================== { "2025-12-13": { "eodhd:EUNL.XETRA": { "prevclose": 110.98, "moeda": null, "fonte": "eodhd", "cached_at": "2025-12-13 00:02:27" }, "twelveAAPL": { "prevclose": 278.029999, "moeda": "USD", "fonte": "twelvedata", "cached_at": "2025-12-13 00:02:27" }, "eodhd:EXXT.XETRA": { "prevclose": 214, "moeda": null, "fonte": "eodhd", "cached_at": "2025-12-13 00:02:28" }, "twelveNVDA": { "prevclose": 180.92999, "moeda": "USD", "fonte": "twelvedata", "cached_at": "2025-12-13 00:02:28" }, "twelveGOOGL": { "prevclose": 312.42999, "moeda": "USD", "fonte": "twelvedata", "cached_at": "2025-12-13 00:02:28" }, "eodhd:VUSA.AS": { "prevclose": 110.916, "moeda": null, "fonte": "eodhd", "cached_at": "2025-12-13 00:02:29" }, "IWDA": { "prev_close": 110.98, "fonte": "stooq:eunl.de", "moeda": null, "cached_at": "2025-12-13 23:15:52" }, "AAPL": { "prev_close": 278.029999, "fonte": "twelveAAPL", "moeda": "USD", "cached_at": "2025-12-13 23:15:52" }, "NDXEX": { "prev_close": 210.9, "fonte": "stooq:exxt.de", "moeda": null, "cached_at": "2025-12-13 23:15:53" }, "NVDA": { "prev_close": 180.92999, "fonte": "twelveNVDA", "moeda": "USD", "cached_at": "2025-12-13 23:15:53" }, "GOOGL": { "prev_close": 312.42999, "fonte": "twelveGOOGL", "moeda": "USD", "cached_at": "2025-12-13 23:15:53" }, "VUSA": { "prev_close": 110.915, "fonte": "stooq:vusa.de", "moeda": null, "cached_at": "2025-12-13 23:15:55" } }, "2025-12-14": { "IWDA": { "prev_close": 110.98, "fonte": "stooq:eunl.de", "moeda": null, "cached_at": "2025-12-14 00:02:46" }, "AAPL": { "prev_close": 278.029999, "fonte": "twelveAAPL", "moeda": "USD", "cached_at": "2025-12-14 00:02:46" }, "NDXEX": { "prev_close": 210.9, "fonte": "stooq:exxt.de", "moeda": null, "cached_at": "2025-12-14 00:02:47" }, "NVDA": { "prev_close": 180.92999, "fonte": "twelveNVDA", "moeda": "USD", "cached_at": "2025-12-14 00:02:48" }, "GOOGL": { "prev_close": 312.42999, "fonte": "twelveGOOGL", "moeda": "USD", "cached_at": "2025-12-14 00:02:48" }, "VUSA": { "prev_close": 110.915, "fonte": "stooq:vusa.de", "moeda": null, "cached_at": "2025-12-14 00:02:49" } } } ======================================================================================== FICHEIRO: dados_csv/tiago/extrato-revolut.csv Tamanho: 59378 bytes ======================================================================================== Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate 2019-10-13T20:45:52.089581Z,,CASH TOP-UP,,,USD 10,USD,1.1090 2019-10-15T15:04:56.402300Z,GOOGL,BUY - MARKET,0.00808315,USD 1237.14,USD 10,USD,1.1041 2019-10-16T16:40:49.118522Z,GOOGL,SELL - MARKET,0.00808315,USD 1244.56,USD 10.05,USD,1.1083 2019-10-16T16:42:15.845933Z,AMZN,BUY - MARKET,0.0056605,USD 1775.46,USD 10.05,USD,1.1083 2020-01-22T06:14:35.117802Z,,CASH TOP-UP,,,USD 150,USD,1.1087 2020-01-22T14:35:09.489834Z,AAPL,BUY - MARKET,0.47175745,USD 317.96,USD 150,USD,1.1087 2020-01-27T19:03:34.378166Z,,CASH TOP-UP,,,USD 100,USD,1.1016 2020-01-27T19:03:59.925033Z,AAPL,BUY - MARKET,0.32237266,USD 310.20,USD 100,USD,1.1017 2020-01-27T19:06:24.636699Z,,CASH TOP-UP,,,USD 100,USD,1.1017 2020-01-27T19:06:44.350393Z,AAPL,BUY - MARKET,0.32203007,USD 310.53,USD 100,USD,1.1016 2020-02-04T18:52:14.721865Z,,CASH TOP-UP,,,USD 100,USD,1.1043 2020-02-04T18:53:01.732348Z,ADBE,BUY - MARKET,0.27270991,USD 366.69,USD 100,USD,1.1044 2020-02-06T16:55:04.812084Z,,CASH TOP-UP,,,USD 100,USD,1.0977 2020-02-06T16:55:36.979717Z,TSLA,BUY - MARKET,0.12870012,USD 777,USD 100,USD,1.0977 2020-02-10T17:27:50.154414Z,AMZN,SELL - MARKET,0.0056605,USD 2121.72,USD 12,USD,1.0918 2020-02-12T17:19:39.458866Z,,CASH WITHDRAWAL,,,USD -12,USD,1.0883 2020-02-14T06:27:43.976551Z,AAPL,DIVIDEND,,,USD 0.73,USD,1.0841 2020-02-14T16:15:09.890489Z,,CASH TOP-UP,,,USD 23.44,USD,1.0844 2020-02-19T15:25:37.972712Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:27:08.446046Z,TSLA,BUY - MARKET,0.13183279,USD 933,USD 124.07,USD,1.0788 2020-02-19T15:31:20.268338Z,,CASH TOP-UP,,,USD 100,USD,1.0786 2020-02-19T15:32:09.673339Z,MA,BUY - MARKET,0.28609409,USD 346.04,USD 100.07,USD,1.0787 2020-02-25T15:34:40.463966Z,,CASH TOP-UP,,,USD 100,USD,1.0852 2020-02-25T15:35:27.862543Z,MA,BUY - MARKET,0.31256977,USD 313.53,USD 99.08,USD,1.0854 2020-02-27T15:58:29.203288Z,,CASH TOP-UP,,,USD 100,USD,1.0989 2020-02-27T15:59:44.008442Z,AMZN,BUY - MARKET,0.05144915,USD 1924.23,USD 100.09,USD,1.0988 2020-02-29T23:14:40.446417Z,,CUSTODY FEE,,,USD -0.01,USD,1.1085 2020-03-10T08:36:25.622472Z,,CASH TOP-UP,,,USD 100,USD,1.1392 2020-03-10T08:43:28.760520Z,,CASH TOP-UP,,,USD 100,USD,1.1385 2020-03-16T15:06:33.044184Z,AAPL,BUY - MARKET,0.39257252,USD 254.73,USD 100,USD,1.1116 2020-03-19T14:18:51.824712Z,AMZN,BUY - MARKET,0.05281643,USD 1893.35,USD 100,USD,1.0791 2020-03-25T19:00:13.188887Z,,CASH TOP-UP,,,USD 100,USD,1.0870 2020-03-25T19:00:56.745398Z,TSLA,BUY - MARKET,0.18182479,USD 549.98,USD 100,USD,1.0875 2020-03-31T23:13:57.154290Z,,CUSTODY FEE,,,USD -0.01,USD,1.1030 2020-04-13T13:44:26.856924Z,AMZN,SELL - MARKET,0.0581643,USD 2068.97,USD 120.33,USD,1.0908 2020-04-14T13:46:27.827041Z,AMZN,SELL - MARKET,0.04610128,USD 2222.06,USD 102.43,USD,1.0963 2020-04-14T13:49:54.123864Z,TSLA,SELL - MARKET,0.18182479,USD 734.50,USD 133.54,USD,1.0962 2020-04-14T13:57:12.990070Z,NFLX,BUY - MARKET,0.25100401,USD 398.40,USD 101.09,USD,1.0962 2020-04-15T13:35:34.237135Z,TSLA,BUY - MARKET,0.13523381,USD 739.46,USD 101.08,USD,1.0879 2020-04-16T13:50:19.111529Z,NFLX,BUY - MARKET,0.22745365,USD 439.65,USD 101.08,USD,1.0879 2020-04-16T15:14:00.808432Z,,CASH TOP-UP,,,USD 150,USD,1.0846 2020-04-16T15:14:35.050777Z,AMZN,BUY - MARKET,0.08295313,USD 2411,USD 201.08,USD,1.0845 2020-04-23T14:28:19.106924Z,,CASH TOP-UP,,,USD 65,USD,1.0835 2020-04-27T13:48:51.812918Z,,CASH TOP-UP,,,USD 150,USD,1.0849 2020-04-27T13:49:44.983233Z,GOOGL,BUY - MARKET,0.15638072,USD 1278.93,USD 201.08,USD,1.0850 2020-04-29T13:25:29.598577Z,,CASH TOP-UP,,,USD 60,USD,1.0862 2020-04-30T15:20:09.164358Z,TSLA,SELL - MARKET,0.13523381,USD 841.36,USD 112.69,USD,1.0945 2020-04-30T23:18:53.565423Z,,CUSTODY FEE,,,USD -0.01,USD,1.0945 2020-05-01T15:48:15.829872Z,TSLA,BUY - MARKET,0.21263626,USD 705.43,USD 151.09,USD,1.1000 2020-05-01T15:48:47.039832Z,,CASH TOP-UP,,,USD 70,USD,1.1000 2020-05-01T15:49:20.695234Z,AMZN,BUY - MARKET,0.04362354,USD 2292.34,USD 101.09,USD,1.1002 2020-05-05T15:31:50.521509Z,AAPL,SELL - MARKET,0.39257252,USD 298.65,USD 117.23,USD,1.0845 2020-05-06T19:08:08.304224Z,TSLA,SELL - MARKET,0.21263626,USD 785.52,USD 167.02,USD,1.0807 2020-05-07T13:31:53.906481Z,MCD,BUY - MARKET,1.11594688,USD 179.22,USD 200,USD,1.0787 2020-05-11T04:29:40.915073Z,MA,DIVIDEND,,,USD 0.20,USD,1.0849 2020-05-11T15:45:23.256201Z,GOOGL,SELL - MARKET,0.15638072,USD 1397.42,USD 217.44,USD,1.0812 2020-05-11T15:57:35.550473Z,AMD,BUY - MARKET,1.80733779,USD 55.33,USD 101.08,USD,1.0815 2020-05-12T16:07:48.403062Z,NFLX,SELL - MARKET,0.25100401,USD 443.18,USD 110.15,USD,1.0866 2020-05-12T19:51:54.916962Z,MA,BUY - MARKET,0.36659579,USD 272.78,USD 101.08,USD,1.0852 2020-05-14T13:39:16.072650Z,GOOGL,BUY - MARKET,0.14908017,USD 1341.56,USD 201.07,USD,1.0794 2020-05-15T06:45:31.771097Z,AAPL,DIVIDEND,,,USD 0.78,USD,1.0803 2020-05-15T14:21:14.417945Z,,CASH TOP-UP,,,USD 200,USD,1.0834 2020-05-15T14:21:43.642288Z,XYZ,BUY - MARKET,2.54097319,USD 78.71,USD 201.08,USD,1.0834 2020-05-20T15:35:46.301014Z,MA,SELL - MARKET,0.36659579,USD 300.47,USD 109.05,USD,1.0994 2020-05-20T15:42:40.689961Z,NVDA,BUY - MARKET,0.34223706,USD 359.40,USD 124.09,USD,1.0989 2020-05-21T11:09:05.866676Z,,CASH TOP-UP,,,USD 200,USD,1.0991 2020-05-21T13:33:35.686825Z,KO,BUY - MARKET,4.34023991,USD 45.85,USD 200.09,USD,1.0984 2020-05-27T15:15:48.029062Z,,CASH TOP-UP,,,USD 101,USD,1.0978 2020-05-27T15:15:56.832046Z,ANSS,BUY - MARKET,0.38406882,USD 260.37,USD 101.09,USD,1.0979 2020-05-28T14:46:13.432873Z,MCD,SELL - MARKET,1.11594688,USD 188.74,USD 209.51,USD,1.1054 2020-05-28T14:46:46.563846Z,QCOM,BUY - MARKET,2.4789291,USD 80.68,USD 201.10,USD,1.1055 2020-05-29T16:04:45.366029Z,XYZ,SELL - MARKET,2.54097319,USD 81.15,USD 205.08,USD,1.1105 2020-05-29T16:07:02.985866Z,MSFT,BUY - MARKET,1.15486141,USD 181.84,USD 211.11,USD,1.1104 2020-05-29T19:26:29.477576Z,ADBE,SELL - MARKET,0.27270991,USD 385.61,USD 104.05,USD,1.1095 2020-05-31T23:19:05.143061Z,,CUSTODY FEE,,,USD -0.02,USD,1.1117 2020-06-01T13:02:55.670900Z,,CASH TOP-UP,,,USD 100,USD,1.1111 2020-06-01T13:42:34.671146Z,UAL,BUY - MARKET,6.8212824,USD 29.32,USD 201.11,USD,1.1117 2020-06-01T16:16:43.298913Z,TSLA,SELL - MARKET,0.12870012,USD 879.56,USD 112.08,USD,1.1131 2020-06-03T14:08:52.405659Z,ANSS,SELL - MARKET,0.38406882,USD 290.47,USD 111.55,USD,1.1224 2020-06-03T14:09:18.216215Z,UAL,BUY - MARKET,7.12250712,USD 31.59,USD 225,USD,1.1218 2020-06-03T15:40:53.775341Z,GOOGL,SELL - MARKET,0.14908017,USD 1435.47,USD 213.99,USD,1.1248 2020-06-03T15:41:39.067184Z,UAL,BUY - MARKET,6.44484412,USD 33.36,USD 216.12,USD,1.1248 2020-06-03T22:53:07.567360Z,,CASH TOP-UP,,,USD 96.40,USD,1.1233 2020-06-04T13:38:22.083446Z,UAL,BUY - MARKET,2.69444444,USD 36,USD 98.12,USD,1.1261 2020-06-04T14:52:37.932806Z,,CASH TOP-UP,,,USD 105.53,USD,1.1334 2020-06-04T14:53:08.914462Z,UAL,BUY - MARKET,2.78884462,USD 37.65,USD 106.13,USD,1.1334 2020-06-04T15:23:45.056331Z,,CASH TOP-UP,,,USD 200,USD,1.1330 2020-06-04T15:24:10.360661Z,UAL,BUY - MARKET,5.20231213,USD 38.06,USD 199.13,USD,1.1330 2020-06-05T13:04:26.828036Z,,CASH TOP-UP,,,USD 113.81,USD,1.1302 2020-06-05T14:18:00.799519Z,UAL,BUY - MARKET,2.4672489,USD 45.80,USD 114.12,USD,1.1297 2020-06-05T17:28:26.976376Z,QCOM,SELL - MARKET,2.4789291,USD 89.12,USD 220.91,USD,1.1289 2020-06-05T17:31:09.772451Z,UAL,BUY - MARKET,4.8456164,USD 44.37,USD 215,USD,1.1287 2020-06-08T14:15:52.005116Z,,CASH TOP-UP,,,USD 102.63,USD,1.1304 2020-06-08T14:16:33.413999Z,ANSS,BUY - MARKET,0.35145678,USD 284.53,USD 100,USD,1.1303 2020-06-08T14:17:24.882389Z,KO,SELL - MARKET,4.34023991,USD 49.70,USD 215.70,USD,1.1304 2020-06-08T14:23:38.760448Z,UAL,BUY - MARKET,4.86896252,USD 46.17,USD 224.80,USD,1.1309 2020-06-09T07:06:15.520922Z,,CASH TOP-UP,,,USD 100,USD,1.1277 2020-06-09T13:51:25.021186Z,UAL,BUY - MARKET,2.22121486,USD 44.12,USD 99.13,USD,1.1346 2020-06-09T14:17:33.110755Z,AMZN,SELL - MARKET,0.04362354,USD 2545.19,USD 109.89,USD,1.1345 2020-06-10T13:37:56.248650Z,UAL,BUY - MARKET,2.43486729,USD 41.07,USD 101.13,USD,1.1373 2020-06-10T13:43:11.542460Z,AAPL,SELL - MARKET,1.11616018,USD 350.18,USD 389.71,USD,1.1369 2020-06-10T13:48:41.773677Z,ANSS,BUY - MARKET,1.03831377,USD 288.93,USD 301.13,USD,1.1366 2020-06-10T14:04:33.156206Z,AMZN,SELL - MARKET,0.08295313,USD 2663.79,USD 219.83,USD,1.1366 2020-06-11T13:37:59.512320Z,TSLA,BUY - MARKET,0.30035742,USD 998.81,USD 301.13,USD,1.1367 2020-06-15T09:43:07.163997Z,,CASH TOP-UP,,,USD 150,USD,1.1250 2020-06-15T14:01:51.523075Z,AAPL,BUY - MARKET,0.44628246,USD 336.11,USD 151.12,USD,1.1280 2020-06-16T21:53:42.937926Z,,CASH TOP-UP,,,USD 97.58,USD,1.1262 2020-06-18T14:35:42.938104Z,UAL,SELL - MARKET,6.8212824,USD 40.04,USD 271.98,USD,1.1212 2020-06-18T14:37:42.274505Z,,CASH TOP-UP,,,USD 192.53,USD,1.1217 2020-06-19T13:52:12.947282Z,MSFT,SELL - MARKET,1.15486141,USD 199.15,USD 228.85,USD,1.1231 2020-06-19T13:53:37.856769Z,GOOGL,BUY - MARKET,0.20775767,USD 1443.99,USD 301.12,USD,1.1231 2020-06-19T14:05:29.762422Z,QCOM,BUY - MARKET,3.3463469,USD 89.65,USD 301.12,USD,1.1226 2020-06-22T13:37:24.868355Z,AAPL,BUY - MARKET,0.56580287,USD 353.48,USD 201.12,USD,1.1228 2020-06-26T06:44:11.028578Z,QCOM,DIVIDEND,,,USD 1.37,USD,1.1215 2020-06-29T04:54:02.365153Z,NVDA,DIVIDEND,,,USD 0.04,USD,1.1243 2020-06-30T18:19:47.514819Z,TSLA,SELL - MARKET,0.13183279,USD 1075.23,USD 141.74,USD,1.1236 2020-06-30T23:13:30.727834Z,,CUSTODY FEE,,,USD -0.03,USD,1.1237 2020-07-01T14:14:41.076966Z,UAL,SELL - MARKET,7.12250712,USD 37.39,USD 266.29,USD,1.1263 2020-07-01T14:24:40.305583Z,TSLA,SELL - MARKET,0.30035742,USD 1118.93,USD 336.06,USD,1.1266 2020-07-01T14:32:04.179320Z,NVDA,SELL - MARKET,0.34223706,USD 382.40,USD 130.86,USD,1.1275 2020-07-01T14:36:38.192960Z,NFLX,SELL - MARKET,0.22745365,USD 464.23,USD 105.58,USD,1.1268 2020-07-01T14:45:25.307546Z,KO,BUY - MARKET,6.61229887,USD 45.37,USD 300,USD,1.1269 2020-07-06T14:03:06.514648Z,AAPL,SELL - MARKET,0.44628246,USD 373.62,USD 166.73,USD,1.1327 2020-07-07T15:08:56.815724Z,UAL,BUY - MARKET,6.00781015,USD 33.29,USD 200,USD,1.1289 2020-07-07T15:09:28.099732Z,TSLA,BUY - MARKET,0.35837412,USD 1395.19,USD 500,USD,1.1289 2020-07-09T13:55:29.714774Z,ZM,BUY - MARKET,0.55248618,USD 271.50,USD 150,USD,1.1329 2020-07-09T17:10:13.780489Z,AMD,SELL - MARKET,1.80733779,USD 56.31,USD 101.76,USD,1.1295 2020-07-10T14:52:58.381420Z,AMZN,BUY - MARKET,0.03145999,USD 3178.64,USD 100,USD,1.1327 2020-07-10T19:29:46.857555Z,TSLA,SELL - MARKET,0.35837412,USD 1534.51,USD 549.91,USD,1.1304 2020-07-13T13:35:28.048770Z,AAPL,SELL - MARKET,0.56580287,USD 390.38,USD 220.87,USD,1.1352 2020-07-13T13:35:47.111924Z,TSLA,BUY - MARKET,0.17648096,USD 1699.90,USD 300,USD,1.1351 2020-07-13T13:35:52.230844Z,AMZN,BUY - MARKET,0.09185548,USD 3266,USD 300,USD,1.1350 2020-07-13T14:51:54.087827Z,MA,SELL - MARKET,0.31256977,USD 296.73,USD 92.74,USD,1.1368 2020-07-14T13:31:59.854077Z,AAPL,BUY - MARKET,0.65824117,USD 379.80,USD 250,USD,1.1369 2020-07-15T13:34:09.322645Z,UAL,SELL - MARKET,6.44484412,USD 34.06,USD 219.50,USD,1.1453 2020-07-15T13:35:04.961261Z,UAL,SELL - MARKET,6.00781015,USD 34.21,USD 205.52,USD,1.1450 2020-07-15T13:36:54.903151Z,AAPL,BUY - MARKET,0.5079494,USD 393.74,USD 200,USD,1.1450 2020-07-15T13:37:08.648684Z,TSLA,BUY - MARKET,0.13297872,USD 1504,USD 200,USD,1.1447 2020-07-17T10:21:42.253727Z,,CASH WITHDRAWAL,,,USD -16,USD,1.1414 2020-07-20T15:28:03.617896Z,GOOGL,SELL - MARKET,0.20775767,USD 1553.01,USD 322.63,USD,1.1444 2020-07-20T15:28:23.429522Z,UAL,BUY - MARKET,9.17150718,USD 32.71,USD 300,USD,1.1443 2020-07-21T13:52:52.140017Z,KO,SELL - MARKET,6.61229887,USD 47.62,USD 314.86,USD,1.1450 2020-07-21T14:53:45.843776Z,AAPL,BUY - MARKET,0.76413652,USD 392.60,USD 300,USD,1.1482 2020-07-23T16:16:56.135853Z,UAL,SELL - MARKET,9.17150718,USD 33.58,USD 307.96,USD,1.1618 2020-07-23T16:17:12.192300Z,AMZN,BUY - MARKET,0.09914274,USD 3025.94,USD 300,USD,1.1619 2020-07-24T13:37:52.361330Z,AMD,BUY - MARKET,1.05263157,USD 66.50,USD 70,USD,1.1611 2020-07-24T15:46:13.810803Z,AMD,SELL - MARKET,1.05263157,USD 68.80,USD 72.41,USD,1.1637 2020-07-24T15:50:14.518607Z,ZM,BUY - MARKET,0.28389503,USD 246.57,USD 70,USD,1.1635 2020-07-25T21:25:27.926085Z,,CASH TOP-UP,,,USD 150,USD,1.1714 2020-07-27T13:40:19.675494Z,TSLA,BUY - MARKET,0.10470034,USD 1432.66,USD 150,USD,1.1746 2020-07-30T13:37:41.742329Z,QCOM,SELL - MARKET,3.3463469,USD 102.67,USD 343.55,USD,1.1800 2020-07-30T13:44:03.123846Z,GOOGL,BUY - MARKET,0.19926934,USD 1505.50,USD 300,USD,1.1804 2020-07-30T16:32:20.847339Z,ANSS,SELL - MARKET,0.35145678,USD 309.60,USD 108.80,USD,1.1801 2020-07-30T16:35:39.859799Z,MSFT,BUY - MARKET,0.73800738,USD 203.25,USD 150,USD,1.1802 2020-07-31T15:21:05.501725Z,AAPL,SELL - MARKET,0.65824117,USD 411.70,USD 270.98,USD,1.1839 2020-07-31T15:23:47.598730Z,GOOGL,BUY - MARKET,0.16989812,USD 1471.47,USD 250,USD,1.1840 2020-07-31T23:43:53.566513Z,,CUSTODY FEE,,,USD -0.03,USD,1.1837 2020-08-03T13:46:32.153897Z,AAPL,SELL - MARKET,1.27208592,USD 444.06,USD 564.86,USD,1.1709 2020-08-03T14:00:31.581377Z,TSLA,BUY - MARKET,0.2030663,USD 1477.35,USD 300,USD,1.1731 2020-08-03T18:28:17.331649Z,ANSS,SELL - MARKET,1.03831377,USD 315.57,USD 327.64,USD,1.1755 2020-08-04T20:41:16.072701Z,,CASH WITHDRAWAL,,,USD -16.50,USD,1.1799 2020-08-05T13:32:48.539437Z,ANSS,BUY - MARKET,0.95910994,USD 312.79,USD 300,USD,1.1881 2020-08-05T13:36:03.481722Z,AMD,BUY - MARKET,1.18990956,USD 84.04,USD 100,USD,1.1891 2020-08-06T09:23:31.359439Z,,CASH TOP-UP,,,USD 300,USD,1.1850 2020-08-06T14:00:31.092775Z,AAPL,BUY - MARKET,0.22504782,USD 444.35,USD 100,USD,1.1859 2020-08-10T04:51:32.749766Z,MA,DIVIDEND,,,USD 0.20,USD,1.1794 2020-08-10T14:52:42.356948Z,UAL,SELL - MARKET,2.6944444,USD 36.55,USD 98.47,USD,1.1769 2020-08-10T14:54:34.374914Z,AMD,BUY - MARKET,1.23701138,USD 80.84,USD 100,USD,1.1768 2020-08-10T14:57:30.636414Z,ANSS,BUY - MARKET,0.32998944,USD 303.04,USD 100,USD,1.1767 2020-08-13T13:31:33.235267Z,TSLA,SELL - MARKET,0.10470034,USD 1607.54,USD 168.30,USD,1.1839 2020-08-13T14:32:36.305371Z,TSLA,SELL - MARKET,0.2030663,USD 1632.37,USD 331.46,USD,1.1859 2020-08-13T14:36:28.249846Z,ZM,BUY - MARKET,0.40695071,USD 245.73,USD 100,USD,1.1851 2020-08-14T06:42:26.713153Z,AAPL,DIVIDEND,,,USD 0.15,USD,1.1819 2020-08-14T13:33:39.022612Z,TSLA,SELL - MARKET,0.1397872,USD 1661.02,USD 232.17,USD,1.1826 2020-08-14T14:12:17.671752Z,XYZ,BUY - MARKET,0.7033338,USD 142.18,USD 100,USD,1.1830 2020-08-17T13:33:39.120706Z,TSLA,BUY - MARKET,0.05902769,USD 1694.12,USD 100,USD,1.1863 2020-08-17T14:36:39.947800Z,TSLA,BUY - MARKET,0.0561394,USD 1781.28,USD 100,USD,1.1883 2020-08-17T16:28:45.503089Z,XYZ,BUY - MARKET,0.66613375,USD 150.12,USD 100,USD,1.1860 2020-08-18T13:40:16.844239Z,TSLA,SELL - MARKET,0.05902769,USD 1883.01,USD 111.14,USD,1.1962 2020-08-18T13:46:26.654Z,ZM,SELL - MARKET,0.40695071,USD 270.87,USD 110.22,USD,1.1962 2020-08-18T14:20:31.458481Z,TSLA,SELL - MARKET,0.17599953,USD 1878.58,USD 330.61,USD,1.1934 2020-08-18T16:27:49.232388Z,UAL,BUY - MARKET,2.9620853,USD 33.76,USD 100,USD,1.1937 2020-08-19T16:01:34.832909Z,AMZN,SELL - MARKET,0.09914274,USD 3306.04,USD 327.75,USD,1.1899 2020-08-19T16:19:13.539922Z,NVDA,BUY - MARKET,0.10171698,USD 491.56,USD 50,USD,1.1872 2020-08-19T16:27:25.319575Z,MA,SELL - MARKET,0.28609409,USD 331.39,USD 94.80,USD,1.1877 2020-08-20T15:13:31.608194Z,TSLA,SELL - MARKET,0.04981235,USD 1966.58,USD 97.95,USD,1.1848 2020-08-20T15:17:03.912150Z,XYZ,SELL - MARKET,0.7033338,USD 156.27,USD 109.90,USD,1.1847 2020-08-20T15:35:58.284968Z,TSLA,BUY - MARKET,0.05034207,USD 1986.41,USD 100,USD,1.1856 2020-08-20T19:11:21.856894Z,TSLA,BUY - MARKET,0.04959308,USD 2016.41,USD 100,USD,1.1860 2020-08-21T13:46:22.168804Z,AAPL,BUY - MARKET,0.41413869,USD 482.93,USD 200,USD,1.1767 2020-08-21T13:46:40.645696Z,TSLA,BUY - MARKET,0.09623805,USD 2078.18,USD 200,USD,1.1765 2020-08-21T16:26:59.511866Z,ZM,SELL - MARKET,0.83638121,USD 290.27,USD 242.76,USD,1.1768 2020-08-21T16:30:38.287214Z,TSLA,BUY - MARKET,0.09596054,USD 2084.19,USD 200,USD,1.1770 2020-08-24T16:07:10.297884Z,UAL,SELL - MARKET,2.9620853,USD 36.19,USD 107.19,USD,1.1805 2020-08-24T16:08:07.511680Z,TSLA,BUY - MARKET,0.09782821,USD 2044.40,USD 200,USD,1.1805 2020-08-25T14:44:00.531640Z,BABA,BUY - MARKET,0.17636684,USD 283.50,USD 50,USD,1.1826 2020-08-25T15:15:44.630812Z,GOOGL,SELL - MARKET,0.16989812,USD 1605.20,USD 272.70,USD,1.1828 2020-08-26T15:07:42.730768Z,ZM,BUY - MARKET,0.1661792,USD 300.88,USD 50,USD,1.1821 2020-08-26T15:42:29.143351Z,BABA,BUY - MARKET,0.17246731,USD 289.91,USD 50,USD,1.1825 2020-08-27T13:56:12.492183Z,MSFT,SELL - MARKET,0.73800738,USD 229.08,USD 169.05,USD,1.1807 2020-08-27T13:57:57.647626Z,UAL,SELL - MARKET,2.78884462,USD 37.49,USD 104.54,USD,1.1803 2020-08-27T14:08:52.657497Z,UAL,SELL - MARKET,5.20231213,USD 36.73,USD 191.07,USD,1.1782 2020-08-27T14:47:04.731766Z,ANSS,SELL - MARKET,0.32998944,USD 331.65,USD 109.43,USD,1.1786 2020-08-27T15:52:39.194814Z,TSLA,BUY - MARKET,0.08780286,USD 2277.83,USD 200,USD,1.1825 2020-08-27T15:59:47.914287Z,TSLA,SELL - MARKET,0.09782821,USD 2272.96,USD 222.35,USD,1.1826 2020-08-27T16:02:06.770299Z,TSLA,BUY - MARKET,0.21983819,USD 2274.40,USD 500,USD,1.1822 2020-08-27T16:40:42.718746Z,TSLA,BUY - MARKET,0.22686231,USD 2203.98,USD 500,USD,1.1825 2020-08-27T17:15:43.206363Z,AAPL,BUY - MARKET,0.40120361,USD 498.50,USD 200,USD,1.1814 2020-08-28T14:57:20.303825Z,TSLA,SELL - MARKET,0.05034207,USD 2272.06,USD 114.37,USD,1.1911 2020-08-28T15:25:39.775903Z,UAL,SELL - MARKET,2.43486729,USD 37.02,USD 90.13,USD,1.1899 2020-08-28T15:30:21.083145Z,NVDA,BUY - MARKET,0.09644131,USD 518.45,USD 50,USD,1.1902 2020-08-31T00:22:15.681429Z,,CASH WITHDRAWAL,,,USD -16.66,USD,1.1915 2020-08-31T08:24:29.814099Z,AAPL,STOCK SPLIT,3.12117036,,USD 0,USD,1.1899 2020-08-31T08:27:18.193687Z,TSLA,STOCK SPLIT,3.10518012,,USD 0,USD,1.1898 2020-08-31T14:23:19.225150Z,TSLA,SELL - MARKET,0.48119025,USD 463.12,USD 222.84,USD,1.1941 2020-08-31T14:25:12.090849Z,TSLA,BUY - MARKET,1.07529194,USD 464.99,USD 500,USD,1.1939 2020-08-31T14:34:07.507538Z,AAPL,SELL - MARKET,0.90019128,USD 128.26,USD 115.45,USD,1.1945 2020-08-31T14:36:41.781166Z,TSLA,SELL - MARKET,0.4798027,USD 465.17,USD 223.18,USD,1.1950 2020-08-31T14:58:49.683011Z,AMD,SELL - MARKET,1.23701138,USD 89.87,USD 111.16,USD,1.1965 2020-08-31T15:00:12.913839Z,AMZN,SELL - MARKET,0.03145999,USD 3492.37,USD 109.86,USD,1.1961 2020-08-31T15:10:00.501852Z,TSLA,BUY - MARKET,0.41160732,USD 485.90,USD 200,USD,1.1951 2020-08-31T15:56:12.322382Z,TSLA,SELL - MARKET,1.13431155,USD 483.77,USD 548.73,USD,1.1955 2020-08-31T19:02:14.692076Z,TSLA,SELL - MARKET,0.2479654,USD 495.19,USD 122.78,USD,1.1935 2020-08-31T19:06:47.005425Z,TSLA,BUY - MARKET,1.00952996,USD 495.28,USD 500,USD,1.1938 2020-08-31T23:54:32.172792Z,,CUSTODY FEE,,,USD -0.02,USD,1.1940 2020-09-01T13:31:35.939299Z,ZM,BUY - MARKET,0.23466466,USD 426.14,USD 100,USD,1.1988 2020-09-01T13:31:46.997999Z,TSLA,BUY - MARKET,1.0119409,USD 494.10,USD 500,USD,1.1988 2020-09-01T13:47:37.140689Z,XYZ,SELL - MARKET,0.66613375,USD 166.08,USD 110.62,USD,1.1977 2020-09-01T13:53:42.126313Z,ZM,BUY - MARKET,0.44881288,USD 445.62,USD 200,USD,1.1969 2020-09-01T13:59:53.248673Z,ZM,SELL - MARKET,0.1661792,USD 453.67,USD 75.38,USD,1.1977 2020-09-01T14:07:15.473203Z,ZM,BUY - MARKET,0.42154073,USD 474.45,USD 200,USD,1.1952 2020-09-01T18:05:30.665718Z,GOOGL,SELL - MARKET,0.19926934,USD 1655.45,USD 329.86,USD,1.1917 2020-09-01T18:07:04.483988Z,ANSS,SELL - MARKET,0.95910994,USD 344.33,USD 330.23,USD,1.1919 2020-09-01T18:13:20.177621Z,NIO,BUY - MARKET,10.07556675,USD 19.85,USD 200,USD,1.1921 2020-09-02T13:33:53.638044Z,NIO,BUY - MARKET,10,USD 20.74,USD 207.40,USD,1.1832 2020-09-02T13:45:31.065500Z,NVDA,SELL - MARKET,0.19815829,USD 577.22,USD 114.37,USD,1.1839 2020-09-02T14:00:41.420342Z,TSLA,BUY - MARKET,0.84973166,USD 447.20,USD 380,USD,1.1834 2020-09-02T14:58:26.424459Z,,CASH TOP-UP,,,USD 200,USD,1.1844 2020-09-04T06:57:55.602815Z,,CASH WITHDRAWAL,,,USD -200,USD,1.1841 2020-09-04T07:21:47.180268Z,,CASH TOP-UP,,,USD 250,USD,1.1845 2020-09-04T07:22:00.765905Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1846 2020-09-10T06:43:18.012788Z,,CASH TOP-UP,,,USD 250,USD,1.1832 2020-09-10T06:43:39.697815Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1832 2020-09-11T07:08:09.301110Z,MSFT,DIVIDEND,,,USD 0.32,USD,1.1840 2020-09-15T14:37:48.200676Z,TSLA,SELL - MARKET,0.65498179,USD 438.20,USD 286.99,USD,1.1850 2020-09-15T14:54:20.817595Z,UAL,SELL - MARKET,2.22121486,USD 37.07,USD 82.33,USD,1.1857 2020-09-17T12:25:07.952921Z,,CASH WITHDRAWAL,,,USD -370.20,USD,1.1805 2020-09-22T13:33:29.786892Z,ZM,SELL - MARKET,0.23466466,USD 469.01,USD 110.05,USD,1.1759 2020-09-22T15:55:51.449872Z,ZM,SELL - MARKET,0.44881288,USD 488.20,USD 219.10,USD,1.1706 2020-09-23T14:38:22.109173Z,ZM,SELL - MARKET,0.42154073,USD 520,USD 219.19,USD,1.1668 2020-09-24T07:30:01.867812Z,,CASH WITHDRAWAL,,,USD -329.15,USD,1.1653 2020-09-25T05:34:43.533083Z,NVDA,DIVIDEND,,,USD 0.03,USD,1.1674 2020-09-25T07:08:24.483137Z,,CASH WITHDRAWAL,,,USD -219.22,USD,1.1668 2020-09-28T15:41:23.188756Z,BABA,SELL - MARKET,0.34883415,USD 275.69,USD 96.16,USD,1.1662 2020-09-29T15:58:04.990015Z,AMD,SELL - MARKET,1.18990956,USD 81.35,USD 96.79,USD,1.1721 2020-09-30T13:41:16.788426Z,NIO,SELL - MARKET,10.07556675,USD 22.13,USD 222.96,USD,1.1695 2020-09-30T23:05:22.729899Z,,CUSTODY FEE,,,USD -0.03,USD,1.1730 2020-10-01T08:39:07.068215Z,,CASH WITHDRAWAL,,,USD -16.40,USD,1.1728 2020-10-01T19:43:49.909598Z,TSLA,SELL - MARKET,0.60709082,USD 448.45,USD 272.23,USD,1.1745 2020-10-02T18:46:35.354198Z,,CASH WITHDRAWAL,,,USD -399.48,USD,1.1719 2020-10-06T13:45:20.572814Z,UAL,SELL - MARKET,2.4672489,USD 36.78,USD 90.74,USD,1.1797 2020-10-06T19:05:39.180375Z,,CASH WITHDRAWAL,,,USD -272.23,USD,1.1754 2020-10-08T14:41:22.813140Z,UAL,SELL - MARKET,4.8456164,USD 37.49,USD 181.65,USD,1.1744 2020-10-08T14:45:00.269291Z,UAL,SELL - MARKET,4.86896256,USD 37.41,USD 182.14,USD,1.1743 2020-10-09T18:26:13.289084Z,AAPL,SELL - MARKET,2.02064706,USD 116.32,USD 235.02,USD,1.1828 2020-10-12T17:56:05.845122Z,AAPL,SELL - MARKET,1.24072214,USD 124.33,USD 154.25,USD,1.1810 2020-10-14T13:30:16.262543Z,NIO,SELL - LIMIT,10,USD 24,USD 239.98,USD,1.1762 2020-10-14T15:26:47.927855Z,TSLA,SELL - MARKET,0.98969047,USD 462.20,USD 457.41,USD,1.1763 2020-10-15T12:02:19.535807Z,,CASH WITHDRAWAL,,,USD -400,USD,1.1708 2020-10-22T09:23:25.613263Z,,CASH WITHDRAWAL,,,USD -680,USD,1.1842 2020-10-22T19:06:30.184890Z,,CASH WITHDRAWAL,,,USD -461.19,USD,1.1819 2020-10-30T16:49:56.657758Z,,CASH TOP-UP,,,USD 230,USD,1.1655 2020-10-30T18:55:13.772909Z,,CASH WITHDRAWAL,,,USD -230,USD,1.1650 2020-11-01T00:12:15.461073Z,,CUSTODY FEE,,,USD -0.01,USD,1.1764 2020-11-02T23:50:23.731454Z,,CASH TOP-UP,,,USD 0.01,USD,1.1643 2020-11-13T17:32:40.396936Z,TSLA,SELL - MARKET,1.09919095,USD 404.95,USD 445.10,USD,1.1829 2020-11-13T17:33:09.255036Z,AMZN,SELL - MARKET,0.09185548,USD 3115.11,USD 286.12,USD,1.1829 2020-11-17T08:14:31.505714Z,,CASH WITHDRAWAL,,,USD -731.22,USD,1.1861 2020-11-26T10:29:43.997425Z,,CASH TOP-UP,,,USD 64.15,USD,1.1908 2020-11-30T14:07:20.231291Z,,CASH TOP-UP,,,USD 600,USD,1.1997 2020-11-30T14:13:04.510383Z,,CASH WITHDRAWAL,,,USD -664.15,USD,1.1995 2020-11-30T23:42:00.247197Z,,CUSTODY FEE,,,USD -0.01,USD,1.1938 2020-12-01T23:01:04.658915Z,,CASH TOP-UP,,,USD 0.01,USD,1.2075 2020-12-03T16:01:52.681026Z,TSLA,SELL - MARKET,1.51430624,USD 587.30,USD 889.32,USD,1.2162 2020-12-03T20:02:02.615104Z,,CASH TOP-UP,,,USD 283.13,USD,1.2146 2020-12-07T09:33:26.482581Z,,CASH TOP-UP,,,USD 245.04,USD,1.2091 2020-12-07T10:19:04.708279Z,,CASH WITHDRAWAL,,,USD -1417.49,USD,1.2098 2020-12-08T20:25:49.896141Z,,CASH TOP-UP,,,USD 600,USD,1.2104 2020-12-08T20:26:38.575792Z,MRNA,BUY - MARKET,3,USD 167.84,USD 503.52,USD,1.2104 2020-12-10T08:24:28.915801Z,,CASH TOP-UP,,,USD 1045.98,USD,1.2095 2020-12-10T14:30:02.653115Z,AMD,BUY - LIMIT,4,USD 89.55,USD 358.20,USD,1.2110 2020-12-10T14:30:13.150135Z,TSLA,BUY - LIMIT,1,USD 573.85,USD 573.85,USD,1.2112 2020-12-10T14:47:14.048156Z,MRNA,BUY - MARKET,1,USD 155.44,USD 155.44,USD,1.2139 2020-12-14T08:42:02.044895Z,,CASH TOP-UP,,,USD 873.84,USD,1.2148 2020-12-14T14:48:21.225847Z,TSLA,BUY - MARKET,1.39009052,USD 617.42,USD 858.27,USD,1.2161 2020-12-14T14:56:33.643638Z,NIO,BUY - MARKET,1,USD 39.90,USD 39.90,USD,1.2163 2020-12-15T14:33:22.241704Z,TSLA,SELL - MARKET,1.42113728,USD 640.27,USD 909.88,USD,1.2156 2020-12-15T14:50:30.838195Z,ANSS,BUY - MARKET,1,USD 345.66,USD 345.66,USD,1.2159 2020-12-15T18:04:07.650518Z,MRNA,BUY - LIMIT,4,USD 145,USD 580,USD,1.2161 2020-12-17T08:40:21.201412Z,,CASH TOP-UP,,,USD 1011.96,USD,1.2241 2020-12-17T14:30:06.433198Z,AAPL,BUY - LIMIT,3,USD 128.98,USD 386.94,USD,1.2249 2020-12-17T14:44:55.714193Z,TSLA,BUY - LIMIT,1,USD 620,USD 620,USD,1.2253 2020-12-17T20:44:47.556398Z,TSLA,SELL - LIMIT,1,USD 650,USD 649.98,USD,1.2263 2020-12-17T20:47:30.660341Z,AAPL,BUY - LIMIT,5,USD 128.63,USD 643.15,USD,1.2263 2020-12-21T13:26:44.115395Z,,CASH TOP-UP,,,USD 934.75,USD,1.2192 2020-12-21T15:25:16.971865Z,AMD,BUY - LIMIT,3,USD 92,USD 276,USD,1.2219 2020-12-22T14:30:05.457349Z,TSLA,BUY - LIMIT,1,USD 647.31,USD 647.31,USD,1.2225 2020-12-23T08:20:49.417315Z,,CASH TOP-UP,,,USD 440.80,USD,1.2179 2020-12-23T10:08:57.914132Z,,CASH TOP-UP,,,USD 1218.96,USD,1.2194 2020-12-23T14:30:12.260390Z,AAPL,BUY - LIMIT,4,USD 132.17,USD 528.68,USD,1.2199 2020-12-23T14:32:40.448977Z,TSLA,BUY - LIMIT,1,USD 630,USD 630,USD,1.2217 2020-12-23T15:56:56.184999Z,AMZN,BUY - MARKET,0.15645779,USD 3195.75,USD 500,USD,1.2185 2020-12-24T15:56:44.818105Z,,CASH TOP-UP,,,USD 14.23,USD,1.2184 2020-12-30T19:41:15.069854Z,TSLA,SELL - LIMIT,2,USD 695,USD 1389.96,USD,1.2289 2020-12-31T12:20:23.184470Z,,CASH TOP-UP,,,USD 500,USD,1.2276 2020-12-31T12:24:43.742Z,,CASH WITHDRAWAL,,,USD -64.98,USD,1.2273 2020-12-31T14:31:39.601626Z,NIO,BUY - LIMIT,10,USD 48.50,USD 485,USD,1.2279 2020-12-31T17:17:42.145519Z,TSLA,BUY - MARKET,1,USD 716.49,USD 716.49,USD,1.2232 2021-01-01T01:29:50.870336Z,,CUSTODY FEE,,,USD -0.04,USD,1.2219 2021-01-04T16:07:56.289208Z,AAPL,BUY - LIMIT,1,USD 130,USD 130,USD,1.2275 2021-01-06T16:21:50.650163Z,TSLA,BUY - MARKET,0.71085433,USD 769.37,USD 546.91,USD,1.2280 2021-01-07T15:55:24.088592Z,TSLA,SELL - LIMIT,2,USD 800,USD 1599.95,USD,1.2262 2021-01-07T16:23:46.257213Z,TSLA,BUY - MARKET,1,USD 805.56,USD 805.56,USD,1.2275 2021-01-08T01:26:54.692376Z,,CASH TOP-UP,,,USD 549.96,USD,1.2246 2021-01-08T09:16:01.965750Z,,CASH WITHDRAWAL,,,USD -71.85,USD,1.2234 2021-01-08T14:34:59.679144Z,TSLA,BUY - MARKET,0.28914567,USD 845.97,USD 244.61,USD,1.2280 2021-01-08T15:22:16.713016Z,TSLA,BUY - MARKET,1,USD 869.32,USD 869.32,USD,1.2229 2021-01-11T15:11:20.833428Z,NIO,BUY - MARKET,2,USD 64.89,USD 129.78,USD,1.2147 2021-01-13T08:40:39.001823Z,,CASH TOP-UP,,,USD 576.16,USD,1.2198 2021-01-13T14:36:16.142906Z,PLUG,BUY - MARKET,8,USD 69.31,USD 554.48,USD,1.2167 2021-01-14T15:14:44.924095Z,TSLA,SELL - LIMIT,1,USD 860,USD 859.97,USD,1.2118 2021-01-14T18:07:30.816970Z,PLUG,SELL - MARKET,8,USD 64.35,USD 514.78,USD,1.2167 2021-01-14T18:07:52.552385Z,MRNA,BUY - MARKET,4,USD 129.08,USD 516.32,USD,1.2168 2021-01-15T15:13:10.226921Z,NIO,BUY - MARKET,15,USD 57.38,USD 860.70,USD,1.2094 2021-01-20T14:30:56.453166Z,NIO,SELL - LIMIT,11,USD 60,USD 659.98,USD,1.2101 2021-01-22T16:33:20.961547Z,TSLA,BUY - MARKET,0.84141694,USD 831.93,USD 700,USD,1.2179 2021-01-25T15:03:48.621618Z,TSLA,SELL - LIMIT,1,USD 900,USD 899.97,USD,1.2129 2021-01-25T15:46:48.750569Z,AAPL,SELL - MARKET,5,USD 144.30,USD 721.47,USD,1.2129 2021-01-25T15:58:40.136461Z,TSLA,BUY - LIMIT,1,USD 870,USD 870,USD,1.2130 2021-01-25T16:04:44.895297Z,AAPL,BUY - LIMIT,5,USD 140,USD 700,USD,1.2129 2021-01-25T18:05:09.838791Z,NIO,BUY - LIMIT,1,USD 59.62,USD 59.62,USD,1.2148 2021-01-27T15:07:02.285287Z,,CASH TOP-UP,,,USD 136.83,USD,1.2080 2021-01-27T15:20:25.147014Z,,CASH TOP-UP,,,USD 470.71,USD,1.2077 2021-01-27T15:43:15.633441Z,AAPL,BUY - MARKET,2,USD 143.31,USD 286.62,USD,1.2091 2021-01-27T15:48:10.015296Z,MRNA,BUY - LIMIT,2,USD 158.09,USD 316.18,USD,1.2094 2021-01-28T07:27:07.598501Z,,CASH TOP-UP,,,USD 1373.27,USD,1.2089 2021-01-28T17:28:28.927848Z,MRNA,BUY - MARKET,3,USD 165.86,USD 497.58,USD,1.2126 2021-01-29T14:30:47.770020Z,MRNA,SELL - LIMIT,6,USD 174,USD 1043.97,USD,1.2153 2021-01-29T14:51:33.499884Z,TSLA,BUY - MARKET,1,USD 840.99,USD 840.99,USD,1.2148 2021-01-29T15:16:26.525884Z,MRNA,BUY - LIMIT,6,USD 177.35,USD 1064.10,USD,1.2147 2021-02-01T04:30:09.384615Z,,CUSTODY FEE,,,USD -0.09,USD,1.2133 2021-02-01T18:09:50.812968Z,,CASH TOP-UP,,,USD 196.46,USD,1.2067 2021-02-01T18:10:12.917721Z,MRNA,BUY - MARKET,1,USD 156.50,USD 156.50,USD,1.2067 2021-02-02T15:02:02.882495Z,ANSS,SELL - MARKET,1,USD 375.59,USD 375.57,USD,1.2033 2021-02-02T15:37:15.304627Z,TSLA,SELL - MARKET,0.71085433,USD 872.04,USD 619.87,USD,1.2029 2021-02-02T15:56:12.366798Z,AAPL,BUY - MARKET,4,USD 135.67,USD 542.68,USD,1.2029 2021-02-03T17:43:36.485615Z,AMZN,SELL - MARKET,0.15645779,USD 3399.26,USD 531.82,USD,1.2031 2021-02-04T17:57:10.745295Z,MRNA,SELL - MARKET,6,USD 172,USD 1031.97,USD,1.1965 2021-02-04T18:01:38.009039Z,,CASH WITHDRAWAL,,,USD -32.26,USD,1.1962 2021-02-05T17:10:07.082216Z,PYPL,BUY - MARKET,3,USD 267.18,USD 801.54,USD,1.2040 2021-02-08T14:56:37.080784Z,MRNA,SELL - LIMIT,6,USD 185,USD 1109.97,USD,1.2061 2021-02-08T15:09:42.308233Z,PYPL,BUY - MARKET,3,USD 280.95,USD 842.85,USD,1.2061 2021-02-08T15:15:57.131010Z,AMZN,BUY - MARKET,0.25,USD 3323.72,USD 830.93,USD,1.2060 2021-02-09T19:58:40.343296Z,NIO,SELL - MARKET,15,USD 62.66,USD 939.87,USD,1.2121 2021-02-09T20:00:27.291440Z,MRNA,BUY - MARKET,3,USD 178.82,USD 536.46,USD,1.2121 2021-02-09T21:20:29.683577Z,,CASH WITHDRAWAL,,,USD -500,USD,1.2121 2021-02-10T14:43:53.048254Z,TSLA,BUY - MARKET,0.69581812,USD 835.75,USD 581.53,USD,1.2135 2021-02-11T15:53:16.248489Z,PYPL,SELL - LIMIT,3,USD 300.01,USD 900,USD,1.2140 2021-02-11T19:21:16.355706Z,PYPL,BUY - LIMIT,3,USD 285,USD 855,USD,1.2133 2021-02-12T07:09:53.382539Z,AAPL,DIVIDEND,,,USD 3.31,USD,1.2126 2021-02-12T15:12:50.744899Z,AMZN,SELL - MARKET,0.25,USD 3250.16,USD 812.51,USD,1.2097 2021-02-12T15:13:55.508641Z,PYPL,BUY - MARKET,2.8,USD 292.47,USD 818.92,USD,1.2098 2021-02-19T18:01:22.470148Z,,CASH WITHDRAWAL,,,USD -41.90,USD,1.2129 2021-03-01T02:07:33.445438Z,,CUSTODY FEE,,,USD -0.08,USD,1.2090 2021-03-02T21:51:18.062393Z,,CASH TOP-UP,,,USD 0.08,USD,1.2091 2021-03-12T14:45:17.576033Z,,CASH TOP-UP,,,USD 178.93,USD,1.1937 2021-03-12T14:45:57.397742Z,NIO,BUY - LIMIT,4,USD 44.30,USD 177.20,USD,1.1933 2021-04-01T07:49:55.154005Z,,CUSTODY FEE,,,USD -0.97,USD,1.1737 2021-04-15T16:45:21.353857Z,AMD,SELL - MARKET,7,USD 83.06,USD 581.42,USD,1.1976 2021-04-19T14:24:42.527100Z,TSLA,BUY - MARKET,0.78607363,USD 699.68,USD 550,USD,1.2032 2021-05-01T08:17:07.806729Z,,CUSTODY FEE,,,USD -1.07,USD,1.2142 2021-05-03T19:47:37.874160Z,MRNA,SELL - MARKET,9,USD 186.87,USD 1681.81,USD,1.2067 2021-05-04T14:18:13.245358Z,GOOGL,BUY - MARKET,0.09823182,USD 2290.50,USD 225,USD,1.2027 2021-05-04T17:03:55.276186Z,MRNA,BUY - MARKET,4,USD 175.47,USD 701.88,USD,1.2021 2021-05-04T17:06:43.250543Z,ANSS,BUY - MARKET,2,USD 350.09,USD 700.18,USD,1.2023 2021-05-04T17:07:18.273114Z,AMZN,BUY - MARKET,0.02585158,USD 3288,USD 85,USD,1.2023 2021-05-14T04:54:27.999346Z,AAPL,DIVIDEND,,,USD 3.55,USD,1.2089 2021-05-24T15:55:44.146809Z,,CASH TOP-UP,,,USD 50,USD,1.2213 2021-05-24T15:56:03.617327Z,SPCE,BUY - MARKET,2,USD 24.93,USD 49.86,USD,1.2212 2021-05-27T15:57:09.986850Z,SPCE,SELL - MARKET,2,USD 28.02,USD 56.03,USD,1.2198 2021-05-27T16:51:08.235670Z,,CASH TOP-UP,,,USD 50,USD,1.2193 2021-05-27T16:52:28.014919Z,,CASH TOP-UP,,,USD 10,USD,1.2195 2021-05-27T16:52:47.221525Z,SPCE,BUY - MARKET,4,USD 28.53,USD 114.12,USD,1.2194 2021-05-27T19:11:54.661834Z,MRNA,SELL - MARKET,4,USD 177.05,USD 708.19,USD,1.2200 2021-05-27T19:12:45.582300Z,SPCE,BUY - LIMIT,23,USD 30.62,USD 704.26,USD,1.2199 2021-06-01T04:34:31.145849Z,,CUSTODY FEE,,,USD -1.03,USD,1.2229 2021-06-07T15:22:20.528310Z,SPCE,SELL - MARKET,27,USD 33.85,USD 913.97,USD,1.2198 2021-06-07T19:32:00.085384Z,NIO,BUY - MARKET,10,USD 43.72,USD 437.20,USD,1.2198 2021-06-08T14:19:53.290150Z,SPCE,BUY - MARKET,12,USD 37.36,USD 448.31,USD,1.2188 2021-06-25T13:30:46.699710Z,SPCE,SELL - LIMIT,12,USD 47.73,USD 572.75,USD,1.1969 2021-06-28T15:36:38.638872Z,NIO,SELL - LIMIT,14,USD 49,USD 685.99,USD,1.1932 2021-07-01T07:07:29.237955Z,,CUSTODY FEE,,,USD -1.02,USD,1.1855 2021-07-01T15:10:49.364022Z,NIO,BUY - LIMIT,10,USD 52,USD 520,USD,1.1869 2021-07-06T14:13:29.561384Z,AMZN,SELL - MARKET,0.02585158,USD 3621.44,USD 93.61,USD,1.1841 2021-07-06T14:13:42.195388Z,GOOGL,SELL - MARKET,0.09823182,USD 2521.08,USD 247.64,USD,1.1841 2021-07-06T15:42:06.615634Z,GOOGL,BUY - MARKET,0.21915668,USD 2509.62,USD 550,USD,1.1830 2021-07-07T13:40:07.363142Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1807 2021-07-08T15:28:51.781770Z,SPCE,SELL - LIMIT,12,USD 50,USD 599.99,USD,1.1848 2021-07-09T14:51:56.656892Z,AAPL,SELL - LIMIT,4,USD 145.04,USD 580.17,USD,1.1875 2021-07-12T13:40:10.104714Z,SPCE,BUY - LIMIT,12,USD 45,USD 540,USD,1.1858 2021-07-14T19:19:12.332908Z,AAPL,SELL - MARKET,4,USD 149.16,USD 596.63,USD,1.1838 2021-07-14T20:06:27.095455Z,,CASH WITHDRAWAL,,,USD -63.73,USD,1.1839 2021-07-15T14:52:57.411248Z,MRNA,BUY - MARKET,1,USD 255.80,USD 255.80,USD,1.1817 2021-07-16T13:30:15.150905Z,SPCE,BUY - LIMIT,24,USD 32.56,USD 781.44,USD,1.1811 2021-07-16T14:00:06.695873Z,MRNA,SELL - LIMIT,1,USD 285,USD 284.99,USD,1.1804 2021-07-16T15:51:31.477893Z,AAPL,BUY - LIMIT,3,USD 147.31,USD 441.92,USD,1.1813 2021-07-23T16:05:00.019087Z,PYPL,SELL - MARKET,3,USD 308.81,USD 926.42,USD,1.1764 2021-07-23T16:05:29.193871Z,MRNA,BUY - MARKET,2,USD 335.27,USD 670.54,USD,1.1765 2021-07-27T06:51:45.976639Z,,CASH WITHDRAWAL,,,USD -250,USD,1.1793 2021-08-01T05:41:21.067616Z,,CUSTODY FEE,,,USD -1.12,USD,1.1999 2021-08-03T18:07:55.781076Z,MRNA,SELL - LIMIT,2,USD 370,USD 739.99,USD,1.1866 2021-08-03T18:10:06.118513Z,AMZN,BUY - MARKET,0.22221761,USD 3375.07,USD 750,USD,1.1866 2021-08-09T14:53:34.032557Z,GOOGL,SELL - MARKET,0.21915668,USD 2716.87,USD 595.41,USD,1.1751 2021-08-09T14:54:08.334621Z,MRNA,BUY - MARKET,1,USD 450.93,USD 450.93,USD,1.1752 2021-08-13T04:42:24.271612Z,AAPL,DIVIDEND,,,USD 2.62,USD,1.1742 2021-08-16T13:39:48.653719Z,AAPL,SELL - LIMIT,4,USD 150,USD 599.99,USD,1.1785 2021-08-19T13:30:23.348630Z,AAPL,BUY - LIMIT,5,USD 144.93,USD 724.65,USD,1.1697 2021-09-01T07:40:38.748966Z,,CUSTODY FEE,,,USD -1.15,USD,1.1800 2021-09-07T13:41:12.356305Z,AAPL,SELL - LIMIT,5,USD 155.05,USD 775.24,USD,1.1862 2021-09-10T16:13:16.888876Z,AAPL,BUY - MARKET,5,USD 149.97,USD 749.85,USD,1.1823 2021-09-17T14:05:43.934832Z,TSLA,SELL - MARKET,0.78607363,USD 758.73,USD 596.41,USD,1.1758 2021-09-17T14:06:29.208538Z,AAPL,BUY - MARKET,4,USD 146.83,USD 587.32,USD,1.1758 2021-10-01T03:10:46.826293Z,,CUSTODY FEE,,,USD -1.11,USD,1.1580 2021-10-01T08:38:11.538983Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1582 2021-10-19T15:35:49.113762Z,ANSS,SELL - MARKET,2,USD 364.67,USD 729.33,USD,1.1638 2021-10-19T15:36:40.367755Z,GOOGL,BUY - MARKET,0.25686385,USD 2859.18,USD 734.42,USD,1.1640 2021-10-21T14:37:31.105249Z,TSLA,SELL - MARKET,0.84141694,USD 895.48,USD 753.46,USD,1.1640 2021-10-25T13:30:27.810820Z,TSLA,SELL - LIMIT,1,USD 951.50,USD 951.49,USD,1.1614 2021-10-25T14:12:51.623985Z,TSLA,SELL - MARKET,0.98496385,USD 956.01,USD 941.63,USD,1.1613 2021-10-25T14:30:51.121969Z,TSLA,SELL - MARKET,0.99999994,USD 974.91,USD 974.90,USD,1.1615 2021-10-25T14:35:27.184763Z,,CASH WITHDRAWAL,,,USD -78.27,USD,1.1616 2021-10-25T16:30:55.577488Z,TSLA,SELL - MARKET,1,USD 992.83,USD 992.81,USD,1.1610 2021-10-26T13:33:01.736631Z,TSLA,BUY - MARKET,1,USD 1044.49,USD 1044.49,USD,1.1609 2021-10-26T13:45:33.604150Z,AAPL,BUY - MARKET,4,USD 150.48,USD 601.92,USD,1.1611 2021-10-27T16:17:31.917375Z,AAPL,BUY - MARKET,10,USD 149.25,USD 1492.49,USD,1.1603 2021-10-29T10:53:14.177467Z,,CASH WITHDRAWAL,,,USD -50,USD,1.1652 2021-11-01T14:50:45.336203Z,TSLA,SELL - LIMIT,1,USD 1150,USD 1149.98,USD,1.1583 2021-11-01T20:36:56.194415Z,,CASH WITHDRAWAL,,,USD -100,USD,1.1609 2021-11-04T01:13:01.959445Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.1613 2021-11-04T03:17:16.783359Z,,CUSTODY FEE,,,USD -1.07,USD,1.1603 2021-11-04T06:29:23.316411Z,,CASH TOP-UP,,,USD 2000,USD,1.1586 2021-11-04T14:10:12.273414Z,NIO,SELL - MARKET,13,USD 43.54,USD 566.02,USD,1.1553 2021-11-04T14:22:38.394300Z,KO,BUY - MARKET,10,USD 56.29,USD 562.89,USD,1.1552 2021-11-04T14:23:41.524349Z,BAC,BUY - MARKET,10,USD 47.49,USD 474.89,USD,1.1551 2021-11-09T16:46:11.784013Z,TSLA,BUY - MARKET,1,USD 1065.78,USD 1065.78,USD,1.1586 2021-11-09T16:52:01.682293Z,SPCE,SELL - LIMIT,24,USD 20.99,USD 503.77,USD,1.1588 2021-11-10T15:33:05.030639Z,TSLA,BUY - MARKET,1,USD 1073.50,USD 1073.50,USD,1.1521 2021-11-17T07:09:11.457335Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1305 2021-11-18T19:06:58.592793Z,AAPL,SELL - LIMIT,2,USD 158,USD 315.99,USD,1.1372 2021-11-19T14:33:40.386692Z,AMZN,SELL - MARKET,0.22221761,USD 3734.13,USD 829.78,USD,1.1315 2021-11-19T16:55:21.098116Z,AAPL,SELL - LIMIT,5,USD 160,USD 799.99,USD,1.1318 2021-11-19T19:20:55.700535Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1292 2021-11-22T10:38:55.919887Z,,CASH WITHDRAWAL,,,USD -153.20,USD,1.1287 2021-11-22T14:38:56.905968Z,PYPL,SELL - MARKET,3,USD 191.85,USD 575.54,USD,1.1242 2021-11-22T14:40:07.462187Z,AAPL,BUY - MARKET,10,USD 163.08,USD 1630.79,USD,1.1243 2021-11-22T14:40:36.826246Z,TSLA,BUY - MARKET,0.5,USD 1181.76,USD 590.88,USD,1.1244 2021-11-22T17:28:58.134841Z,MRNA,BUY - LIMIT,1,USD 287.97,USD 287.97,USD,1.1255 2021-11-26T14:30:44.164387Z,MRNA,SELL - LIMIT,1,USD 320,USD 319.99,USD,1.1289 2021-11-26T15:11:21.748088Z,AAPL,BUY - LIMIT,2,USD 158.17,USD 316.34,USD,1.1300 2021-11-26T17:15:02.710330Z,MRNA,SELL - MARKET,1,USD 327.96,USD 327.95,USD,1.1300 2021-11-26T17:19:19.840447Z,AMZN,BUY - MARKET,0.09497631,USD 3527.09,USD 334.99,USD,1.1297 2021-11-30T20:55:44.227431Z,AAPL,SELL - LIMIT,7,USD 165,USD 1154.98,USD,1.1337 2021-12-01T16:17:49.426751Z,AAPL,SELL - LIMIT,15,USD 170,USD 2549.98,USD,1.1331 2021-12-02T06:08:45.125392Z,,CUSTODY FEE,,,USD -1.07,USD,1.1325 2021-12-02T09:09:32.353819Z,,CASH WITHDRAWAL,,,USD -300,USD,1.1325 2021-12-02T09:09:59.218758Z,,CASH TOP-UP,,,USD 100,USD,1.1324 2021-12-02T14:30:31.195638Z,AAPL,BUY - LIMIT,7,USD 158.72,USD 1111.04,USD,1.1345 2021-12-02T14:48:54.578317Z,AAPL,BUY - MARKET,3,USD 160.89,USD 482.67,USD,1.1349 2021-12-02T17:17:29.448590Z,AMZN,BUY - MARKET,0.08667514,USD 3461.20,USD 300,USD,1.1310 2021-12-02T17:22:47.526948Z,AAPL,BUY - MARKET,9,USD 163.26,USD 1469.33,USD,1.1307 2021-12-03T15:52:09.743899Z,SPCE,SELL - MARKET,12,USD 14.32,USD 171.84,USD,1.1280 2021-12-06T15:14:43.715974Z,AAPL,SELL - MARKET,4,USD 167.09,USD 668.35,USD,1.1290 2021-12-06T15:23:37.271485Z,,CASH TOP-UP,,,USD 50,USD,1.1293 2021-12-06T15:24:23.771651Z,TSLA,BUY - LIMIT,1,USD 992.90,USD 992.90,USD,1.1291 2021-12-10T20:40:03.360809Z,AAPL,SELL - MARKET,5,USD 178.17,USD 890.85,USD,1.1316 2021-12-10T20:46:05.031639Z,,CASH WITHDRAWAL,,,USD -26.65,USD,1.1319 2021-12-13T14:31:24.268753Z,AAPL,SELL - LIMIT,7,USD 181,USD 1266.98,USD,1.1294 2021-12-13T17:18:39.928392Z,AAPL,BUY - MARKET,4,USD 178.20,USD 712.80,USD,1.1302 2021-12-14T07:45:33.061233Z,,CASH WITHDRAWAL,,,USD -150,USD,1.1279 2021-12-14T19:27:37.943686Z,TSLA,BUY - MARKET,0.5,USD 943.68,USD 471.84,USD,1.1264 2021-12-14T19:27:59.893606Z,AAPL,BUY - MARKET,4,USD 174.17,USD 696.68,USD,1.1264 2021-12-17T08:05:11.817525Z,KO,DIVIDEND,,,USD 3.57,USD,1.1323 2021-12-21T22:24:23.051009Z,,CASH TOP-UP,,,USD 550,USD,1.1288 2021-12-25T17:04:42.634707Z,,CASH TOP-UP,,,USD 100,USD,1.1315 2021-12-27T16:07:19.048883Z,TSLA,SELL - MARKET,0.5,USD 1102.70,USD 551.34,USD,1.1327 2021-12-28T15:52:44.354571Z,AMZN,BUY - MARKET,0.05822687,USD 3434.84,USD 200,USD,1.1295 2022-01-03T15:04:47.514435Z,TSLA,SELL - MARKET,1,USD 1153.59,USD 1153.57,USD,1.1309 2022-01-03T17:21:55.035249Z,ANSS,BUY - MARKET,2,USD 393.43,USD 786.86,USD,1.1288 2022-01-03T20:22:20.865769Z,TSLA,SELL - MARKET,0.5,USD 1194.86,USD 597.42,USD,1.1302 2022-01-04T05:38:05.560396Z,BAC,DIVIDEND,,,USD 1.78,USD,1.1307 2022-01-04T10:52:06.498921Z,,CUSTODY FEE,,,USD -1.16,USD,1.1303 2022-01-06T14:54:57.808284Z,TSLA,BUY - LIMIT,1,USD 1050,USD 1050,USD,1.1330 2022-01-11T14:44:35.020133Z,AAPL,BUY - LIMIT,6,USD 171,USD 1026,USD,1.1324 2022-02-02T13:11:56.907881Z,,CUSTODY FEE,,,USD -1.22,USD,1.1324 2022-02-02T14:35:03.638282Z,PYPL,SELL - MARKET,2.8,USD 136.33,USD 381.71,USD,1.1317 2022-02-02T14:38:16.310927Z,GOOGL,BUY - MARKET,0.1370781,USD 3006.68,USD 412.15,USD,1.1318 2022-02-15T05:59:54.545870Z,AAPL,DIVIDEND,,,USD 6.17,USD,1.1320 2022-02-17T19:14:51.499522Z,KO,SELL - LIMIT,10,USD 62,USD 619.99,USD,1.1365 2022-02-18T14:43:59.084299Z,TSLA,BUY - MARKET,0.5,USD 863.86,USD 431.93,USD,1.1344 2022-02-18T16:23:53.036317Z,O,BUY - MARKET,2,USD 67.03,USD 134.06,USD,1.1336 2022-02-28T12:59:53.335490Z,,CASH TOP-UP,,,USD 250,USD,1.1198 2022-02-28T14:38:21.778362Z,KO,BUY - MARKET,2,USD 61.93,USD 123.86,USD,1.1225 2022-03-02T06:56:23.623381Z,,CUSTODY FEE,,,USD -1.16,USD,1.1104 2022-03-02T16:10:30.245886Z,MSFT,BUY - MARKET,0.62199751,USD 297.67,USD 185.15,USD,1.1092 2022-03-16T05:35:16.177499Z,O,DIVIDEND,,,USD 0.42,USD,1.0978 2022-03-22T15:06:09.673524Z,TSLA,SELL - MARKET,0.5,USD 942.18,USD 471.08,USD,1.1033 2022-03-25T09:15:31.379423Z,,CASH WITHDRAWAL,,,USD -257.83,USD,1.1004 2022-03-28T04:32:31.012802Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0955 2022-04-02T04:06:59.837476Z,,CUSTODY FEE,,,USD -1.24,USD,1.1051 2022-04-04T04:35:23.159499Z,KO,DIVIDEND,,,USD 0.75,USD,1.1051 2022-04-13T19:27:21.376535Z,AAPL,BUY - MARKET,1,USD 170.66,USD 170.66,USD,1.0892 2022-04-14T11:17:15.965883Z,,CASH TOP-UP,,,USD 200,USD,1.0905 2022-04-14T13:30:19.229173Z,TWTR,BUY - LIMIT,4,USD 48.42,USD 193.68,USD,1.0829 2022-04-19T05:08:35.489675Z,O,DIVIDEND,,,USD 0.42,USD,1.0772 2022-04-19T13:30:44.030267Z,TWTR,BUY - LIMIT,1,USD 47.24,USD 47.24,USD,1.0798 2022-04-20T17:05:03.527689Z,O,SELL - LIMIT,2,USD 75,USD 149.99,USD,1.0848 2022-04-22T13:56:13.446949Z,O,BUY - LIMIT,2,USD 74,USD 148,USD,1.0817 2022-05-03T04:22:39.919354Z,,CUSTODY FEE,,,USD -1.11,USD,1.0519 2022-05-16T05:21:24.813176Z,O,DIVIDEND,,,USD 0.42,USD,1.0410 2022-05-16T05:26:42.889192Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0407 2022-05-20T08:17:11.587079Z,,CASH TOP-UP,,,USD 150,USD,1.0562 2022-05-20T13:30:08.229515Z,AAPL,BUY - LIMIT,1,USD 139.02,USD 139.02,USD,1.0564 2022-06-02T05:19:39.349765Z,,CUSTODY FEE,,,USD -1.05,USD,1.0657 2022-06-06T05:21:09.168520Z,AMZN,STOCK SPLIT,4.55768808,,USD 0,USD,1.0738 2022-06-07T15:18:23.292832Z,,CASH TOP-UP,,,USD 10,USD,1.0702 2022-06-07T15:19:02.548830Z,AMZN,BUY - MARKET,0.2024336,USD 122.26,USD 24.75,USD,1.0700 2022-06-10T04:51:36.764084Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0635 2022-06-16T04:24:09.940734Z,O,DIVIDEND,,,USD 0.42,USD,1.0441 2022-06-27T04:21:07.933377Z,BAC,DIVIDEND,,,USD 1.78,USD,1.0571 2022-07-02T10:16:19.663439Z,,CUSTODY FEE,,,USD -0.96,USD,1.0432 2022-07-05T04:30:14.263191Z,KO,DIVIDEND,,,USD 0.75,USD,1.0442 2022-07-18T04:23:43.057183Z,O,DIVIDEND,,,USD 0.42,USD,1.0105 2022-07-18T05:13:29.606545Z,GOOGL,STOCK SPLIT,7.48489705,,USD 0,USD,1.0100 2022-07-21T16:32:01.558198Z,AAPL,SELL - LIMIT,1,USD 155.04,USD 155.02,USD,1.0194 2022-07-29T15:15:54.355733Z,,CASH TOP-UP,,,USD 150,USD,1.0209 2022-08-02T14:00:10.449611Z,,CUSTODY FEE,,,USD -1.13,USD,1.0210 2022-08-16T06:38:59.962142Z,AAPL,DIVIDEND,,,USD 6.65,USD,1.0171 2022-08-16T06:48:27.180503Z,O,DIVIDEND,,,USD 0.42,USD,1.0165 2022-08-25T08:29:28.839969Z,TSLA,STOCK SPLIT,6,,USD 0,USD,0.9997 2022-09-03T11:43:40.762285Z,,CUSTODY FEE,,,USD -1.08,USD,0.9961 2022-09-12T05:35:58.495990Z,MSFT,DIVIDEND,,,USD 0.33,USD,1.0096 2022-09-14T14:19:49.128161Z,AAPL,BUY - LIMIT,2,USD 155.78,USD 311.56,USD,0.9982 2022-09-16T05:17:20.255485Z,O,DIVIDEND,,,USD 0.42,USD,0.9995 2022-10-03T04:32:31.694830Z,BAC,DIVIDEND,,,USD 1.87,USD,0.9807 2022-10-04T04:31:18.366499Z,,CUSTODY FEE,,,USD -1,USD,0.9841 2022-10-04T06:15:22.053724Z,KO,DIVIDEND,,,USD 0.75,USD,0.9861 2022-10-05T14:17:47.799690Z,TWTR,SELL - MARKET,5,USD 50.93,USD 254.64,USD,0.9852 2022-10-17T04:30:26.662073Z,O,DIVIDEND,,,USD 0.42,USD,0.9748 2022-11-02T09:58:08.362246Z,,CUSTODY FEE,,,USD -1,USD,0.9906 2022-11-11T10:43:43.775454Z,AAPL,DIVIDEND,,,USD 7.04,USD,1.0271 2022-11-16T06:44:25.085056Z,O,DIVIDEND,,,USD 0.42,USD,1.0383 2022-12-02T06:58:53.260720Z,,CUSTODY FEE,,,USD -0.97,USD,1.0532 2022-12-09T07:49:09.937455Z,MSFT,DIVIDEND,,,USD 0.36,USD,1.0582 2022-12-16T06:53:22.378091Z,KO,DIVIDEND,,,USD 0.75,USD,1.0667 2022-12-16T06:58:57.301385Z,O,DIVIDEND,,,USD 0.42,USD,1.0662 2022-12-20T14:35:52.087523Z,AAPL,BUY - LIMIT,2,USD 130,USD 260,USD,1.0620 2023-01-03T05:33:54.622583Z,BAC,DIVIDEND,,,USD 1.87,USD,1.0672 2023-01-04T09:51:33.829102Z,,CUSTODY FEE,,,USD -0.84,USD,1.0625 2023-01-17T05:40:19.551093Z,O,DIVIDEND,,,USD 0.35,USD,1.0831 2023-01-23T16:49:31.990Z,AAPL,SELL - LIMIT,2,USD 143,USD 285.98,USD,1.0868 2023-01-23T16:50:31.944Z,TSLA,BUY - MARKET,2,USD 141.48,USD 282.96,USD,1.0866 2023-01-26T14:30:02.502Z,TSLA,SELL - LIMIT,2,USD 159.99,USD 319.96,USD,1.0901 2023-01-30T15:28:04.951Z,AAPL,BUY - MARKET,2,USD 143.94,USD 287.88,USD,1.0889 2023-02-01T04:47:19.689616Z,,CUSTODY FEE,,,USD -0.95,USD,1.0871 2023-02-16T07:10:29.099680Z,O,DIVIDEND,,,USD 0.35,USD,1.0707 2023-02-17T07:05:43.640146Z,AAPL,DIVIDEND,,,USD 6.12,USD,1.0641 2023-03-01T11:12:23.865134Z,,CASH TOP-UP,,,USD 250,USD,1.0669 2023-03-01T14:45:06.338Z,BRK.B,BUY - LIMIT,1,USD 303.16,USD 303.16,USD,1.0685 2023-03-02T08:37:29.518195Z,,CUSTODY FEE,,,USD -1,USD,1.0636 2023-03-13T05:01:07.362448Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0731 2023-03-16T05:53:51.457497Z,O,DIVIDEND,,,USD 0.36,USD,1.0618 2023-03-22T14:28:40.213Z,AAPL,SELL - LIMIT,2,USD 160,USD 319.98,USD,1.0794 2023-04-03T04:34:36.432266Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0809 2023-04-04T07:43:19.011071Z,KO,DIVIDEND,,,USD 0.64,USD,1.0919 2023-04-04T10:05:57.474134Z,,CUSTODY FEE,,,USD -1.08,USD,1.0941 2023-04-17T05:14:59.411865Z,O,DIVIDEND,,,USD 0.36,USD,1.1000 2023-05-02T16:58:09.717081Z,,CUSTODY FEE,,,USD -1.07,USD,1.1010 2023-05-05T13:33:41.989Z,AAPL,SELL - LIMIT,2,USD 172,USD 343.98,USD,1.0998 2023-05-08T16:49:22.657920Z,,CASH TOP-UP,,,USD 150,USD,1.1037 2023-05-08T16:50:05.075Z,TSLA,BUY - MARKET,1,USD 171.76,USD 171.76,USD,1.1037 2023-05-16T05:28:06.065980Z,O,DIVIDEND,,,USD 0.36,USD,1.0890 2023-05-19T06:32:05.730565Z,AAPL,DIVIDEND,,,USD 5.71,USD,1.0800 2023-05-23T13:45:40.451Z,TSLA,SELL - LIMIT,1,USD 190,USD 189.98,USD,1.0783 2023-05-23T13:53:42.530Z,AAPL,BUY - MARKET,1,USD 172.79,USD 172.79,USD,1.0783 2023-05-25T13:41:55.501Z,MSFT,SELL - MARKET,0.62199751,USD 321.63,USD 200.03,USD,1.0722 2023-05-26T14:28:00.905Z,TSLA,BUY - MARKET,1,USD 190.12,USD 190.12,USD,1.0743 2023-06-02T08:57:47.333209Z,,CUSTODY FEE,,,USD -1.13,USD,1.0788 2023-06-02T13:30:02.757Z,TSLA,SELL - LIMIT,1,USD 210,USD 209.98,USD,1.0779 2023-06-05T11:24:00.663315Z,,CASH TOP-UP,,,USD 100,USD,1.0703 2023-06-06T07:53:30.801799Z,,CASH WITHDRAWAL,,,USD -200,USD,1.0725 2023-06-06T15:58:37.683Z,AAPL,BUY - MARKET,4,USD 178.62,USD 714.50,USD,1.0706 2023-06-09T06:10:29.033529Z,MSFT,DIVIDEND,,,USD 0.29,USD,1.0787 2023-06-14T15:52:32.276Z,BRK.B,SELL - LIMIT,1,USD 340,USD 339.98,USD,1.0868 2023-06-14T16:30:12.174Z,TSLA,BUY - MARKET,1,USD 258,USD 258,USD,1.0872 2023-06-15T13:53:37.361Z,AAPL,SELL - LIMIT,19,USD 185.01,USD 3515.15,USD,1.0909 2023-06-15T14:32:54.586Z,BRK.B,BUY - MARKET,4,USD 338.24,USD 1352.95,USD,1.0927 2023-06-16T04:49:46.803865Z,O,DIVIDEND,,,USD 0.36,USD,1.0954 2023-06-20T17:34:39.166Z,TSLA,BUY - MARKET,2,USD 271.03,USD 542.06,USD,1.0929 2023-06-30T15:35:47.990Z,AAPL,BUY - MARKET,4,USD 192.45,USD 769.79,USD,1.0928 2023-07-03T04:42:47.064493Z,BAC,DIVIDEND,,,USD 1.54,USD,1.0929 2023-07-04T06:14:58.867435Z,,CUSTODY FEE,,,USD -1.19,USD,1.0914 2023-07-05T04:38:30.594392Z,KO,DIVIDEND,,,USD 0.64,USD,1.0888 2023-07-17T04:29:28.019975Z,O,DIVIDEND,,,USD 0.36,USD,1.1239 2023-07-19T13:58:34.924Z,TSLA,BUY - MARKET,3,USD 296.58,USD 889.74,USD,1.1228 2023-08-02T09:34:03.883636Z,,CUSTODY FEE,,,USD -1.31,USD,1.0994 2023-08-16T04:35:04.390352Z,O,DIVIDEND,,,USD 0.36,USD,1.0928 2023-08-18T04:57:05.333405Z,AAPL,DIVIDEND,,,USD 4.03,USD,1.0901 2023-09-02T03:13:46.440774Z,,CUSTODY FEE,,,USD -1.27,USD,1.0790 2023-09-09T08:05:14.452584Z,,TRANSFER FROM REVOLUT BANK UAB TO REVOLUT SECURITIES EUROPE UAB,,,USD 117.44,USD,1.0719 2023-09-09T09:34:24.443702Z,GOOGL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,7.878839,,USD 0,USD,1.0719 2023-09-09T09:34:24.561658Z,O,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:24.660297Z,TSLA,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,15,,USD 0,USD,1.0719 2023-09-09T09:34:24.767410Z,BAC,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,10,,USD 0,USD,1.0719 2023-09-09T09:34:24.873457Z,BRK.B,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,4,,USD 0,USD,1.0719 2023-09-09T09:34:24.979123Z,KO,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.079904Z,ANSS,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,2,,USD 0,USD,1.0719 2023-09-09T09:34:25.189128Z,AMZN,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,5,,USD 0,USD,1.0719 2023-09-09T09:34:25.292873Z,AAPL,TRANSFER FROM REVOLUT TRADING LTD TO REVOLUT SECURITIES EUROPE UAB,24,,USD 0,USD,1.0719 2023-09-13T15:07:29.260651Z,,CASH TOP-UP,,,USD 11.76,USD,1.0756 2023-09-13T15:08:11.622299Z,,CASH TOP-UP,,,USD 400,USD,1.0757 2023-09-13T15:09:28.691Z,AAPL,BUY - LIMIT,3,USD 175.02,USD 525.05,USD,1.0757 2023-09-18T10:59:47.342077Z,O,DIVIDEND,,,USD 0.36,USD,1.0686 2023-10-01T07:39:16.220080Z,,CUSTODY FEE,,,USD -1.25,USD,1.0595 2023-10-02T11:08:11.013935Z,BAC,DIVIDEND,,,USD 1.68,USD,1.0550 2023-10-03T12:35:09.127138Z,KO,DIVIDEND,,,USD 0.78,USD,1.0488 2023-10-16T13:27:58.306547Z,O,DIVIDEND,,,USD 0.43,USD,1.0557 2023-11-02T07:47:24.136368Z,,CUSTODY FEE,,,USD -1.17,USD,1.0617 2023-11-16T12:42:39.810501Z,O,DIVIDEND,,,USD 0.43,USD,1.0863 2023-11-16T14:31:16.694Z,AAPL,SELL - LIMIT,6,USD 190,USD 1139.98,USD,1.0885 2023-11-17T18:26:36.033179Z,AAPL,DIVIDEND,,,USD 5.51,USD,1.0913 2023-12-01T10:05:46.401211Z,,CUSTODY FEE,,,USD -1.19,USD,1.0922 2023-12-13T13:32:17.638Z,AAPL,SELL - LIMIT,7,USD 196,USD 1371.98,USD,1.0814 2023-12-14T11:33:48.192861Z,,CASH WITHDRAWAL,,,USD -490,USD,1.0942 2023-12-14T11:42:42.236702Z,,CASH WITHDRAWAL,,,USD -540,USD,1.0945 2023-12-14T11:44:57.481825Z,,CASH TOP-UP,,,EUR 493.36,EUR,1.0000 2023-12-14T11:46:14.224594Z,,CASH TOP-UP,,,EUR 22.55,EUR,1.0000 2023-12-14T11:46:28.633Z,EUNL,BUY - MARKET,6,EUR 81.89,EUR 491.33,EUR,1.0000 2023-12-14T11:46:58.960291Z,,CASH WITHDRAWAL,,,EUR -22.55,EUR,1.0000 2023-12-18T14:35:49.692078Z,O,DIVIDEND,,,USD 0.43,USD,1.0945 2023-12-18T14:42:19.088Z,AAPL,BUY - LIMIT,2,USD 195,USD 390,USD,1.0946 2023-12-18T16:03:32.089281Z,KO,DIVIDEND,,,USD 0.78,USD,1.0937 2023-12-22T14:53:30.293Z,ANSS,SELL - MARKET,2,USD 334.81,USD 669.60,USD,1.1060 2023-12-22T14:55:28Z,AAPL,BUY - MARKET,3,USD 195.24,USD 585.73,USD,1.1059 2023-12-29T17:03:07.509Z,AAPL,BUY - MARKET,3,USD 192.32,USD 576.95,USD,1.1082 2024-01-01T07:00:29.342845Z,,CUSTODY FEE,,,USD -1.18,USD,1.1060 2024-01-01T07:00:29.400142Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-01-03T17:20:49.193495Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0927 2024-01-08T09:32:34.413Z,AAPL,BUY - LIMIT,3,USD 180,USD 540,USD,1.0945 2024-01-16T12:06:46.872915Z,O,DIVIDEND,,,USD 0.43,USD,1.0909 2024-01-25T14:32:03.923Z,BRK.B,SELL - LIMIT,4,USD 380,USD 1519.98,USD,1.0876 2024-01-25T14:46:38.746Z,TSLA,SELL - MARKET,3,USD 187.76,USD 563.25,USD,1.0875 2024-01-25T14:53:37.441Z,NVDA,BUY - MARKET,3,USD 621.78,USD 1865.35,USD,1.0876 2024-01-29T15:13:05.633327Z,,CASH WITHDRAWAL,,,USD -288.99,USD,1.0829 2024-01-31T16:53:08.153Z,TSLA,SELL - LIMIT,3,USD 190,USD 569.98,USD,1.0877 2024-01-31T17:17:42.114Z,MSFT,BUY - MARKET,1,USD 402.58,USD 402.58,USD,1.0869 2024-02-01T03:25:42.443177Z,,CUSTODY FEE,,,USD -1.10,USD,1.0837 2024-02-01T03:25:42.504846Z,,CUSTODY FEE,,,EUR -0.05,EUR,1.0000 2024-02-02T18:27:54.549Z,AMZN,SELL - MARKET,5,USD 171.96,USD 859.78,USD,1.0804 2024-02-02T18:28:56.258Z,NVDA,BUY - MARKET,1,USD 659.78,USD 659.78,USD,1.0805 2024-02-02T18:42:33.310Z,AAPL,BUY - MARKET,1,USD 186.01,USD 186.01,USD,1.0809 2024-02-05T19:01:24.403Z,TSLA,SELL - MARKET,3,USD 181.48,USD 544.43,USD,1.0765 2024-02-05T19:13:49.716Z,NVDA,BUY - MARKET,1,USD 688.87,USD 688.87,USD,1.0765 2024-02-09T18:38:36.240Z,NVDA,SELL - LIMIT,3,USD 720,USD 2159.97,USD,1.0809 2024-02-09T19:04:23.041Z,TSLA,SELL - MARKET,4,USD 192.78,USD 771.11,USD,1.0811 2024-02-13T14:35:34.549398Z,,CASH WITHDRAWAL,,,USD -755.30,USD,1.0737 2024-02-16T15:48:11.314342Z,O,DIVIDEND,,,USD 0.43,USD,1.0796 2024-02-16T17:20:34.309565Z,AAPL,DIVIDEND,,,USD 5.30,USD,1.0789 2024-02-21T21:25:57.106Z,NVDA,BUY - LIMIT,3,USD 679,USD 2037,USD,1.0838 2024-03-01T09:08:46.556Z,TSLA,SELL - LIMIT,2,USD 201.22,USD 402.43,USD,1.0834 2024-03-05T17:02:20.128Z,BRK.B,BUY - LIMIT,1,USD 400,USD 400,USD,1.0882 2024-03-11T09:45:10.733671Z,,CASH TOP-UP,,,USD 1091.80,USD,1.0964 2024-03-11T09:45:57.889Z,NVDA,BUY - LIMIT,1,USD 889.33,USD 889.33,USD,1.0964 2024-03-11T14:04:39.233521Z,,CASH TOP-UP,,,USD 126.74,USD,1.0941 2024-03-15T12:28:23.824579Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0914 2024-03-18T13:44:16.977280Z,O,DIVIDEND,,,USD 0.43,USD,1.0912 2024-03-28T12:59:32.090109Z,NVDA,DIVIDEND,,,USD 0.17,USD,1.0831 2024-04-01T14:18:52.459Z,AAPL,BUY - LIMIT,3,USD 170,USD 510,USD,1.0768 2024-04-02T17:32:27.807174Z,KO,DIVIDEND,,,USD 0.82,USD,1.0788 2024-04-02T17:50:08.293837Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0789 2024-04-12T13:53:08.110Z,GOOGL,SELL - LIMIT,5,USD 160,USD 799.98,USD,1.0659 2024-04-16T11:57:48.211880Z,O,DIVIDEND,,,USD 0.43,USD,1.0668 2024-04-22T13:42:17.982936Z,,CASH WITHDRAWAL,,,USD -720,USD,1.0653 2024-04-22T13:43:26.153902Z,,CASH TOP-UP,,,EUR 675.75,EUR,1.0000 2024-04-22T13:44:05.671Z,EUNL,BUY - MARKET,7,EUR 88.42,EUR 618.93,EUR,1.0000 2024-04-26T13:30:00.940Z,GOOGL,SELL - MARKET,2.878839,USD 174.33,USD 501.85,USD,1.0733 2024-04-30T14:37:07.030880Z,,CASH WITHDRAWAL,,,USD -398.79,USD,1.0728 2024-05-16T08:51:27.652167Z,O,DIVIDEND,,,USD 0.43,USD,1.0895 2024-05-17T10:26:14.210180Z,AAPL,DIVIDEND,,,USD 6.16,USD,1.0867 2024-05-20T13:54:41.117Z,NVDA,SELL - LIMIT,1,USD 950,USD 949.98,USD,1.0889 2024-05-22T21:14:39.325Z,NVDA,SELL - LIMIT,5,USD 1000,USD 4999.85,USD,1.0847 2024-05-28T15:44:41.483Z,NVDA,BUY - MARKET,3,USD 1120.59,USD 3361.77,USD,1.0899 2024-06-05T10:11:57.724Z,KO,SELL - LIMIT,2,USD 63.92,USD 127.83,USD,1.0890 2024-06-06T12:20:06.768Z,NVDA,BUY - LIMIT,2,USD 1249.18,USD 2498.35,USD,1.0907 2024-06-10T12:35:45.964651Z,NVDA,STOCK SPLIT,45,,USD 0,USD,1.0778 2024-06-11T14:16:51.891Z,AAPL,SELL - LIMIT,6,USD 200,USD 1199.96,USD,1.0748 2024-06-12T13:53:20.883Z,AAPL,BUY - MARKET,7,USD 213.95,USD 1497.64,USD,1.0856 2024-06-14T10:17:31.111265Z,MSFT,DIVIDEND,,,USD 0.64,USD,1.0709 2024-06-17T10:18:03.287961Z,O,DIVIDEND,,,USD 0.44,USD,1.0728 2024-06-17T18:01:31.892Z,MSFT,SELL - LIMIT,1,USD 450,USD 449.98,USD,1.0750 2024-06-20T15:19:16.531Z,AAPL,BUY - LIMIT,2,USD 210,USD 420,USD,1.0741 2024-07-01T11:01:29.101517Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.0772 2024-07-01T12:19:36.098603Z,BAC,DIVIDEND,,,USD 2.04,USD,1.0768 2024-07-02T15:09:31.105Z,AAPL,SELL - LIMIT,9,USD 220,USD 1979.93,USD,1.0762 2024-07-03T14:43:34.756Z,TSLA,BUY - MARKET,2,USD 247.92,USD 495.85,USD,1.0825 2024-07-11T12:30:08.457Z,BAC,SELL - LIMIT,10,USD 42,USD 419.98,USD,1.0899 2024-07-11T13:25:05.444Z,TSM,BUY - LIMIT,10,USD 193.86,USD 1938.61,USD,1.0915 2024-07-16T08:59:29.967862Z,O,DIVIDEND,,,USD 0.44,USD,1.0923 2024-07-17T14:40:33.756Z,O,SELL - MARKET,2,USD 57.17,USD 114.32,USD,1.0957 2024-07-23T14:02:29.334480Z,,CASH TOP-UP,,,EUR 800,EUR,1.0000 2024-07-23T14:03:16.459Z,EXXT,BUY - MARKET,4.84403203,EUR 177.28,EUR 858.75,EUR,1.0000 2024-07-30T13:34:15.782Z,BRK.B,SELL - LIMIT,1,USD 440,USD 439.98,USD,1.0832 2024-08-01T21:50:35.835874Z,,CASH TOP-UP,,,USD 1077.48,USD,1.0809 2024-08-01T21:51:25.637Z,AAPL,BUY - LIMIT,5,USD 218.85,USD 1094.25,USD,1.0809 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,2,USD 204.90,USD 409.80,USD,1.0966 2024-08-05T08:00:00.036Z,AAPL,BUY - LIMIT,1,USD 204.90,USD 204.90,USD,1.0966 2024-08-16T15:20:28.266341Z,AAPL,DIVIDEND,,,USD 6.59,USD,1.1011 2024-08-29T11:33:30.727Z,AAPL,SELL - LIMIT,5,USD 230,USD 1149.96,USD,1.1113 2024-09-05T08:59:30.602Z,TSLA,SELL - LIMIT,2,USD 225.22,USD 450.43,USD,1.1118 2024-10-04T10:47:03.807610Z,NVDA,DIVIDEND,,,USD 0.42,USD,1.1053 2024-10-10T08:38:54.394212Z,TSM,DIVIDEND,,,USD 4.93,USD,1.0958 2024-10-11T14:46:49.313Z,TSM,SELL - MARKET,10,USD 189.81,USD 1898.01,USD,1.0965 2024-10-17T10:50:43.300Z,NVDA,SELL - LIMIT,10,USD 140,USD 1399.95,USD,1.0885 2024-11-06T15:32:35.795880Z,,CASH TOP-UP,,,USD 34.98,USD,1.0750 2024-11-06T15:32:48.038Z,AAPL,BUY - MARKET,21,USD 225.81,USD 4741.95,USD,1.0750 2024-11-06T15:33:20.894832Z,,CASH WITHDRAWAL,,,USD -34.98,USD,1.0748 2024-11-15T10:57:21.547072Z,AAPL,DIVIDEND,,,USD 9.99,USD,1.0596 2024-11-25T15:51:08.045065Z,,CASH TOP-UP,,,USD 1004,USD,1.0525 2024-11-25T15:51:44.437Z,NVDA,BUY - MARKET,8,USD 137.70,USD 1101.58,USD,1.0526 2024-11-26T14:35:15.260Z,AAPL,SELL - LIMIT,9,USD 235,USD 2114.93,USD,1.0517 2024-11-29T12:41:10.527444Z,,CASH WITHDRAWAL,,,USD -2000,USD,1.0574 2024-12-18T15:56:03.404813Z,EXXT,DIVIDEND,,,EUR 0.51,EUR,1.0000 2024-12-18T18:45:05.272532Z,,CASH TOP-UP,,,USD 2006.76,USD,1.0513 2024-12-18T18:45:59.510540Z,,CASH WITHDRAWAL,,,USD -2240.70,USD,1.0514 2024-12-18T18:47:39.084460Z,,CASH TOP-UP,,,EUR 2133.85,EUR,1.0000 2024-12-18T18:49:15.187Z,EXXT,BUY - LIMIT,10,EUR 203.80,EUR 2038,EUR,1.0000 2024-12-19T08:40:07.479915Z,,CASH TOP-UP,,,USD 0.02,USD,1.0415 2024-12-30T10:55:50.865219Z,NVDA,DIVIDEND,,,USD 0.41,USD,1.0464 2025-01-06T14:49:38.005Z,NVDA,SELL - LIMIT,20,USD 150,USD 2999.91,USD,1.0408 2025-01-07T09:50:04.477942Z,,CASH WITHDRAWAL,,,USD -3000,USD,1.0449 2025-01-07T15:54:48.223347Z,,CASH TOP-UP,,,USD 3001.30,USD,1.0396 2025-01-07T15:56:07.411Z,NVDA,BUY - LIMIT,21,USD 142.77,USD 2998.17,USD,1.0396 2025-01-28T08:48:36.329627Z,,CASH TOP-UP,,,USD 245,USD,1.0451 2025-01-28T09:07:04.086Z,NVDA,BUY - LIMIT,2,USD 123.58,USD 247.17,USD,1.0449 2025-02-14T20:37:33.255111Z,AAPL,DIVIDEND,,,USD 8.08,USD,1.0521 2025-03-19T15:56:49.384716Z,EXXT,DIVIDEND,,,EUR 1.67,EUR,1.0000 2025-04-03T15:56:21.046251Z,NVDA,DIVIDEND,,,USD 0.43,USD,1.1083 2025-05-16T18:36:19.943256Z,AAPL,DIVIDEND,,,USD 8.40,USD,1.1172 2025-05-28T20:38:28.721Z,NVDA,SELL - LIMIT,20,USD 140,USD 2799.99,USD,1.1318 2025-05-29T22:34:38.868352Z,,CASH WITHDRAWAL,,,USD -2818.20,USD,1.1398 2025-06-18T14:58:51.657905Z,EXXT,DIVIDEND,,,EUR 3.70,EUR,1.0000 2025-07-02T11:16:20.772081Z,,CASH TOP-UP,,,USD 2000,USD,1.1797 2025-07-03T14:46:34.490Z,NVDA,BUY - LIMIT,12,USD 159.89,USD 1918.68,USD,1.1784 2025-07-10T07:34:53.882147Z,NVDA,DIVIDEND,,,USD 0.26,USD,1.1761 2025-08-08T15:39:25.511Z,AAPL,SELL - LIMIT,3,USD 225,USD 674.99,USD,1.1692 2025-08-14T23:12:20.834326Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1674 2025-08-20T17:26:50.819936Z,,CASH WITHDRAWAL,,,USD -764.31,USD,1.1692 2025-10-02T19:05:09.782319Z,NVDA,DIVIDEND,,,USD 0.37,USD,1.1750 2025-10-16T08:44:53.616001Z,,CASH TOP-UP,,,USD 1502.57,USD,1.1685 2025-10-16T08:47:26.528Z,NVDA,BUY - LIMIT,8,USD 181.79,USD 1454.35,USD,1.1686 2025-11-11T15:34:00.722Z,AAPL,SELL - MARKET,5,USD 273.91,USD 1369.52,USD,1.1626 2025-11-11T16:59:52.307677Z,,CASH TOP-UP,,,USD 500,USD,1.1619 2025-11-11T18:05:47.274Z,NVDA,BUY - LIMIT,9,USD 193.60,USD 1742.36,USD,1.1619 2025-11-11T18:06:31.280523Z,,CASH WITHDRAWAL,,,USD -175,USD,1.1618 2025-11-13T21:09:36.155137Z,AAPL,DIVIDEND,,,USD 7.74,USD,1.1658 ======================================================================================== FICHEIRO: dados_csv/tiago/historico-ativos.csv Tamanho: 3416 bytes ======================================================================================== Período,EURUSD,AAPL,TSLA,NVDA,GOOGL ,1.1643,280.68,450.20,183.45,317.62 2018/12/31,0.8760,39.44,22.19,33.38, 2019/01/31,0.8850,41.61,20.47,35.94, 2019/02/28,0.8920,43.29,21.33,38.57, 2019/03/31,0.9000,47.81,19.28,45.57, 2019/04/30,0.9200,50.17,15.91,45.25, 2019/05/31,0.9500,43.77,12.34,33.87, 2019/06/30,0.9700,50.39,15.14,41.54, 2019/07/31,0.9750,53.26,16.11,42.18, 2019/08/31,0.9600,51.43,15.00,41.04, 2019/09/30,0.9200,55.99,16.06,43.52, 2019/10/31,0.8800,62.19,20.99,50.26, 2019/11/30,0.8800,66.04,22.32,52.31, 2019/12/31,0.8500,73.41,27.89,58.83, 2020/01/31,0.8800,77.38,43.37,59.11, 2020/02/29,0.8600,74.70,49.57,69.11, 2020/03/31,0.8500,63.57,34.93,65.90, 2020/04/30,0.8600,73.45,52.13,73.07, 2020/05/31,0.8600,80.46,59.87,88.06, 2020/06/30,0.8600,91.20,71.99,94.98, 2020/07/31,0.8600,106.26,95.38,106.15, 2020/08/31,0.8600,129.04,166.11,133.75, 2020/09/30,0.8300,115.81,143.00,135.31, 2020/10/31,0.8300,108.77,133.50,125.81, 2020/11/30,0.8300,119.05,189.20,134.01, 2020/12/31,0.8300,132.69,235.22,130.55, 2021/01/31,0.8200,134.14,279.94,132.37, 2021/02/28,0.8400,127.79,239.48,138.42, 2021/03/31,0.8400,122.15,222.64,133.48, 2021/04/30,0.8300,131.46,236.48,150.10, 2021/05/31,0.8200,124.28,207.97,162.65, 2021/06/30,0.8500,136.96,226.57,200.03, 2021/07/31,0.8600,145.52,236.56,197.50, 2021/08/31,0.8500,151.83,245.24,223.85, 2021/09/30,0.8600,141.50,258.49,207.16, 2021/10/31,0.8800,148.96,402.86,258.27, 2021/11/30,0.8800,165.30,381.59,326.76, 2021/12/31,0.8800,177.57,352.26,294.11, 2022/01/31,0.8800,174.78,312.24,244.86, 2022/02/28,0.8900,165.12,290.14,243.85, 2022/03/31,0.9200,174.61,359.20,272.86, 2022/04/30,0.9400,157.96,300.98,195.33, 2022/05/31,0.9500,148.84,252.75,186.72, 2022/06/30,0.9600,136.72,224.47,151.59, 2022/07/31,0.9700,161.51,297.28,184.41, 2022/08/31,0.9800,157.22,275.61,150.94, 2022/09/30,0.9700,138.20,265.25,121.39, 2022/10/31,0.9700,153.34,227.54,134.97, 2022/11/30,0.9800,148.03,194.70,169.23, 2022/12/30,0.9900,129.93,123.18,146.14, 2023/01/31,1.0000,144.29,173.22,195.37, 2023/02/28,1.0100,147.41,205.71,232.16, 2023/03/31,1.0800,164.90,207.46,277.77, 2023/04/30,1.1000,169.59,161.83,289.10, 2023/05/31,1.0800,177.25,203.93,378.34, 2023/06/30,1.0900,193.97,261.77,423.02, 2023/07/31,1.1100,196.45,267.43,467.29, 2023/08/31,1.0900,187.87,258.08,493.55, 2023/09/30,1.0600,173.75,251.60,447.82, 2023/10/31,1.0600,170.77,200.84,407.80, 2023/11/30,1.0900,189.95,240.08,467.70, 2023/12/31,1.1000,192.53,248.48,495.22, 2024/01/31,1.0800,184.40,187.29,61.53, 2024/02/29,1.0800,180.75,201.88,79.11, 2024/03/31,1.0800,170.03,175.22,90.36, 2024/04/30,1.0700,170.33,183.28,86.40, 2024/05/31,1.0800,192.25,178.08,109.63, 2024/06/27,1.0700,210.62,197.88,123.54, 2024/07/30,1.0900,222.08,232.07,117.02, 2024/08/31,1.1100,222.77,210.60,108.00, 2024/09/30,1.1100,233.00,261.63,121.44, 2024/10/31,1.0900,225.91,249.85,132.76, 2024/11/30,1.0800,239.59,357.09,134.29, 2024/12/31,1.0500,250.42,403.84,120.07, 2025/01/31,1.0800,236.00,292.98,124.92, 2025/02/28,1.0900,241.84,259.16,108.38, 2025/03/31,1.0900,222.13,282.16,108.92, 2025/04/30,1.1000,212.50,342.69,137.38, 2025/05/31,1.1200,201.70,317.66,157.99, 2025/06/30,1.1300,205.17,308.27,177.87, 2025/07/31,1.1400,207.57,329.36,170.78, 2025/08/31,1.1500,229.72,444.72,186.58, 2025/09/30,1.1600,254.63,456.56,202.49, 2025/10/31,1.1600,270.37,430.14,179.92, 2025/11/30,1.1600,283.10,454.48,183.38, 2025/12/31,1.1643,280.68,450.20,183.45,317.62 ======================================================================================== FICHEIRO: dados_csv/tiago/historico-cambio-date.txt Tamanho: 19 bytes ======================================================================================== 2025-12-08 17:36:36 ======================================================================================== FICHEIRO: dados_csv/tiago/historico-cambio.json Tamanho: 8403 bytes ======================================================================================== { "2019-09-30": 1.0938, "2019-10-07": 1.1007, "2019-10-14": 1.1064, "2019-10-21": 1.1132, "2019-10-28": 1.1116, "2019-11-04": 1.1094, "2019-11-11": 1.1019, "2019-11-18": 1.1069, "2019-11-25": 1.1005, "2019-12-02": 1.1073, "2019-12-09": 1.1108, "2019-12-16": 1.1127, "2019-12-23": 1.1103, "2019-12-30": 1.1191, "2020-01-06": 1.1136, "2020-01-13": 1.1132, "2020-01-20": 1.1083, "2020-01-27": 1.1022, "2020-02-03": 1.1022, "2020-02-10": 1.0895, "2020-02-17": 1.0808, "2020-02-24": 1.0895, "2020-03-02": 1.1177, "2020-03-09": 1.1305, "2020-03-16": 1.0916, "2020-03-23": 1.0882, "2020-03-30": 1.0923, "2020-04-06": 1.0854, "2020-04-13": 1.0904, "2020-04-20": 1.0827, "2020-04-27": 1.0862, "2020-05-04": 1.0844, "2020-05-11": 1.0829, "2020-05-18": 1.0929, "2020-05-25": 1.1006, "2020-06-01": 1.1213, "2020-06-08": 1.1321, "2020-06-15": 1.1245, "2020-06-22": 1.1245, "2020-06-29": 1.1238, "2020-07-06": 1.1304, "2020-07-13": 1.1398, "2020-07-20": 1.1529, "2020-07-27": 1.1759, "2020-08-03": 1.1801, "2020-08-10": 1.1793, "2020-08-17": 1.1862, "2020-08-24": 1.1834, "2020-08-31": 1.1889, "2020-09-07": 1.1817, "2020-09-14": 1.1853, "2020-09-21": 1.17, "2020-09-28": 1.1712, "2020-10-05": 1.1779, "2020-10-12": 1.1755, "2020-10-19": 1.1825, "2020-10-26": 1.1756, "2020-11-02": 1.176, "2020-11-09": 1.1813, "2020-11-16": 1.1855, "2020-11-23": 1.1896, "2020-11-30": 1.2065, "2020-12-07": 1.2119, "2020-12-14": 1.2199, "2020-12-21": 1.2193, "2020-12-28": 1.2258, "2021-01-04": 1.2286, "2021-01-11": 1.2147, "2021-01-18": 1.2123, "2021-01-25": 1.2127, "2021-02-01": 1.2025, "2021-02-08": 1.2102, "2021-02-15": 1.2111, "2021-02-22": 1.2154, "2021-03-01": 1.202, "2021-03-08": 1.1911, "2021-03-15": 1.1911, "2021-03-22": 1.1844, "2021-03-29": 1.1749, "2021-04-05": 1.1864, "2021-04-12": 1.1944, "2021-04-19": 1.2041, "2021-04-26": 1.2091, "2021-05-03": 1.2038, "2021-05-10": 1.2132, "2021-05-17": 1.2194, "2021-05-24": 1.2209, "2021-05-31": 1.2183, "2021-06-07": 1.2168, "2021-06-14": 1.2036, "2021-06-21": 1.1924, "2021-06-28": 1.1878, "2021-07-05": 1.1846, "2021-07-12": 1.1824, "2021-07-19": 1.1771, "2021-07-26": 1.1834, "2021-08-02": 1.1858, "2021-08-09": 1.1741, "2021-08-16": 1.1726, "2021-08-23": 1.1744, "2021-08-30": 1.1834, "2021-09-06": 1.1846, "2021-09-13": 1.1792, "2021-09-20": 1.1722, "2021-09-27": 1.1642, "2021-10-04": 1.1582, "2021-10-11": 1.1579, "2021-10-18": 1.163, "2021-10-25": 1.1615, "2021-11-01": 1.1569, "2021-11-08": 1.1524, "2021-11-15": 1.1349, "2021-11-22": 1.1251, "2021-11-29": 1.1317, "2021-12-06": 1.1285, "2021-12-13": 1.1303, "2021-12-20": 1.1299, "2021-12-27": 1.1321, "2022-01-03": 1.1313, "2022-01-10": 1.1387, "2022-01-17": 1.136, "2022-01-24": 1.1229, "2022-01-31": 1.1298, "2022-02-07": 1.1429, "2022-02-14": 1.1351, "2022-02-21": 1.1281, "2022-02-28": 1.1094, "2022-03-07": 1.0971, "2022-03-14": 1.1001, "2022-03-21": 1.1005, "2022-03-28": 1.1066, "2022-04-04": 1.0935, "2022-04-11": 1.0866, "2022-04-18": 1.0834, "2022-04-25": 1.0606, "2022-05-02": 1.055, "2022-05-09": 1.0492, "2022-05-16": 1.0518, "2022-05-23": 1.0691, "2022-05-30": 1.0722, "2022-06-06": 1.069, "2022-06-13": 1.0445, "2022-06-20": 1.0521, "2022-06-27": 1.0492, "2022-07-04": 1.0253, "2022-07-11": 1.0054, "2022-07-18": 1.0193, "2022-07-25": 1.0166, "2022-08-01": 1.0213, "2022-08-08": 1.0262, "2022-08-15": 1.0144, "2022-08-22": 0.9968, "2022-08-29": 1.0003, "2022-09-05": 0.9958, "2022-09-12": 1.0053, "2022-09-19": 0.9904, "2022-09-26": 0.9662, "2022-10-03": 0.9845, "2022-10-10": 0.9716, "2022-10-17": 0.9779, "2022-10-24": 0.9945, "2022-10-31": 0.9879, "2022-11-07": 1.0058, "2022-11-14": 1.0364, "2022-11-21": 1.0327, "2022-11-28": 1.0439, "2022-12-05": 1.0542, "2022-12-12": 1.0599, "2022-12-19": 1.0618, "2022-12-26": 1.0645, "2023-01-02": 1.0586, "2023-01-09": 1.075, "2023-01-16": 1.0827, "2023-01-23": 1.0873, "2023-01-30": 1.0911, "2023-02-06": 1.0734, "2023-02-13": 1.0694, "2023-02-20": 1.0634, "2023-02-27": 1.0615, "2023-03-06": 1.0599, "2023-03-13": 1.0642, "2023-03-20": 1.078, "2023-03-27": 1.0844, "2023-04-03": 1.0906, "2023-04-10": 1.0975, "2023-04-17": 1.0962, "2023-04-24": 1.1017, "2023-05-01": 1.1024, "2023-05-08": 1.0954, "2023-05-15": 1.0841, "2023-05-22": 1.0774, "2023-05-29": 1.072, "2023-06-05": 1.0721, "2023-06-12": 1.083, "2023-06-19": 1.0929, "2023-06-26": 1.0922, "2023-07-03": 1.0892, "2023-07-10": 1.1074, "2023-07-17": 1.1205, "2023-07-24": 1.1068, "2023-07-31": 1.0971, "2023-08-07": 1.0984, "2023-08-14": 1.0908, "2023-08-21": 1.085, "2023-08-28": 1.0842, "2023-09-04": 1.0738, "2023-09-11": 1.0712, "2023-09-18": 1.0672, "2023-09-25": 1.0581, "2023-10-02": 1.0517, "2023-10-09": 1.0572, "2023-10-16": 1.0564, "2023-10-23": 1.0577, "2023-10-30": 1.0625, "2023-11-06": 1.0694, "2023-11-13": 1.0797, "2023-11-20": 1.0922, "2023-11-27": 1.0938, "2023-12-04": 1.0802, "2023-12-11": 1.0843, "2023-12-18": 1.0966, "2023-12-25": 1.1076, "2024-01-01": 1.0937, "2024-01-08": 1.0952, "2024-01-15": 1.0893, "2024-01-22": 1.0886, "2024-01-29": 1.0841, "2024-02-05": 1.0759, "2024-02-12": 1.0758, "2024-02-19": 1.0813, "2024-02-26": 1.0831, "2024-03-04": 1.0879, "2024-03-11": 1.092, "2024-03-18": 1.0864, "2024-03-25": 1.0829, "2024-04-01": 1.0806, "2024-04-08": 1.0786, "2024-04-15": 1.0653, "2024-04-22": 1.0685, "2024-04-29": 1.072, "2024-05-06": 1.0759, "2024-05-13": 1.0827, "2024-05-20": 1.085, "2024-05-27": 1.085, "2024-06-03": 1.0868, "2024-06-10": 1.0744, "2024-06-17": 1.0717, "2024-06-24": 1.0707, "2024-07-01": 1.0771, "2024-07-08": 1.0844, "2024-07-15": 1.0913, "2024-07-22": 1.0861, "2024-07-29": 1.0819, "2024-08-05": 1.093, "2024-08-12": 1.0976, "2024-08-19": 1.1099, "2024-08-26": 1.1123, "2024-09-02": 1.1069, "2024-09-09": 1.1043, "2024-09-16": 1.1142, "2024-09-23": 1.1152, "2024-09-30": 1.1084, "2024-10-07": 1.0958, "2024-10-14": 1.0886, "2024-10-21": 1.0813, "2024-10-28": 1.0835, "2024-11-04": 1.0811, "2024-11-11": 1.0603, "2024-11-18": 1.0526, "2024-11-25": 1.053, "2024-12-02": 1.0526, "2024-12-09": 1.0522, "2024-12-16": 1.0455, "2024-12-23": 1.0408, "2024-12-30": 1.0363, "2025-01-06": 1.0343, "2025-01-13": 1.0263, "2025-01-20": 1.0398, "2025-01-27": 1.0429, "2025-02-03": 1.0354, "2025-02-10": 1.0376, "2025-02-17": 1.0452, "2025-02-24": 1.0468, "2025-03-03": 1.0674, "2025-03-10": 1.0872, "2025-03-17": 1.0876, "2025-03-24": 1.0804, "2025-03-31": 1.0912, "2025-04-07": 1.1078, "2025-04-14": 1.1354, "2025-04-21": 1.1406, "2025-04-28": 1.1362, "2025-05-05": 1.1315, "2025-05-12": 1.1162, "2025-05-19": 1.1287, "2025-05-26": 1.1335, "2025-06-02": 1.1405, "2025-06-09": 1.1476, "2025-06-16": 1.1529, "2025-06-23": 1.1615, "2025-06-30": 1.1767, "2025-07-07": 1.1707, "2025-07-14": 1.1637, "2025-07-21": 1.1714, "2025-07-28": 1.1513, "2025-08-04": 1.1601, "2025-08-11": 1.1663, "2025-08-18": 1.1651, "2025-08-25": 1.1656, "2025-09-01": 1.1672, "2025-09-08": 1.1716, "2025-09-15": 1.1793, "2025-09-22": 1.1748, "2025-09-29": 1.1735, "2025-10-06": 1.163, "2025-10-13": 1.1615, "2025-10-20": 1.1611, "2025-10-27": 1.1602, "2025-11-03": 1.1518, "2025-11-10": 1.1598, "2025-11-17": 1.156, "2025-11-24": 1.1565, "2025-12-01": 1.1648, "2025-12-08": 1.16 } ======================================================================================== FICHEIRO: dados_csv/tiago/lucro-mensal.json Tamanho: 46810 bytes ======================================================================================== { "ok": true, "user": "tiago", "moeda": "EUR", "compatibilidade": true, "totalmeses": 75, "investimentoinicial": 8376.05, "series": [ { "mes": "2019-10", "ganhos": 0.01, "dividendos": 0, "taxas": 0, "net": 0.01, "deltarealizado": 0.01, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2019-10-31", "fxeurusdfimmes": 1.1116, "carteiravalor": 0, "investimentoacumulado": 9.02, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 9.02, "precofonte": "stooq" }, { "mes": "2019-11", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2019-11-30", "fxeurusdfimmes": 1.1005, "carteiravalor": 0, "investimentoacumulado": 9.02, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 9.02, "precofonte": "stooq" }, { "mes": "2019-12", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2019-12-31", "fxeurusdfimmes": 1.1191, "carteiravalor": 0, "investimentoacumulado": 9.02, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 9.02, "precofonte": "stooq" }, { "mes": "2020-01", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 0.01, "naorealizadofimmes": 0, "fimmesusado": "2020-01-31", "fxeurusdfimmes": 1.1022, "carteiravalor": 0, "investimentoacumulado": 325.86, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 325.86, "precofonte": "stooq" }, { "mes": "2020-02", "ganhos": -11.02, "dividendos": 0.67, "taxas": 0.01, "net": -10.36, "deltarealizado": -11.02, "deltanaorealizado": 0, "realizadoacumulado": -11.01, "naorealizadofimmes": 0, "fimmesusado": "2020-02-29", "fxeurusdfimmes": 1.0895, "carteiravalor": 0, "investimentoacumulado": 886.68, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 886.68, "precofonte": "stooq" }, { "mes": "2020-03", "ganhos": 30.8, "dividendos": 0, "taxas": 0.01, "net": 30.79, "deltarealizado": 30.8, "deltanaorealizado": 0, "realizadoacumulado": 19.79, "naorealizadofimmes": 0, "fimmesusado": "2020-03-31", "fxeurusdfimmes": 1.0923, "carteiravalor": 0, "investimentoacumulado": 1154.29, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 1154.29, "precofonte": "stooq" }, { "mes": "2020-04", "ganhos": 51.45, "dividendos": 0, "taxas": 0.01, "net": 51.44, "deltarealizado": 51.45, "deltanaorealizado": 0, "realizadoacumulado": 71.24, "naorealizadofimmes": 0, "fimmesusado": "2020-04-30", "fxeurusdfimmes": 1.0862, "carteiravalor": 0, "investimentoacumulado": 1546.08, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 1546.08, "precofonte": "stooq" }, { "mes": "2020-05", "ganhos": 54.59, "dividendos": 0.91, "taxas": 0.02, "net": 55.48, "deltarealizado": 54.59, "deltanaorealizado": 0, "realizadoacumulado": 125.83, "naorealizadofimmes": 0, "fimmesusado": "2020-05-31", "fxeurusdfimmes": 1.1006, "carteiravalor": 0, "investimentoacumulado": 2068.29, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 2068.29, "precofonte": "stooq" }, { "mes": "2020-06", "ganhos": 150.41, "dividendos": 1.26, "taxas": 0.03, "net": 151.65, "deltarealizado": 150.41, "deltanaorealizado": 0, "realizadoacumulado": 276.24, "naorealizadofimmes": 0, "fimmesusado": "2020-06-30", "fxeurusdfimmes": 1.1238, "carteiravalor": 0, "investimentoacumulado": 3185.52, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3185.52, "precofonte": "stooq" }, { "mes": "2020-07", "ganhos": 228.27, "dividendos": 0, "taxas": 0.03, "net": 228.24, "deltarealizado": 228.27, "deltanaorealizado": 0, "realizadoacumulado": 504.51, "naorealizadofimmes": 0, "fimmesusado": "2020-07-31", "fxeurusdfimmes": 1.1759, "carteiravalor": 0, "investimentoacumulado": 3299.56, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3299.56, "precofonte": "stooq" }, { "mes": "2020-08", "ganhos": 315.03, "dividendos": 0.3, "taxas": 0.02, "net": 315.31, "deltarealizado": 315.03, "deltanaorealizado": 0, "realizadoacumulado": 819.54, "naorealizadofimmes": 0, "fimmesusado": "2020-08-31", "fxeurusdfimmes": 1.1889, "carteiravalor": 0, "investimentoacumulado": 3524.76, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 3524.76, "precofonte": "stooq" }, { "mes": "2020-09", "ganhos": 197.51, "dividendos": 0.3, "taxas": 0.03, "net": 197.78, "deltarealizado": 197.51, "deltanaorealizado": 0, "realizadoacumulado": 1017.05, "naorealizadofimmes": 0, "fimmesusado": "2020-09-30", "fxeurusdfimmes": 1.1712, "carteiravalor": 0, "investimentoacumulado": 2740.79, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 2740.79, "precofonte": "stooq" }, { "mes": "2020-10", "ganhos": 152.69, "dividendos": 0, "taxas": 0, "net": 152.69, "deltarealizado": 152.69, "deltanaorealizado": 0, "realizadoacumulado": 1169.74, "naorealizadofimmes": 0, "fimmesusado": "2020-10-31", "fxeurusdfimmes": 1.1756, "carteiravalor": 0, "investimentoacumulado": 848.15, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 848.15, "precofonte": "stooq" }, { "mes": "2020-11", "ganhos": 628.09, "dividendos": 0, "taxas": 0.02, "net": 628.07, "deltarealizado": 628.09, "deltanaorealizado": 0, "realizadoacumulado": 1797.83, "naorealizadofimmes": 0, "fimmesusado": "2020-11-30", "fxeurusdfimmes": 1.2065, "carteiravalor": 0, "investimentoacumulado": 231.98, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 231.98, "precofonte": "stooq" }, { "mes": "2020-12", "ganhos": 587.27, "dividendos": 0, "taxas": 0, "net": 587.27, "deltarealizado": 587.27, "deltanaorealizado": 0, "realizadoacumulado": 2385.1, "naorealizadofimmes": 0, "fimmesusado": "2020-12-31", "fxeurusdfimmes": 1.2258, "carteiravalor": 0, "investimentoacumulado": 4896.91, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 4896.91, "precofonte": "stooq" }, { "mes": "2021-01", "ganhos": 840.14, "dividendos": 0, "taxas": 0.03, "net": 840.11, "deltarealizado": 840.14, "deltanaorealizado": 0, "realizadoacumulado": 3225.24, "naorealizadofimmes": 0, "fimmesusado": "2021-01-31", "fxeurusdfimmes": 1.2127, "carteiravalor": 0, "investimentoacumulado": 6097.03, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6097.03, "precofonte": "stooq" }, { "mes": "2021-02", "ganhos": 434.55, "dividendos": 2.73, "taxas": 0.07, "net": 437.21, "deltarealizado": 434.55, "deltanaorealizado": 0, "realizadoacumulado": 3659.79, "naorealizadofimmes": 0, "fimmesusado": "2021-02-28", "fxeurusdfimmes": 1.2154, "carteiravalor": 0, "investimentoacumulado": 5785.82, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5785.82, "precofonte": "stooq" }, { "mes": "2021-03", "ganhos": 0, "dividendos": 0, "taxas": 0.07, "net": -0.07, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 3659.79, "naorealizadofimmes": 0, "fimmesusado": "2021-03-31", "fxeurusdfimmes": 1.1749, "carteiravalor": 0, "investimentoacumulado": 5935.78, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5935.78, "precofonte": "stooq" }, { "mes": "2021-04", "ganhos": -35.14, "dividendos": 0, "taxas": 0.83, "net": -35.97, "deltarealizado": -35.14, "deltanaorealizado": 0, "realizadoacumulado": 3624.65, "naorealizadofimmes": 0, "fimmesusado": "2021-04-30", "fxeurusdfimmes": 1.2091, "carteiravalor": 0, "investimentoacumulado": 5935.78, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5935.78, "precofonte": "stooq" }, { "mes": "2021-05", "ganhos": 76.83, "dividendos": 2.94, "taxas": 0.88, "net": 78.89, "deltarealizado": 76.83, "deltanaorealizado": 0, "realizadoacumulado": 3701.48, "naorealizadofimmes": 0, "fimmesusado": "2021-05-31", "fxeurusdfimmes": 1.2183, "carteiravalor": 0, "investimentoacumulado": 6025.92, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6025.92, "precofonte": "stooq" }, { "mes": "2021-06", "ganhos": 226.91, "dividendos": 0, "taxas": 0.84, "net": 226.07, "deltarealizado": 226.91, "deltanaorealizado": 0, "realizadoacumulado": 3928.4, "naorealizadofimmes": 0, "fimmesusado": "2021-06-30", "fxeurusdfimmes": 1.1878, "carteiravalor": 0, "investimentoacumulado": 6025.92, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6025.92, "precofonte": "stooq" }, { "mes": "2021-07", "ganhos": 330.87, "dividendos": 0, "taxas": 0.86, "net": 330.01, "deltarealizado": 330.87, "deltanaorealizado": 0, "realizadoacumulado": 4259.26, "naorealizadofimmes": 0, "fimmesusado": "2021-07-31", "fxeurusdfimmes": 1.1834, "carteiravalor": 0, "investimentoacumulado": 5760.1, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5760.1, "precofonte": "stooq" }, { "mes": "2021-08", "ganhos": 155.84, "dividendos": 2.23, "taxas": 0.93, "net": 157.13, "deltarealizado": 155.84, "deltanaorealizado": 0, "realizadoacumulado": 4415.1, "naorealizadofimmes": 0, "fimmesusado": "2021-08-31", "fxeurusdfimmes": 1.1834, "carteiravalor": 0, "investimentoacumulado": 5760.1, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5760.1, "precofonte": "stooq" }, { "mes": "2021-09", "ganhos": 127.34, "dividendos": 0, "taxas": 0.97, "net": 126.36, "deltarealizado": 127.34, "deltanaorealizado": 0, "realizadoacumulado": 4542.44, "naorealizadofimmes": 0, "fimmesusado": "2021-09-30", "fxeurusdfimmes": 1.1642, "carteiravalor": 0, "investimentoacumulado": 5760.1, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5760.1, "precofonte": "stooq" }, { "mes": "2021-10", "ganhos": 646.5, "dividendos": 0, "taxas": 0.96, "net": 645.54, "deltarealizado": 646.5, "deltanaorealizado": 0, "realizadoacumulado": 5188.94, "naorealizadofimmes": 0, "fimmesusado": "2021-10-31", "fxeurusdfimmes": 1.1615, "carteiravalor": 0, "investimentoacumulado": 5606.64, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5606.64, "precofonte": "stooq" }, { "mes": "2021-11", "ganhos": 14.25, "dividendos": 5.46, "taxas": 0.92, "net": 18.79, "deltarealizado": 14.25, "deltanaorealizado": 0, "realizadoacumulado": 5203.19, "naorealizadofimmes": 0, "fimmesusado": "2021-11-30", "fxeurusdfimmes": 1.1317, "carteiravalor": 0, "investimentoacumulado": 5255.95, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5255.95, "precofonte": "stooq" }, { "mes": "2021-12", "ganhos": 400.05, "dividendos": 3.15, "taxas": 0.94, "net": 402.26, "deltarealizado": 400.05, "deltanaorealizado": 0, "realizadoacumulado": 5603.25, "naorealizadofimmes": 0, "fimmesusado": "2021-12-31", "fxeurusdfimmes": 1.1321, "carteiravalor": 0, "investimentoacumulado": 5542.71, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5542.71, "precofonte": "stooq" }, { "mes": "2022-01", "ganhos": 202.99, "dividendos": 1.57, "taxas": 1.03, "net": 203.54, "deltarealizado": 202.99, "deltanaorealizado": 0, "realizadoacumulado": 5806.23, "naorealizadofimmes": 0, "fimmesusado": "2022-01-31", "fxeurusdfimmes": 1.1298, "carteiravalor": 0, "investimentoacumulado": 5542.71, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5542.71, "precofonte": "stooq" }, { "mes": "2022-02", "ganhos": -281.36, "dividendos": 5.45, "taxas": 1.08, "net": -276.98, "deltarealizado": -281.36, "deltanaorealizado": 0, "realizadoacumulado": 5524.88, "naorealizadofimmes": 0, "fimmesusado": "2022-02-28", "fxeurusdfimmes": 1.1094, "carteiravalor": 0, "investimentoacumulado": 5765.97, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5765.97, "precofonte": "stooq" }, { "mes": "2022-03", "ganhos": 47.55, "dividendos": 2.01, "taxas": 1.04, "net": 48.51, "deltarealizado": 47.55, "deltanaorealizado": 0, "realizadoacumulado": 5572.42, "naorealizadofimmes": 0, "fimmesusado": "2022-03-31", "fxeurusdfimmes": 1.1066, "carteiravalor": 0, "investimentoacumulado": 5531.66, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5531.66, "precofonte": "stooq" }, { "mes": "2022-04", "ganhos": 20, "dividendos": 1.07, "taxas": 1.12, "net": 19.95, "deltarealizado": 20, "deltanaorealizado": 0, "realizadoacumulado": 5592.43, "naorealizadofimmes": 0, "fimmesusado": "2022-04-30", "fxeurusdfimmes": 1.0606, "carteiravalor": 0, "investimentoacumulado": 5715.07, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5715.07, "precofonte": "stooq" }, { "mes": "2022-05", "ganhos": 0, "dividendos": 6.79, "taxas": 1.06, "net": 5.74, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5592.43, "naorealizadofimmes": 0, "fimmesusado": "2022-05-31", "fxeurusdfimmes": 1.0722, "carteiravalor": 0, "investimentoacumulado": 5857.08, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5857.08, "precofonte": "stooq" }, { "mes": "2022-06", "ganhos": 0, "dividendos": 2.4, "taxas": 0.99, "net": 1.41, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5592.43, "naorealizadofimmes": 0, "fimmesusado": "2022-06-30", "fxeurusdfimmes": 1.0492, "carteiravalor": 0, "investimentoacumulado": 5866.43, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 5866.43, "precofonte": "stooq" }, { "mes": "2022-07", "ganhos": 19.91, "dividendos": 1.13, "taxas": 0.92, "net": 20.12, "deltarealizado": 19.91, "deltanaorealizado": 0, "realizadoacumulado": 5612.34, "naorealizadofimmes": 0, "fimmesusado": "2022-07-31", "fxeurusdfimmes": 1.0166, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-08", "ganhos": 0, "dividendos": 6.95, "taxas": 1.11, "net": 5.84, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5612.34, "naorealizadofimmes": 0, "fimmesusado": "2022-08-31", "fxeurusdfimmes": 1.0003, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-09", "ganhos": 0, "dividendos": 0.75, "taxas": 1.08, "net": -0.34, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5612.34, "naorealizadofimmes": 0, "fimmesusado": "2022-09-30", "fxeurusdfimmes": 0.9662, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-10", "ganhos": 35.87, "dividendos": 3.1, "taxas": 1.02, "net": 37.96, "deltarealizado": 35.87, "deltanaorealizado": 0, "realizadoacumulado": 5648.21, "naorealizadofimmes": 0, "fimmesusado": "2022-10-31", "fxeurusdfimmes": 0.9879, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-11", "ganhos": 0, "dividendos": 7.26, "taxas": 1.01, "net": 6.25, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5648.21, "naorealizadofimmes": 0, "fimmesusado": "2022-11-30", "fxeurusdfimmes": 1.0439, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2022-12", "ganhos": 0, "dividendos": 1.44, "taxas": 0.92, "net": 0.52, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5648.21, "naorealizadofimmes": 0, "fimmesusado": "2022-12-31", "fxeurusdfimmes": 1.0645, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2023-01", "ganhos": 52.18, "dividendos": 2.08, "taxas": 0.79, "net": 53.47, "deltarealizado": 52.18, "deltanaorealizado": 0, "realizadoacumulado": 5700.39, "naorealizadofimmes": 0, "fimmesusado": "2023-01-31", "fxeurusdfimmes": 1.0911, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2023-02", "ganhos": 0, "dividendos": 6.08, "taxas": 0.87, "net": 5.2, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5700.39, "naorealizadofimmes": 0, "fimmesusado": "2023-02-28", "fxeurusdfimmes": 1.0615, "carteiravalor": 0, "investimentoacumulado": 6013.36, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6013.36, "precofonte": "stooq" }, { "mes": "2023-03", "ganhos": 32.98, "dividendos": 0.61, "taxas": 0.94, "net": 32.65, "deltarealizado": 32.98, "deltanaorealizado": 0, "realizadoacumulado": 5733.38, "naorealizadofimmes": 0, "fimmesusado": "2023-03-31", "fxeurusdfimmes": 1.0844, "carteiravalor": 0, "investimentoacumulado": 6247.68, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6247.68, "precofonte": "stooq" }, { "mes": "2023-04", "ganhos": 0, "dividendos": 2.34, "taxas": 0.99, "net": 1.35, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 5733.38, "naorealizadofimmes": 0, "fimmesusado": "2023-04-30", "fxeurusdfimmes": 1.1017, "carteiravalor": 0, "investimentoacumulado": 6247.68, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6247.68, "precofonte": "stooq" }, { "mes": "2023-05", "ganhos": 41.28, "dividendos": 5.62, "taxas": 0.97, "net": 45.93, "deltarealizado": 41.28, "deltanaorealizado": 0, "realizadoacumulado": 5774.66, "naorealizadofimmes": 0, "fimmesusado": "2023-05-31", "fxeurusdfimmes": 1.072, "carteiravalor": 0, "investimentoacumulado": 6383.59, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6383.59, "precofonte": "stooq" }, { "mes": "2023-06", "ganhos": 546.47, "dividendos": 0.6, "taxas": 1.05, "net": 546.02, "deltarealizado": 546.47, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-06-30", "fxeurusdfimmes": 1.0922, "carteiravalor": 0, "investimentoacumulado": 6290.54, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6290.54, "precofonte": "stooq" }, { "mes": "2023-07", "ganhos": 0, "dividendos": 2.32, "taxas": 1.09, "net": 1.23, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-07-31", "fxeurusdfimmes": 1.0971, "carteiravalor": 0, "investimentoacumulado": 6290.54, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6290.54, "precofonte": "stooq" }, { "mes": "2023-08", "ganhos": 0, "dividendos": 4.03, "taxas": 1.19, "net": 2.83, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-08-31", "fxeurusdfimmes": 1.0842, "carteiravalor": 0, "investimentoacumulado": 6290.54, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6290.54, "precofonte": "stooq" }, { "mes": "2023-09", "ganhos": 0, "dividendos": 0.34, "taxas": 110.74, "net": -110.4, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-09-30", "fxeurusdfimmes": 1.0581, "carteiravalor": 0, "investimentoacumulado": 6673.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6673.32, "precofonte": "stooq" }, { "mes": "2023-10", "ganhos": 0, "dividendos": 2.74, "taxas": 1.18, "net": 1.56, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 6321.13, "naorealizadofimmes": 0, "fimmesusado": "2023-10-31", "fxeurusdfimmes": 1.0625, "carteiravalor": 0, "investimentoacumulado": 6673.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6673.32, "precofonte": "stooq" }, { "mes": "2023-11", "ganhos": 141.25, "dividendos": 5.44, "taxas": 1.1, "net": 145.6, "deltarealizado": 141.25, "deltanaorealizado": 0, "realizadoacumulado": 6462.38, "naorealizadofimmes": 0, "fimmesusado": "2023-11-30", "fxeurusdfimmes": 1.0938, "carteiravalor": 0, "investimentoacumulado": 6673.32, "saldocaixafimmes": 0, "valorcarteira": 0, "investimentoinicial": 6673.32, "precofonte": "stooq" }, { "mes": "2023-12", "ganhos": 105.13, "dividendos": 1.11, "taxas": 1.09, "net": 105.14, "deltarealizado": 105.13, "deltanaorealizado": 0, "realizadoacumulado": 6567.51, "naorealizadofimmes": 0, "fimmesusado": "2023-12-31", "fxeurusdfimmes": 1.1076, "carteiravalor": 0, "investimentoacumulado": 6225.49, "saldocaixafimmes": 2.03, "valorcarteira": 2.03, "investimentoinicial": 6225.49, "precofonte": "stooq" }, { "mes": "2024-01", "ganhos": -410.16, "dividendos": 2.26, "taxas": 1.12, "net": -409.01, "deltarealizado": -410.16, "deltanaorealizado": 0, "realizadoacumulado": 6157.35, "naorealizadofimmes": 0, "fimmesusado": "2024-01-31", "fxeurusdfimmes": 1.0841, "carteiravalor": 0, "investimentoacumulado": 5958.62, "saldocaixafimmes": 1.98, "valorcarteira": 1.98, "investimentoinicial": 5958.62, "precofonte": "stooq" }, { "mes": "2024-02", "ganhos": -573.44, "dividendos": 5.31, "taxas": 1.07, "net": -569.19, "deltarealizado": -573.44, "deltanaorealizado": 0, "realizadoacumulado": 5583.91, "naorealizadofimmes": 0, "fimmesusado": "2024-02-29", "fxeurusdfimmes": 1.0831, "carteiravalor": 0, "investimentoacumulado": 5255.17, "saldocaixafimmes": 1.93, "valorcarteira": 1.93, "investimentoinicial": 5255.17, "precofonte": "stooq" }, { "mes": "2024-03", "ganhos": -278.08, "dividendos": 1.14, "taxas": 0, "net": -276.95, "deltarealizado": -278.08, "deltanaorealizado": 0, "realizadoacumulado": 5305.83, "naorealizadofimmes": 0, "fimmesusado": "2024-03-31", "fxeurusdfimmes": 1.0829, "carteiravalor": 0, "investimentoacumulado": 6366.81, "saldocaixafimmes": 1.93, "valorcarteira": 1.93, "investimentoinicial": 6366.81, "precofonte": "stooq" }, { "mes": "2024-04", "ganhos": 842.23, "dividendos": 3.05, "taxas": 0, "net": 845.28, "deltarealizado": 842.23, "deltanaorealizado": 0, "realizadoacumulado": 6148.06, "naorealizadofimmes": 0, "fimmesusado": "2024-04-30", "fxeurusdfimmes": 1.072, "carteiravalor": 0, "investimentoacumulado": 5994.97, "saldocaixafimmes": 58.75, "valorcarteira": 58.75, "investimentoinicial": 5994.97, "precofonte": "stooq" }, { "mes": "2024-05", "ganhos": 1531.43, "dividendos": 6.06, "taxas": 0, "net": 1537.5, "deltarealizado": 1531.43, "deltanaorealizado": 0, "realizadoacumulado": 7679.49, "naorealizadofimmes": 0, "fimmesusado": "2024-05-31", "fxeurusdfimmes": 1.085, "carteiravalor": 0, "investimentoacumulado": 5994.97, "saldocaixafimmes": 58.75, "valorcarteira": 58.75, "investimentoinicial": 5994.97, "precofonte": "stooq" }, { "mes": "2024-06", "ganhos": 219.78, "dividendos": 1.01, "taxas": 0, "net": 220.78, "deltarealizado": 219.78, "deltanaorealizado": 0, "realizadoacumulado": 7899.26, "naorealizadofimmes": 0, "fimmesusado": "2024-06-30", "fxeurusdfimmes": 1.0707, "carteiravalor": 0, "investimentoacumulado": 5994.97, "saldocaixafimmes": 58.75, "valorcarteira": 58.75, "investimentoinicial": 5994.97, "precofonte": "stooq" }, { "mes": "2024-07", "ganhos": 335.47, "dividendos": 2.69, "taxas": 0, "net": 338.15, "deltarealizado": 335.47, "deltanaorealizado": 0, "realizadoacumulado": 8234.73, "naorealizadofimmes": 0, "fimmesusado": "2024-07-31", "fxeurusdfimmes": 1.0819, "carteiravalor": 0, "investimentoacumulado": 6794.97, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 6794.97, "precofonte": "stooq" }, { "mes": "2024-08", "ganhos": 148.28, "dividendos": 5.98, "taxas": 0, "net": 154.26, "deltarealizado": 148.28, "deltanaorealizado": 0, "realizadoacumulado": 8383.01, "naorealizadofimmes": 0, "fimmesusado": "2024-08-31", "fxeurusdfimmes": 1.1123, "carteiravalor": 0, "investimentoacumulado": 7791.81, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 7791.81, "precofonte": "stooq" }, { "mes": "2024-09", "ganhos": -53.43, "dividendos": 0, "taxas": 0, "net": -53.43, "deltarealizado": -53.43, "deltanaorealizado": 0, "realizadoacumulado": 8329.58, "naorealizadofimmes": 0, "fimmesusado": "2024-09-30", "fxeurusdfimmes": 1.1084, "carteiravalor": 0, "investimentoacumulado": 7791.81, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 7791.81, "precofonte": "stooq" }, { "mes": "2024-10", "ganhos": 253.24, "dividendos": 9.38, "taxas": 0, "net": 262.62, "deltarealizado": 253.24, "deltanaorealizado": 0, "realizadoacumulado": 8582.83, "naorealizadofimmes": 0, "fimmesusado": "2024-10-31", "fxeurusdfimmes": 1.0835, "carteiravalor": 0, "investimentoacumulado": 7791.81, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 7791.81, "precofonte": "stooq" }, { "mes": "2024-11", "ganhos": 374.48, "dividendos": 18.86, "taxas": 0, "net": 393.33, "deltarealizado": 374.48, "deltanaorealizado": 0, "realizadoacumulado": 8957.3, "naorealizadofimmes": 0, "fimmesusado": "2024-11-30", "fxeurusdfimmes": 1.053, "carteiravalor": 0, "investimentoacumulado": 5916.77, "saldocaixafimmes": -0, "valorcarteira": -0, "investimentoinicial": 5916.77, "precofonte": "stooq" }, { "mes": "2024-12", "ganhos": 0, "dividendos": 1.29, "taxas": 0, "net": 1.29, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 8957.3, "naorealizadofimmes": 0, "fimmesusado": "2024-12-31", "fxeurusdfimmes": 1.0363, "carteiravalor": 0, "investimentoacumulado": 7606.01, "saldocaixafimmes": 96.36, "valorcarteira": 96.36, "investimentoinicial": 7606.01, "precofonte": "stooq" }, { "mes": "2025-01", "ganhos": 834.89, "dividendos": 0, "taxas": 0, "net": 834.89, "deltarealizado": 834.89, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-01-31", "fxeurusdfimmes": 1.0429, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 96.36, "valorcarteira": 96.36, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-02", "ganhos": 0, "dividendos": 15.36, "taxas": 0, "net": 15.36, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-02-28", "fxeurusdfimmes": 1.0468, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 96.36, "valorcarteira": 96.36, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-03", "ganhos": 0, "dividendos": 1.67, "taxas": 0, "net": 1.67, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-03-31", "fxeurusdfimmes": 1.0912, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 98.03, "valorcarteira": 98.03, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-04", "ganhos": 0, "dividendos": 0.78, "taxas": 0, "net": 0.78, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9792.19, "naorealizadofimmes": 0, "fimmesusado": "2025-04-30", "fxeurusdfimmes": 1.1362, "carteiravalor": 0, "investimentoacumulado": 8106.64, "saldocaixafimmes": 98.03, "valorcarteira": 98.03, "investimentoinicial": 8106.64, "precofonte": "stooq" }, { "mes": "2025-05", "ganhos": 183.33, "dividendos": 15.04, "taxas": 0, "net": 198.37, "deltarealizado": 183.33, "deltanaorealizado": 0, "realizadoacumulado": 9975.53, "naorealizadofimmes": 0, "fimmesusado": "2025-05-31", "fxeurusdfimmes": 1.1335, "carteiravalor": 0, "investimentoacumulado": 3161.56, "saldocaixafimmes": 98.03, "valorcarteira": 98.03, "investimentoinicial": 3161.56, "precofonte": "stooq" }, { "mes": "2025-06", "ganhos": 0, "dividendos": 3.7, "taxas": 0, "net": 3.7, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9975.53, "naorealizadofimmes": 0, "fimmesusado": "2025-06-30", "fxeurusdfimmes": 1.1767, "carteiravalor": 0, "investimentoacumulado": 3161.56, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 3161.56, "precofonte": "stooq" }, { "mes": "2025-07", "ganhos": 0, "dividendos": 0.44, "taxas": 0, "net": 0.44, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9975.53, "naorealizadofimmes": 0, "fimmesusado": "2025-07-31", "fxeurusdfimmes": 1.1513, "carteiravalor": 0, "investimentoacumulado": 6552.26, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 6552.26, "precofonte": "stooq" }, { "mes": "2025-08", "ganhos": 19.43, "dividendos": 13.26, "taxas": 0, "net": 32.69, "deltarealizado": 19.43, "deltanaorealizado": 0, "realizadoacumulado": 9994.96, "naorealizadofimmes": 0, "fimmesusado": "2025-08-31", "fxeurusdfimmes": 1.1656, "carteiravalor": 0, "investimentoacumulado": 5244.85, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 5244.85, "precofonte": "stooq" }, { "mes": "2025-09", "ganhos": 0, "dividendos": 0, "taxas": 0, "net": 0, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9994.96, "naorealizadofimmes": 0, "fimmesusado": "2025-09-30", "fxeurusdfimmes": 1.1735, "carteiravalor": 0, "investimentoacumulado": 5244.85, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 5244.85, "precofonte": "stooq" }, { "mes": "2025-10", "ganhos": 0, "dividendos": 0.63, "taxas": 0, "net": 0.63, "deltarealizado": 0, "deltanaorealizado": 0, "realizadoacumulado": 9994.96, "naorealizadofimmes": 0, "fimmesusado": "2025-10-31", "fxeurusdfimmes": 1.1602, "carteiravalor": 0, "investimentoacumulado": 7816.64, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 7816.64, "precofonte": "stooq" }, { "mes": "2025-11", "ganhos": 165.63, "dividendos": 13.28, "taxas": 0, "net": 178.91, "deltarealizado": 165.63, "deltanaorealizado": 0, "realizadoacumulado": 10160.59, "naorealizadofimmes": 0, "fimmesusado": "2025-11-30", "fxeurusdfimmes": 1.1565, "carteiravalor": 0, "investimentoacumulado": 8376.05, "saldocaixafimmes": 101.73, "valorcarteira": 101.73, "investimentoinicial": 8376.05, "precofonte": "stooq" }, { "mes": "2025-12", "ganhos": 2672.48, "dividendos": 0.7, "taxas": 6.43, "net": 2666.75, "deltarealizado": 0, "deltanaorealizado": 2672.48, "realizadoacumulado": 10160.59, "naorealizadofimmes": 2672.48, "fimmesusado": "2025-12-26", "fxeurusdfimmes": 1.17, "carteiravalor": 21418.51, "investimentoacumulado": 8376.05, "saldocaixafimmes": 102.43, "valorcarteira": 21520.94, "investimentoinicial": 8376.05, "precofonte": "stooq" } ], "metodo": "FORMULA_INTERNA Realizado NoRealizado + Stooq + dividendos - taxas", "stooqcache": "\/var\/www\/html\/beta\/dados_csv\/cache", "timestamp": "2025-12-26 16:42:27", "cache": { "hit": false, "file": "lucro-mensal.json" } } ======================================================================================== FICHEIRO: dados_csv/tiago/movimentos-caixa.csv Tamanho: 16668 bytes ======================================================================================== Ordem,Data,Tipo,Valor,Moeda,Descricao,TaxaCambio 1,2019-10-13,Depósito,10,USD,CASH TOP-UP,1.109 2,2020-01-22,Depósito,150,USD,CASH TOP-UP,1.1087 3,2020-01-27,Depósito,100,USD,CASH TOP-UP,1.1016 4,2020-01-27,Depósito,100,USD,CASH TOP-UP,1.1017 5,2020-02-04,Depósito,100,USD,CASH TOP-UP,1.1043 6,2020-02-06,Depósito,100,USD,CASH TOP-UP,1.0977 7,2020-02-12,Levantamento,-12,USD,CASH WITHDRAWAL,1.0883 8,2020-02-14,Dividendo,0.73,USD,AAPL DIVIDEND,1.0841 9,2020-02-14,Depósito,23.44,USD,CASH TOP-UP,1.0844 10,2020-02-19,Depósito,100,USD,CASH TOP-UP,1.0786 11,2020-02-19,Depósito,100,USD,CASH TOP-UP,1.0786 12,2020-02-25,Depósito,100,USD,CASH TOP-UP,1.0852 13,2020-02-27,Depósito,100,USD,CASH TOP-UP,1.0989 14,2020-02-29,Outros,-0.01,USD,CUSTODY FEE,1.1085 15,2020-03-10,Depósito,100,USD,CASH TOP-UP,1.1392 16,2020-03-10,Depósito,100,USD,CASH TOP-UP,1.1385 17,2020-03-25,Depósito,100,USD,CASH TOP-UP,1.087 18,2020-03-31,Outros,-0.01,USD,CUSTODY FEE,1.103 19,2020-04-16,Depósito,150,USD,CASH TOP-UP,1.0846 20,2020-04-23,Depósito,65,USD,CASH TOP-UP,1.0835 21,2020-04-27,Depósito,150,USD,CASH TOP-UP,1.0849 22,2020-04-29,Depósito,60,USD,CASH TOP-UP,1.0862 23,2020-04-30,Outros,-0.01,USD,CUSTODY FEE,1.0945 24,2020-05-01,Depósito,70,USD,CASH TOP-UP,1.1 25,2020-05-11,Dividendo,0.2,USD,MA DIVIDEND,1.0849 26,2020-05-15,Dividendo,0.78,USD,AAPL DIVIDEND,1.0803 27,2020-05-15,Depósito,200,USD,CASH TOP-UP,1.0834 28,2020-05-21,Depósito,200,USD,CASH TOP-UP,1.0991 29,2020-05-27,Depósito,101,USD,CASH TOP-UP,1.0978 30,2020-05-31,Outros,-0.02,USD,CUSTODY FEE,1.1117 31,2020-06-01,Depósito,100,USD,CASH TOP-UP,1.1111 32,2020-06-03,Depósito,96.4,USD,CASH TOP-UP,1.1233 33,2020-06-04,Depósito,105.53,USD,CASH TOP-UP,1.1334 34,2020-06-04,Depósito,200,USD,CASH TOP-UP,1.133 35,2020-06-05,Depósito,113.81,USD,CASH TOP-UP,1.1302 36,2020-06-08,Depósito,102.63,USD,CASH TOP-UP,1.1304 37,2020-06-09,Depósito,100,USD,CASH TOP-UP,1.1277 38,2020-06-15,Depósito,150,USD,CASH TOP-UP,1.125 39,2020-06-16,Depósito,97.58,USD,CASH TOP-UP,1.1262 40,2020-06-18,Depósito,192.53,USD,CASH TOP-UP,1.1217 41,2020-06-26,Dividendo,1.37,USD,QCOM DIVIDEND,1.1215 42,2020-06-29,Dividendo,0.04,USD,NVDA DIVIDEND,1.1243 43,2020-06-30,Outros,-0.03,USD,CUSTODY FEE,1.1237 44,2020-07-17,Levantamento,-16,USD,CASH WITHDRAWAL,1.1414 45,2020-07-25,Depósito,150,USD,CASH TOP-UP,1.1714 46,2020-07-31,Outros,-0.03,USD,CUSTODY FEE,1.1837 47,2020-08-04,Levantamento,-16.5,USD,CASH WITHDRAWAL,1.1799 48,2020-08-06,Depósito,300,USD,CASH TOP-UP,1.185 49,2020-08-10,Dividendo,0.2,USD,MA DIVIDEND,1.1794 50,2020-08-14,Dividendo,0.15,USD,AAPL DIVIDEND,1.1819 51,2020-08-31,Levantamento,-16.66,USD,CASH WITHDRAWAL,1.1915 52,2020-08-31,Outros,-0.02,USD,CUSTODY FEE,1.194 53,2020-09-02,Depósito,200,USD,CASH TOP-UP,1.1844 54,2020-09-04,Levantamento,-200,USD,CASH WITHDRAWAL,1.1841 55,2020-09-04,Depósito,250,USD,CASH TOP-UP,1.1845 56,2020-09-04,Levantamento,-250,USD,CASH WITHDRAWAL,1.1846 57,2020-09-10,Depósito,250,USD,CASH TOP-UP,1.1832 58,2020-09-10,Levantamento,-250,USD,CASH WITHDRAWAL,1.1832 59,2020-09-11,Dividendo,0.32,USD,MSFT DIVIDEND,1.184 60,2020-09-17,Levantamento,-370.2,USD,CASH WITHDRAWAL,1.1805 61,2020-09-24,Levantamento,-329.15,USD,CASH WITHDRAWAL,1.1653 62,2020-09-25,Dividendo,0.03,USD,NVDA DIVIDEND,1.1674 63,2020-09-25,Levantamento,-219.22,USD,CASH WITHDRAWAL,1.1668 64,2020-09-30,Outros,-0.03,USD,CUSTODY FEE,1.173 65,2020-10-01,Levantamento,-16.4,USD,CASH WITHDRAWAL,1.1728 66,2020-10-02,Levantamento,-399.48,USD,CASH WITHDRAWAL,1.1719 67,2020-10-06,Levantamento,-272.23,USD,CASH WITHDRAWAL,1.1754 68,2020-10-15,Levantamento,-400,USD,CASH WITHDRAWAL,1.1708 69,2020-10-22,Levantamento,-680,USD,CASH WITHDRAWAL,1.1842 70,2020-10-22,Levantamento,-461.19,USD,CASH WITHDRAWAL,1.1819 71,2020-10-30,Depósito,230,USD,CASH TOP-UP,1.1655 72,2020-10-30,Levantamento,-230,USD,CASH WITHDRAWAL,1.165 73,2020-11-01,Outros,-0.01,USD,CUSTODY FEE,1.1764 74,2020-11-02,Depósito,0.01,USD,CASH TOP-UP,1.1643 75,2020-11-17,Levantamento,-731.22,USD,CASH WITHDRAWAL,1.1861 76,2020-11-26,Depósito,64.15,USD,CASH TOP-UP,1.1908 77,2020-11-30,Depósito,600,USD,CASH TOP-UP,1.1997 78,2020-11-30,Levantamento,-664.15,USD,CASH WITHDRAWAL,1.1995 79,2020-11-30,Outros,-0.01,USD,CUSTODY FEE,1.1938 80,2020-12-01,Depósito,0.01,USD,CASH TOP-UP,1.2075 81,2020-12-03,Depósito,283.13,USD,CASH TOP-UP,1.2146 82,2020-12-07,Depósito,245.04,USD,CASH TOP-UP,1.2091 83,2020-12-07,Levantamento,-1417.49,USD,CASH WITHDRAWAL,1.2098 84,2020-12-08,Depósito,600,USD,CASH TOP-UP,1.2104 85,2020-12-10,Depósito,1045.98,USD,CASH TOP-UP,1.2095 86,2020-12-14,Depósito,873.84,USD,CASH TOP-UP,1.2148 87,2020-12-17,Depósito,1011.96,USD,CASH TOP-UP,1.2241 88,2020-12-21,Depósito,934.75,USD,CASH TOP-UP,1.2192 89,2020-12-23,Depósito,440.8,USD,CASH TOP-UP,1.2179 90,2020-12-23,Depósito,1218.96,USD,CASH TOP-UP,1.2194 91,2020-12-24,Depósito,14.23,USD,CASH TOP-UP,1.2184 92,2020-12-31,Depósito,500,USD,CASH TOP-UP,1.2276 93,2020-12-31,Levantamento,-64.98,USD,CASH WITHDRAWAL,1.2273 94,2021-01-01,Outros,-0.04,USD,CUSTODY FEE,1.2219 95,2021-01-08,Depósito,549.96,USD,CASH TOP-UP,1.2246 96,2021-01-08,Levantamento,-71.85,USD,CASH WITHDRAWAL,1.2234 97,2021-01-13,Depósito,576.16,USD,CASH TOP-UP,1.2198 98,2021-01-27,Depósito,136.83,USD,CASH TOP-UP,1.208 99,2021-01-27,Depósito,470.71,USD,CASH TOP-UP,1.2077 100,2021-01-28,Depósito,1373.27,USD,CASH TOP-UP,1.2089 101,2021-02-01,Outros,-0.09,USD,CUSTODY FEE,1.2133 102,2021-02-01,Depósito,196.46,USD,CASH TOP-UP,1.2067 103,2021-02-04,Levantamento,-32.26,USD,CASH WITHDRAWAL,1.1962 104,2021-02-09,Levantamento,-500,USD,CASH WITHDRAWAL,1.2121 105,2021-02-12,Dividendo,3.31,USD,AAPL DIVIDEND,1.2126 106,2021-02-19,Levantamento,-41.9,USD,CASH WITHDRAWAL,1.2129 107,2021-03-01,Outros,-0.08,USD,CUSTODY FEE,1.209 108,2021-03-02,Depósito,0.08,USD,CASH TOP-UP,1.2091 109,2021-03-12,Depósito,178.93,USD,CASH TOP-UP,1.1937 110,2021-04-01,Outros,-0.97,USD,CUSTODY FEE,1.1737 111,2021-05-01,Outros,-1.07,USD,CUSTODY FEE,1.2142 112,2021-05-14,Dividendo,3.55,USD,AAPL DIVIDEND,1.2089 113,2021-05-24,Depósito,50,USD,CASH TOP-UP,1.2213 114,2021-05-27,Depósito,50,USD,CASH TOP-UP,1.2193 115,2021-05-27,Depósito,10,USD,CASH TOP-UP,1.2195 116,2021-06-01,Outros,-1.03,USD,CUSTODY FEE,1.2229 117,2021-07-01,Outros,-1.02,USD,CUSTODY FEE,1.1855 118,2021-07-14,Levantamento,-63.73,USD,CASH WITHDRAWAL,1.1839 119,2021-07-27,Levantamento,-250,USD,CASH WITHDRAWAL,1.1793 120,2021-08-01,Outros,-1.12,USD,CUSTODY FEE,1.1999 121,2021-08-13,Dividendo,2.62,USD,AAPL DIVIDEND,1.1742 122,2021-09-01,Outros,-1.15,USD,CUSTODY FEE,1.18 123,2021-10-01,Outros,-1.11,USD,CUSTODY FEE,1.158 124,2021-10-01,Levantamento,-50,USD,CASH WITHDRAWAL,1.1582 125,2021-10-25,Levantamento,-78.27,USD,CASH WITHDRAWAL,1.1616 126,2021-10-29,Levantamento,-50,USD,CASH WITHDRAWAL,1.1652 127,2021-11-01,Levantamento,-100,USD,CASH WITHDRAWAL,1.1609 128,2021-11-04,Levantamento,-2000,USD,CASH WITHDRAWAL,1.1613 129,2021-11-04,Outros,-1.07,USD,CUSTODY FEE,1.1603 130,2021-11-04,Depósito,2000,USD,CASH TOP-UP,1.1586 131,2021-11-17,Dividendo,6.17,USD,AAPL DIVIDEND,1.1305 132,2021-11-19,Levantamento,-150,USD,CASH WITHDRAWAL,1.1292 133,2021-11-22,Levantamento,-153.2,USD,CASH WITHDRAWAL,1.1287 134,2021-12-02,Outros,-1.07,USD,CUSTODY FEE,1.1325 135,2021-12-02,Levantamento,-300,USD,CASH WITHDRAWAL,1.1325 136,2021-12-02,Depósito,100,USD,CASH TOP-UP,1.1324 137,2021-12-06,Depósito,50,USD,CASH TOP-UP,1.1293 138,2021-12-10,Levantamento,-26.65,USD,CASH WITHDRAWAL,1.1319 139,2021-12-14,Levantamento,-150,USD,CASH WITHDRAWAL,1.1279 140,2021-12-17,Dividendo,3.57,USD,KO DIVIDEND,1.1323 141,2021-12-21,Depósito,550,USD,CASH TOP-UP,1.1288 142,2021-12-25,Depósito,100,USD,CASH TOP-UP,1.1315 143,2022-01-04,Dividendo,1.78,USD,BAC DIVIDEND,1.1307 144,2022-01-04,Outros,-1.16,USD,CUSTODY FEE,1.1303 145,2022-02-02,Outros,-1.22,USD,CUSTODY FEE,1.1324 146,2022-02-15,Dividendo,6.17,USD,AAPL DIVIDEND,1.132 147,2022-02-28,Depósito,250,USD,CASH TOP-UP,1.1198 148,2022-03-02,Outros,-1.16,USD,CUSTODY FEE,1.1104 149,2022-03-16,Dividendo,0.42,USD,O DIVIDEND,1.0978 150,2022-03-25,Levantamento,-257.83,USD,CASH WITHDRAWAL,1.1004 151,2022-03-28,Dividendo,1.78,USD,BAC DIVIDEND,1.0955 152,2022-04-02,Outros,-1.24,USD,CUSTODY FEE,1.1051 153,2022-04-04,Dividendo,0.75,USD,KO DIVIDEND,1.1051 154,2022-04-14,Depósito,200,USD,CASH TOP-UP,1.0905 155,2022-04-19,Dividendo,0.42,USD,O DIVIDEND,1.0772 156,2022-05-03,Outros,-1.11,USD,CUSTODY FEE,1.0519 157,2022-05-16,Dividendo,0.42,USD,O DIVIDEND,1.041 158,2022-05-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0407 159,2022-05-20,Depósito,150,USD,CASH TOP-UP,1.0562 160,2022-06-02,Outros,-1.05,USD,CUSTODY FEE,1.0657 161,2022-06-07,Depósito,10,USD,CASH TOP-UP,1.0702 162,2022-06-10,Dividendo,0.33,USD,MSFT DIVIDEND,1.0635 163,2022-06-16,Dividendo,0.42,USD,O DIVIDEND,1.0441 164,2022-06-27,Dividendo,1.78,USD,BAC DIVIDEND,1.0571 165,2022-07-02,Outros,-0.96,USD,CUSTODY FEE,1.0432 166,2022-07-05,Dividendo,0.75,USD,KO DIVIDEND,1.0442 167,2022-07-18,Dividendo,0.42,USD,O DIVIDEND,1.0105 168,2022-07-29,Depósito,150,USD,CASH TOP-UP,1.0209 169,2022-08-02,Outros,-1.13,USD,CUSTODY FEE,1.021 170,2022-08-16,Dividendo,6.65,USD,AAPL DIVIDEND,1.0171 171,2022-08-16,Dividendo,0.42,USD,O DIVIDEND,1.0165 172,2022-09-03,Outros,-1.08,USD,CUSTODY FEE,0.9961 173,2022-09-12,Dividendo,0.33,USD,MSFT DIVIDEND,1.0096 174,2022-09-16,Dividendo,0.42,USD,O DIVIDEND,0.9995 175,2022-10-03,Dividendo,1.87,USD,BAC DIVIDEND,0.9807 176,2022-10-04,Outros,-1,USD,CUSTODY FEE,0.9841 177,2022-10-04,Dividendo,0.75,USD,KO DIVIDEND,0.9861 178,2022-10-17,Dividendo,0.42,USD,O DIVIDEND,0.9748 179,2022-11-02,Outros,-1,USD,CUSTODY FEE,0.9906 180,2022-11-11,Dividendo,7.04,USD,AAPL DIVIDEND,1.0271 181,2022-11-16,Dividendo,0.42,USD,O DIVIDEND,1.0383 182,2022-12-02,Outros,-0.97,USD,CUSTODY FEE,1.0532 183,2022-12-09,Dividendo,0.36,USD,MSFT DIVIDEND,1.0582 184,2022-12-16,Dividendo,0.75,USD,KO DIVIDEND,1.0667 185,2022-12-16,Dividendo,0.42,USD,O DIVIDEND,1.0662 186,2023-01-03,Dividendo,1.87,USD,BAC DIVIDEND,1.0672 187,2023-01-04,Outros,-0.84,USD,CUSTODY FEE,1.0625 188,2023-01-17,Dividendo,0.35,USD,O DIVIDEND,1.0831 189,2023-02-01,Outros,-0.95,USD,CUSTODY FEE,1.0871 190,2023-02-16,Dividendo,0.35,USD,O DIVIDEND,1.0707 191,2023-02-17,Dividendo,6.12,USD,AAPL DIVIDEND,1.0641 192,2023-03-01,Depósito,250,USD,CASH TOP-UP,1.0669 193,2023-03-02,Outros,-1,USD,CUSTODY FEE,1.0636 194,2023-03-13,Dividendo,0.29,USD,MSFT DIVIDEND,1.0731 195,2023-03-16,Dividendo,0.36,USD,O DIVIDEND,1.0618 196,2023-04-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0809 197,2023-04-04,Dividendo,0.64,USD,KO DIVIDEND,1.0919 198,2023-04-04,Outros,-1.08,USD,CUSTODY FEE,1.0941 199,2023-04-17,Dividendo,0.36,USD,O DIVIDEND,1.1 200,2023-05-02,Outros,-1.07,USD,CUSTODY FEE,1.101 201,2023-05-08,Depósito,150,USD,CASH TOP-UP,1.1037 202,2023-05-16,Dividendo,0.36,USD,O DIVIDEND,1.089 203,2023-05-19,Dividendo,5.71,USD,AAPL DIVIDEND,1.08 204,2023-06-02,Outros,-1.13,USD,CUSTODY FEE,1.0788 205,2023-06-05,Depósito,100,USD,CASH TOP-UP,1.0703 206,2023-06-06,Levantamento,-200,USD,CASH WITHDRAWAL,1.0725 207,2023-06-09,Dividendo,0.29,USD,MSFT DIVIDEND,1.0787 208,2023-06-16,Dividendo,0.36,USD,O DIVIDEND,1.0954 209,2023-07-03,Dividendo,1.54,USD,BAC DIVIDEND,1.0929 210,2023-07-04,Outros,-1.19,USD,CUSTODY FEE,1.0914 211,2023-07-05,Dividendo,0.64,USD,KO DIVIDEND,1.0888 212,2023-07-17,Dividendo,0.36,USD,O DIVIDEND,1.1239 213,2023-08-02,Outros,-1.31,USD,CUSTODY FEE,1.0994 214,2023-08-16,Dividendo,0.36,USD,O DIVIDEND,1.0928 215,2023-08-18,Dividendo,4.03,USD,AAPL DIVIDEND,1.0901 216,2023-09-02,Outros,-1.27,USD,CUSTODY FEE,1.079 218,2023-09-13,Depósito,11.76,USD,CASH TOP-UP,1.0756 219,2023-09-13,Depósito,400,USD,CASH TOP-UP,1.0757 220,2023-09-18,Dividendo,0.36,USD,O DIVIDEND,1.0686 221,2023-10-01,Outros,-1.25,USD,CUSTODY FEE,1.0595 222,2023-10-02,Dividendo,1.68,USD,BAC DIVIDEND,1.055 223,2023-10-03,Dividendo,0.78,USD,KO DIVIDEND,1.0488 224,2023-10-16,Dividendo,0.43,USD,O DIVIDEND,1.0557 225,2023-11-02,Outros,-1.17,USD,CUSTODY FEE,1.0617 226,2023-11-16,Dividendo,0.43,USD,O DIVIDEND,1.0863 227,2023-11-17,Dividendo,5.51,USD,AAPL DIVIDEND,1.0913 228,2023-12-01,Outros,-1.19,USD,CUSTODY FEE,1.0922 229,2023-12-14,Levantamento,-490,USD,CASH WITHDRAWAL,1.0942 230,2023-12-14,Levantamento,-540,USD,CASH WITHDRAWAL,1.0945 231,2023-12-14,Depósito,493.36,EUR,CASH TOP-UP,1 232,2023-12-14,Depósito,22.55,EUR,CASH TOP-UP,1 233,2023-12-14,Levantamento,-22.55,EUR,CASH WITHDRAWAL,1 234,2023-12-18,Dividendo,0.43,USD,O DIVIDEND,1.0945 235,2023-12-18,Dividendo,0.78,USD,KO DIVIDEND,1.0937 236,2024-01-01,Outros,-1.18,USD,CUSTODY FEE,1.106 237,2024-01-01,Outros,-0.05,EUR,CUSTODY FEE,1 238,2024-01-03,Dividendo,2.04,USD,BAC DIVIDEND,1.0927 239,2024-01-16,Dividendo,0.43,USD,O DIVIDEND,1.0909 240,2024-01-29,Levantamento,-288.99,USD,CASH WITHDRAWAL,1.0829 241,2024-02-01,Outros,-1.1,USD,CUSTODY FEE,1.0837 242,2024-02-01,Outros,-0.05,EUR,CUSTODY FEE,1 243,2024-02-13,Levantamento,-755.3,USD,CASH WITHDRAWAL,1.0737 244,2024-02-16,Dividendo,0.43,USD,O DIVIDEND,1.0796 245,2024-02-16,Dividendo,5.3,USD,AAPL DIVIDEND,1.0789 246,2024-03-11,Depósito,1091.8,USD,CASH TOP-UP,1.0964 247,2024-03-11,Depósito,126.74,USD,CASH TOP-UP,1.0941 248,2024-03-15,Dividendo,0.64,USD,MSFT DIVIDEND,1.0914 249,2024-03-18,Dividendo,0.43,USD,O DIVIDEND,1.0912 250,2024-03-28,Dividendo,0.17,USD,NVDA DIVIDEND,1.0831 251,2024-04-02,Dividendo,0.82,USD,KO DIVIDEND,1.0788 252,2024-04-02,Dividendo,2.04,USD,BAC DIVIDEND,1.0789 253,2024-04-16,Dividendo,0.43,USD,O DIVIDEND,1.0668 254,2024-04-22,Levantamento,-720,USD,CASH WITHDRAWAL,1.0653 255,2024-04-22,Depósito,675.75,EUR,CASH TOP-UP,1 256,2024-04-30,Levantamento,-398.79,USD,CASH WITHDRAWAL,1.0728 257,2024-05-16,Dividendo,0.43,USD,O DIVIDEND,1.0895 258,2024-05-17,Dividendo,6.16,USD,AAPL DIVIDEND,1.0867 259,2024-06-14,Dividendo,0.64,USD,MSFT DIVIDEND,1.0709 260,2024-06-17,Dividendo,0.44,USD,O DIVIDEND,1.0728 261,2024-07-01,Dividendo,0.42,USD,NVDA DIVIDEND,1.0772 262,2024-07-01,Dividendo,2.04,USD,BAC DIVIDEND,1.0768 263,2024-07-16,Dividendo,0.44,USD,O DIVIDEND,1.0923 264,2024-07-23,Depósito,800,EUR,CASH TOP-UP,1 265,2024-08-01,Depósito,1077.48,USD,CASH TOP-UP,1.0809 266,2024-08-16,Dividendo,6.59,USD,AAPL DIVIDEND,1.1011 267,2024-10-04,Dividendo,0.42,USD,NVDA DIVIDEND,1.1053 268,2024-10-10,Dividendo,4.93,USD,TSM DIVIDEND,1.0958 269,2024-11-06,Depósito,34.98,USD,CASH TOP-UP,1.075 270,2024-11-06,Levantamento,-34.98,USD,CASH WITHDRAWAL,1.0748 271,2024-11-15,Dividendo,9.99,USD,AAPL DIVIDEND,1.0596 272,2024-11-25,Depósito,1004,USD,CASH TOP-UP,1.0525 273,2024-11-29,Levantamento,-2000,USD,CASH WITHDRAWAL,1.0574 274,2024-12-18,Dividendo,0.51,EUR,EXXT DIVIDEND,1 275,2024-12-18,Depósito,2006.76,USD,CASH TOP-UP,1.0513 276,2024-12-18,Levantamento,-2240.7,USD,CASH WITHDRAWAL,1.0514 277,2024-12-18,Depósito,2133.85,EUR,CASH TOP-UP,1 278,2024-12-19,Depósito,0.02,USD,CASH TOP-UP,1.0415 279,2024-12-30,Dividendo,0.41,USD,NVDA DIVIDEND,1.0464 280,2025-01-07,Levantamento,-3000,USD,CASH WITHDRAWAL,1.0449 281,2025-01-07,Depósito,3001.3,USD,CASH TOP-UP,1.0396 282,2025-01-28,Depósito,245,USD,CASH TOP-UP,1.0451 283,2025-02-14,Dividendo,8.08,USD,AAPL DIVIDEND,1.0521 284,2025-03-19,Dividendo,1.67,EUR,EXXT DIVIDEND,1 285,2025-04-03,Dividendo,0.43,USD,NVDA DIVIDEND,1.1083 286,2025-05-16,Dividendo,8.4,USD,AAPL DIVIDEND,1.1172 287,2025-05-29,Levantamento,-2818.2,USD,CASH WITHDRAWAL,1.1398 288,2025-06-18,Dividendo,3.7,EUR,EXXT DIVIDEND,1 289,2025-07-02,Depósito,2000,USD,CASH TOP-UP,1.1797 290,2025-07-10,Dividendo,0.26,USD,NVDA DIVIDEND,1.1761 291,2025-08-14,Dividendo,7.74,USD,AAPL DIVIDEND,1.1674 292,2025-08-20,Levantamento,-764.31,USD,CASH WITHDRAWAL,1.1692 293,2025-10-02,Dividendo,0.37,USD,NVDA DIVIDEND,1.175 294,2025-10-16,Depósito,1502.57,USD,CASH TOP-UP,1.1685 295,2025-11-11,Depósito,500,USD,CASH TOP-UP,1.1619 296,2025-11-11,Levantamento,-175,USD,CASH WITHDRAWAL,1.1618 297,2025-11-13,Dividendo,7.74,USD,AAPL DIVIDEND,1.16584 298,2021-01-28,Levantamento,-1561.03,USD,Acerto Filipe Lucro Filipe,1.2089 299,2021-01-28,Levantamento,-12.45,USD,Acerto Filipe Lucro Maria,1.2089 300,2021-01-28,Outros,813.87,USD,Acerto,1.2089 301,2025-12-17,Dividendo,0.7,EUR,EXXT DIVIDEND,1 302,2025-12-26,Dividendo,0.51,USD,NVIDIA DIVIDEND, 302,2026-01-13,Levantamento,-1828.99,USD,CASH WITHDRAWAL, 303,2026-01-16,Levantamento,-1581.35,EUR,CASH WITHDRAWAL,1 304,2026-01-16,Levantamento,-4323.99,USD,CASH WITHDRAWAL, 305,2026-01-19,Levantamento,-3186.27,EUR,CASH WITHDRAWAL,1 306,2026-02-12,Dividendo,5.08,USD,AAPL DIVIDEND, 307,2026-04-01,Dividendo,0.31,USD,NVIDIA DIVIDEND, 308,2026-04-30,Depósito,600,USD,CASH TOP-UP, 309,2026-05-14,Dividendo,5.28,USD,AAPL DIVIDEND, ======================================================================================== FICHEIRO: dados_csv/tiago/precos-atuais.json Tamanho: 831 bytes ======================================================================================== { "precos": { "AAPL": { "preco": 277.24, "moeda": "USD", "timestamp": "2025-12-09 21:00:01", "fonte": "API" }, "NVDA": { "preco": 184.98, "moeda": "USD", "timestamp": "2025-12-09 21:00:01", "fonte": "API" }, "IWDA": { "preco": 110.95, "moeda": "EUR", "timestamp": "2025-12-09 21:00:01", "fonte": "manual" }, "NDXEX": { "preco": 213.35, "moeda": "EUR", "timestamp": "2025-12-09 21:00:01", "fonte": "manual" } }, "cambio": { "EUR_USD": 1.16, "USD_EUR": 0.8621, "fonte": "Exchange Rate API", "timestamp": "2025-12-09 21:00:01" } } ======================================================================================== FICHEIRO: dados_csv/tiago/transacoes-acoes.csv Tamanho: 29472 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2019-10-15","2019-10-16","NASDAQ:GOOGL","0.161663","0","10.00","10.05","1.1041","1.1083","USD" "2","2019-10-16","2020-02-10","NASDAQ:AMZN","0.11321","0","10.05","12.00","","","USD" "3","2020-01-22","2020-06-10","NASDAQ:AAPL","1.8870298","0","150.00","164.64","","","USD" "4","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28949064","0","100.00","112.51","","","USD" "5","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28812028","0","100.00","112.57","","","USD" "6","2020-02-04","2020-05-29","NASDAQ:ADBE","0.27270991","0","100.00","104.05","","","USD" "7","2020-02-06","2020-04-30","NASDAQ:TSLA","1.9305018","0","100.00","112.68","","","USD" "8","2020-02-19","2020-02-25","NYSE:MA","0.28609409","0","100.07","94.80","1.0787","1.1877","USD" "9","2020-02-19","2020-04-14","NASDAQ:TSLA","1.97749185","0","124.07","133.54","","","USD" "10","2020-02-25","2020-05-20","NYSE:MA","0.31256977","0","99.08","92.74","1.0854","1.1368","USD" "11","2020-02-27","2020-04-14","NASDAQ:AMZN","1.028983","0","100.09","102.44","","","USD" "12","2020-03-19","2020-04-13","NASDAQ:AMZN","1.0563286","0","100.00","120.33","1.0791","1.0908","USD" "13","2020-03-19","2020-05-05","NASDAQ:AAPL","1.57029008","0","100.00","117.24","","","USD" "14","2020-03-25","2020-03-25","NASDAQ:TSLA","2.72737185","0","100.01","133.53","","","USD" "15","2020-04-07","2020-05-25","NYSE:MCD","1.11594688","0","200.00","209.51","1.0787","1.1054","USD" "16","2020-04-14","2020-05-12","NASDAQ:NFLX","0.25100401","0","101.09","110.15","1.0962","1.0866","USD" "17","2020-04-15","2020-04-30","NASDAQ:TSLA","2.02850715","0","101.08","112.68","","","USD" "18","2020-04-16","2020-06-10","NASDAQ:AMZN","1.6590626","0","201.08","219.83","","","USD" "19","2020-04-16","2020-07-01","NASDAQ:NFLX","0.22745365","0","101.08","105.58","1.0879","1.1268","USD" "20","2020-04-27","2020-05-11","NASDAQ:GOOGL","3.1276144","0","201.08","217.44","1.0850","1.0812","USD" "21","2020-05-01","2020-06-09","NASDAQ:AMZN","0.8724708","0","101.09","109.89","","","USD" "22","2020-05-01","2020-05-06","NASDAQ:TSLA","3.1895439","0","151.09","167.02","","","USD" "23","2020-05-11","2020-07-09","NASDAQ:AMD","1.80733779","0","101.08","101.77","","","USD" "24","2020-05-12","2020-08-19","NYSE:MA","0.36659579","0","101.08","109.05","1.0852","1.0994","USD" "25","2020-05-14","2020-06-03","NASDAQ:GOOGL","2.9816034","0","201.07","213.99","1.0794","1.1248","USD" "26","2020-05-15","2020-05-29","NYSE:SQ","2.54097319","0","201.08","205.08","1.0834","1.1105","USD" "27","2020-05-20","2020-07-01","NASDAQ:NVDA","3.4223706","0","124.09","130.86","","","USD" "28","2020-05-21","2020-06-08","NYSE:KO","4.34023991","0","200.08","215.7","1.0984","1.1304","USD" "29","2020-05-27","2020-06-03","NASDAQ:ANSS","0.38406882","0","101.09","111.55","1.0979","1.1224","USD" "30","2020-05-28","2020-06-05","NASDAQ:QCOM","2.4789291","0","201.10","220.91","1.1055","1.1289","USD" "31","2020-05-29","2020-07-19","NASDAQ:MSFT","1.15486141","0","211.11","228.85","1.1104","1.1231","USD" "32","2020-06-01","2020-06-18","NASDAQ:UAL","6.8212824","0","201.11","271.98","1.1117","1.1212","USD" "33","2020-06-03","2020-07-01","NASDAQ:UAL","7.12250712","0","225.00","266.29","1.1218","1.1262","USD" "34","2020-06-03","2020-07-15","NASDAQ:UAL","6.44484412","0","216.12","219.50","1.1248","1.1453","USD" "35","2020-06-04","2020-08-10","NASDAQ:UAL","2.69444444","0","98.12","98.47","1.1261","1.1797","USD" "36","2020-06-04","2020-08-27","NASDAQ:UAL","2.78884462","0","106.13","104.54","1.1334","1.1803","USD" "37","2020-06-04","2020-08-27","NASDAQ:UAL","5.20231213","0","199.13","191.07","1.1330","1.1782","USD" "38","2020-06-05","2020-10-06","NASDAQ:UAL","2.4672489","0","114.12","90.74","1.1297","1.1797","USD" "39","2020-06-05","2020-10-08","NASDAQ:UAL","4.8456164","0","215","181.65","1.1287","1.1744","USD" "40","2020-06-08","2020-10-08","NASDAQ:UAL","4.86896252","0","224.80","181.65","1.1309","1.1743","USD" "41","2020-06-08","2020-07-30","NASDAQ:ANSS","0.35145678","0","100.00","108.80","1.1303","1.1801","USD" "42","2020-06-09","2020-09-15","NASDAQ:UAL","2.22121486","0","99.13","82.33","1.1346","1.1857","USD" "43","2020-06-10","2020-08-28","NASDAQ:UAL","2.43486729","0","101.13","90.13","1.1373","1.1899","USD" "44","2020-06-10","2020-08-03","NASDAQ:ANSS","1.03831377","0","301.13","327.64","","","USD" "45","2020-06-11","2020-07-01","NASDAQ:TSLA","4.5053613","0","301.14","336.05","","","USD" "46","2020-06-15","2020-07-06","NASDAQ:AAPL","1.78512984","0","151.11","166.73","","","USD" "47","2020-06-19","2020-06-20","NASDAQ:GOOGL","4.1551534","0","301.12","322.63","1.1231","1.1444","USD" "48","2020-06-19","2020-07-30","NASDAQ:QCOM","3.3463469","0","301.12","343.55","1.1226","1.1800","USD" "49","2020-06-22","2020-07-13","NASDAQ:AAPL","2.26321148","0","201.12","220.87","1.1228","1.1352","USD" "50","2020-07-01","2020-07-21","NYSE:KO","6.61229887","0","300","314.86","1.1269","1.145","USD" "51","2020-07-07","2020-07-10","NASDAQ:TSLA","5.3756118","0","500","549.91","1.1289","1.1304","USD" "52","2020-07-07","2020-07-15","NASDAQ:UAL","6.00781015","0","200.00","205.52","1.1289","1.1450","USD" "53","2020-07-07","2020-08-21","NASDAQ:ZM","0.55248618","0","150.00","160.37","1.1329","1.1768","USD" "54","2020-07-10","2020-08-31","NASDAQ:AMZN","0.6291998","0","100.00","109.86","1.1327","1.1961","USD" "55","2020-07-13","2020-08-18","NASDAQ:TSLA","2.6472144","0","300.01","330.61","1.1351","1.1934","USD" "56","2020-07-13","2020-11-13","NASDAQ:AMZN","1.8371096","0","300.01","286.13","1.135","1.1829","USD" "57","2020-07-14","2020-07-31","NASDAQ:AAPL","2.63296468","0","250.00","270.98","1.1369","1.1839","USD" "58","2020-07-15","2020-08-03","NASDAQ:AAPL","2.0317988","0","199.99","225.55","","","USD" "59","2020-07-15","2020-07-30","NASDAQ:TSLA","1.9946808","0","200.01","232.18","","","USD" "60","2020-07-20","2020-07-23","NASDAQ:UAL","9.17150718","0","300.00","307.96","1.1443","1.1618","USD" "61","2020-07-20","2020-08-03","NASDAQ:AAPL","3.05654608","0","300.00","339.31","","","USD" "62","2020-07-23","2020-11-13","NASDAQ:AMZN","1.9828548","0","300.01","327.75","","","USD" "63","2020-07-24","2020-07-24","NASDAQ:AMD","1.05263157","0","70.00","72.41","","","USD" "64","2020-07-24","2020-08-21","NASDAQ:ZM","0.28389503","0","70.00","82.40","1.1635","1.1768","USD" "65","2020-07-27","2020-08-13","NASDAQ:TSLA","1.5705051","0","150.00","168.30","1.1746","1.1839","USD" "66","2020-07-30","2020-09-01","NASDAQ:GOOGL","3.9853868","0","300.00","329.87","1.1804","1.1917","USD" "67","2020-07-30","2020-08-27","NASDAQ:MSFT","0.73800738","0","150.00","169.05","1.1802","1.1807","USD" "68","2020-07-31","2020-08-25","NASDAQ:GOOGL","3.3979624","0","250","272.70","1.1840","1.1828","USD" "69","2020-08-03","2020-08-13","NASDAQ:TSLA","3.0459945","0","300.00","331.46","1.1731","1.1859","USD" "70","2020-08-05","2020-09-01","NASDAQ:ANSS","0.95910994","0","300.00","330.23","","","USD" "71","2020-08-05","2020-09-29","NASDAQ:AMD","1.18990956","0","100.00","96.79","","","USD" "72","2020-08-06","2020-08-31","NASDAQ:AAPL","0.90019128","0","100.00","115.45","","","USD" "73","2020-08-10","2020-08-31","NASDAQ:AMD","1.23701138","0","100.00","111.16","","","USD" "74","2020-08-10","2020-08-27","NASDAQ:ANSS","0.32998944","0","100.00","109.43","","","USD" "75","2020-08-13","2020-08-18","NASDAQ:ZM","0.40695071","0","100.00","110.22","1.1851","1.1962","USD" "76","2020-08-14","2020-08-20","NYSE:SQ","0.7033338","0","100.00","109.90","1.1830","1.1847","USD" "77","2020-08-17","2020-08-18","NASDAQ:TSLA","0.88541535","0","100.00","111.14","","","USD" "78","2020-08-17","2020-08-31","NASDAQ:TSLA","0.842091","0","100.00","97.95","","","USD" "79","2020-08-17","2020-09-01","NYSE:SQ","0.66613375","0","100.00","110.62","1.1860","1.1977","USD" "80","2020-08-18","2020-08-24","NASDAQ:UAL","2.9620853","0","100.00","107.19","1.1937","1.1805","USD" "81","2020-08-19","2020-09-02","NASDAQ:NVDA","1.0171698","0","50.00","58.70","","","USD" "82","2020-08-20","2020-08-28","NASDAQ:TSLA","0.75513105","0","100.00","114.37","","","USD" "83","2020-08-21","2020-12-17","NASDAQ:AAPL","1.6575476","0","200.00","213.11","","","USD" "84","2020-08-21","2020-08-31","NASDAQ:TSLA","1.44357075","0","200.01","222.84","","","USD" "85","2020-08-21","2020-08-31","NASDAQ:TSLA","1.44357075","0","200.01","222.84","","","USD" "86","2020-08-24","2020-08-27","NASDAQ:TSLA","1.46742315","0","200.00","222.35","","","USD" "87","2020-08-25","2020-09-28","NYSE:BABA","0.17636684","0","50.00","48.62","1.1826","1.1662","USD" "88","2020-08-26","2020-09-01","NASDAQ:ZM","0.1661792","0","50.00","75.38","1.1821","1.1977","USD" "89","2020-08-26","2020-09-28","NYSE:BABA","0.17246731","0","50.00","47.54","1.1825","1.1662","USD" "90","2020-08-27","2020-12-03","NASDAQ:TSLA","1.3170429","0","200.01","257.80","","","USD" "91","2020-08-27","2020-11-13","NASDAQ:TSLA","3.29757285","0","500.01","445.11","","","USD" "92","2020-08-27","2020-08-31","NASDAQ:TSLA","3.29757285","0","499.99","548.72","","","USD" "93","2020-08-27","2020-12-17","NASDAQ:AAPL","1.60481444","0","200.01","206.33","","","USD" "94","2020-08-28","2020-09-02","NASDAQ:NVDA","0.9644131","0","50.00","55.67","","","USD" "95","2020-08-15","2020-12-03","NASDAQ:TSLA","3.22587582","0","500.01","631.53","","","USD" "96","2020-08-15","2020-12-15","NASDAQ:TSLA","1.23482196","0","200.00","263.70","","","USD" "97","2020-08-20","2020-08-31","NASDAQ:TSLA","0.75513105","0","100.00","122.78","","","USD" "98","2020-08-15","2020-12-15","NASDAQ:TSLA","3.02858988","0","499.99","649.98","","","USD" "99","2020-09-01","2020-09-22","NASDAQ:ZM","0.23466466","0","100.00","110.05","1.1988","1.1759","USD" "100","2020-09-01","2020-12-10","NASDAQ:TSLA","3.0358227","0","500.00","631.60","","","USD" "101","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.10","1.1969","1.1706","USD" "102","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.1","1.1952","1.1668","USD" "103","2020-09-01","2020-09-30","NYSE:NIO","10.07556675","0","200.00","222.96","1.1921","1.1695","USD" "104","2020-09-02","2020-09-02","NYSE:NIO","10","0","207.40","239.98","1.1832","1.1762","USD" "105","2020-09-02","2020-11-18","NASDAQ:TSLA","2.54919498","0","380.01","418.48","","","USD" "106","2020-09-04","2020-12-17","NASDAQ:AAPL","2.01871739","0","248.38","259.55","","","USD" "107","2020-09-04","2020-10-01","NASDAQ:TSLA","1.82127246","0","250.01","272.23","","","USD" "108","2020-09-10","2020-09-15","NASDAQ:TSLA","1.96494537","0","250.00","286.99","","","USD" "109","2020-09-17","2020-10-01","NASDAQ:ANSS","1.19565287","0","371.31","399.46","","","USD" "110","2020-09-24","2020-10-01","NASDAQ:TSLA","2.69316786","0","329.16","351.43","","","USD" "111","2020-09-24","2020-10-13","NASDAQ:ZM","0.74879082","0","351.43","382.32","","","USD" "112","2020-09-25","2020-10-09","NASDAQ:AAPL","2.02064706","0","219.22","235.02","","","USD" "113","2020-10-01","2020-10-21","NASDAQ:GOOGL","5.3886366","0","399.41","429.69","","","USD" "114","2020-10-02","2020-10-14","NASDAQ:TSLA","2.96907141","0","419.03","457.42","","","USD" "115","2020-10-06","2020-10-13","NASDAQ:AAPL","2.41595669","0","272.23","299.26","","","USD" "116","2020-10-13","2021-02-02","NASDAQ:Z","1","0","101.17","114.81","","","USD" "117","2020-10-15","2020-11-18","NASDAQ:TSLA","3","0","448.20","492.48","","","USD" "118","2020-10-15","2021-02-02","NASDAQ:ANSS","1","0","345.66","375.57","","","USD" "119","2020-10-20","2020-12-09","NASDAQ:ZM","0.8230289","0","429.69","338.03","","","USD" "120","2020-10-22","2020-10-29","NYSE:NIO","19.00692924","0","521.17","604.42","","","USD" "121","2020-10-30","2020-11-03","NYSE:NIO","19","0","581.21","654.36","","","USD" "122","2020-10-30","2020-11-05","NASDAQ:AAPL","2.37198781","0","258.07","282.79","","","USD" "123","2020-11-04","2020-11-05","NYSE:NIO","17.55848346","0","654.23","727.80","","","USD" "124","2020-11-06","2020-11-12","NYSE:NIO","20","0","824.80","980.00","","","USD" "125","2020-11-12","2020-11-23","NASDAQ:ZM","1","0","435.44","428.76","","","USD" "126","2020-11-13","2020-11-23","NYSE:NIO","12","0","541.20","660.00","","","USD" "127","2020-11-17","2020-11-23","NYSE:NIO","15","0","715.20","825.00","","","USD" "128","2020-11-18","2020-12-15","NASDAQ:AAPL","4","0","479.04","506.60","","","USD" "129","2020-11-23","2020-11-27","NASDAQ:MRNA","8","0","809.60","998.80","","","USD" "130","2020-11-23","2020-12-15","NASDAQ:AAPL","4","0","457.24","505.36","","","USD" "131","2020-11-24","2021-01-20","NYSE:NIO","11","0","584.32","659.98","","1.2101","USD" "132","2020-11-30","2020-12-17","NASDAQ:AAPL","2","0","234.84","255.76","","","USD" "133","2020-11-24","2021-01-12","NYSE:NIO","9","0","478.08","576.18","","","USD" "134","2020-11-25","2021-01-29","NASDAQ:MRNA","5","0","730.10","762.90","","","USD" "135","2020-12-03","2020-12-07","NASDAQ:AAPL","-2.06461594","0","-254.05","-249.61","","","USD" "136","2020-11-25","2021-01-26","NASDAQ:MRNA","5","0","730.10","870.00","","1.2153","USD" "137","2020-12-07","2021-02-04","NASDAQ:MRNA","3","0.01","466.20","515.99","","1.1965","USD" "138","2020-12-07","2020-12-21","NYSE:NIO","8","0","352.24","391.84","","","USD" "139","2020-12-08","2021-02-08","NASDAQ:MRNA","3","0.02","503.52","554.98","1.2104","1.2061","USD" "140","2020-12-10","2021-01-29","NASDAQ:MRNA","1","0","155.44","173.97","1.2139","1.2153","USD" "141","2020-12-10","2020-12-17","NASDAQ:TSLA","3","0","573.85","649.98","1.2112","1.2263","USD" "142","2020-12-11","2020-12-14","NASDAQ:TSLA","-1.17027156","0","-244.72","-240.85","","","USD" "143","2020-12-14","2020-12-30","NASDAQ:TSLA","3","0","617.43","694.98","","","USD" "144","2020-12-14","2020-12-21","NYSE:NIO","1","0","39.90","48.96","1.2163","","USD" "145","2020-12-15","2021-01-26","NASDAQ:MRNA","4","0","580.00","610.36","1.2161","","USD" "146","2020-12-17","2021-01-07","NASDAQ:TSLA","3","0","620.01","799.95","","","USD" "147","2020-12-22","2021-01-14","NASDAQ:TSLA","3","0","647.31","859.97","1.2225","1.2118","USD" "148","2020-12-23","2020-12-30","NASDAQ:TSLA","3","0","630.00","694.98","","","USD" "149","2020-12-31","2021-01-06","NYSE:NIO","10","0","485.00","550.00","1.2279","","USD" "150","2020-12-31","2021-01-07","NASDAQ:TSLA","2.581293","0","616.49","688.35","","","USD" "151","2020-12-31","2021-01-07","NASDAQ:TSLA","0.418707","0","100.00","111.66","","","USD" "152","2021-01-04","2021-07-09","NASDAQ:AAPL","1","0","130.00","145.03","","","USD" "153","2021-01-06","2021-02-02","NASDAQ:TSLA","0.71085433","0","546.91","619.87","1.228","1.2029","USD" "154","2021-01-07","2021-01-25","NASDAQ:TSLA","1","0","805.56","899.97","1.2275","1.2129","USD" "155","2021-01-08","2021-10-25","NASDAQ:TSLA","0.86743701","0","244.61","276.43","","","USD" "156","2021-01-08","2021-10-25","NASDAQ:TSLA","1.68863022","0","489.31","549.31","","","USD" "157","2021-01-08","2021-10-25","NASDAQ:TSLA","1.31136978","0","380.00","426.58","","","USD" "158","2021-01-13","2021-01-14","NASDAQ:PLUG","8","0.02","554.48","514.78","1.2167","1.2167","USD" "159","2021-01-11","2021-01-14","NYSE:NIO","2","0","129.78","87.08","1.2147","1.1553","USD" "160","2020-12-21","2021-04-15","NASDAQ:AMD","3","0","276.00","249.18","","","USD" "161","2020-12-23","2021-02-03","NASDAQ:AMZN","2.691074","0","430.01","457.37","","","USD" "162","2020-12-23","2021-02-03","NASDAQ:AMZN","0.4380818","0","70.00","74.46","","","USD" "163","2020-12-23","2021-07-14","NASDAQ:AAPL","4","0","528.68","596.64","","","USD" "164","2020-12-17","2021-07-09","NASDAQ:AAPL","3","0","386.94","435.12","","","USD" "165","2020-12-17","2021-01-25","NASDAQ:AAPL","5","0","643.15","721.47","1.2263","1.2129","USD" "166","2020-12-07","2021-04-15","NASDAQ:AMD","4","0","358.20","332.24","","","USD" "167","2021-01-14","2021-01-21","NASDAQ:MRNA","4","0","516.32","538.84","1.2168","","USD" "168","2021-01-15","2021-02-09","NYSE:NIO","15","0","860.7","939.87","1.2094","1.2121","USD" "169","2021-01-22","2021-10-21","NASDAQ:TSLA","2.52425082","0","700","753.46","1.2179","1.164","USD" "170","2021-01-25","2021-10-25","NASDAQ:TSLA","3","0","870","992.81","1.213","1.161","USD" "171","2021-01-25","2021-09-07","NASDAQ:AAPL","5","0","700.00","775.25","","","USD" "172","2021-01-25","2021-11-04","NYSE:NIO","1","0","59.62","43.54","1.2148","1.1553","USD" "173","2021-01-27","2021-11-18","NASDAQ:AAPL","2","0","286.62","316.00","","","USD" "174","2021-01-27","2021-02-04","NASDAQ:MRNA","2","0.01","316.18","343.99","1.2094","1.1965","USD" "175","2021-01-27","2021-02-08","NASDAQ:MRNA","3","0.01","497.58","554.97","1.2126","1.2061","USD" "176","2021-01-29","2021-10-25","NASDAQ:TSLA","3","0","840.99","951.49","1.2148","1.1614","USD" "177","2021-01-29","2021-05-03","NASDAQ:MRNA","6","0","1064.10","1121.21","1.2147","1.2067","USD" "178","2021-02-01","2021-02-04","NASDAQ:MRNA","1","0.01","156.50","171.99","1.2067","1.1965","USD" "179","2021-02-02","2021-08-16","NASDAQ:AAPL","4","0","542.68","600.00","","","USD" "180","2021-02-05","2021-02-11","NASDAQ:PYPL","3","0","801.54","900.00","1.2040","1.2140","USD" "181","2021-02-08","2021-07-23","NASDAQ:PYPL","3","0","842.85","926.42","1.2061","1.1764","USD" "182","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.25","","","USD" "183","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.27","","","USD" "184","2021-02-09","2021-05-03","NASDAQ:MRNA","3","0","536.46","560.6","1.2121","1.2067","USD" "185","2021-02-10","2021-10-25","NASDAQ:TSLA","2.08745436","0","581.52","665.19","","","USD" "186","2021-02-11","2021-11-22","NASDAQ:PYPL","3","0","855","575.54","1.2133","1.1242","USD" "187","2021-02-12","2022-02-02","NASDAQ:PYPL","2.8","0","818.92","381.71","1.2098","1.1317","USD" "188","2021-03-12","2021-06-28","NYSE:NIO","4","0","177.20","159.99","1.1933","1.1932","USD" "189","2021-04-19","2021-09-17","NASDAQ:TSLA","2.35822089","0","550","596.41","1.2032","1.1758","USD" "190","2021-05-04","2021-07-06","NASDAQ:GOOGL","1.9646364","0","225","247.64","1.2027","1.1841","USD" "191","2021-05-04","2021-05-27","NASDAQ:MRNA","4","0.01","701.88","708.19","1.2021","1.2200","USD" "192","2021-05-04","2021-10-19","NASDAQ:ANSS","2","0","700.18","729.33","","","USD" "193","2021-05-04","2021-07-06","NASDAQ:AMZN","0.5170316","0","85","93.61","1.2023","1.1841","USD" "194","2021-05-24","2021-05-27","NYSE:SPCE","0.2","0","49.86","56.03","1.2212","1.2198","USD" "195","2021-05-27","2021-06-07","NYSE:SPCE","0.2","0","114.12","135.42","1.2194","1.2198","USD" "196","2021-05-27","2021-06-07","NYSE:SPCE","1","0","704.26","778.55","1.2199","1.2198","USD" "197","2021-06-07","2021-06-28","NYSE:NIO","10","0","437.20","490.00","1.2198","1.1932","USD" "198","2021-06-08","2021-06-25","NYSE:SPCE","0.6","0","448.31","572.75","1.2188","1.1969","USD" "199","2021-07-01","2021-11-04","NYSE:NIO","10","0","520","435.40","1.1869","1.1553","USD" "200","2021-07-06","2021-08-09","NASDAQ:GOOGL","4.3831336","0","550","595.41","1.1830","1.1751","USD" "201","2021-07-07","2021-07-08","NYSE:SPCE","0.6","0","540","599.99","1.1807","1.1848","USD" "202","2021-07-12","2021-12-03","NYSE:SPCE","0.6","0","540.00","171.84","1.1858","1.1280","USD" "203","2021-07-15","2021-07-16","NASDAQ:MRNA","1","0.01","255.80","284.99","1.1817","1.1804","USD" "204","2021-07-16","2021-11-09","NYSE:SPCE","1.2","0","781.44","503.77","1.1811","1.1588","USD" "205","2021-07-16","2021-11-29","NASDAQ:AAPL","1","0","147.32","164.98","","","USD" "206","2021-07-16","2021-11-29","NASDAQ:AAPL","2","0","294.60","330.00","","","USD" "207","2021-07-23","2021-08-03","NASDAQ:MRNA","2","0.01","670.54","739.99","1.1765","1.1866","USD" "208","2021-08-03","2021-11-19","NASDAQ:AMZN","4.4443522","0","750","829.78","1.1866","1.1315","USD" "209","2021-08-09","2021-11-26","NASDAQ:MRNA","1","0","287.97","327.95","1.1255","1.1300","USD" "210","2021-08-19","2021-11-19","NASDAQ:AAPL","5","0","724.65","800.00","","","USD" "211","2021-09-10","2021-12-01","NASDAQ:AAPL","5","0","749.85","850.00","","","USD" "212","2021-09-17","2021-11-29","NASDAQ:AAPL","4","0","587.32","660.00","","","USD" "213","2021-10-26","2021-11-01","NASDAQ:TSLA","3","0","1044.49","1149.98","1.1609","1.1583","USD" "214","2021-10-26","2021-12-06","NASDAQ:AAPL","4","0","601.92","668.36","","","USD" "215","2021-10-27","2021-12-01","NASDAQ:AAPL","7","0","1044.75","1190.00","","","USD" "216","2021-10-27","2021-12-01","NASDAQ:AAPL","3","0","447.75","510.00","","","USD" "217","2021-11-04","2022-02-17","NYSE:KO","10","0","562.89","619.99","1.1552","1.1365","USD" "218","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "219","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "220","2021-12-02","2021-12-13","NASDAQ:AAPL","7","0","1111.04","1266.98","1.1345","1.1294","USD" "221","2021-12-02","2021-12-10","NASDAQ:AAPL","3","0","482.67","534.51","","","USD" "222","2021-12-06","2022-01-03","NASDAQ:TSLA","3","0","992.9","1153.57","1.1291","1.1309","USD" "223","2021-12-14","2021-12-27","NASDAQ:TSLA","1.2","0","377.47","441.07","","","USD" "224","2021-12-14","2021-12-27","NASDAQ:TSLA","0.3","0","94.37","110.27","","","USD" "225","2021-11-10","2022-01-03","NASDAQ:TSLA","1.5","0","536.75","597.42","","","USD" "226","2022-02-18","2022-03-22","NASDAQ:TSLA","1.2","0","345.54","376.86","","","USD" "227","2022-02-18","2022-03-22","NASDAQ:TSLA","0.3","0","86.38","94.22","","","USD" "228","2022-02-18","2022-04-20","NYSE:O","2","0","134.06","149.99","1.1336","1.0848","USD" "229","2022-04-14","2022-10-05","NYSE:TWTR","4","0","193.68","203.72","1.0829","0.9852","USD" "230","2022-04-19","2022-10-05","NYSE:TWTR","1","0","47.24","50.93","1.0798","0.9852","USD" "231","2022-05-20","2022-07-21","NASDAQ:AAPL","1","0","139.02","155.02","","","USD" "232","2022-07-27","2022-07-27","NASDAQ:AAPL","1","0","162.00","162.00","","","USD" "233","2022-01-03","2023-12-27","NASDAQ:ANSS","2","0","786.86","669.60","","","USD" "234","2022-01-11","2023-11-16","NASDAQ:AAPL","6","0","1026","1139.98","1.1324","1.0885","USD" "235","2022-02-02","2023-05-25","NASDAQ:MSFT","0.62199751","0","185.15","200.03","1.1092","1.0722","USD" "236","2021-11-09","2024-01-01","NASDAQ:TSLA","3","0","1065.78","1065.78","","","USD" "237","2021-11-22","2023-06-15","NASDAQ:AAPL","8.5","0","1386.18","1572.67","","","USD" "238","2021-11-22","2023-06-15","NASDAQ:AAPL","1.5","0","244.62","277.50","","","USD" "239","2021-12-02","2023-06-15","NASDAQ:AAPL","7","0","1142.82","1295.00","","","USD" "240","2021-12-02","2023-06-15","NASDAQ:AAPL","2","0","326.52","370.00","","","USD" "241","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","392.00","","","USD" "242","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","391.98","","","USD" "243","2021-12-14","2023-12-13","NASDAQ:AAPL","3","0","522.51","588.00","","","USD" "244","2022-04-13","2023-12-14","NASDAQ:AAPL","1","0","170.66","196.00","","","USD" "245","2022-09-14","2023-05-05","NASDAQ:AAPL","2","0","311.56","343.98","","","USD" "246","2022-12-20","2023-01-23","NASDAQ:AAPL","2","0","260.00","285.98","","","USD" "247","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "248","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "249","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "250","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "251","2023-03-01","2023-06-14","NYSE:BRK.B","1","0","303.16","339.98","1.0685","1.0868","USD" "252","2023-05-08","2023-05-23","NASDAQ:TSLA","1","0","171.76","189.98","","","USD" "253","2023-05-26","2023-06-02","NASDAQ:TSLA","1","0","190.12","209.98","","","USD" "254","2022-01-06","2024-01-25","NASDAQ:TSLA","2.7","0","945.00","506.93","","","USD" "255","2022-01-06","2024-01-25","NASDAQ:TSLA","0.3","0","105.00","56.32","","","USD" "256","2023-01-01","2024-04-26","NASDAQ:GOOGL","1.8369098","0","276.14","320.23","","","USD" "257","2022-02-02","2024-04-26","NASDAQ:GOOGL","0.9046522","0","136.00","157.69","","","USD" "258","2022-02-28","2024-06-05","NYSE:KO","2","0","123.86","127.83","1.1225","1.0890","USD" "259","2021-10-15","2024-04-12","NASDAQ:GOOGL","5","0","714.80","1498.30","","","USD" "260","2021-11-04","2024-07-11","NYSE:BAC","10","0","474.89","419.98","1.1551","1.0899","USD" "261","2024-01-01","2024-03-01","NASDAQ:TSLA","2","0","710.52","402.44","","","USD" "262","2024-01-01","2024-02-09","NASDAQ:TSLA","1","0","355.26","192.78","","","USD" "263","2021-11-10","2024-02-09","NASDAQ:TSLA","0.525","0","187.86","101.21","","","USD" "264","2021-11-10","2024-02-09","NASDAQ:TSLA","0.975","0","348.88","187.95","","","USD" "265","2021-11-22","2024-02-09","NASDAQ:TSLA","1.5","0","590.88","289.17","","","USD" "266","2021-11-26","2024-02-02","NASDAQ:AMZN","1.8995262","0","334.98","326.64","","","USD" "267","2021-12-02","2024-02-02","NASDAQ:AMZN","1.7335028","0","300.00","298.09","","","USD" "268","2021-12-14","2024-04-26","NASDAQ:AAPL","1","0","174.17","170.00","","","USD" "269","2021-12-28","2024-02-02","NASDAQ:AMZN","1.1645374","0","200.00","200.24","","","USD" "270","2024-04-22","2024-07-17","NYSE:O","2","0","148.00","114.32","1.0817","1.0957","USD" "271","2022-06-07","2024-02-02","NASDAQ:AMZN","0.2024336","0","24.75","34.81","","","USD" "272","2023-05-23","2024-06-11","NASDAQ:AAPL","1","0","172.79","199.96","","","USD" "273","2023-06-06","2024-07-02","NASDAQ:AAPL","3","0","535.89","660.00","","","USD" "274","2023-06-06","2024-04-26","NASDAQ:AAPL","1","0","178.63","170.00","","","USD" "275","2023-06-14","2024-01-31","NASDAQ:TSLA","1","0","258.00","189.98","","","USD" "276","2023-06-15","2024-01-25","NYSE:BRK.B","4","0","1352.95","1519.98","1.0927","1.0876","USD" "277","2023-06-20","2024-01-31","NASDAQ:TSLA","2","0","542.06","380.00","","","USD" "278","2023-06-30","2024-08-28","NASDAQ:AAPL","4","0","769.80","919.96","","","USD" "279","2023-07-19","2024-02-07","NASDAQ:TSLA","2","0","593.16","362.96","","","USD" "280","2023-07-19","2024-02-07","NASDAQ:TSLA","1","0","296.58","181.47","","","USD" "281","2023-09-13","2024-07-02","NASDAQ:AAPL","3","0","525.06","660.00","","","USD" "282","2023-12-14","2024-08-28","NASDAQ:AAPL","1","0","196.00","230.00","","","USD" "283","2023-12-18","2024-11-26","NASDAQ:AAPL","2","0","390.00","470.00","","","USD" "284","2023-12-22","2024-11-26","NASDAQ:AAPL","3","0","585.72","705.00","","","USD" "285","2024-01-01","2024-11-26","NASDAQ:AAPL","3","0","576.96","705.00","","","USD" "286","2024-01-08","2024-07-02","NASDAQ:AAPL","3","0","540.00","659.93","","","USD" "287","2024-01-25","2024-02-09","NASDAQ:NVDA","30","0","1865.35","2159.97","1.0876","1.0809","USD" "288","2024-01-31","2024-06-17","NASDAQ:MSFT","1","0","402.58","449.98","1.0869","1.0750","USD" "289","2024-02-02","2024-05-20","NASDAQ:NVDA","10","0","659.78","949.98","1.0805","1.0889","USD" "290","2024-02-02","2024-11-26","NASDAQ:AAPL","1","0","186.01","234.93","","","USD" "291","2024-02-05","2024-05-22","NASDAQ:NVDA","10","0","688.87","999.85","","","USD" "292","2024-02-21","2024-05-22","NASDAQ:NVDA","30","0","2037.00","3000.00","","","USD" "293","2024-03-05","2024-07-30","NYSE:BRK.B","1","0","400.00","439.98","1.0882","1.0832","USD" "294","2024-03-11","2024-05-22","NASDAQ:NVDA","10","0","889.33","1000.00","","","USD" "295","2024-04-01","2024-06-11","NASDAQ:AAPL","2","0","340.00","400.00","","","USD" "296","2021-10-15","2024-04-26","NASDAQ:GOOGL","0.137277","0","19.63","23.93","","","USD" "297","2024-04-26","2024-06-11","NASDAQ:AAPL","3","0","510.00","600.00","","","USD" "298","2024-07-03","2024-09-05","NASDAQ:TSLA","2","0","495.86","450.44","","","USD" "299","2024-07-11","2024-11-10","NYSE:TSM","10","0","1938.61","1898.01","1.0915","1.0965","USD" "300","2024-05-28","2024-10-17","NASDAQ:NVDA","10","0.05","1120.60","1399.95","","","USD" "301","2023-12-14","2026-01-14","AMS:IWDA","6","0.05","491.33","682.58","","","EUR" "302","2024-04-22","2026-01-14","AMS:IWDA","7","0.06","618.93","796.34","","","EUR" "303","2024-05-28","2025-01-06","NASDAQ:NVDA","20","0.09","2241.20","2999.91","","","USD" "304","2024-06-06","2025-05-28","NASDAQ:NVDA","20","0","2498.35","2799.99","1.0907","1.1318","USD" "305","2024-06-12","2026-01-12","NASDAQ:AAPL","7","0.01","1497.65","1819.99","","","USD" "306","2024-06-20","","NASDAQ:AAPL","2","0","420.00","","","","USD" "307","2024-07-23","2026-01-15","INDEXNASDAQ:NDX","4.84403203","0","858.75","1039.77","","","EUR" "308","2024-08-01","2025-11-11","NASDAQ:AAPL","5","0","1094.25","1369.52","1.0809","1.1626","USD" "309","2024-08-05","2025-08-08","NASDAQ:AAPL","1","0","204.90","225.00","","","USD" "310","2024-08-05","2025-08-08","NASDAQ:AAPL","2","0","409.80","449.98","","","USD" "3","2024-11-06","","NASDAQ:AAPL","21","0","4741.95","","","","USD" "3","2024-11-25","2025-02-24","NASDAQ:NVDA","8","0.01","1101.58","1559.99","","","USD" "313","2024-12-18","2026-01-15","INDEXNASDAQ:NDX","10","0","2038.00","2146.50","","","EUR" "314","2025-01-06","2026-01-15","NASDAQ:NVDA","21","0.01","2998.17","3947.99","","","USD" "315","2025-01-27","2026-01-15","NASDAQ:NVDA","2","0.01","247.18","376","","","USD" "316","2025-07-03","2026-04-15","NASDAQ:NVDA","12","0.06","1918.68","2399.94","","","USD" "317","2025-10-16","","NASDAQ:NVDA","8","0","1454.35","","","","USD" "318","2025-11-11","","NASDAQ:NVDA","9","0","1742.36","","","","USD" "319","2026-02-27","","NASDAQ:NVDA","8","0","1464","","","","USD" "320","2026-04-29","","NASDAQ:NVDA","11","0","2298.12","","","","USD" "321","2026-06-08","","NASDAQ:NVDA","3.84990476","0","808.48","","","","USD" ======================================================================================== FICHEIRO: dados_csv/tiago/transacoes-vistos.json Tamanho: 66 bytes ======================================================================================== { "versao": "1.0", "vistos": {}, "ultima_atualizacao": "" } ======================================================================================== FICHEIRO: dados_csv/transacoes-acoes.csv Tamanho: 29114 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes,CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda "1","2019-10-15","2019-10-16","NASDAQ:GOOGL","0.00808315","0","10.00","10.05","1.1041","1.1083","USD" "2","2019-10-16","2020-02-10","NASDAQ:AMZN","0.0056605","0","10.05","12.00","","","USD" "3","2020-01-22","2020-06-10","NASDAQ:AAPL","0.47175745","0","150.00","164.64","","","USD" "4","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28949064","0","100.00","112.51","","","USD" "5","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28812028","0","100.00","112.57","","","USD" "6","2020-02-04","2020-05-29","NASDAQ:ADBE","0.27270991","0","100.00","104.05","","","USD" "7","2020-02-06","2020-04-30","NASDAQ:TSLA","0.12870012","0","100.00","112.68","","","USD" "8","2020-02-19","2020-02-25","NYSE:MA","0.28609409","0","100.07","94.80","1.0787","1.1877","USD" "9","2020-02-19","2020-04-14","NASDAQ:TSLA","0.13183279","0","124.07","133.54","","","USD" "10","2020-02-25","2020-05-20","NYSE:MA","0.31256977","0","98.08","92.74","1.0854","1.1368","USD" "11","2020-02-27","2020-04-14","NASDAQ:AMZN","0.05144915","0","100.09","102.44","","","USD" "12","2020-03-19","2020-04-13","NASDAQ:AMZN","0.05281643","0","100.00","120.33","1.0791","1.0908","USD" "13","2020-03-19","2020-05-05","NASDAQ:AAPL","1.57029008","0","100.00","117.24","","","USD" "14","2020-03-25","2020-03-25","NASDAQ:TSLA","2.72737185","0","100.01","133.53","","","USD" "15","2020-04-07","2020-05-25","NYSE:MCD","1.11594688","0","200.00","209.51","1.0787","1.1054","USD" "16","2020-04-14","2020-05-12","NASDAQ:NFLX","0.25100401","0","101.09","110.15","1.0962","1.0866","USD" "17","2020-04-15","2020-04-30","NASDAQ:TSLA","0.13523381","0","101.08","112.68","","","USD" "18","2020-04-16","2020-06-10","NASDAQ:AMZN","0.08295313","0","201.08","219.83","","","USD" "19","2020-04-16","2020-07-01","NASDAQ:NFLX","0.22745365","0","101.08","105.58","1.0879","1.1268","USD" "20","2020-04-27","2020-05-11","NASDAQ:GOOGL","0.15638072","0","201.08","217.44","1.0850","1.0812","USD" "21","2020-05-01","2020-06-09","NASDAQ:AMZN","0.04362354","0","101.09","109.89","","","USD" "22","2020-05-01","2020-05-06","NASDAQ:TSLA","0.21263626","0","151.09","167.02","","","USD" "23","2020-05-11","2020-07-09","NASDAQ:AMD","1.80733779","0","101.08","101.77","","","USD" "24","2020-05-12","2020-08-19","NYSE:MA","0.36659579","0","101.08","109.05","1.0852","1.0994","USD" "25","2020-05-14","2020-06-03","NASDAQ:GOOGL","0.14908017","","201.07","213.99","1.0794","1.1248","USD" "26","2020-05-15","2020-05-29","NYSE:SQ","2.54097319","0","201.08","205.08","1.0834","1.1105","USD" "27","2020-05-20","2020-07-01","NASDAQ:NVDA","0.34223706","0","124.09","130.86","","","USD" "28","2020-05-21","2020-06-08","NYSE:KO","4.34023991","0","200.08","215.7","1.0984","1.1304","USD" "29","2020-05-27","2020-06-03","NASDAQ:ANSS","0.38406882","0","101.09","111.55","1.0979","1.1224","USD" "30","2020-05-28","2020-06-05","NASDAQ:QCOM","2.4789291","0","201.10","220.91","1.1055","1.1289","USD" "31","2020-05-29","2020-07-19","NASDAQ:MSFT","1.15486141","0","211.11","228.85","1.1104","1.1231","USD" "32","2020-06-01","2020-06-18","NASDAQ:UAL","6.8212824","0","201.11","271.98","1.1117","1.1212","USD" "33","2020-06-03","2020-07-01","NASDAQ:UAL","7.12250712","0","225.00","266.29","1.1218","1.1262","USD" "34","2020-06-03","2020-07-15","NASDAQ:UAL","6.44484412","0","216.12","219.50","1.1248","1.1453","USD" "35","2020-06-04","2020-08-10","NASDAQ:UAL","2.69444444","0","98.12","98.47","1.1261","1.1797","USD" "36","2020-06-04","2020-08-27","NASDAQ:UAL","2.78884462","0","106.13","104.54","1.1334","1.1803","USD" "37","2020-06-04","2020-08-27","NASDAQ:UAL","5.20231213","0","199.13","191.07","1.1330","1.1782","USD" "38","2020-06-05","2020-10-06","NASDAQ:UAL","2.4672489","0","114.12","90.74","1.1297","1.1797","USD" "39","2020-06-05","2020-10-08","NASDAQ:UAL","4.8456164","0","215","181.65","1.1287","1.1744","USD" "40","2020-06-08","2020-10-08","NASDAQ:UAL","4.86896252","0","224.80","182.14","1.1309","1.1743","USD" "41","2020-06-08","2020-07-30","NASDAQ:ANSS","0.35145678","0","100.00","108.80","1.1303","1.1801","USD" "42","2020-06-09","2020-09-15","NASDAQ:UAL","2.22121486","0","99.13","82.33","1.1346","1.1857","USD" "43","2020-06-10","2020-08-28","NASDAQ:UAL","2.43486729","0","101.13","90.13","1.1373","1.1899","USD" "44","2020-06-10","2020-08-03","NASDAQ:ANSS","1.03831377","0","301.13","327.64","","","USD" "45","2020-06-11","2020-07-01","NASDAQ:TSLA","0.30035742","0","301.14","336.05","","","USD" "46","2020-06-15","2020-07-06","NASDAQ:AAPL","0.44628246","0","151.11","166.73","","","USD" "47","2020-06-19","2020-06-20","NASDAQ:GOOGL","4.1551534","0","301.12","322.63","1.1231","1.1444","USD" "48","2020-06-19","2020-07-30","NASDAQ:QCOM","3.3463469","0","301.12","343.55","1.1226","1.1800","USD" "49","2020-06-22","2020-07-13","NASDAQ:AAPL","0.56580287","0","201.12","220.87","1.1228","1.1352","USD" "50","2020-07-01","2020-07-21","NYSE:KO","6.61229887","0","300","314.86","1.1269","1.145","USD" "51","2020-07-07","2020-07-10","NASDAQ:TSLA","0.35837412","0","500","549.91","1.1289","1.1304","USD" "52","2020-07-07","2020-07-15","NASDAQ:UAL","6.00781015","0","200.00","205.52","1.1289","1.1450","USD" "53","2020-07-07","2020-08-21","NASDAQ:ZM","0.55248618","0","150.00","160.37","1.1329","1.1768","USD" "54","2020-07-10","2020-08-31","NASDAQ:AMZN","0.03145999","0","100.00","109.86","1.1327","1.1961","USD" "55","2020-07-13","2020-08-18","NASDAQ:TSLA","0.17648096","0","300.01","330.61","1.1351","1.1934","USD" "56","2020-07-13","2020-11-13","NASDAQ:AMZN","0.09185548","0","300.01","286.13","1.135","1.1829","USD" "57","2020-07-14","2020-07-31","NASDAQ:AAPL","0.65824117","0","250.00","270.98","1.1369","1.1839","USD" "58","2020-07-15","2020-08-03","NASDAQ:AAPL","2.0317988","0","199.99","225.55","","","USD" "59","2020-07-15","2020-07-30","NASDAQ:TSLA","1.9946808","0","200.01","232.18","","","USD" "60","2020-07-20","2020-07-23","NASDAQ:UAL","9.17150718","0","300.00","307.98","1.1443","1.1618","USD" "61","2020-07-20","2020-08-03","NASDAQ:AAPL","3.05654608","0","300.00","339.31","","","USD" "62","2020-07-23","2020-11-13","NASDAQ:AMZN","1.9828548","0","300.01","327.75","","","USD" "63","2020-07-24","2020-07-24","NASDAQ:AMD","1.05263157","0","70.00","72.41","","","USD" "64","2020-07-24","2020-08-21","NASDAQ:ZM","0.28389503","0","70.00","82.40","1.1635","1.1768","USD" "65","2020-07-27","2020-08-13","NASDAQ:TSLA","0.10470034","0","150.00","168.30","1.1746","1.1839","USD" "66","2020-07-30","2020-09-01","NASDAQ:GOOGL","0.19926934","0","300.00","329.87","1.1804","1.1917","USD" "67","2020-07-30","2020-08-27","NASDAQ:MSFT","0.73800738","0","150.00","169.05","1.1802","1.1807","USD" "68","2020-07-31","2020-08-25","NASDAQ:GOOGL","0.16989812","0","250","272.70","1.1840","1.1828","USD" "69","2020-08-03","2020-08-13","NASDAQ:TSLA","0.2030663","0","300.00","331.46","1.1731","1.1859","USD" "70","2020-08-05","2020-09-01","NASDAQ:ANSS","0.95910994","0","300.00","330.23","","","USD" "71","2020-08-05","2020-09-29","NASDAQ:AMD","1.18990956","0","100.00","96.79","","","USD" "72","2020-08-06","2020-08-31","NASDAQ:AAPL","0.22504782","0","100.00","115.45","","","USD" "73","2020-08-10","2020-08-31","NASDAQ:AMD","1.23701138","0","100.00","111.16","","","USD" "74","2020-08-10","2020-08-27","NASDAQ:ANSS","0.32998944","0","100.00","109.43","","","USD" "75","2020-08-13","2020-08-18","NASDAQ:ZM","0.40695071","0","100.00","110.22","1.1851","1.1962","USD" "76","2020-08-14","2020-08-20","NYSE:SQ","0.7033338","0","100.00","109.90","1.1830","1.1847","USD" "77","2020-08-17","2020-08-18","NASDAQ:TSLA","0.05902769","0","100.00","111.14","","","USD" "78","2020-08-17","2020-08-31","NASDAQ:TSLA","0.842091","0","100.00","97.95","","","USD" "79","2020-08-17","2020-09-01","NYSE:SQ","0.66613375","0","100.00","110.62","1.1860","1.1977","USD" "80","2020-08-18","2020-08-24","NASDAQ:UAL","2.9620853","0","100.00","107.19","1.1937","1.1805","USD" "81","2020-08-19","2020-09-02","NASDAQ:NVDA","0.10171698","0","50.00","58.70","","","USD" "82","2020-08-20","2020-08-28","NASDAQ:TSLA","0.05034207","0","100.00","114.37","","","USD" "83","2020-08-21","2020-12-17","NASDAQ:AAPL","1.6575476","0","200.00","213.11","","","USD" "84","2020-08-21","2020-08-31","NASDAQ:TSLA","0.09623805","0","200.01","222.84","","","USD" "85","2020-08-21","2020-08-31","NASDAQ:TSLA","0.09623805","0","200.01","222.84","","","USD" "86","2020-08-24","2020-08-27","NASDAQ:TSLA","0.09782821","0","200.00","222.35","","","USD" "87","2020-08-25","2020-09-28","NYSE:BABA","0.17636684","0","50.00","48.62","1.1826","1.1662","USD" "88","2020-08-26","2020-09-01","NASDAQ:ZM","0.1661792","0","50.00","75.38","1.1821","1.1977","USD" "89","2020-08-26","2020-09-28","NYSE:BABA","0.17246731","0","50.00","47.54","1.1825","1.1662","USD" "90","2020-08-27","2020-12-03","NASDAQ:TSLA","1.3170429","0","200.01","257.80","","","USD" "91","2020-08-27","2020-11-13","NASDAQ:TSLA","0.21983819","0","500.01","445.11","","","USD" "92","2020-08-27","2020-08-31","NASDAQ:TSLA","0.21983819","0","499.99","548.72","","","USD" "93","2020-08-27","2020-12-17","NASDAQ:AAPL","1.60481444","0","200.01","206.33","","","USD" "94","2020-08-28","2020-09-02","NASDAQ:NVDA","0.09644131","0","50.00","55.67","","","USD" "95","2020-08-15","2020-12-03","NASDAQ:TSLA","3.22587582","0","500.01","631.53","","","USD" "96","2020-08-15","2020-12-15","NASDAQ:TSLA","1.23482196","0","200.00","263.70","","","USD" "97","2020-08-20","2020-08-31","NASDAQ:TSLA","0.05034207","0","100.00","122.78","","","USD" "98","2020-08-15","2020-12-15","NASDAQ:TSLA","3.02858988","0","499.99","649.98","","","USD" "99","2020-09-01","2020-09-22","NASDAQ:ZM","0.23466466","0","100.00","110.05","1.1988","1.1759","USD" "100","2020-09-01","2020-12-10","NASDAQ:TSLA","3.0358227","0","500.00","631.60","","","USD" "101","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.10","1.1969","1.1706","USD" "102","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","0","200.00","219.19","1.1952","1.1668","USD" "103","2020-09-01","2020-09-30","NYSE:NIO","10.07556675","0","200.00","222.96","1.1921","1.1695","USD" "104","2020-09-02","2020-09-02","NYSE:NIO","10","0","207.40","239.98","1.1832","1.1762","USD" "105","2020-09-02","2020-11-18","NASDAQ:TSLA","2.54919498","0","380.01","418.48","","","USD" "106","2020-09-04","2020-12-17","NASDAQ:AAPL","2.01871739","0","248.38","259.55","","","USD" "107","2020-09-04","2020-10-01","NASDAQ:TSLA","1.82127246","0","250.01","272.23","","","USD" "108","2020-09-10","2020-09-15","NASDAQ:TSLA","1.96494537","0","250.00","287.02","","","USD" "109","2020-09-17","2020-10-01","NASDAQ:ANSS","1.19565287","0","371.31","399.46","","","USD" "110","2020-09-24","2020-10-01","NASDAQ:TSLA","2.69316786","0","329.16","351.43","","","USD" "111","2020-09-24","2020-10-13","NASDAQ:ZM","0.74879082","0","351.43","382.32","","","USD" "112","2020-09-25","2020-10-09","NASDAQ:AAPL","2.02064706","0","219.22","235.02","","","USD" "113","2020-10-01","2020-10-21","NASDAQ:GOOGL","5.3886366","0","399.41","429.69","","","USD" "114","2020-10-02","2020-10-14","NASDAQ:TSLA","2.96907141","0","419.03","457.42","","","USD" "115","2020-10-06","2020-10-13","NASDAQ:AAPL","2.41595669","0","272.23","299.26","","","USD" "116","2020-10-13","2021-02-02","NASDAQ:Z","1","0","101.17","114.81","","","USD" "117","2020-10-15","2020-11-18","NASDAQ:TSLA","3","0","448.20","492.48","","","USD" "118","2020-10-15","2021-02-02","NASDAQ:ANSS","1","0","345.66","375.57","","","USD" "119","2020-10-20","2020-12-09","NASDAQ:ZM","0.8230289","0","429.69","338.03","","","USD" "120","2020-10-22","2020-10-29","NYSE:NIO","19.00692924","0","521.17","604.42","","","USD" "121","2020-10-30","2020-11-03","NYSE:NIO","19","0","581.21","654.36","","","USD" "122","2020-10-30","2020-11-05","NASDAQ:AAPL","2.37198781","0","258.07","282.79","","","USD" "123","2020-11-04","2020-11-05","NYSE:NIO","17.55848346","0","654.23","727.80","","","USD" "124","2020-11-06","2020-11-12","NYSE:NIO","20","0","824.80","980.00","","","USD" "125","2020-11-12","2020-11-23","NASDAQ:ZM","1","0","435.44","428.76","","","USD" "126","2020-11-13","2020-11-23","NYSE:NIO","12","0","541.20","660.00","","","USD" "127","2020-11-17","2020-11-23","NYSE:NIO","15","0","715.20","825.00","","","USD" "128","2020-11-18","2020-12-15","NASDAQ:AAPL","4","0","479.04","506.60","","","USD" "129","2020-11-23","2020-11-27","NASDAQ:MRNA","8","0","809.60","998.80","","","USD" "130","2020-11-23","2020-12-15","NASDAQ:AAPL","4","0","457.24","505.36","","","USD" "131","2020-11-24","2021-01-20","NYSE:NIO","11","0","584.32","659.98","","1.2101","USD" "132","2020-11-30","2020-12-17","NASDAQ:AAPL","2","0","234.84","255.76","","","USD" "133","2020-11-24","2021-01-12","NYSE:NIO","9","0","478.08","576.18","","","USD" "134","2020-11-25","2021-01-29","NASDAQ:MRNA","5","0","730.10","762.90","","","USD" "135","2020-12-03","2020-12-07","NASDAQ:AAPL","-2.06461594","0","-254.05","-249.61","","","USD" "136","2020-11-25","2021-01-26","NASDAQ:MRNA","5","0","730.10","870.00","","1.2153","USD" "137","2020-12-07","2021-02-04","NASDAQ:MRNA","3","0.01","466.20","515.99","","1.1965","USD" "138","2020-12-07","2020-12-21","NYSE:NIO","8","0","352.24","391.84","","","USD" "139","2020-12-08","2021-02-08","NASDAQ:MRNA","3","0.02","503.52","554.98","1.2104","1.2061","USD" "140","2020-12-10","2021-01-29","NASDAQ:MRNA","1","0","155.44","173.97","1.2139","1.2153","USD" "141","2020-12-10","2020-12-17","NASDAQ:TSLA","1","0","573.85","649.98","1.2112","1.2263","USD" "142","2020-12-11","2020-12-14","NASDAQ:TSLA","-1.17027156","0","-244.72","-240.85","","","USD" "143","2020-12-14","2020-12-30","NASDAQ:TSLA","3","0","617.43","694.98","","","USD" "144","2020-12-14","2020-12-21","NYSE:NIO","1","0","39.90","48.96","1.2163","","USD" "145","2020-12-15","2021-01-26","NASDAQ:MRNA","4","0","580.00","610.36","1.2161","","USD" "146","2020-12-17","2021-01-07","NASDAQ:TSLA","3","0","620.01","799.95","","","USD" "147","2020-12-22","2021-01-14","NASDAQ:TSLA","1","0","647.31","859.97","1.2225","1.2118","USD" "148","2020-12-23","2020-12-30","NASDAQ:TSLA","3","0","630.00","694.98","","","USD" "149","2020-12-31","2021-01-06","NYSE:NIO","10","0","485.00","550.00","1.2279","","USD" "150","2020-12-31","2021-01-07","NASDAQ:TSLA","2.581293","0","616.49","688.35","","","USD" "151","2020-12-31","2021-01-07","NASDAQ:TSLA","0.418707","0","100.00","111.66","","","USD" "152","2021-01-04","2021-07-09","NASDAQ:AAPL","1","0","130.00","145.03","","","USD" "153","2021-01-06","2021-02-02","NASDAQ:TSLA","0.71085433","0","546.91","619.87","1.228","1.2029","USD" "154","2021-01-07","2021-01-25","NASDAQ:TSLA","1","0","805.56","899.97","1.2275","1.2129","USD" "155","2021-01-08","2021-10-25","NASDAQ:TSLA","0.86743701","0","244.74","276.43","","","USD" "156","2021-01-08","2021-10-25","NASDAQ:TSLA","1.68863022","0","489.31","549.31","","","USD" "157","2021-01-08","2021-10-25","NASDAQ:TSLA","1.31136978","0","380.00","426.58","","","USD" "158","2021-01-13","2021-01-14","NASDAQ:PLUG","8","0.02","554.48","514.78","1.2167","1.2167","USD" "159","2021-01-11","2021-01-14","NYSE:NIO","2","0","129.78","87.08","1.2147","1.1553","USD" "160","2020-12-21","2021-04-15","NASDAQ:AMD","3","0","276.00","249.18","","","USD" "161","2020-12-23","2021-02-03","NASDAQ:AMZN","2.691074","0","430.01","457.37","","","USD" "162","2020-12-23","2021-02-03","NASDAQ:AMZN","0.4380818","0","70.00","74.46","","","USD" "163","2020-12-23","2021-07-14","NASDAQ:AAPL","4","0","528.68","596.64","","","USD" "164","2020-12-17","2021-07-09","NASDAQ:AAPL","3","0","386.94","435.12","","","USD" "165","2020-12-17","2021-01-25","NASDAQ:AAPL","5","0","643.15","721.47","1.2263","1.2129","USD" "166","2020-12-07","2021-04-15","NASDAQ:AMD","4","0","358.20","332.24","","","USD" "167","2021-01-14","2021-01-21","NASDAQ:MRNA","4","0","516.32","538.84","1.2168","","USD" "168","2021-01-15","2021-02-09","NYSE:NIO","15","0","860.7","939.87","1.2094","1.2121","USD" "169","2021-01-22","2021-10-21","NASDAQ:TSLA","0.84141694","0","700","753.46","1.2179","1.164","USD" "170","2021-01-25","2021-10-25","NASDAQ:TSLA","1","0","870","992.81","1.213","1.161","USD" "171","2021-01-25","2021-09-07","NASDAQ:AAPL","5","0","700.00","775.25","","","USD" "172","2021-01-25","2021-11-04","NYSE:NIO","1","0","59.62","43.54","1.2148","1.1553","USD" "173","2021-01-27","2021-11-18","NASDAQ:AAPL","2","0","286.62","316.00","","","USD" "174","2021-01-27","2021-02-04","NASDAQ:MRNA","2","0.01","316.18","343.99","1.2094","1.1965","USD" "175","2021-01-27","2021-02-08","NASDAQ:MRNA","3","0.01","497.58","554.97","1.2126","1.2061","USD" "176","2021-01-29","2021-10-25","NASDAQ:TSLA","1","0","840.99","951.49","1.2148","1.1614","USD" "177","2021-01-29","2021-05-03","NASDAQ:MRNA","6","0","1064.10","1121.21","1.2147","1.2067","USD" "178","2021-02-01","2021-02-04","NASDAQ:MRNA","1","0.01","156.50","171.99","1.2067","1.1965","USD" "179","2021-02-02","2021-08-16","NASDAQ:AAPL","4","0","542.68","600.00","","","USD" "180","2021-02-05","2021-02-11","NASDAQ:PYPL","3","0","801.54","900.00","1.2040","1.2140","USD" "181","2021-02-08","2021-07-23","NASDAQ:PYPL","3","0","842.85","926.42","1.2061","1.1764","USD" "182","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.25","","","USD" "183","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","0","415.48","406.27","","","USD" "184","2021-02-09","2021-05-03","NASDAQ:MRNA","3","0","536.46","560.6","1.2121","1.2067","USD" "185","2021-02-10","2021-10-25","NASDAQ:TSLA","2.08745436","0","581.52","665.19","","","USD" "186","2021-02-11","2021-11-22","NASDAQ:PYPL","3","0","855","575.54","1.2133","1.1242","USD" "187","2021-02-12","2022-02-02","NASDAQ:PYPL","2.8","0","818.92","381.71","1.2098","1.1317","USD" "188","2021-03-12","2021-06-28","NYSE:NIO","4","0","177.20","159.99","1.1933","1.1932","USD" "189","2021-04-19","2021-09-17","NASDAQ:TSLA","0.78607363","0","550","596.41","1.2032","1.1758","USD" "190","2021-05-04","2021-07-06","NASDAQ:GOOGL","0.09823182","0","225","247.64","1.2027","1.1841","USD" "191","2021-05-04","2021-05-27","NASDAQ:MRNA","4","0.01","701.88","708.19","1.2021","1.2200","USD" "192","2021-05-04","2021-10-19","NASDAQ:ANSS","2","0","700.18","729.33","","","USD" "193","2021-05-04","2021-07-06","NASDAQ:AMZN","0.02585158","0","85","93.61","1.2023","1.1841","USD" "194","2021-05-24","2021-05-27","NYSE:SPCE","2","0","49.86","56.03","1.2212","1.2198","USD" "195","2021-05-27","2021-06-07","NYSE:SPCE","4","0","114.12","135.42","1.2194","1.2198","USD" "196","2021-05-27","2021-06-07","NYSE:SPCE","23","0","704.26","778.55","1.2199","1.2198","USD" "197","2021-06-07","2021-06-28","NYSE:NIO","10","0","437.20","490.00","1.2198","1.1932","USD" "198","2021-06-08","2021-06-25","NYSE:SPCE","12","0","448.31","572.75","1.2188","1.1969","USD" "199","2021-07-01","2021-11-04","NYSE:NIO","10","0","520","435.40","1.1869","1.1553","USD" "200","2021-07-06","2021-08-09","NASDAQ:GOOGL","0.21915668","0","550","595.41","1.1830","1.1751","USD" "201","2021-07-07","2021-07-08","NYSE:SPCE","12","0","540","599.99","1.1807","1.1848","USD" "202","2021-07-12","2021-12-03","NYSE:SPCE","12","0","540.00","171.84","1.1858","1.1280","USD" "203","2021-07-15","2021-07-16","NASDAQ:MRNA","1","0.01","255.80","284.99","1.1817","1.1804","USD" "204","2021-07-16","2021-11-09","NYSE:SPCE","24","0","781.44","503.77","1.1811","1.1588","USD" "205","2021-07-16","2021-11-29","NASDAQ:AAPL","1","0","147.32","164.98","","","USD" "206","2021-07-16","2021-11-29","NASDAQ:AAPL","2","0","294.60","330.00","","","USD" "207","2021-07-23","2021-08-03","NASDAQ:MRNA","2","0.01","670.54","739.99","1.1765","1.1866","USD" "208","2021-08-03","2021-11-19","NASDAQ:AMZN","0.22221761","0","750","829.78","1.1866","1.1315","USD" "209","2021-08-09","2021-11-26","NASDAQ:MRNA","1","0","287.97","327.95","1.1255","1.1300","USD" "210","2021-08-19","2021-11-19","NASDAQ:AAPL","5","0","724.65","800.00","","","USD" "211","2021-09-10","2021-12-01","NASDAQ:AAPL","5","0","749.85","850.00","","","USD" "212","2021-09-17","2021-11-29","NASDAQ:AAPL","4","0","587.32","660.00","","","USD" "213","2021-10-26","2021-11-01","NASDAQ:TSLA","1","0","1044.49","1149.98","1.1609","1.1583","USD" "214","2021-10-26","2021-12-06","NASDAQ:AAPL","4","0","601.92","668.36","","","USD" "215","2021-10-27","2021-12-01","NASDAQ:AAPL","7","0","1044.75","1190.00","","","USD" "216","2021-10-27","2021-12-01","NASDAQ:AAPL","3","0","447.75","510.00","","","USD" "217","2021-11-04","2022-02-17","NYSE:KO","10","0","562.89","619.99","1.1552","1.1365","USD" "218","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "219","2021-11-26","2021-12-10","NASDAQ:AAPL","1","0","158.17","178.17","","","USD" "220","2021-12-02","2021-12-13","NASDAQ:AAPL","7","0","1111.04","1266.98","1.1345","1.1294","USD" "221","2021-12-02","2021-12-10","NASDAQ:AAPL","3","0","482.67","534.51","","","USD" "222","2021-12-06","2022-01-03","NASDAQ:TSLA","1","0","992.9","1153.57","1.1291","1.1309","USD" "223","2021-12-14","2021-12-27","NASDAQ:TSLA","1.2","0","377.47","441.07","","","USD" "224","2021-12-14","2021-12-27","NASDAQ:TSLA","0.3","0","94.37","110.27","","","USD" "225","2021-11-10","2022-01-03","NASDAQ:TSLA","1.5","0","536.75","597.42","","","USD" "226","2022-02-18","2022-03-22","NASDAQ:TSLA","1.2","0","345.54","376.86","","","USD" "227","2022-02-18","2022-03-22","NASDAQ:TSLA","0.3","0","86.38","94.22","","","USD" "228","2022-02-18","2022-04-20","NYSE:O","2","0","134.06","149.99","1.1336","1.0848","USD" "229","2022-04-14","2022-10-05","NYSE:TWTR","4","0","193.68","203.72","1.0829","0.9852","USD" "230","2022-04-19","2022-10-05","NYSE:TWTR","1","0","47.24","50.93","1.0798","0.9852","USD" "231","2022-05-20","2022-07-21","NASDAQ:AAPL","1","0","139.02","155.02","","","USD" "232","2022-07-27","2022-07-27","NASDAQ:AAPL","1","0","162.00","162.00","","","USD" "233","2022-01-03","2023-12-27","NASDAQ:ANSS","2","0","786.86","669.60","","","USD" "234","2022-01-11","2023-11-16","NASDAQ:AAPL","6","0","1026","1139.98","1.1324","1.0885","USD" "235","2022-02-02","2023-05-25","NASDAQ:MSFT","0.62199751","0","185.15","200.03","1.1092","1.0722","USD" "236","2021-11-09","2024-01-01","NASDAQ:TSLA","3","0","1065.78","1065.78","","","USD" "237","2021-11-22","2023-06-15","NASDAQ:AAPL","8.5","0","1386.18","1572.67","","","USD" "238","2021-11-22","2023-06-15","NASDAQ:AAPL","1.5","0","244.62","277.50","","","USD" "239","2021-12-02","2023-06-15","NASDAQ:AAPL","7","0","1142.82","1295.00","","","USD" "240","2021-12-02","2023-06-15","NASDAQ:AAPL","2","0","326.52","370.00","","","USD" "241","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","392.00","","","USD" "242","2021-12-13","2023-12-13","NASDAQ:AAPL","2","0","356.40","391.98","","","USD" "243","2021-12-14","2023-12-13","NASDAQ:AAPL","3","0","522.51","588.00","","","USD" "244","2022-04-13","2023-12-14","NASDAQ:AAPL","1","0","170.66","196.00","","","USD" "245","2022-09-14","2023-05-05","NASDAQ:AAPL","2","0","311.56","343.98","","","USD" "246","2022-12-20","2023-01-23","NASDAQ:AAPL","2","0","260.00","285.98","","","USD" "247","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "248","2023-01-23","2023-01-26","NASDAQ:TSLA","1","0","141.48","159.98","","","USD" "249","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "250","2023-01-30","2023-03-22","NASDAQ:AAPL","1","0","143.94","159.99","","","USD" "251","2023-03-01","2023-06-14","NYSE:BRK.B","1","0","303.16","339.98","1.0685","1.0868","USD" "252","2023-05-08","2023-05-23","NASDAQ:TSLA","1","0","171.76","189.98","","","USD" "253","2023-05-26","2023-06-02","NASDAQ:TSLA","1","0","190.12","209.98","","","USD" "254","2022-01-06","2024-01-25","NASDAQ:TSLA","2.7","0","945.00","506.93","","","USD" "255","2022-01-06","2024-01-25","NASDAQ:TSLA","0.3","0","105.00","56.32","","","USD" "256","2023-01-01","2024-04-26","NASDAQ:GOOGL","1.8369098","0","276.14","320.23","","","USD" "257","2022-02-02","2024-04-26","NASDAQ:GOOGL","0.9046522","0","136.00","157.69","","","USD" "258","2022-02-28","2024-06-05","NYSE:KO","2","0","123.86","127.83","1.1225","1.0890","USD" "259","2021-10-15","2024-04-12","NASDAQ:GOOGL","5","0","714.80","1498.30","","","USD" "260","2021-11-04","2024-07-11","NYSE:BAC","10","0","474.89","419.98","1.1551","1.0899","USD" "261","2024-01-01","2024-03-01","NASDAQ:TSLA","2","0","710.52","402.44","","","USD" "262","2024-01-01","2024-02-09","NASDAQ:TSLA","1","0","355.26","192.78","","","USD" "263","2021-11-10","2024-02-09","NASDAQ:TSLA","0.525","0","187.86","101.21","","","USD" "264","2021-11-10","2024-02-09","NASDAQ:TSLA","0.975","0","348.88","187.95","","","USD" "265","2021-11-22","2024-02-09","NASDAQ:TSLA","1.5","0","590.88","289.17","","","USD" "266","2021-11-26","2024-02-02","NASDAQ:AMZN","1.8995262","0","334.98","326.64","","","USD" "267","2021-12-02","2024-02-02","NASDAQ:AMZN","1.7335028","0","300.00","298.09","","","USD" "268","2021-12-14","2024-04-26","NASDAQ:AAPL","1","0","174.17","170.00","","","USD" "269","2021-12-28","2024-02-02","NASDAQ:AMZN","1.1645374","0","200.00","200.24","","","USD" "270","2024-04-22","2024-07-17","NYSE:O","2","0","148.00","114.32","1.0817","1.0957","USD" "271","2022-06-07","2024-02-02","NASDAQ:AMZN","0.2024336","0","24.75","34.81","","","USD" "272","2023-05-23","2024-06-11","NASDAQ:AAPL","1","0","172.79","199.96","","","USD" "273","2023-06-06","2024-07-02","NASDAQ:AAPL","3","0","535.89","660.00","","","USD" "274","2023-06-06","2024-04-26","NASDAQ:AAPL","1","0","178.63","170.00","","","USD" "275","2023-06-14","2024-01-31","NASDAQ:TSLA","1","0","258.00","189.98","","","USD" "276","2023-06-15","2024-01-25","NYSE:BRK.B","4","0","1352.95","1519.98","1.0927","1.0876","USD" "277","2023-06-20","2024-01-31","NASDAQ:TSLA","2","0","542.06","380.00","","","USD" "278","2023-06-30","2024-08-28","NASDAQ:AAPL","4","0","769.80","919.96","","","USD" "279","2023-07-19","2024-02-07","NASDAQ:TSLA","2","0","593.16","362.96","","","USD" "280","2023-07-19","2024-02-07","NASDAQ:TSLA","1","0","296.58","181.47","","","USD" "281","2023-09-13","2024-07-02","NASDAQ:AAPL","3","0","525.06","660.00","","","USD" "282","2023-12-14","2024-08-28","NASDAQ:AAPL","1","0","196.00","230.00","","","USD" "283","2023-12-18","2024-11-26","NASDAQ:AAPL","2","0","390.00","470.00","","","USD" "284","2023-12-22","2024-11-26","NASDAQ:AAPL","3","0","585.72","705.00","","","USD" "285","2024-01-01","2024-11-26","NASDAQ:AAPL","3","0","576.96","705.00","","","USD" "286","2024-01-08","2024-07-02","NASDAQ:AAPL","3","0","540.00","659.93","","","USD" "287","2024-01-25","2024-02-09","NASDAQ:NVDA","3","0","1865.35","2159.97","1.0876","1.0809","USD" "288","2024-01-31","2024-06-17","NASDAQ:MSFT","1","0","402.58","449.98","1.0869","1.0750","USD" "289","2024-02-02","2024-05-20","NASDAQ:NVDA","1","0","659.78","949.98","1.0805","1.0889","USD" "290","2024-02-02","2024-11-26","NASDAQ:AAPL","1","0","186.01","234.93","","","USD" "291","2024-02-05","2024-05-22","NASDAQ:NVDA","10","0","688.87","999.85","","","USD" "292","2024-02-21","2024-05-22","NASDAQ:NVDA","30","0","2037.00","3000.00","","","USD" "293","2024-03-05","2024-07-30","NYSE:BRK.B","1","0","400.00","439.98","1.0882","1.0832","USD" "294","2024-03-11","2024-05-22","NASDAQ:NVDA","10","0","889.33","1000.00","","","USD" "295","2024-04-01","2024-06-11","NASDAQ:AAPL","2","0","340.00","400.00","","","USD" "296","2021-10-15","2024-04-26","NASDAQ:GOOGL","0.137277","0","19.63","23.93","","","USD" "297","2024-04-26","2024-06-11","NASDAQ:AAPL","3","0","510.00","600.00","","","USD" "298","2024-07-03","2024-09-05","NASDAQ:TSLA","2","0","495.86","450.44","","","USD" "299","2024-07-11","2024-11-10","NYSE:TSM","10","0","1938.61","1898.01","1.0915","1.0965","USD" "300","2024-05-28","2024-10-17","NASDAQ:NVDA","10","0","1120.60","1400.00","","","USD" "301","2023-12-14","","AMS:IWDA","6","0.05","491.33","","","","EUR" "302","2024-04-22","","AMS:IWDA","7","0.06","618.93","","","","EUR" "303","2024-05-28","2025-01-06","NASDAQ:NVDA","20","0","2241.20","3000.00","","","USD" "304","2024-06-06","2025-05-28","NASDAQ:NVDA","2","0","2498.35","2799.99","1.0907","1.1318","USD" "305","2024-06-12","","NASDAQ:AAPL","7","0","1497.65","","","","USD" "306","2024-06-20","","NASDAQ:AAPL","2","0","420.00","","","","USD" "307","2024-07-23","","INDEXNASDAQ:NDX","4.84403203","0","858.75","","","","EUR" "308","2024-08-01","2025-11-11","NASDAQ:AAPL","5","0","1094.25","1369.52","1.0809","1.1626","USD" "309","2024-08-05","2025-08-08","NASDAQ:AAPL","1","0","204.90","225.00","","","USD" "310","2024-08-05","2025-08-08","NASDAQ:AAPL","2","0","409.80","449.98","","","USD" "311","2024-11-06","","NASDAQ:AAPL","21","0","4742.01","","","","USD" "312","2024-11-25","","NASDAQ:NVDA","8","0","1101.60","","","","USD" "313","2024-12-18","","INDEXNASDAQ:NDX","10","0","2038.00","","","","EUR" "314","2025-01-06","","NASDAQ:NVDA","21","0","2998.17","","","","USD" "315","2025-01-27","","NASDAQ:NVDA","2","0","247.18","","","","USD" "316","2025-07-03","","NASDAQ:NVDA","12","0","1918.68","","","","USD" "317","2025-10-16","","NASDAQ:NVDA","8","0","1454.32","","","","USD" "318","2025-11-11","","NASDAQ:NVDA","9","0","1742.40","","","","USD" ======================================================================================== FICHEIRO: dados_csv/transacoes-vistos.json Tamanho: 66 bytes ======================================================================================== { "versao": "1.0", "vistos": {}, "ultima_atualizacao": "" } ======================================================================================== FICHEIRO: dados_csv/variacao-dia.json Tamanho: 2328 bytes ======================================================================================== { "ok": true, "timestamp": "2025-12-14 11:13:10", "variacao": { "IWDA": { "ticker": "IWDA", "moeda": "EUR", "preco": 110.31, "pct_dia": -0.6037, "prev_close": 110.98, "fonte_preco": "stooq:EUNL.DE", "fonte_prevclose": "stooq:eunl.de", "ts_preco": "2025-12-14 00:06:18" }, "AAPL": { "ticker": "AAPL", "moeda": "USD", "preco": 278.28, "pct_dia": 0.0899, "prev_close": 278.029999, "fonte_preco": "twelveAAPL", "fonte_prevclose": "twelveAAPL", "ts_preco": "2025-12-14 00:06:18" }, "NDXEX": { "ticker": "NDXEX", "moeda": "EUR", "preco": 208.6, "pct_dia": -1.0906, "prev_close": 210.9, "fonte_preco": "stooq:EXXT.DE", "fonte_prevclose": "stooq:exxt.de", "ts_preco": "2025-12-14 00:06:18" }, "NVDA": { "ticker": "NVDA", "moeda": "USD", "preco": 175.020004, "pct_dia": -3.2664, "prev_close": 180.92999, "fonte_preco": "twelveNVDA", "fonte_prevclose": "twelveNVDA", "ts_preco": "2025-12-14 00:06:18" }, "GOOGL": { "ticker": "GOOGL", "moeda": "USD", "preco": 309.29001, "pct_dia": -1.005, "prev_close": 312.42999, "fonte_preco": "twelveGOOGL", "fonte_prevclose": "twelveGOOGL", "ts_preco": "2025-12-14 00:06:18" }, "VUSA": { "ticker": "VUSA", "moeda": "EUR", "preco": 110.235, "pct_dia": -0.6131, "prev_close": 110.915, "fonte_preco": "stooq:VUSA.DE", "fonte_prevclose": "stooq:vusa.de", "ts_preco": "2025-12-14 00:06:18" }, "XAUEUR": { "ticker": "XAUEUR", "moeda": "EUR", "preco": 3677.2689145299146, "pct_dia": 0, "prev_close": null, "fonte_preco": "twelveXAU\/USD->EUR", "fonte_prevclose": null, "ts_preco": "2025-12-14 00:06:18" } } } ======================================================================================== FICHEIRO: debug-env.php Tamanho: 1882 bytes ======================================================================================== pplx_api_key() !== '', 'iwda_config' => [ 'perplexityquery' => $iwda['perplexityquery'] ?? 'N/A', 'perplexityclosequery' => $iwda['perplexityclosequery'] ?? 'N/A', ], 'ndxex_config' => [ 'perplexityquery' => $ndxex['perplexityquery'] ?? 'N/A', 'perplexityclosequery' => $ndxex['perplexityclosequery'] ?? 'N/A', ], 'vusa_config' => [ 'perplexityquery' => $vusa['perplexityquery'] ?? 'N/A', 'perplexityclosequery' => $vusa['perplexityclosequery'] ?? 'N/A', ], ]; // 2) Chamar Perplexity para preço atual $dbgIwda = $dbgNdxex = $dbgVusa = null; $result['iwda_price'] = obterPrecoAtualPerplexity($iwda['perplexityquery'], $iwda['moeda'] ?? 'EUR', $dbgIwda); $result['ndxex_price'] = obterPrecoAtualPerplexity($ndxex['perplexityquery'], $ndxex['moeda'] ?? 'EUR', $dbgNdxex); $result['vusa_price'] = obterPrecoAtualPerplexity($vusa['perplexityquery'], $vusa['moeda'] ?? 'EUR', $dbgVusa); // 3) Previous close $result['iwda_prevclose'] = obterPrevClosePerplexity($iwda['perplexityclosequery'], $iwda['moeda'] ?? 'EUR'); $result['ndxex_prevclose'] = obterPrevClosePerplexity($ndxex['perplexityclosequery'], $ndxex['moeda'] ?? 'EUR'); $result['vusa_prevclose'] = obterPrevClosePerplexity($vusa['perplexityclosequery'], $vusa['moeda'] ?? 'EUR'); // 4) Debug detalhado das respostas $result['debug'] = [ 'iwda' => $dbgIwda, 'ndxex' => $dbgNdxex, 'vusa' => $dbgVusa, ]; echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); ======================================================================================== FICHEIRO: edf_links.csv Tamanho: 19900 bytes ======================================================================================== #,Projeto,Link Original,PDF Local,Status,Tamanho 1,EDF Results 2025,https://defence-industry-space.ec.europa.eu/document/download/da0507e0-0c76-4f23-8585-40176f757231_en?filename=EDF%202025%20results%20-%20general%20factsheet%20v6.pdf,EDF 2025 results - general factsheet v6.pdf,"OK (957,094B)",957094 2,RESILIENCE-R-2025 - Third research action for medical counter measures against CBRN threats perform,https://defence-industry-space.ec.europa.eu/document/download/75e43754-64f3-4b6c-88c7-9886fc18e469_en?filename=FACTSHEET_EDF_2025_RA_SGA_MCBRN_MCM_STEP_101254210_RESILIENCE_R_2025.pdf,FACTSHEET_EDF_2025_RA_SGA_MCBRN_MCM_STEP_101254210_RESILIENCE_R_2025.pdf,"OK (419,575B)",419575 3,RESILIENCE-D-25 - Second development SGA action for Medical Counter Measures against CBRN threats p,https://defence-industry-space.ec.europa.eu/document/download/a7ad745b-662b-4d6c-bb0d-80740fe62527_en?filename=FACTSHEET_EDF_2025_DA_SGA_MCBRN_MCM_STEP_101254257_RESILIENCE_D_25.pdf,FACTSHEET_EDF_2025_DA_SGA_MCBRN_MCM_STEP_101254257_RESILIENCE_D_25.pdf,"OK (414,761B)",414761 4,SALUBRIS - Strategic Autonomous Logistic Uncrewed Battlefield tRiage Intervention System,https://defence-industry-space.ec.europa.eu/document/download/46d901f0-5011-4157-b235-3be62519f735_en?filename=FACTSHEET_EDF_2025_RA_MCBRN_ATE_101304840_SALUBRIS.pdf,FACTSHEET_EDF_2025_RA_MCBRN_ATE_101304840_SALUBRIS.pdf,"OK (419,623B)",419623 5,ANEMOS - Airborne New European MIDS Operational Solution,https://defence-industry-space.ec.europa.eu/document/download/7d9a1223-9214-42ce-806e-b2200ca39b14_en?filename=FACTSHEET_EDF_2025_RA_C4ISR_MIDS_STEP_101304725_ANEMOS.pdf,FACTSHEET_EDF_2025_RA_C4ISR_MIDS_STEP_101304725_ANEMOS.pdf,"OK (348,785B)",348785 6,SPIRIT-Small Pitch Improved Resolution for Infrared Technology,https://defence-industry-space.ec.europa.eu/document/download/685989cd-658d-48e1-a6ef-a945554b248e_en?filename=FACTSHEET_EDF_2025_DA_SENS_IRD_STEP_101304763_SPIRIT.pdf,FACTSHEET_EDF_2025_DA_SENS_IRD_STEP_101304763_SPIRIT.pdf,"OK (351,946B)",351946 7,SHIMBAD-SHIpborne MultiBand AESA Demonstrator,https://defence-industry-space.ec.europa.eu/document/download/37bfe3da-4f35-450f-bdff-229bdedc3d7b_en?filename=FACTSHEET_EDF_2025_DA_SENS_MB4DR_STEP_101304839_SHIMBAD.pdf,FACTSHEET_EDF_2025_DA_SENS_MB4DR_STEP_101304839_SHIMBAD.pdf,"OK (421,111B)",421111 8,ECC2-European Cyber Command and Control System,https://defence-industry-space.ec.europa.eu/document/download/92d2b328-c040-41a2-9f8a-f6acf3da5a7e_en?filename=FACTSHEET_EDF_2025_DA_CYBER_CDOC_STEP_101304685_ECC2.pdf,FACTSHEET_EDF_2025_DA_CYBER_CDOC_STEP_101304685_ECC2.pdf,"OK (424,836B)",424836 9,STRATUS-STRATUS – Swarm Threat Resilience and Adaptive Tactical UxV Security,https://defence-industry-space.ec.europa.eu/document/download/3cea0490-a702-4c8f-81fd-a7ec3256b55a_en?filename=FACTSHEET_EDF_2025_LS_RA_SI_CYBER_3RAV_STEP_101304998_STRATUS.pdf,FACTSHEET_EDF_2025_LS_RA_SI_CYBER_3RAV_STEP_101304998_STRATUS.pdf,"OK (352,005B)",352005 10,"ASIMOV-Autonomous System for Inspection, Maintenance, defence Operations and manoeuVres",https://defence-industry-space.ec.europa.eu/document/download/712cd5bf-beb5-4ced-8386-fa84b68f8b3d_en?filename=FACTSHEET_EDF_2025_DA_SI_SPACE_3OS_101304654_ASIMOV.pdf,FACTSHEET_EDF_2025_DA_SI_SPACE_3OS_101304654_ASIMOV.pdf,"OK (529,371B)",529371 11,SPIDER2-Space-based Persistent ISR for Defence and Europe Reinforcement - phase 2,https://defence-industry-space.ec.europa.eu/document/download/c6838cc9-dc6b-4b66-a028-69ef453e278f_en?filename=FACTSHEET_EDF_2025_DA_SPACE_SBISR_101304864_SPIDER2.pdf,FACTSHEET_EDF_2025_DA_SPACE_SBISR_101304864_SPIDER2.pdf,"OK (442,590B)",442590 12,DIALOG-AI - Defence Innovative Assessments and Live-tests of Operational Generative AI,https://defence-industry-space.ec.europa.eu/document/download/c65bd04d-9892-4a42-a996-5df7cca748e7_en?filename=FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDO_101304676_DIALOG_AI.pdf,FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDO_101304676_DIALOG_AI.pdf,"OK (412,661B)",412661 13,"AI-SHIELD- Secure, Human-AI, Interactive, Edge, Language, Dialogue",https://defence-industry-space.ec.europa.eu/document/download/575cdef2-f951-4550-b303-16c0c5645c40_en?filename=FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101305024_AI_SHIELD.pdf,FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101305024_AI_SHIELD.pdf,"OK (411,960B)",411960 14,LLM Secret-Sovereign and trusted large language models for European defence and security,https://defence-industry-space.ec.europa.eu/document/download/174a2e88-f09d-4183-ad79-27bf1c3940c0_en?filename=FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101304809_LLM_Secret.pdf,FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101304809_LLM_Secret.pdf,"OK (414,027B)",414027 15,MIDAS-Middleware for Intelligent Defense AI Dialogue Systems,https://defence-industry-space.ec.europa.eu/document/download/f69c20ea-cc20-4bd3-b965-8fae5ae47cdd_en?filename=FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101304907_MIDAS.pdf,FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101304907_MIDAS.pdf,"OK (412,326B)",412326 16,RHESIS-Robust privacy-preserving adaptive Human-AI dialoguE System for trustworthy and explaInable ,https://defence-industry-space.ec.europa.eu/document/download/335b8017-1887-4dd8-91de-72d629964094_en?filename=FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101304888_RHESIS.pdf,FACTSHEET_EDF_2025_LS_RA_CHALLENGE_DIGIT_HAIDP_STEP_101304888_RHESIS.pdf,"OK (513,801B)",513801 17,MINERVA-Modular Integration of Naval Energy Systems for Resilient Vessels Application,https://defence-industry-space.ec.europa.eu/document/download/2e44dd94-c5a4-488e-b667-ca0bbdcfd110_en?filename=FACTSHEET_EDF_2025_LS_RA_SI_ENERENV_NH2PS_STEP_101302020_MINERVA.pdf,FACTSHEET_EDF_2025_LS_RA_SI_ENERENV_NH2PS_STEP_101302020_MINERVA.pdf,"OK (419,928B)",419928 18,SHARP-Sovereign High-performance Architecture for Rotorcraft Propulsion,https://defence-industry-space.ec.europa.eu/document/download/4d259b13-17b4-4cea-a08c-c9749f9fa0a4_en?filename=FACTSHEET_EDF_2025_RA_ENERENV_PSR_101300447_SHARP.pdf,FACTSHEET_EDF_2025_RA_ENERENV_PSR_101300447_SHARP.pdf,"OK (520,717B)",520717 19,AETHER-Advanced Engines and Thermal-electric energy for Highly- integrated systems for European Read,https://defence-industry-space.ec.europa.eu/document/download/34f76263-5d2f-4389-b565-1090573ae6f8_en?filename=FACTSHEET_EDF_2025_DA_ENERENV_APEM_101304670_AETHER.pdf,FACTSHEET_EDF_2025_DA_ENERENV_APEM_101304670_AETHER.pdf,"OK (422,463B)",422463 20,EURECA-EUropean REsilient Chiplet Architecture,https://defence-industry-space.ec.europa.eu/document/download/0eb14cfb-6ae1-4b32-b069-7aa21a091872_en?filename=FACTSHEET_EDF_2025_RA_MATCOMP_CDA_STEP_101302983_EURECA.pdf,FACTSHEET_EDF_2025_RA_MATCOMP_CDA_STEP_101302983_EURECA.pdf,"OK (350,276B)",350276 21,EICACS 2-European Initiative for Collaborative Air Combat Standardisation 2,https://defence-industry-space.ec.europa.eu/document/download/8e47a86f-f4a8-440a-a96b-054c101616c9_en?filename=FACTSHEET_EDF_2025_DA_AIR_CAC_101304940_EICACS_2.pdf,FACTSHEET_EDF_2025_DA_AIR_CAC_101304940_EICACS_2.pdf,"OK (429,941B)",429941 22,EPIIC2-Enhanced Pilot Interfaces & Interactions for fighter Cockpit Phase 2,https://defence-industry-space.ec.europa.eu/document/download/3a04b04c-5e3f-4fef-a122-7060599ba884_en?filename=FACTSHEET_EDF_2025_DA_AIR_EPE_101302981_EPIIC2.pdf,FACTSHEET_EDF_2025_DA_AIR_EPE_101302981_EPIIC2.pdf,"OK (424,611B)",424611 23,D-STORM-Drone-based Scalable Tactical Operations Responsive Munitions,https://defence-industry-space.ec.europa.eu/document/download/2b8899d9-ee74-41a0-becb-bbe00c39f0bc_en?filename=FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101301002_D_STORM.pdf,FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101301002_D_STORM.pdf,"OK (415,319B)",415319 24,EURODAMM-European Drone-Based Affordable Mass Munitions,https://defence-industry-space.ec.europa.eu/document/download/e361419d-7f53-4d64-9ff8-36acc654297a_en?filename=FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304876_EURODAMM.pdf,FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304876_EURODAMM.pdf,"OK (412,998B)",412998 25,LUMINA-Loitering Unmanned Munitions with Intelligent Networked Autonomy,https://defence-industry-space.ec.europa.eu/document/download/8baa8e6d-4401-4c53-b32c-843cff99afad_en?filename=FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304721_LUMINA.pdf,FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304721_LUMINA.pdf,"OK (413,876B)",413876 26,"SKYRAPTOR-Mass-affordable, cost-efficient drone-based loitering munition & Small UCAS weapon systems",https://defence-industry-space.ec.europa.eu/document/download/87c8ac65-78ce-4434-9b20-314f1ca3e087_en?filename=FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304909_SKYRAPTOR.pdf,FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304909_SKYRAPTOR.pdf,"OK (515,003B)",515003 27,TALON-Tactical Affordable Loitering Ordnance and Nodes,https://defence-industry-space.ec.europa.eu/document/download/4c5b6405-d0fa-4f9d-8d10-8f939b29c298_en?filename=FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304941_TALON.pdf,FACTSHEET_EDF_2025_DA_SI_GROUND_DAMM_101304941_TALON.pdf,"OK (415,949B)",415949 28,FAMOUS3-European Future Highly Mobile Augmented Armoured Systems 3,https://defence-industry-space.ec.europa.eu/document/download/72819edb-5440-42bf-8bd0-c5da9df1094c_en?filename=FACTSHEET_EDF_2025_DA_GROUND_FM2LP_101305018_FAMOUS3.pdf,FACTSHEET_EDF_2025_DA_GROUND_FM2LP_101305018_FAMOUS3.pdf,"OK (432,679B)",432679 29,LATACC2-LAnd TActical Collaborative Combat Phase 2,https://defence-industry-space.ec.europa.eu/document/download/8376595a-e80e-4d26-82cc-ad0702146ba6_en?filename=FACTSHEET_EDF_2025_DA_GROUND_LCC_STEP_101304780_LATACC2.pdf,FACTSHEET_EDF_2025_DA_GROUND_LCC_STEP_101304780_LATACC2.pdf,"OK (431,750B)",431750 30,TRIDENT-Next generaTion Resilient long-range European Counter-Battery system via heterogeneous Sens,https://defence-industry-space.ec.europa.eu/document/download/5c22ea8f-8079-42eb-bd49-b1a85d0dfd75_en?filename=FACTSHEET_EDF_2025_RA_GROUND_CBC_101304820_TRIDENT.pdf,FACTSHEET_EDF_2025_RA_GROUND_CBC_101304820_TRIDENT.pdf,"OK (464,034B)",464034 31,ACHILE2 - Augmented Capability for HIgh end soLdiErs,https://defence-industry-space.ec.europa.eu/document/download/ee618007-4257-4e76-bcc7-b5c0f53154a0_en?filename=FACTSHEET_EDF_2025_DA_PROTMOB_SS_101304808_ACHILE_2.pdf,FACTSHEET_EDF_2025_DA_PROTMOB_SS_101304808_ACHILE_2.pdf,"OK (425,839B)",425839 32,E-DOMINION - European – Digitalization Of Maritime Innovation for Naval Integrated Platforms and CO,https://defence-industry-space.ec.europa.eu/document/download/90601d01-9fc9-4141-865b-741a80692baa_en?filename=FACTSHEET_EDF_2025_DA_NAVAL_DSNCC_STEP_101303456_E_DOMINION.pdf,FACTSHEET_EDF_2025_DA_NAVAL_DSNCC_STEP_101303456_E_DOMINION.pdf,"OK (423,218B)",423218 33,SHIELD - Subsea Heterogeneous Integrated Ecosystem Link Development,https://defence-industry-space.ec.europa.eu/document/download/178862ee-14e0-4707-a140-690c4cf3ae54_en?filename=FACTSHEET_EDF_2025_DA_UWW_AUWN_STEP_101304758_SHIELD.pdf,FACTSHEET_EDF_2025_DA_UWW_AUWN_STEP_101304758_SHIELD.pdf,"OK (523,147B)",523147 34,SWORD - Stand-off Anti-Submarine Warfare Operations by Remote Deployment,https://defence-industry-space.ec.europa.eu/document/download/e3f4ae90-84cc-49c5-a368-0d9a4841db40_en?filename=FACTSHEET_EDF_2025_RA_UWW_SOASW_101300787_SWORD.pdf,FACTSHEET_EDF_2025_RA_UWW_SOASW_101300787_SWORD.pdf,"OK (352,656B)",352656 35,DART - Digital Architecture Framework for SoS Readiness and Digital Twin Integration,https://defence-industry-space.ec.europa.eu/document/download/af747e51-8205-448f-b748-f49446834dd3_en?filename=FACTSHEET_EDF_2025_RA_SIMTRAIN_DAFAS_101304889_DART.pdf,FACTSHEET_EDF_2025_RA_SIMTRAIN_DAFAS_101304889_DART.pdf,"OK (521,579B)",521579 36,"EVOLVE - European Vision for interOperable Live, Virtual, constructive Ecosystem",https://defence-industry-space.ec.europa.eu/document/download/af2178b2-0d61-4c77-9e31-20cbb196aa10_en?filename=FACTSHEET_EDF_2025_RA_SIMTRAIN_LVC_STEP_101301032_EVOLVE.pdf,FACTSHEET_EDF_2025_RA_SIMTRAIN_LVC_STEP_101301032_EVOLVE.pdf,"OK (422,415B)",422415 37,DEEP-TECH - derwater Technology Capability Enabler for EU NextGeneration Deep-Sea Operations and Aut,https://defence-industry-space.ec.europa.eu/document/download/8caf6084-533b-4b92-8c06-ff87ba414788_en?filename=FACTSHEET_EDF_2025_LS_RA_DIS_GDET_101303940_DEEP_TECH.pdf,FACTSHEET_EDF_2025_LS_RA_DIS_GDET_101303940_DEEP_TECH.pdf,"OK (421,959B)",421959 38,ABYSSA - Advanced Breakthrough sYstems for SubSea Autonomy,https://defence-industry-space.ec.europa.eu/document/download/898292f3-dd5f-4128-adcb-a5eb2c222d44_en?filename=FACTSHEET_EDF_2025_LS_RA_DIS_GDET_101304558_ABYSSA.pdf,FACTSHEET_EDF_2025_LS_RA_DIS_GDET_101304558_ABYSSA.pdf,"OK (423,185B)",423185 39,CoPaNA-Concatenated Parity codes on Neutral Atoms,https://defence-industry-space.ec.europa.eu/document/download/8c23dd25-b959-408d-8d1f-a9c3cdb6765c_en?filename=FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304930_CoPaNA.pdf,FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304930_CoPaNA.pdf,"OK (408,317B)",408317 40,NEXTSWIR - eNabling EXTended SWIR imaging,https://defence-industry-space.ec.europa.eu/document/download/9f85d2fe-30b0-4b8f-a3eb-abd6319d0648_en?filename=FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304913_NEXTSWIR.pdf,FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304913_NEXTSWIR.pdf,"OK (412,436B)",412436 41,SOLARES - Soldier Operational Autonomous Resilient Energy System,https://defence-industry-space.ec.europa.eu/document/download/7592fe97-dc34-40fb-9fc7-0ae51a5c3096_en?filename=FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304904_SOLARES.pdf,FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304904_SOLARES.pdf,"OK (412,409B)",412409 42,SPECTRE - European Unified Aerial Security Ecosystem - Systemic Protection and Escalation Control f,https://defence-industry-space.ec.europa.eu/document/download/71744893-d23c-4466-99b0-0eb18bb29c3c_en?filename=FACTSHEET_EDF_2025_LS_RA_DIS_NT_101305046_SPECTRE.pdf,FACTSHEET_EDF_2025_LS_RA_DIS_NT_101305046_SPECTRE.pdf,"OK (413,924B)",413924 43,Spin Defender - Spin-based neural networks for RF processing and learning at the edge,https://defence-industry-space.ec.europa.eu/document/download/9e8afaee-4f48-4f43-bcf1-095d5259c8d7_en?filename=FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304788_Spin_Defender.pdf,FACTSHEET_EDF_2025_LS_RA_DIS_NT_101304788_Spin_Defender.pdf,"OK (410,197B)",410197 44,FAST TRAIN - Fused Analytics and Smart Textiles for real-time operational readiness in soldier TRAI,https://defence-industry-space.ec.europa.eu/document/download/42c6fa4f-1235-42c0-abc5-359ac0cf560c_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304741_FAST_TRAIN.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304741_FAST_TRAIN.pdf,"OK (509,571B)",509571 45,AEGIS-NET - Autonomous Expeditionary Guardian and Interceptor Swarm through distributed Networked E,https://defence-industry-space.ec.europa.eu/document/download/fe8fd417-9c33-4197-ac63-93e4fddd222c_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101305073_AEGIS_NET.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101305073_AEGIS_NET.pdf,"OK (413,010B)",413010 46,EM-Mortar - Electro Magnetic Modular Ordnance for Rapid Tactical Artillery Response,https://defence-industry-space.ec.europa.eu/document/download/2d7e501e-39c3-4473-88f8-f292153f04ec_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304777_EM_Mortar.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304777_EM_Mortar.pdf,"OK (411,934B)",411934 47,MANTIS - Next Generation Modular AI-driven live augmented Training System,https://defence-industry-space.ec.europa.eu/document/download/300a3ad2-dd03-4f4d-9639-187fbee10850_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101300765_MANTIS.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101300765_MANTIS.pdf,"OK (412,952B)",412952 48,PRIORITY - Disruptive Materials for Submarine Invisibility,https://defence-industry-space.ec.europa.eu/document/download/d2815315-ce1a-41ec-92f3-09d383bcf402_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304832_PRIORITY.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304832_PRIORITY.pdf,"OK (411,297B)",411297 49,R3DSurfin - Towards Robust 3D printed metallic components production for military applications by t,https://defence-industry-space.ec.europa.eu/document/download/4944cccc-e783-45c5-8300-9dd9d2798c7b_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304902_R3DSurfin.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304902_R3DSurfin.pdf,"OK (413,608B)",413608 50,ResistCAM - High-temperature resistant and durable multispectral camouflage system,https://defence-industry-space.ec.europa.eu/document/download/abd78542-ad56-41f4-8e35-0de59062fbb2_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304970_ResistCAM.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304970_ResistCAM.pdf,"OK (409,545B)",409545 51,TAC - TACTICAL-CAPTURE: Development Of Tactically Responsive In-Space Mobility And Standard Interfac,https://defence-industry-space.ec.europa.eu/document/download/554d5147-63ed-4ed8-b851-1952710df2a1_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304917_TAC.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304917_TAC.pdf,"OK (506,928B)",506928 52,U-HARRIER - Unmanned Heavy-lift Aerial Reconnaissance and Resilient Integrated European Response,https://defence-industry-space.ec.europa.eu/document/download/3b14368d-4e96-46cf-ad22-dbfd1d74560e_en?filename=FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304865_U_HARRIER.pdf,FACTSHEET_EDF_2025_LS_RA_SMERO_NT_101304865_U_HARRIER.pdf,"OK (413,702B)",413702 53,5G4DEF - 5G NTN FOR EUROPEAN DEFENCE OPERATIONS,https://defence-industry-space.ec.europa.eu/document/download/1d94605e-73c7-415e-9d19-bb77bd4327c2_en?filename=FACTSHEET_EDF_2025_LS_DA_SME_NT_101305012_5G4DEF.pdf,FACTSHEET_EDF_2025_LS_DA_SME_NT_101305012_5G4DEF.pdf,"OK (508,771B)",508771 54,EOBLINDING - Tracking and Degrading Operation and Performance of Earth Observation Satellites,https://defence-industry-space.ec.europa.eu/document/download/3e931535-0850-42dd-89d6-320df5f1b597_en?filename=FACTSHEET_EDF_2025_LS_DA_SME_NT_101304978_EOBLINDING.pdf,FACTSHEET_EDF_2025_LS_DA_SME_NT_101304978_EOBLINDING.pdf,"OK (411,102B)",411102 55,GNSS_ARMOUR - Multilayer anti-jam protection for GNSS receivers,https://defence-industry-space.ec.europa.eu/document/download/924dae8c-dc04-4216-a4b3-ab3ad4fbdc30_en?filename=FACTSHEET_EDF_2025_LS_DA_SME_NT_101304835_GNSS_ARMOUR.pdf,FACTSHEET_EDF_2025_LS_DA_SME_NT_101304835_GNSS_ARMOUR.pdf,"OK (409,182B)",409182 56,NEVMA - Neuromorphic Event-Driven Vision for Multiple Defense Applications,https://defence-industry-space.ec.europa.eu/document/download/9cf8bbb9-850c-4d1d-b17a-fd4700b64972_en?filename=FACTSHEET_EDF_2025_LS_DA_SME_NT_101304923_NEVMA.pdf,FACTSHEET_EDF_2025_LS_DA_SME_NT_101304923_NEVMA.pdf,"OK (409,325B)",409325 57,RESIST-REsilient Semiconductor Integrated design SysTem,https://defence-industry-space.ec.europa.eu/document/download/1c937b0b-82e1-4177-9e92-81e54ba70286_en?filename=FACTSHEET_EDF_2025_LS_DA_SME_NT_101304980_RESIST.pdf,FACTSHEET_EDF_2025_LS_DA_SME_NT_101304980_RESIST.pdf,"OK (508,669B)",508669 58,SEQULITE-LIGHTWEIGHT SECURE COMMUNICATION PROTOCOL WITH HW-BACKED POST-QUANTUM CRYPTOGRAPHY,https://defence-industry-space.ec.europa.eu/document/download/e5f74276-dcf6-409e-b99b-5b49ffa4101b_en?filename=FACTSHEET_EDF_2025_LS_DA_SME_NT_101305023_SEQULITE.pdf,FACTSHEET_EDF_2025_LS_DA_SME_NT_101305023_SEQULITE.pdf,"OK (511,447B)",511447 59,SOUND2-Sonobuoy Optimization for Unmanned Deployment and Underwater Detection,https://defence-industry-space.ec.europa.eu/document/download/cfc1f493-47cf-4940-a371-af4c8850c81e_en?filename=FACTSHEET_EDF_2025_LS_DA_SME_NT_101304700_SOUND2.pdf,FACTSHEET_EDF_2025_LS_DA_SME_NT_101304700_SOUND2.pdf,"OK (416,231B)",416231 60,EOA-V2 - Enhancing Opportunities for All - Volume 2,https://defence-industry-space.ec.europa.eu/document/download/caea2590-7d8b-4d72-9c0c-bb8051e7232e_en?filename=FACTSHEET_EDF_2025_CSA_101305005_EOA-V2.pdf,FACTSHEET_EDF_2025_CSA_101305005_EOA-V2.pdf,"OK (520,491B)",520491 ======================================================================================== FICHEIRO: edf_simple_page_v2.html Tamanho: 4529 bytes ======================================================================================== EDF 2025 - 60 Projetos

EDF 2025 – Factsheets dos 60 Projetos

Esta página contém links locais para os 60 factsheets EDF 2025 guardados na pasta edf_simple_v2/. Clicar num link individual faz download desse PDF. O botão abaixo tenta descarregar todos os PDFs em série (o browser pode pedir autorização para múltiplos downloads).

Lista de PDFs

# Nome do ficheiro Download
1 EDF 2025 results - general factsheet v6.pdf Download
2 FACTSHEET_EDF_2025_RA_MCBRN_ATE_101304840_SALUBRIS.pdf Download
3 FACTSHEET_EDF_2025_RA_SGA_MCBRN_MCM_STEP_101254210_RESILIENCE_R_2025.pdf Download
4 FACTSHEET_EDF_2025_DA_SGA_MCBRN_MCM_STEP_101254257_RESILIENCE_D_25.pdf Download
======================================================================================== FICHEIRO: estilos-backend.css Tamanho: 6586 bytes ======================================================================================== /* ======================================== estilos-backend.css - SISTEMA MODULAR ========================================*/ /* ========================================*/ /* 1. ESTILO BASE DA PÃGINA */ .body-padrao { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font-size: 13px; color: #111827; background: #f3f4f6; margin: 0; padding: 20px; line-height: 1.5; min-height: 100vh; } /* ========================================*/ /* 2 Card padrao */ .card-padrao { background: #ffffff; border-radius: 20px; border: 1px solid #e5e7eb; padding: 24px; max-width: 1100px; margin: 0 auto 20px auto; } /* RESPONSIVO */ @media (max-width: 768px) { .body-padrao { padding: 12px; } } /* ========================================*/ /* 3. TÃTULOS PADRÃO */ .titulo-padrao h1 { font-size: 24px; letter-spacing: -0.03em; margin: 0 0 4px 0; font-weight: 700; color: #111827; } .titulo-padrao h2 { font-size: 16px; letter-spacing: -0.02em; margin-top: 12px; margin-bottom: 4px; } .titulo-padrao p.small { font-size: 13px; color: #6b7280; margin: 0 0 16px 0; } /* ======================================== 4. header-padrao - HEADER FLEX (ESQUERDA/DIREITA) ======================================== */ .header-padrao { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; } /* ======================================== tabs-padrao - ABAS (dentro do header Dirieta) ======================================== */ .tabs-padrao { display: flex; gap: 8px; margin: 0; } .tabs-padrao .tab-button { padding: 6px 12px; border-radius: 999px; border: 1px solid #d1d5db; background: #f9fafb; font-size: 12px; cursor: pointer; font-weight: 500; transition: all 0.2s ease; } .tabs-padrao .tab-button.tab-active { background: #2563eb; color: #f9fafb; border-color: #1d4ed8; } .tabs-padrao .tab-button:hover:not(.tab-active) { background: #eff6ff; transform: translateY(-1px); } /* ======================================== toolbar-direita - BOTÕES AZUL/BRANCO ======================================== REGRA AUTOMÃTICA: = AZUL |
A carregar dados fiscais...
Saldo fiscal vendas
0,00 €
Ano selecionado
Imposto estimado
0,00 €
Estimativa
Dividendos registados
0,00 €
Convertidos para EUR

Vendas de ações / ETF

  • Lista apenas vendas com data no ano escolhido.
  • Converte para EUR usando taxa da linha ou histórico cambial.
  • Mostra uma base prática para preencher o IRS.

Dividendos

  • Usa os movimentos de caixa marcados como Dividendo.
  • Mostra valor recebido e convertido para EUR.
  • Verificar se é necessário declarar dividendos.

Vendas no ano selecionado

Venda Ativo Compra Dias Aquisição EUR Realização EUR Ganho/Perda EUR Taxa Nota

Dividendos no ano selecionado

Data Descrição Moeda Valor EUR Observação

Checklist

  1. Selecionar o ano fiscal pretendido.
  2. Usar a tabela de vendas como base para preencher as operações realizadas.
  3. Usar a tabela de dividendos como base de conferência.
  4. Confirmar o extrato do broker/banco antes da submissão final.
======================================================================================== FICHEIRO: lucro-mensal-grafico.html Tamanho: 33130 bytes ======================================================================================== Lucro Mensal (Gráfico)

Gráfico Detalhado

ΔRealizado + ΔNãoRealizado + dividendos - taxas

A carregar…
Lucro Total
€0,00
—
Lucro (último mês)
€0,00
—
Rentabilidade
0,0%
Janela selecionada
Meses
0
—
Lucro (mês) Lucro Total Valor Carteira Invest. Inicial
======================================================================================== FICHEIRO: manifest.webmanifest Tamanho: 565 bytes ======================================================================================== { "name": "Site Financeiro", "short_name": "Financeiro", "description": "Resumo da carteira e transações financeiras em formato app.", "start_url": "/resumo.html?user=tiago", "scope": "/", "display": "standalone", "background_color": "#f3f4f6", "theme_color": "#22c55e", "lang": "pt-PT", "icons": [ { "src": "/icon.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { "src": "/icon.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" } ] } ======================================================================================== FICHEIRO: pwa-register.js Tamanho: 306 bytes ======================================================================================== (function registerPwa() { if (!('serviceWorker' in navigator)) { return; } window.addEventListener('load', function () { navigator.serviceWorker .register('/sw.js') .catch(function (error) { console.warn('Falha ao registar Service Worker:', error); }); }); })(); ======================================================================================== FICHEIRO: resumo.html Tamanho: 63352 bytes ======================================================================================== Resumo da Carteira

Resumo da Carteira

Dados calculados automaticamente a partir do ficheiro de transações guardado no servidor.

Carregando taxas de câmbio... Carregando preços...
Valor da Carteira
0,00 €
Somatório do valor final apenas das ações não vendidas.
Investimento Inicial
0,00 €
Dinheiro Investido.
Lucro / Prejuízo da Carteira
0,00 € (0,00%)
Lucro não realizado das posições que ainda estão abertas.
Saldo em Caixa
EUR: 0,00 €
USD: 0,00 $
Dinheiro disponível para investido.

Resumo por Ação

Nome da Ação Nº Ações Preço Médio Compra Preço Atual % Dia Valor Mercado Valor Ganhos % Ganho
Nome da Ação Investido Valor Ganho
Total 0,00 - - 0,00% 0,00 € 0,00 € -
Total 0,00 € 0,00 € 0,00 €

Variaçao por Ativo

A carregar...
======================================================================================== FICHEIRO: roteiro-amesterdao-belgica-mapa.html Tamanho: 27968 bytes ======================================================================================== Roteiro Amesterdão e Bélgica

Mapa do roteiro: Amesterdão, Países Baixos e Bélgica

Este HTML junta hotéis, voos e pontos do programa diário entre 3 e 10 de junho de 2026. Podes selecionar vários dias ao mesmo tempo para ver todos os locais combinados no mesmo mapa.

Mapa interativo

Como usar

  • Clica em vários dias para combinar locais no mesmo mapa.
  • O botão de recentramento ajusta a vista aos dias atualmente selecionados.
  • Os hotéis aparecem nos dias em que servem de base.

Hotéis

Amesterdão: Park Inn by Radisson Amsterdam City West, La Guardiaweg 59, Westpoort, 1043 DE Amesterdão, Países Baixos.

Bruxelas: YOOMA Urban Lodge, Square De L'aviation 23-27, Anderlecht, 1070 Bruxelas, Bélgica.

======================================================================================== FICHEIRO: sw.js Tamanho: 1320 bytes ======================================================================================== const CACHE_VERSION = 'site-financeiro-v1'; const STATIC_ASSETS = [ '/', '/index.html', '/resumo.html', '/estilos-backend.css', '/icon.png', '/manifest.webmanifest', '/pwa-register.js' ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_VERSION).then((cache) => cache.addAll(STATIC_ASSETS)) ); self.skipWaiting(); }); self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all( keys .filter((key) => key !== CACHE_VERSION) .map((key) => caches.delete(key)) ) ) ); self.clients.claim(); }); self.addEventListener('fetch', (event) => { const { request } = event; if (request.method !== 'GET') { return; } event.respondWith( caches.match(request).then((cachedResponse) => { if (cachedResponse) { return cachedResponse; } return fetch(request) .then((networkResponse) => { if (request.url.startsWith(self.location.origin) && networkResponse.ok) { const copy = networkResponse.clone(); caches.open(CACHE_VERSION).then((cache) => cache.put(request, copy)); } return networkResponse; }) .catch(() => caches.match('/index.html')); }) ); }); ======================================================================================== FICHEIRO: transacoes-acoes.csv Tamanho: 45543 bytes ======================================================================================== Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,ValorInicial,ValorFinal,Comissoes,CustoInicialTotal,CustoFinalTotal,Ganho,Moeda "1","2019-10-13","2019-11-16","NASDAQ:GOOGL","0.161663","61.86","62.19","0","10.00","10.05","0.05","USD" "2","2019-10-16","2020-02-10","NASDAQ:AMZN","0.11321","88.77","106.04","0","10.05","12.00","1.96","USD" "3","2020-01-22","2020-06-10","NASDAQ:AAPL","1.8870298","79.49","87.25","0","150.00","164.64","14.64","USD" "4","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28949064","77.55","87.25","0","100.00","112.51","12.51","USD" "5","2020-01-27","2020-06-10","NASDAQ:AAPL","1.28812028","77.63","87.39","0","100.00","112.57","12.57","USD" "6","2020-02-04","2020-05-29","NASDAQ:ADBE","0.27270991","366.69","381.53","0","100.00","104.05","4.05","USD" "7","2020-02-06","2020-05-01","NASDAQ:TSLA","1.9305018","51.80","58.37","0","100.00","112.68","12.68","USD" "8","2020-02-19","2020-02-25","NYSE:MA","0.28609409","346.04","331.37","0","99.00","94.80","-4.20","USD" "9","2020-02-19","2020-04-15","NASDAQ:TSLA","1.97749185","62.74","67.53","0","124.07","133.54","9.47","USD" "10","2020-02-25","2020-05-20","NYSE:MA","0.31256977","313.53","296.71","0","98.00","92.74","-5.26","USD" "11","2020-02-27","2020-04-13","NASDAQ:AMZN","1.028983","97.27","99.55","0","100.09","102.44","2.35","USD" "12","2020-03-19","2020-04-14","NASDAQ:AMZN","1.0563286","94.67","113.91","0","100.00","120.33","20.32","USD" "13","2020-03-19","2020-05-05","NASDAQ:AAPL","1.57029008","63.68","74.66","0","100.00","117.24","17.24","USD" "14","2020-03-25","2020-03-25","NASDAQ:TSLA","2.72737185","36.67","48.96","0","100.01","133.53","33.52","USD" "15","2020-04-07","2020-05-25","NYSE:MCD","1.11594688","179.22","187.74","0","200.00","209.51","9.51","USD" "16","2020-04-14","2020-05-12","NASDAQ:NFLX","0.25100401","402.74","438.85","0","101.09","110.15","9.06","USD" "17","2020-04-14","2020-04-30","NASDAQ:TSLA","2.02850715","49.83","55.55","0","101.08","112.68","11.60","USD" "18","2020-04-16","2020-06-10","NASDAQ:AMZN","1.6590626","121.20","132.5025","0","201.08","219.83","18.75","USD" "19","2020-04-16","2020-07-01","NASDAQ:NFLX","0.22745365","444.40","464.20","0","101.08","105.58","4.50","USD" "20","2020-04-27","2020-05-11","NASDAQ:GOOGL","3.1276144","64.29","69.52","0","201.07","217.43","16.36","USD" "21","2020-05-01","2020-06-09","NASDAQ:AMZN","0.8724708","115.87","125.95","0","101.09","109.89","8.79","USD" "22","2020-05-01","2020-05-06","NASDAQ:TSLA","3.1895439","47.37","52.37","0","151.09","167.04","15.95","USD" "23","2020-05-11","2020-07-09","NASDAQ:AMD","1.80733779","55.93","56.31","0","101.08","101.77","0.69","USD" "24","2020-05-12","2020-08-19","NYSE:MA","0.36659579","275.73","297.48","0","101.08","109.05","7.97","USD" "25","2020-05-14","2020-06-03","NASDAQ:GOOGL","2.9816034","67.44","71.77","0","201.08","213.99","12.91","USD" "26","2020-05-15","2020-05-29","NYSE:SQ","2.54097319","79.14","80.71","0","201.09","205.08","3.99","USD" "27","2020-05-20","2020-07-01","NASDAQ:NVDA","0.34223706","362.58","382.36","0","124.09","130.86","6.77","USD" "28","2020-05-21","2020-06-08","NYSE:KO","4.3392935","46.11","49.71","0","200.08","215.71","15.62","USD" "29","2020-05-27","2020-06-03","NASDAQ:ANSS","0.38406882","263.21","290.44","0","101.09","111.55","10.46","USD" "30","2020-05-28","2020-06-05","NASDAQ:QCOM","2.4789291","81.12","89.12","0","201.09","220.92","19.83","USD" "31","2020-05-29","2020-07-19","NASDAQ:MSFT","1.15486141","182.80","198.16","0","211.11","228.85","17.74","USD" "32","2020-06-01","2020-06-18","NASDAQ:UAL","6.8212824","29.48","39.87","0","201.09","271.96","70.87","USD" "33","2020-06-03","2020-07-01","NASDAQ:UAL","7.12250712","31.59","37.39","0","225.00","266.31","41.31","USD" "34","2020-06-03","2020-07-15","NASDAQ:UAL","6.44484412","33.53","34.06","0","216.10","219.51","3.42","USD" "35","2020-06-04","2020-08-27","NASDAQ:UAL","2.78884462","38.06","37.49","0","106.14","104.55","-1.59","USD" "36","2020-06-04","2020-08-10","NASDAQ:UAL","2.69444444","36.42","36.55","0","98.13","98.48","0.35","USD" "37","2020-06-04","2020-08-27","NASDAQ:UAL","5.20231213","38.28","36.73","0","199.14","191.08","-8.06","USD" "38","2020-06-05","2020-10-06","NASDAQ:UAL","2.4672489","46.25","36.78","0","114.11","90.75","-23.36","USD" "39","2020-06-05","2020-10-08","NASDAQ:UAL","4.8456164","44.37","37.49","0","215.00","181.66","-33.34","USD" "40","2020-06-08","2020-10-08","NASDAQ:UAL","4.86896252","46.17","37.41","0","224.80","182.15","-42.65","USD" "41","2020-06-08","2020-07-30","NASDAQ:ANSS","0.35145678","284.53","309.58","0","100.00","108.80","8.80","USD" "42","2020-06-09","2020-09-15","NASDAQ:UAL","2.22121486","44.63","37.07","0","99.13","82.34","-16.79","USD" "43","2020-06-10","2020-08-28","NASDAQ:UAL","2.43486729","41.53","37.02","0","101.12","90.14","-10.98","USD" "44","2020-06-10","2020-08-03","NASDAQ:ANSS","1.03831377","290.02","315.55","0","301.13","327.64","26.51","USD" "45","2020-06-11","2020-07-01","NASDAQ:TSLA","4.5053613","66.84","74.59","0","301.14","336.05","34.92","USD" "46","2020-06-15","2020-07-06","NASDAQ:AAPL","1.78512984","84.65","93.40","0","151.11","166.73","15.62","USD" "47","2020-06-19","2020-06-20","NASDAQ:GOOGL","4.1551534","72.47","77.65","0","301.12","322.65","21.52","USD" "48","2020-06-19","2020-07-30","NASDAQ:QCOM","3.3463469","89.98","102.67","0","301.10","343.57","42.47","USD" "49","2020-06-22","2020-07-13","NASDAQ:AAPL","2.26321148","88.86","97.59","0","201.11","220.87","19.76","USD" "50","2020-07-01","2020-07-21","NYSE:KO","6.61229887","45.37","47.62","0","300.00","314.88","14.88","USD" "51","2020-07-07","2020-07-10","NASDAQ:TSLA","5.3756118","93.01","102.30","0","499.99","549.93","49.94","USD" "52","2020-07-07","2020-07-15","NASDAQ:UAL","6.00781015","33.29","34.21","0","200.00","205.53","5.53","USD" "53","2020-07-07","2020-08-21","NASDAQ:ZM","0.55248618","271.50","290.26","0","150.00","160.36","10.36","USD" "54","2020-07-10","2020-09-01","NASDAQ:AMZN","0.6291998","158.93","174.61","0","100.00","109.86","9.87","USD" "55","2020-07-13","2020-08-18","NASDAQ:TSLA","2.63999295","113.64","125.23","0","300.01","330.61","30.60","USD" "56","2020-07-13","2020-11-13","NASDAQ:AMZN","1.838162","163.21","155.66","0","300.01","286.13","-13.88","USD" "57","2020-07-14","2020-07-31","NASDAQ:AAPL","2.63296468","94.95","102.92","0","250.00","270.98","20.98","USD" "58","2020-07-15","2020-08-03","NASDAQ:AAPL","2.0317988","98.43","111.01","0","199.99","225.55","25.56","USD" "59","2020-07-15","2020-07-30","NASDAQ:TSLA","1.9946808","100.27","116.40","0","200.01","232.18","32.17","USD" "60","2020-07-20","2020-10-08","NASDAQ:UAL","9.17150718","32.71","33.58","0","300.00","307.98","7.98","USD" "61","2020-07-20","2020-08-03","NASDAQ:AAPL","3.05654608","98.15","111.01","0","300.00","339.31","39.31","USD" "62","2020-07-23","2020-11-13","NASDAQ:AMZN","1.9828548","151.30","165.29","0","300.01","327.75","27.74","USD" "63","2020-07-24","2020-07-24","NASDAQ:AMD","1.05263157","66.50","68.79","0","70.00","72.41","2.41","USD" "64","2020-07-24","2020-08-21","NASDAQ:ZM","0.28389503","246.57","290.26","0","70.00","82.40","12.40","USD" "65","2020-07-27","2020-08-13","NASDAQ:TSLA","1.5705051","95.51","107.16","0","150.00","168.30","18.30","USD" "66","2020-07-30","2020-09-01","NASDAQ:GOOGL","3.9853868","75.28","82.77","0","300.02","329.87","29.85","USD" "67","2020-07-30","2020-08-27","NASDAQ:MSFT","0.73800738","203.25","229.06","0","150.00","169.05","19.05","USD" "68","2020-07-31","2020-08-26","NASDAQ:GOOGL","3.3979624","73.57","80.26","0","249.99","272.72","22.73","USD" "69","2020-08-01","2020-08-13","NASDAQ:TSLA","3.0459945","98.49","108.82","0","300.00","331.47","31.47","USD" "70","2020-08-05","2020-09-01","NASDAQ:ANSS","0.95910994","312.79","344.31","0","300.00","330.23","30.23","USD" "71","2020-08-05","2020-09-29","NASDAQ:AMD","1.18990956","84.04","81.34","0","100.00","96.79","-3.21","USD" "72","2020-08-06","2020-08-31","NASDAQ:AAPL","0.90019128","111.09","128.25","0","100.00","115.45","15.45","USD" "73","2020-08-10","2020-08-31","NASDAQ:AMD","1.23701138","80.84","89.86","0","100.00","111.16","11.16","USD" "74","2020-08-10","2020-08-27","NASDAQ:ANSS","0.32998944","303.04","331.63","0","100.00","109.43","9.43","USD" "75","2020-08-13","2020-08-18","NASDAQ:ZM","0.40695071","245.73","270.85","0","100.00","110.22","10.22","USD" "76","2020-08-14","2020-08-20","NYSE:SQ","0.7033338","142.18","156.25","0","100.00","109.90","9.90","USD" "77","2020-08-17","2020-08-18","NASDAQ:TSLA","0.88541535","112.94","125.5266667","0","100.00","111.14","11.14","USD" "78","2020-08-17","2020-08-31","NASDAQ:TSLA","0.842091","118.75","116.32","0","100.00","97.95","-2.05","USD" "79","2020-08-17","2020-09-01","NYSE:SQ","0.66613375","150.12","166.07","0","100.00","110.62","10.62","USD" "80","2020-08-18","2020-08-24","NASDAQ:UAL","2.9620853","33.76","36.19","0","100.00","107.20","7.20","USD" "81","2020-08-19","2020-09-02","NASDAQ:NVDA","0.10171698","491.56","577.12","0","50.00","58.70","8.70","USD" "82","2020-08-20","2020-08-28","NASDAQ:TSLA","0.75513105","132.43","151.46","0","100.00","114.37","14.37","USD" "83","2020-08-21","2020-12-17","NASDAQ:AAPL","1.6575476","120.66","128.57","0","200.00","213.11","13.11","USD" "84","2020-08-21","2020-08-31","NASDAQ:TSLA","1.44357075","138.55","154.37","0","200.01","222.84","22.84","USD" "85","2020-08-21","2020-08-31","NASDAQ:TSLA","1.4394081","138.95","155.05","0","200.01","223.18","23.17","USD" "86","2020-08-24","2020-08-27","NASDAQ:TSLA","1.46742315","136.29","151.53","0","200.00","222.36","22.36","USD" "87","2020-08-25","2020-09-28","NYSE:BABA","0.17636684","283.50","275.69","0","50.00","48.62","-1.38","USD" "88","2020-08-26","2020-09-01","NASDAQ:ZM","0.1661792","300.88","453.63","0","50.00","75.38","25.38","USD" "89","2020-08-26","2020-09-28","NYSE:BABA","0.17246731","289.91","275.65","0","50.00","47.54","-2.46","USD" "90","2020-08-27","2020-12-03","NASDAQ:TSLA","1.3170429","151.86","195.74","0","200.01","257.80","57.79","USD" "91","2020-08-27","2020-11-13","NASDAQ:TSLA","3.29757285","151.63","134.98","0","500.01","445.11","-54.90","USD" "92","2020-08-27","2020-08-31","NASDAQ:TSLA","3.40293465","146.93","161.25","0","499.99","548.72","48.73","USD" "93","2020-08-27","2020-12-17","NASDAQ:AAPL","1.60481444","124.63","128.57","0","200.01","206.33","6.32","USD" "94","2020-08-28","2020-09-02","NASDAQ:NVDA","0.09644131","518.45","577.22","0","50.00","55.67","5.67","USD" "95","2020-08-15","2020-12-03","NASDAQ:TSLA","3.22587582","155.00","195.77","0","500.01","631.53","131.52","USD" "96","2020-08-15","2020-12-15","NASDAQ:TSLA","1.23482196","161.97","213.55","0","200.00","263.70","63.69","USD" "97","2020-08-20","2020-08-31","NASDAQ:TSLA","0.7438962","134.43","165.05","0","100.00","122.78","22.78","USD" "98","2020-08-15","2020-12-15","NASDAQ:TSLA","3.02858988","165.09","213.55","0","499.99","646.76","146.77","USD" "99","2020-09-01","2020-09-22","NASDAQ:ZM","0.23466466","426.14","468.95","0","100.00","110.05","10.05","USD" "100","2020-09-01","2020-12-10","NASDAQ:TSLA","3.0358227","164.70","208.05","0","500.00","631.60","131.60","USD" "101","2020-09-01","2020-09-22","NASDAQ:ZM","0.44881288","445.62","488.18","0","200.00","219.10","19.10","USD" "102","2020-09-01","2020-09-23","NASDAQ:ZM","0.42154073","474.45","519.98","0","200.00","219.19","19.19","USD" "103","2020-09-01","2020-09-30","NYSE:NIO","10.07556675","19.85","22.13","0","200.00","222.97","22.97","USD" "104","2020-09-02","2020-09-02","NYSE:NIO","10","20.74","24.00","0","207.40","240.00","32.60","USD" "105","2020-09-02","2020-11-18","NASDAQ:TSLA","2.54919498","149.07","164.16","0","380.01","418.48","38.47","USD" "106","2020-09-04","2020-12-17","NASDAQ:AAPL","2.01871739","123.04","128.57","0","248.38","259.55","11.16","USD" "107","2020-09-04","2020-10-01","NASDAQ:TSLA","1.82127246","137.27","149.47","0","250.01","272.23","22.22","USD" "108","2020-09-10","2020-09-15","NASDAQ:TSLA","1.96494537","127.23","146.07","0","250.00","287.02","37.02","USD" "109","2020-09-17","2020-10-01","NASDAQ:ANSS","1.19565287","310.55","334.09","0","371.31","399.46","28.15","USD" "110","2020-09-24","2020-10-01","NASDAQ:TSLA","2.69316786","122.22","130.49","0","329.16","351.43","22.27","USD" "111","2020-09-24","2020-10-13","NASDAQ:ZM","0.74879082","469.33","510.58","0","351.43","382.32","30.89","USD" "112","2020-09-25","2020-10-09","NASDAQ:AAPL","2.02064706","108.49","116.31","0","219.22","235.02","15.80","USD" "113","2020-10-01","2020-10-21","NASDAQ:GOOGL","5.3886366","74.12","79.74","0","399.41","429.69","30.28","USD" "114","2020-10-02","2020-10-14","NASDAQ:TSLA","2.96907141","141.13","154.06","0","419.03","457.42","38.39","USD" "115","2020-10-06","2020-10-13","NASDAQ:AAPL","2.41595669","112.68","123.87","0","272.23","299.26","27.03","USD" "116","2020-10-13","2021-02-02","NASDAQ:Z","1","101.17","114.81","0","101.17","114.81","13.64","USD" "117","2020-10-15","2020-11-18","NASDAQ:TSLA","3","149.40","164.16","0","448.20","492.48","44.28","USD" "118","2020-10-15","2021-02-02","NASDAQ:ANSS","1","351.53","375.57","0","351.53","375.57","24.04","USD" "119","2020-10-20","2020-12-09","NASDAQ:ZM","0.8230289","522.08","410.71","0","429.69","338.03","-91.66","USD" "120","2020-10-22","2020-10-29","NYSE:NIO","19.00692924","27.42","31.80","0","521.17","604.42","83.25","USD" "121","2020-10-30","2020-11-03","NYSE:NIO","19","30.59","34.44","0","581.21","654.36","73.15","USD" "122","2020-10-30","2020-11-05","NASDAQ:AAPL","2.37198781","108.80","119.22","0","258.07","282.79","24.72","USD" "123","2020-11-04","2020-11-05","NYSE:NIO","17.55848346","37.26","41.45","0","654.23","727.80","73.57","USD" "124","2020-11-06","2020-11-12","NYSE:NIO","20","41.24","49.00","0","824.80","980.00","155.20","USD" "125","2020-11-12","2020-11-23","NASDAQ:ZM","1","435.44","428.76","0","435.44","428.76","-6.68","USD" "126","2020-11-13","2020-11-23","NYSE:NIO","12","45.10","55.00","0","541.20","660.00","118.80","USD" "127","2020-11-17","2020-11-23","NYSE:NIO","15","47.68","55.00","0","715.20","825.00","109.80","USD" "128","2020-11-18","2020-12-15","NASDAQ:AAPL","4","119.76","126.65","0","479.04","506.60","27.56","USD" "129","2020-11-23","2020-11-27","NASDAQ:MRNA","8","101.20","124.85","0","809.60","998.80","189.20","USD" "130","2020-11-23","2020-12-15","NASDAQ:AAPL","4","114.31","126.34","0","457.24","505.36","48.12","USD" "131","2020-11-24","2021-01-20","NYSE:NIO","11","53.12","60.00","0","584.32","660.00","75.68","USD" "132","2020-11-30","2020-12-17","NASDAQ:AAPL","2","117.42","127.88","0","234.84","255.76","20.92","USD" "133","2020-11-24","2021-01-12","NYSE:NIO","9","53.12","64.02","0","478.08","576.18","98.10","USD" "134","2020-11-25","2021-01-29","NASDAQ:MRNA","5","146.02","152.58","0","730.10","762.90","32.80","USD" "135","2020-12-03","2020-12-07","NASDAQ:AAPL","-2.06461594","123.05","120.90","0","-254.05","-249.61","4.44","USD" "136","2020-12-07","2021-04-15","NASDAQ:AMD","4","95.30","95.30","0","381.20","381.20","0.00","USD" "137","2020-11-25","2021-01-26","NASDAQ:MRNA","5","146.02","174.00","0","730.10","870.00","139.90","USD" "138","2020-12-07","2021-02-04","NASDAQ:MRNA","3","155.40","172.00","0","466.20","516.00","49.80","USD" "139","2020-12-07","2020-12-21","NYSE:NIO","8","44.03","48.98","0","352.24","391.84","39.60","USD" "140","2020-12-08","2021-02-08","NASDAQ:MRNA","3","167.84","185.00","0","503.52","555.00","51.48","USD" "141","2020-12-08","2020-12-15","NASDAQ:ANSS","-1","338.47","345.66","0","-338.47","-345.66","-7.19","USD" "142","2020-12-08","2020-12-10","NASDAQ:AMD","-4","92.49","89.55","0","-369.96","-358.20","11.76","USD" "143","2020-12-10","2021-01-29","NASDAQ:MRNA","1","155.44","173.97","0","155.44","173.97","18.53","USD" "144","2020-12-10","2020-12-17","NASDAQ:TSLA","3","191.28","216.66","0","573.84","649.98","76.14","USD" "145","2020-12-11","2020-12-14","NASDAQ:TSLA","-1.17027156","209.11","205.81","0","-244.72","-240.85","3.86","USD" "146","2020-12-14","2020-12-30","NASDAQ:TSLA","3","205.81","231.66","0","617.43","694.98","77.55","USD" "147","2020-12-14","2020-12-21","NYSE:NIO","1","39.90","48.96","0","39.90","48.96","9.06","USD" "148","2020-12-15","2021-01-26","NASDAQ:MRNA","4","145.00","152.59","0","580.00","610.36","30.36","USD" "149","2020-12-17","2020-12-31","NASDAQ:AAPL","3","128.98","128.98","0","386.94","386.94","0.00","USD" "150","2020-12-17","2021-01-07","NASDAQ:TSLA","3","206.67","266.65","0","620.01","799.95","179.94","USD" "151","2020-12-17","2020-12-31","NASDAQ:AAPL","5","128.63","128.63","0","643.15","643.15","0.00","USD" "152","2020-12-21","2020-12-31","NASDAQ:AMD","3","92.00","92.00","0","276.00","276.00","0.00","USD" "153","2020-12-22","2021-01-14","NASDAQ:TSLA","3","215.77","286.66","0","647.31","859.98","212.67","USD" "154","2020-12-23","2020-12-31","NASDAQ:AAPL","4","132.17","132.17","0","528.68","528.68","0.00","USD" "155","2020-12-23","2020-12-30","NASDAQ:TSLA","3","210.00","231.66","0","630.00","694.98","64.98","USD" "156","2020-12-23","2020-12-31","NASDAQ:AMZN","2.691074","159.79","159.79","0","430.01","430.01","0.00","USD" "157","2020-12-23","2020-12-31","NASDAQ:AMZN","0.4380818","159.79","159.79","0","70.00","70.00","0.00","USD" "158","2020-12-31","2021-01-06","NYSE:NIO","10","48.50","55.00","0","485.00","550.00","65.00","USD" "159","2020-12-31","2021-01-07","NASDAQ:TSLA","2.581293","238.83","266.67","0","616.49","688.35","71.86","USD" "160","2020-12-31","2021-01-07","NASDAQ:TSLA","0.418707","238.83","266.67","0","100.00","111.66","11.66","USD" "161","2021-01-04","2021-07-09","NASDAQ:AAPL","1","130.00","145.03","0","130.00","145.03","15.03","USD" "162","2021-01-06","2021-02-02","NASDAQ:TSLA","2.13256299","256.46","290.67","0","546.92","619.87","72.95","USD" "163","2021-01-07","2021-01-25","NASDAQ:TSLA","3","268.52","299.99","0","805.56","899.97","94.41","USD" "164","2021-01-08","2021-10-25","NASDAQ:TSLA","0.86743701","282.14","318.67","0","244.74","276.43","31.69","USD" "165","2021-01-08","2021-10-25","NASDAQ:TSLA","1.68863022","289.77","325.30","0","489.31","549.31","60.00","USD" "166","2021-01-08","2021-10-25","NASDAQ:TSLA","1.31136978","289.77","325.29","0","380.00","426.58","46.58","USD" "167","2021-01-13","2021-11-04","NASDAQ:PLUG","8","69.31","64.35","0","554.48","514.80","-39.68","USD" "168","2021-01-11","2021-01-14","NYSE:NIO","2","64.89","43.54","0","129.78","87.08","-42.70","USD" "169","2021-01-01","2021-04-15","NASDAQ:AMD","3","92.00","83.06","0","276.00","249.18","-26.82","USD" "170","2021-01-01","2021-02-03","NASDAQ:AMZN","2.691074","159.79","169.96","0","430.01","457.37","27.37","USD" "171","2021-01-01","2021-02-03","NASDAQ:AMZN","0.4380818","159.79","169.96","0","70.00","74.46","4.46","USD" "172","2021-01-01","2021-07-14","NASDAQ:AAPL","4","132.17","149.16","0","528.68","596.64","67.96","USD" "173","2021-01-01","2021-07-09","NASDAQ:AAPL","3","128.98","145.04","0","386.94","435.12","48.18","USD" "174","2021-01-01","2021-01-25","NASDAQ:AAPL","5","128.63","144.29","0","643.15","721.45","78.30","USD" "175","2021-01-01","2021-04-15","NASDAQ:AMD","4","95.30","83.06","0","381.20","332.24","-48.96","USD" "176","2021-01-14","2021-01-21","NASDAQ:MRNA","4","129.08","134.71","0","516.32","538.84","22.52","USD" "177","2021-01-15","2021-02-09","NYSE:NIO","15","57.38","62.66","0","860.70","939.90","79.20","USD" "178","2021-01-22","2021-10-21","NASDAQ:TSLA","2.52425082","277.31","298.49","0","700.00","753.46","53.46","USD" "179","2021-01-25","2021-10-25","NASDAQ:TSLA","3","290.00","330.94","0","870.00","992.82","122.82","USD" "180","2021-01-25","2021-09-07","NASDAQ:AAPL","5","140.00","155.05","0","700.00","775.25","75.25","USD" "181","2021-01-25","2021-11-04","NYSE:NIO","1","59.62","43.54","0","59.62","43.54","-16.08","USD" "182","2021-01-27","2021-11-18","NASDAQ:AAPL","2","143.31","158.00","0","286.62","316.00","29.38","USD" "183","2021-01-27","2021-02-04","NASDAQ:MRNA","2","158.09","172.00","0","316.18","344.00","27.82","USD" "184","2021-01-27","2021-02-08","NASDAQ:MRNA","3","165.86","184.99","0","497.58","554.97","57.39","USD" "185","2021-01-29","2021-10-25","NASDAQ:TSLA","3","280.33","317.16","0","840.99","951.48","110.49","USD" "186","2021-01-29","2021-05-03","NASDAQ:MRNA","6","177.35","186.87","0","1064.10","1121.22","57.12","USD" "187","2021-02-01","2021-02-04","NASDAQ:MRNA","1","156.50","171.99","0","156.50","171.99","15.49","USD" "188","2021-02-02","2021-08-16","NASDAQ:AAPL","4","135.67","150.00","0","542.68","600.00","57.32","USD" "189","2021-02-05","2021-02-11","NASDAQ:PYPL","3","267.18","300.00","0","801.54","900.00","98.46","USD" "190","2021-02-08","2021-07-23","NASDAQ:PYPL","3","280.95","308.81","0","842.85","926.43","83.58","USD" "191","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","166.19","162.50","0","415.48","406.25","-9.23","USD" "192","2021-02-08","2021-02-12","NASDAQ:AMZN","2.5","166.19","162.51","0","415.48","406.27","-9.20","USD" "193","2021-02-09","2021-05-03","NASDAQ:MRNA","3","178.82","186.87","0","536.46","560.61","24.15","USD" "194","2021-02-10","2021-10-25","NASDAQ:TSLA","2.08745436","278.58","318.66","0","581.52","665.19","83.67","USD" "195","2021-02-10","2021-11-22","NASDAQ:PYPL","3","285.00","191.85","0","855.00","575.55","-279.45","USD" "196","2021-02-12","2022-02-02","NASDAQ:PYPL","1.8","292.47","136.32","0","526.45","245.38","-281.07","USD" "197","2021-02-12","2022-02-02","NASDAQ:PYPL","1","292.47","136.33","0","292.47","136.33","-156.14","USD" "198","2021-03-12","2021-06-28","NYSE:NIO","4","44.30","49.00","0","177.20","196.00","18.80","USD" "199","2021-04-19","2021-09-17","NASDAQ:TSLA","2.35822089","233.23","252.91","0","550.01","596.42","46.41","USD" "200","2021-05-04","2021-07-06","NASDAQ:GOOGL","1.9646364","114.53","126.05","0","225.01","247.64","22.63","USD" "201","2021-05-04","2021-05-27","NASDAQ:MRNA","4","175.47","177.05","0","701.88","708.20","6.32","USD" "202","2021-05-04","2021-10-19","NASDAQ:ANSS","2","350.09","364.67","0","700.18","729.34","29.16","USD" "203","2021-05-04","2021-07-06","NASDAQ:AMZN","0.5170316","164.40","181.05","0","85.00","93.61","8.61","USD" "204","2021-05-24","2021-05-27","NYSE:SPCE","2","24.93","28.02","0","49.86","56.04","6.18","USD" "205","2021-05-27","2021-06-07","NYSE:SPCE","4","28.53","33.85","0","114.12","135.40","21.28","USD" "206","2021-05-27","2021-06-07","NYSE:SPCE","23","30.62","33.85","0","704.26","778.55","74.29","USD" "207","2021-06-07","2021-06-28","NYSE:NIO","10","43.72","49.00","0","437.20","490.00","52.80","USD" "208","2021-06-08","2021-06-25","NYSE:SPCE","12","37.36","47.73","0","448.32","572.76","124.44","USD" "209","2021-07-01","2021-11-04","NYSE:NIO","5","52.00","43.54","0","260.00","217.70","-42.30","USD" "210","2021-07-01","2021-11-04","NYSE:NIO","5","52.00","43.54","0","260.00","217.70","-42.30","USD" "211","2021-07-06","2021-08-09","NASDAQ:GOOGL","2.1915668","125.48","135.84","0","275.00","297.70","22.70","USD" "212","2021-07-06","2021-08-09","NASDAQ:GOOGL","2.1915668","125.48","135.84","0","275.00","297.70","22.70","USD" "213","2021-07-07","2021-07-08","NYSE:SPCE","11","45.00","50.00","0","495.00","550.00","55.00","USD" "214","2021-07-07","2021-07-08","NYSE:SPCE","1","45.00","50.00","0","45.00","50.00","5.00","USD" "215","2021-07-12","2021-12-03","NYSE:SPCE","12","45.00","14.32","0","540.00","171.84","-368.16","USD" "216","2021-07-15","2021-07-16","NASDAQ:MRNA","1","255.80","285.00","0","255.80","285.00","29.20","USD" "217","2021-07-16","2021-11-09","NYSE:SPCE","18","32.56","20.99","0","586.08","377.82","-208.26","USD" "218","2021-07-16","2021-11-09","NYSE:SPCE","6","32.56","20.99","0","195.36","125.94","-69.42","USD" "219","2021-07-16","2021-11-29","NASDAQ:AAPL","1","147.32","164.98","0","147.32","164.98","17.66","USD" "220","2021-07-16","2021-11-29","NASDAQ:AAPL","2","147.30","165.00","0","294.60","330.00","35.40","USD" "221","2021-07-23","2021-08-03","NASDAQ:MRNA","2","335.27","370.00","0","670.54","740.00","69.46","USD" "222","2021-08-03","2021-11-19","NASDAQ:AMZN","4.4443522","168.75","186.71","0","749.98","829.80","79.82","USD" "223","2021-08-09","2021-11-26","NASDAQ:MRNA","0.5","450.93","327.96","0","225.47","163.98","-61.49","USD" "224","2021-08-09","2021-11-26","NASDAQ:MRNA","0.5","450.93","327.94","0","225.47","163.97","-61.50","USD" "225","2021-08-19","2021-11-19","NASDAQ:AAPL","5","144.93","160.00","0","724.65","800.00","75.35","USD" "226","2021-09-10","2021-12-01","NASDAQ:AAPL","5","149.97","170.00","0","749.85","850.00","100.15","USD" "227","2021-09-17","2021-11-29","NASDAQ:AAPL","4","146.83","165.00","0","587.32","660.00","72.68","USD" "228","2021-10-15","2022-01-01","NASDAQ:GOOGL","5.137277","142.96","142.96","0","734.43","734.43","0.00","USD" "229","2021-10-26","2021-11-01","NASDAQ:TSLA","3","348.16","383.33","0","1044.48","1149.99","105.51","USD" "230","2021-10-26","2021-12-06","NASDAQ:AAPL","4","150.48","167.09","0","601.92","668.36","66.44","USD" "231","2021-10-27","2021-12-01","NASDAQ:AAPL","7","149.25","170.00","0","1044.75","1190.00","145.25","USD" "232","2021-10-27","2021-12-01","NASDAQ:AAPL","3","149.25","170.00","0","447.75","510.00","62.25","USD" "233","2021-11-04","2022-02-17","NYSE:KO","8","56.29","62.00","0","450.32","496.00","45.68","USD" "234","2021-11-04","2022-01-01","NYSE:BAC","8","47.49","47.49","0","379.92","379.92","0.00","USD" "235","2021-11-04","2022-02-17","NYSE:KO","2","56.29","62.00","0","112.58","124.00","11.42","USD" "236","2021-11-04","2022-01-01","NYSE:BAC","2","47.49","47.49","0","94.98","94.98","0.00","USD" "237","2021-11-09","2022-01-01","NASDAQ:TSLA","3","355.26","355.26","0","1065.78","1065.78","0.00","USD" "238","2021-11-10","2022-01-01","NASDAQ:TSLA","0.525","357.83","357.83","0","187.86","187.86","0.00","USD" "239","2021-11-10","2022-01-01","NASDAQ:TSLA","0.975","357.83","357.83","0","348.88","348.88","0.00","USD" "240","2021-11-22","2022-01-01","NASDAQ:AAPL","8.5","163.08","163.08","0","1386.18","1386.18","0.00","USD" "241","2021-11-22","2022-01-01","NASDAQ:TSLA","1.5","393.92","393.92","0","590.88","590.88","0.00","USD" "242","2021-11-22","2022-01-01","NASDAQ:AAPL","1.5","163.08","163.08","0","244.62","244.62","0.00","USD" "243","2021-11-22","2021-11-26","NASDAQ:MRNA","1","287.97","319.99","0","287.97","319.99","32.02","USD" "244","2021-11-26","2021-12-10","NASDAQ:AAPL","1","158.17","178.17","0","158.17","178.17","20.00","USD" "245","2021-11-26","2022-01-01","NASDAQ:AMZN","1.8995262","176.35","176.35","0","334.98","334.98","0.00","USD" "246","2021-11-26","2021-12-10","NASDAQ:AAPL","1","158.17","178.17","0","158.17","178.17","20.00","USD" "247","2021-12-02","2021-12-13","NASDAQ:AAPL","7","158.72","181.00","0","1111.04","1267.00","155.96","USD" "248","2021-12-02","2021-12-10","NASDAQ:AAPL","3","160.89","178.17","0","482.67","534.51","51.84","USD" "249","2021-12-02","2022-01-01","NASDAQ:AMZN","1.7335028","173.06","173.06","0","300.00","300.00","0.00","USD" "250","2021-12-02","2022-01-01","NASDAQ:AAPL","7","163.26","163.26","0","1142.82","1142.82","0.00","USD" "251","2021-12-02","2022-01-01","NASDAQ:AAPL","2","163.26","163.26","0","326.52","326.52","0.00","USD" "252","2021-12-06","2022-01-03","NASDAQ:TSLA","3","330.97","384.52","0","992.91","1153.56","160.65","USD" "253","2021-12-13","2022-01-01","NASDAQ:AAPL","2","178.20","178.20","0","356.40","356.40","0.00","USD" "254","2021-12-13","2022-01-01","NASDAQ:AAPL","2","178.20","178.20","0","356.40","356.40","0.00","USD" "255","2021-12-14","2022-01-01","NASDAQ:AAPL","3","174.17","174.17","0","522.51","522.51","0.00","USD" "256","2021-12-14","2021-12-27","NASDAQ:TSLA","1.2","314.56","367.56","0","377.47","441.07","63.60","USD" "257","2021-12-14","2022-01-01","NASDAQ:AAPL","1","174.17","174.17","0","174.17","174.17","0.00","USD" "258","2021-12-14","2021-12-27","NASDAQ:TSLA","0.3","314.56","367.57","0","94.37","110.27","15.90","USD" "259","2021-12-28","2022-01-01","NASDAQ:AMZN","1.1645374","171.74","171.74","0","200.00","200.00","0.00","USD" "260","2021-11-10","2022-01-03","NASDAQ:TSLA","1.5","357.83","398.28","0","536.75","597.42","60.67","USD" "261","2022-01-03","2023-01-01","NASDAQ:ANSS","2","393.43","393.43","0","786.86","786.86","0.00","USD" "262","2022-01-06","2023-01-01","NASDAQ:TSLA","2.7","350","350","0","945.00","945.00","0.00","USD" "263","2022-01-06","2023-01-01","NASDAQ:TSLA","0.3","350","350","0","105.00","105.00","0.00","USD" "264","2022-01-11","2023-01-01","NASDAQ:AAPL","6","171","171","0","1026.00","1026.00","0.00","USD" "265","2022-02-02","2023-01-01","NASDAQ:GOOGL","1.8369098","150.33","150.33","0","276.14","276.14","0.00","USD" "266","2022-02-02","2023-01-01","NASDAQ:GOOGL","0.9046522","150.33","150.33","0","136.00","136.00","0.00","USD" "267","2022-02-18","2022-03-22","NASDAQ:TSLA","1.2","287.95","314.05","0","345.54","376.86","31.32","USD" "268","2022-02-18","2022-03-22","NASDAQ:TSLA","0.3","287.95","314.06","0","86.38","94.22","7.83","USD" "269","2022-02-18","2022-04-20","NYSE:O","2","67.03","75","0","134.06","150.00","15.94","USD" "270","2022-02-28","2023-01-01","NYSE:KO","2","61.93","61.93","0","123.86","123.86","0.00","USD" "271","2022-02-02","2023-01-01","NASDAQ:MSFT","0.62199751","297.67","297.67","0","185.15","185.15","0.00","USD" "272","2022-01-01","2023-01-01","NASDAQ:GOOGL","5.137277","142.96","142.96","0","734.43","734.43","0.00","USD" "273","2022-01-01","2023-01-01","NYSE:BAC","8","47.49","47.49","0","379.92","379.92","0.00","USD" "274","2022-01-01","2023-01-01","NYSE:BAC","2","47.49","47.49","0","94.98","94.98","0.00","USD" "275","2022-01-01","2023-01-01","NASDAQ:TSLA","3","355.26","355.26","0","1065.78","1065.78","0.00","USD" "276","2022-01-01","2023-01-01","NASDAQ:TSLA","0.525","357.83","357.83","0","187.86","187.86","0.00","USD" "277","2022-01-01","2023-01-01","NASDAQ:TSLA","0.975","357.83","357.83","0","348.88","348.88","0.00","USD" "278","2022-01-01","2023-01-01","NASDAQ:AAPL","8.5","163.08","163.08","0","1386.18","1386.18","0.00","USD" "279","2022-01-01","2023-01-01","NASDAQ:TSLA","1.5","393.92","393.92","0","590.88","590.88","0.00","USD" "280","2022-01-01","2023-01-01","NASDAQ:AAPL","1.5","163.08","163.08","0","244.62","244.62","0.00","USD" "281","2022-01-01","2023-01-01","NASDAQ:AMZN","1.8995262","176.35","176.35","0","334.98","334.98","0.00","USD" "282","2022-01-01","2023-01-01","NASDAQ:AMZN","1.7335028","173.06","173.06","0","300.00","300.00","0.00","USD" "283","2022-01-01","2023-01-01","NASDAQ:AAPL","7","163.26","163.26","0","1142.82","1142.82","0.00","USD" "284","2022-01-01","2023-01-01","NASDAQ:AAPL","2","163.26","163.26","0","326.52","326.52","0.00","USD" "285","2022-01-01","2023-01-01","NASDAQ:AAPL","2","178.2","178.2","0","356.40","356.40","0.00","USD" "286","2022-01-01","2023-01-01","NASDAQ:AAPL","2","178.2","178.2","0","356.40","356.40","0.00","USD" "287","2022-01-01","2023-01-01","NASDAQ:AAPL","3","174.17","174.17","0","522.51","522.51","0.00","USD" "288","2022-01-01","2023-01-01","NASDAQ:AAPL","1","174.17","174.17","0","174.17","174.17","0.00","USD" "289","2022-01-01","2023-01-01","NASDAQ:AMZN","1.1645374","171.74","171.74","0","200.00","200.00","0.00","USD" "290","2022-04-13","2023-01-01","NASDAQ:AAPL","1","170.66","170.66","0","170.66","170.66","0.00","USD" "291","2022-04-14","2022-10-05","NYSE:TWTR","4","48.42","50.93","0","193.68","203.72","10.04","USD" "292","2022-04-19","2022-10-05","NYSE:TWTR","1","47.24","50.93","0","47.24","50.93","3.69","USD" "293","2022-04-22","2023-01-01","NYSE:O","2","74","74","0","148.00","148.00","0.00","USD" "294","2022-05-20","2022-07-21","NASDAQ:AAPL","1","139.02","155.02","0","139.02","155.02","16.00","USD" "295","2022-06-07","2023-01-01","NASDAQ:AMZN","0.2024336","122.26","122.26","0","24.75","24.75","0.00","USD" "296","2022-07-27","2022-07-27","NASDAQ:AAPL","1","162","162","0","162.00","162.00","0.00","USD" "297","2022-09-14","2023-01-01","NASDAQ:AAPL","2","155.78","155.78","0","311.56","311.56","0.00","USD" "298","2022-12-20","2023-01-01","NASDAQ:AAPL","2","130","130","0","260.00","260.00","0.00","USD" "299","2023-01-01","2023-12-27","NASDAQ:ANSS","2","393.43","334.8","0","786.86","669.60","-117.26","USD" "300","2023-01-01","2024-01-01","NASDAQ:TSLA","2.7","350","350","0","945.00","945.00","0.00","USD" "301","2023-01-01","2024-01-01","NASDAQ:TSLA","0.3","350","350","0","105.00","105.00","0.00","USD" "302","2023-01-01","2023-11-16","NASDAQ:AAPL","6","171","190","0","1026.00","1140.00","114.00","USD" "303","2023-01-01","2024-01-01","NASDAQ:GOOGL","1.8369098","150.33","150.33","0","276.14","276.14","0.00","USD" "304","2023-01-01","2024-01-01","NASDAQ:GOOGL","0.9046522","150.33","150.33","0","136.00","136.00","0.00","USD" "305","2023-01-01","2024-01-01","NYSE:KO","2","61.93","61.93","0","123.86","123.86","0.00","USD" "306","2023-01-01","2023-05-25","NASDAQ:MSFT","0.62199751","297.67","321.63","0","185.15","200.05","14.90","USD" "307","2023-01-01","2024-01-01","NASDAQ:GOOGL","5.137277","142.96","142.96","0","734.43","734.43","0.00","USD" "308","2023-01-01","2024-01-01","NYSE:BAC","8","47.49","47.49","0","379.92","379.92","0.00","USD" "309","2023-01-01","2024-01-01","NYSE:BAC","2","47.49","47.49","0","94.98","94.98","0.00","USD" "310","2023-01-01","2024-01-01","NASDAQ:TSLA","3","355.26","355.26","0","1065.78","1065.78","0.00","USD" "311","2023-01-01","2024-01-01","NASDAQ:TSLA","0.525","357.83","357.83","0","187.86","187.86","0.00","USD" "312","2023-01-01","2024-01-01","NASDAQ:TSLA","0.975","357.83","357.83","0","348.88","348.88","0.00","USD" "313","2023-01-01","2023-06-15","NASDAQ:AAPL","8.5","163.08","185.02","0","1386.18","1572.67","186.49","USD" "314","2023-01-01","2024-01-01","NASDAQ:TSLA","1.5","393.92","393.92","0","590.88","590.88","0.00","USD" "315","2023-01-01","2023-06-15","NASDAQ:AAPL","1.5","163.08","185","0","244.62","277.50","32.88","USD" "316","2023-01-01","2024-01-01","NASDAQ:AMZN","1.8995262","176.35","176.35","0","334.98","334.98","0.00","USD" "317","2023-01-01","2024-01-01","NASDAQ:AMZN","1.7335028","173.06","173.06","0","300.00","300.00","0.00","USD" "318","2023-01-01","2023-06-15","NASDAQ:AAPL","7","163.26","185","0","1142.82","1295.00","152.18","USD" "319","2023-01-01","2023-06-15","NASDAQ:AAPL","2","163.26","185","0","326.52","370.00","43.48","USD" "320","2023-01-01","2023-12-13","NASDAQ:AAPL","2","178.2","196","0","356.40","392.00","35.60","USD" "321","2023-01-01","2023-12-13","NASDAQ:AAPL","2","178.2","195.99","0","356.40","391.98","35.58","USD" "322","2023-01-01","2023-12-13","NASDAQ:AAPL","3","174.17","196","0","522.51","588.00","65.49","USD" "323","2023-01-01","2024-01-01","NASDAQ:AAPL","1","174.17","174.17","0","174.17","174.17","0.00","USD" "324","2023-01-01","2024-01-01","NASDAQ:AMZN","1.1645374","171.74","171.74","0","200.00","200.00","0.00","USD" "325","2023-01-01","2023-12-14","NASDAQ:AAPL","1","170.66","196","0","170.66","196.00","25.34","USD" "326","2023-01-01","2024-01-01","NYSE:O","2","74","74","0","148.00","148.00","0.00","USD" "327","2023-01-01","2024-01-01","NASDAQ:AMZN","0.2024336","122.26","122.26","0","24.75","24.75","0.00","USD" "328","2023-01-01","2023-05-05","NASDAQ:AAPL","2","155.78","171.99","0","311.56","343.98","32.42","USD" "329","2023-01-01","2023-01-23","NASDAQ:AAPL","2","130","142.99","0","260.00","285.98","25.98","USD" "330","2023-01-23","2023-01-26","NASDAQ:TSLA","1","141.48","159.98","0","141.48","159.98","18.50","USD" "331","2023-01-23","2023-01-26","NASDAQ:TSLA","1","141.48","159.98","0","141.48","159.98","18.50","USD" "332","2023-01-30","2023-03-22","NASDAQ:AAPL","1","143.94","159.99","0","143.94","159.99","16.05","USD" "333","2023-01-30","2023-03-22","NASDAQ:AAPL","1","143.94","159.99","0","143.94","159.99","16.05","USD" "334","2023-03-01","2023-06-14","NYSE:BRK.B","1","303.16","339.98","0","303.16","339.98","36.82","USD" "335","2023-05-08","2023-05-23","NASDAQ:TSLA","1","171.76","189.98","0","171.76","189.98","18.22","USD" "336","2023-05-23","2024-01-01","NASDAQ:AAPL","1","172.79","172.79","0","172.79","172.79","0.00","USD" "337","2023-05-26","2023-06-02","NASDAQ:TSLA","1","190.12","209.98","0","190.12","209.98","19.86","USD" "338","2023-06-06","2024-01-01","NASDAQ:AAPL","3","178.63","178.63","0","535.89","535.89","0.00","USD" "339","2023-06-06","2024-01-01","NASDAQ:AAPL","1","178.63","178.63","0","178.63","178.63","0.00","USD" "340","2023-06-14","2024-01-01","NASDAQ:TSLA","1","258","258","0","258.00","258.00","0.00","USD" "341","2023-06-15","2024-01-01","NYSE:BRK.B","3","338.24","338.24","0","1014.72","1014.72","0.00","USD" "342","2023-06-15","2024-01-01","NYSE:BRK.B","1","338.24","338.24","0","338.24","338.24","0.00","USD" "343","2023-06-20","2024-01-01","NASDAQ:TSLA","2","271.03","271.03","0","542.06","542.06","0.00","USD" "344","2023-06-30","2024-01-01","NASDAQ:AAPL","4","192.45","192.45","0","769.80","769.80","0.00","USD" "345","2023-07-19","2024-01-01","NASDAQ:TSLA","2","296.58","296.58","0","593.16","593.16","0.00","USD" "346","2023-07-19","2024-01-01","NASDAQ:TSLA","1","296.58","296.58","0","296.58","296.58","0.00","USD" "347","2023-09-13","2024-01-01","NASDAQ:AAPL","3","175.02","175.02","0","525.06","525.06","0.00","USD" "348","2023-12-14","2024-01-01","NASDAQ:AAPL","1","196","196","0","196.00","196.00","0.00","USD" "349","2023-12-14","2024-01-01","AMS:IWDA","6","81.89","81.89","0","491.34","491.34","0.00","EUR" "350","2023-12-18","2024-01-01","NASDAQ:AAPL","2","195","195","0","390.00","390.00","0.00","USD" "351","2023-12-22","2024-01-01","NASDAQ:AAPL","3","195.24","195.24","0","585.72","585.72","0.00","USD" "352","2024-01-01","2024-01-25","NASDAQ:TSLA","2.7","350","187.75","0","945.00","506.93","-438.08","USD" "353","2024-01-01","2024-01-25","NASDAQ:TSLA","0.3","350","187.74","0","105.00","56.32","-48.68","USD" "354","2024-01-01","2024-04-26","NASDAQ:GOOGL","1.8369098","150.33","174.33","0","276.14","320.23","44.09","USD" "355","2024-01-01","2024-04-26","NASDAQ:GOOGL","0.9046522","150.33","174.31","0","136.00","157.69","21.69","USD" "356","2024-01-01","2024-06-05","NYSE:KO","2","61.93","63.92","0","123.86","127.84","3.98","USD" "357","2024-01-01","2024-04-12","NASDAQ:GOOGL","5","142.96","299.66","0","714.80","1498.30","783.50","USD" "358","2024-01-01","2024-07-11","NYSE:BAC","8","47.49","42","0","379.92","336.00","-43.92","USD" "359","2024-01-01","2024-04-26","NYSE:BAC","2","47.49","38.13","0","94.98","76.26","-18.72","USD" "360","2024-01-01","2024-03-01","NASDAQ:TSLA","2","355.26","201.22","0","710.52","402.44","-308.08","USD" "361","2024-01-01","2024-02-09","NASDAQ:TSLA","1","355.26","192.78","0","355.26","192.78","-162.48","USD" "362","2024-01-01","2024-02-09","NASDAQ:TSLA","0.525","357.83","192.78","0","187.86","101.21","-86.65","USD" "363","2024-01-01","2024-02-09","NASDAQ:TSLA","0.975","357.83","192.77","0","348.88","187.95","-160.93","USD" "364","2024-01-01","2024-02-09","NASDAQ:TSLA","1.5","393.92","192.78","0","590.88","289.17","-301.71","USD" "365","2024-01-01","2024-02-02","NASDAQ:AMZN","1.8995262","176.35","171.96","0","334.98","326.64","-8.34","USD" "366","2024-01-01","2024-02-02","NASDAQ:AMZN","1.7335028","173.06","171.96","0","300.00","298.09","-1.91","USD" "367","2024-01-01","2024-04-26","NASDAQ:AAPL","1","174.17","170","0","174.17","170.00","-4.17","USD" "368","2024-01-01","2024-02-02","NASDAQ:AMZN","1.1645374","171.74","171.95","0","200.00","200.24","0.24","USD" "369","2024-01-01","2024-04-26","NYSE:O","2","74","53.92","0","148.00","107.84","-40.16","USD" "370","2024-01-01","2024-02-02","NASDAQ:AMZN","0.2024336","122.26","171.96","0","24.75","34.81","10.06","USD" "371","2024-01-01","2024-06-11","NASDAQ:AAPL","1","172.79","199.96","0","172.79","199.96","27.17","USD" "372","2024-01-01","2024-07-02","NASDAQ:AAPL","3","178.63","220","0","535.89","660.00","124.11","USD" "373","2024-01-01","2024-04-26","NASDAQ:AAPL","1","178.63","170","0","178.63","170.00","-8.63","USD" "374","2024-01-01","2024-01-31","NASDAQ:TSLA","1","258","189.98","0","258.00","189.98","-68.02","USD" "375","2024-01-01","2024-01-25","NYSE:BRK.B","3","338.24","380","0","1014.72","1140.00","125.28","USD" "376","2024-01-01","2024-01-25","NYSE:BRK.B","1","338.24","379.98","0","338.24","379.98","41.74","USD" "377","2024-01-01","2024-01-31","NASDAQ:TSLA","2","271.03","190","0","542.06","380.00","-162.06","USD" "378","2024-01-01","2024-08-28","NASDAQ:AAPL","4","192.45","229.99","0","769.80","919.96","150.16","USD" "379","2024-01-01","2024-02-07","NASDAQ:TSLA","2","296.58","181.48","0","593.16","362.96","-230.20","USD" "380","2024-01-01","2024-02-07","NASDAQ:TSLA","1","296.58","181.47","0","296.58","181.47","-115.11","USD" "381","2024-01-01","2024-07-02","NASDAQ:AAPL","3","175.02","220","0","525.06","660.00","134.94","USD" "382","2024-01-01","2024-08-28","NASDAQ:AAPL","1","196","230","0","196.00","230.00","34.00","USD" "383","2024-01-01","2025-01-01","AMS:IWDA","6","81.89","81.89","0","491.34","491.34","0.00","EUR" "384","2024-01-01","2024-11-26","NASDAQ:AAPL","2","195","235","0","390.00","470.00","80.00","USD" "385","2024-01-01","2024-11-26","NASDAQ:AAPL","3","195.24","235","0","585.72","705.00","119.28","USD" "386","2024-01-01","2024-11-26","NASDAQ:AAPL","3","192.32","235","0","576.96","705.00","128.04","USD" "387","2024-01-08","2024-07-02","NASDAQ:AAPL","3","180","219.977","0","540.00","659.93","119.93","USD" "388","2024-01-25","2024-02-09","NASDAQ:NVDA","30","62.17833333","72","0","1865.35","2160.00","294.65","USD" "389","2024-01-31","2024-06-17","NASDAQ:MSFT","1","402.58","449.98","0","402.58","449.98","47.40","USD" "390","2024-02-02","2024-05-20","NASDAQ:NVDA","10","65.978","95","0","659.78","950.00","290.22","USD" "391","2024-02-02","2024-11-26","NASDAQ:AAPL","1","186.01","234.93","0","186.01","234.93","48.92","USD" "392","2024-02-05","2024-05-22","NASDAQ:NVDA","10","68.887","99.985","0","688.87","999.85","310.98","USD" "393","2024-02-21","2024-05-22","NASDAQ:NVDA","30","67.9","100","0","2037.00","3000.00","963.00","USD" "394","2024-03-05","2024-07-30","NYSE:BRK.B","1","400","439.98","0","400.00","439.98","39.98","USD" "395","2024-03-11","2024-05-22","NASDAQ:NVDA","10","88.933","100","0","889.33","1000.00","110.67","USD" "396","2024-04-01","2024-06-11","NASDAQ:AAPL","2","170","200","0","340.00","400.00","60.00","USD" "397","2024-01-01","2024-04-26","NASDAQ:GOOGL","0.137277","142.96","174.33","0","19.63","23.93","4.31","USD" "398","2024-04-22","2025-01-01","AMS:IWDA","7","88.42","88.42","0","618.94","618.94","0.00","EUR" "399","2024-04-26","2024-06-11","NASDAQ:AAPL","3","170","200","0","510.00","600.00","90.00","USD" "400","2024-04-26","2024-07-11","NYSE:BAC","2","38.13","41.99","0","76.26","83.98","7.72","USD" "401","2024-04-26","2024-07-17","NYSE:O","2","53.92","57.16","0","107.84","114.32","6.48","USD" "402","2024-05-28","2025-01-01","NASDAQ:NVDA","20","112.06","112.06","0","2241.20","2241.20","0.00","USD" "403","2024-06-06","2025-01-01","NASDAQ:NVDA","20","124.92","124.92","0","2498.40","2498.40","0.00","USD" "404","2024-06-12","2025-01-01","NASDAQ:AAPL","7","213.95","213.95","0","1497.65","1497.65","0.00","USD" "405","2024-06-20","2025-01-01","NASDAQ:AAPL","2","210","210","0","420.00","420.00","0.00","USD" "406","2024-07-03","2024-09-05","NASDAQ:TSLA","2","247.93","225.22","0","495.86","450.44","-45.42","USD" "407","2024-07-11","2024-11-10","NYSE:TSM","10","193.86","189.8","0","1938.60","1898.00","-40.60","USD" "408","2024-07-23","2025-01-01","INDEXNASDAQ:NDX","4.84403203","177.28","177.28","0","858.75","858.75","0.00","EUR" "409","2024-08-01","2025-01-01","NASDAQ:AAPL","5","218.85","218.85","0","1094.25","1094.25","0.00","USD" "410","2024-08-05","2025-01-01","NASDAQ:AAPL","1","204.9","204.9","0","204.90","204.90","0.00","USD" "411","2024-08-05","2025-01-01","NASDAQ:AAPL","2","204.9","204.9","0","409.80","409.80","0.00","USD" "412","2024-05-28","2024-10-17","NASDAQ:NVDA","10","112.06","140","0","1120.60","1400.00","279.40","USD" "413","2024-11-06","2025-01-01","NASDAQ:AAPL","21","225.81","225.81","0","4742.01","4742.01","0.00","USD" "414","2024-11-25","2025-01-01","NASDAQ:NVDA","8","137.7","137.7","0","1101.60","1101.60","0.00","USD" "415","2024-11-18","2025-01-01","INDEXNASDAQ:NDX","10","203.8","203.8","0","2038.00","2038.00","0.00","EUR" "416","2025-01-01","","AMS:IWDA","6","81.88","","0.05","491.33","","","EUR" "417","2025-01-01","","AMS:IWDA","7","88.41","","0.06","618.93","","","EUR" "418","2025-01-01","2025-01-06","NASDAQ:NVDA","20","112.06","150","0","2241.20","3000.00","758.80","USD" "419","2025-01-01","2025-05-28","NASDAQ:NVDA","20","124.92","140","0","2498.40","2800.00","301.60","USD" "420","2025-01-01","","NASDAQ:AAPL","7","213.95","","0","1497.65","","","USD" "421","2025-01-01","","NASDAQ:AAPL","2","210","","0","420.00","","","USD" "422","2025-01-01","","INDEXNASDAQ:NDX","4.84403203","177.28","","0","858.75","","","EUR" "423","2025-01-01","2025-11-11","NASDAQ:AAPL","5","218.85","273.9","0","1094.25","1369.50","275.25","USD" "424","2025-01-01","2025-08-08","NASDAQ:AAPL","1","204.9","225","0","204.90","225.00","20.10","USD" "425","2025-01-01","2025-08-08","NASDAQ:AAPL","2","204.9","224.99","0","409.80","449.98","40.18","USD" "426","2025-01-01","","NASDAQ:AAPL","21","225.81","","0","4742.01","","","USD" "427","2025-01-01","","NASDAQ:NVDA","8","137.7","","0","1101.60","","","USD" "428","2025-01-01","","INDEXNASDAQ:NDX","10","203.8","","0","2038.00","","","EUR" "429","2025-01-06","","NASDAQ:NVDA","21","142.77","","0","2998.17","","","USD" "430","2025-01-27","","NASDAQ:NVDA","2","123.59","","0","247.18","","","USD" "431","2025-07-03","","NASDAQ:NVDA","12","159.89","","0","1918.68","","","USD" "432","2025-10-16","","NASDAQ:NVDA","8","181.79","","0","1454.32","","","USD" "433","2025-11-11","","NASDAQ:NVDA","9","193.60","","0","1742.40","","","USD" ======================================================================================== FICHEIRO: transacoes.html Tamanho: 25559 bytes ======================================================================================== Base de dados de compras e vendas

Transações de Ações

Dados calculados automaticamente a partir do ficheiro de transações guardado no servidor.

+ Adicionar linha
Nº Data Compra Data Venda Nome da Ação Nº Ações V. Inicial V. Final Comissão Custo Inical Custo Final Ganho % Ganho Tx Compra Tx Venda Moeda Ativas
======================================================================================== FICHEIRO: verificar-revolut.html Tamanho: 28043 bytes ======================================================================================== Verificar Diferenças Revolut

🔠Verificar Diferenças Revolut

📊 Resumo

Resumo Caixa

Detalhes Caixa

📋 Detalhes das Diferenças

🔧 w Completo (Debug)

Clique em "Verificar" para ver os dados...
======================================================================================== FICHEIRO: verificar_diferencas_revolut.php Tamanho: 23201 bytes ======================================================================================== require_once __DIR__ . '/api/utilizador.php'; // getUserId() e userFilePath() vêm de api/utilizador.php function vistosLoad(): array { $path = userFilePath('transacoes-vistos.json'); if (!is_file($path)) return ['vistos' => []]; $raw = @file_get_contents($path); $j = json_decode((string)$raw, true); if (!is_array($j)) $j = []; $vistos = $j['vistos'] ?? []; if (!is_array($vistos)) $vistos = []; foreach (['alterarlinha', 'adicionartransacao', 'removertransacao'] as $t) { if (!isset($vistos[$t]) || !is_array($vistos[$t])) $vistos[$t] = []; } return ['vistos' => $vistos]; } function vistoCheck(array $vistos, string $tipo, string $id): bool { return isset($vistos['vistos'][$tipo]) && is_array($vistos['vistos'][$tipo]) && !empty($vistos['vistos'][$tipo][$id]); } function vistoIdLinha($linha): string { return 'L:' . trim((string)$linha); } // Ficheiros específicos do utilizador atual $ficheiroRevolut = userFilePath('extrato-revolut.csv'); $ficheiroTransacoes = userFilePath('transacoes-acoes.csv'); $ficheiroCaixa = userFilePath('movimentos-caixa.csv'); // Filtro opcional por ano (?ano=2020, 2021, ...) $anoFiltro = isset($_GET['ano']) && preg_match('/^\d{4}$/', $_GET['ano']) ? $_GET['ano'] : null; // Verificações iniciais if (!file_exists($ficheiroRevolut)) { echo json_encode([ 'ok' => false, 'error' => 'Extrato Revolut não encontrado para este utilizador. Importe primeiro o ficheiro (extrato-revolut.csv).', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if (!file_exists($ficheiroTransacoes)) { echo json_encode([ 'ok' => false, 'error' => 'Ficheiro de transações (transacoes-acoes.csv) não encontrado para este utilizador.', 'user' => getUserId() ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // FILTRO POR ANO function filtrarPorAno($items, $ano) { if (!$ano || empty($items)) return $items; return array_filter($items, function($item) use ($ano) { $camposData = ['data', 'dataCompra', 'dataVenda']; foreach ($camposData as $campo) { if (isset($item[$campo]) && !empty($item[$campo])) { if (preg_match('/^' . $ano . '[-\/]/', $item[$campo])) { return true; } } } return false; }); } // ✅ NORMALIZAR TICKER - VERSÃO COMPLETA COM TODOS OS MAPEAMENTOS function normalizarTicker($nomeAcao) { $n = strtoupper(trim($nomeAcao)); // ✅ MAPEAMENTO EXPLÃCITO DE ETFs if (strpos($n, 'IWDA') !== false || strpos($n, 'EUNL') !== false) { return 'IWDA'; } if (strpos($n, 'NDX') !== false || strpos($n, 'EXXT') !== false || strpos($n, 'EQQQ') !== false) { return 'EQQQ'; } // ✅ MAPEAMENTO DE AÇÕES ESPECÃFICAS $mapa = [ 'SQ' => 'SQ', // Block (Square) 'Z' => 'Z', // Zillow 'BRK.B' => 'BRKB', // Berkshire Hathaway 'BRKB' => 'BRKB', // Já normalizado 'AAPL' => 'AAPL', 'NVDA' => 'NVDA', 'TSLA' => 'TSLA', 'GOOGL' => 'GOOGL', 'AMZN' => 'AMZN', 'MSFT' => 'MSFT', 'TSM' => 'TSM', 'BAC' => 'BAC', 'O' => 'O', 'KO' => 'KO', ]; // Remove prefixos de bolsa $n = preg_replace('/^(NASDAQ|NYSE|INDEXNASDAQ|AMS):?/', '', $n); // Remove caracteres especiais e pontos $n = preg_replace('/[^A-Z0-9]/', '', $n); // Verifica se está no mapa if (isset($mapa[$n])) { return $mapa[$n]; } return $n; } // LER REVOLUT (extrato) function lerRevolut($ficheiro) { if (!file_exists($ficheiro)) { return ['error' => 'Ficheiro não encontrado: ' . basename($ficheiro)]; } $fh = fopen($ficheiro, 'r'); if (!$fh) { return ['error' => 'Erro ao abrir: ' . basename($ficheiro)]; } // Cabeçalho: // Date,Ticker,Type,Quantity,Price per share,Total Amount,Currency,FX Rate fgetcsv($fh, 0, ','); $movimentos = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 8) continue; $dataCompleta = trim($row[0]); $data = substr($dataCompleta, 0, 10); // YYYY-MM-DD $ticker = trim($row[1]); $tipo = trim($row[2]); $quantidade = trim($row[3]); $preco = trim($row[4]); $totalAmount = trim($row[5]); $moeda = trim($row[6]); $fxRaw = trim($row[7]); // Limpeza de valor total $valorLimpo = preg_replace('/[A-Z]{3}\s*/', '', $totalAmount); $valorLimpo = str_replace(',', '.', $valorLimpo); $valorNum = floatval($valorLimpo); // Limpeza de preço $precoLimpo = preg_replace('/[A-Z]{3}\s*/', '', $preco); $precoLimpo = str_replace(',', '.', $precoLimpo); $precoNum = floatval($precoLimpo); // FX rate $fxNum = $fxRaw !== '' ? floatval(str_replace(',', '.', $fxRaw)) : null; $movimentos[] = [ 'data' => $data, 'ticker' => strtoupper($ticker), 'tipo' => $tipo, 'quantidade' => floatval(str_replace(',', '.', $quantidade)), 'preco' => $precoNum, 'valor' => $valorNum, 'moeda' => $moeda, 'fx' => $fxNum, ]; } fclose($fh); return $movimentos; } // LER TRANSAÇÕES (formato novo: 11 colunas) function lerTransacoesAtuais($ficheiro) { if (!file_exists($ficheiro)) return []; $fh = fopen($ficheiro, 'r'); if (!$fh) return []; // Cabeçalho: Ordem,DataCompra,DataVenda,NomeAcao,NumAcoes,Comissoes, // CustoInicial,CustoFinal,TaxaCompra,TaxaVenda,Moeda fgetcsv($fh, 0, ','); $transacoes = []; while (($row = fgetcsv($fh, 0, ',')) !== false) { if (count($row) < 11) continue; $transacoes[] = [ 'ordem' => trim($row[0]), 'dataCompra' => trim($row[1]), 'dataVenda' => trim($row[2]), 'nomeAcao' => trim($row[3]), 'numAcoes' => floatval(str_replace(',', '.', $row[4])), 'comissoes' => floatval(str_replace(',', '.', $row[5])), 'custoInicial' => floatval(str_replace(',', '.', $row[6])), 'custoFinal' => floatval(str_replace(',', '.', $row[7])), 'taxaCompra' => isset($row[8]) ? floatval(str_replace(',', '.', $row[8])) : 0.0, 'taxaVenda' => isset($row[9]) ? floatval(str_replace(',', '.', $row[9])) : 0.0, 'moeda' => trim($row[10]), ]; } fclose($fh); return $transacoes; } // COMPARAR COM LÓGICA RESTRITIVA function compararDados($revolut, $transacoesAtuais, $vistos) { $diferencas = [ 'duplicatasexatas' => [], 'alterarlinha' => [], 'adicionartransacao' => [], 'removertransacao' => [], 'totais' => [ 'revolutcompras' => 0, 'revolutvendas' => 0, 'transacoestotal' => count($transacoesAtuais) ] ]; // Agrupar Revolut por ticker $revolutPorTicker = []; foreach ($revolut as $mov) { $ticker = strtoupper($mov['ticker']); if (!isset($revolutPorTicker[$ticker])) { $revolutPorTicker[$ticker] = ['compras' => [], 'vendas' => []]; } if (stripos($mov['tipo'], 'BUY') !== false) { $revolutPorTicker[$ticker]['compras'][] = $mov; $diferencas['totais']['revolutcompras']++; } elseif (stripos($mov['tipo'], 'SELL') !== false) { $revolutPorTicker[$ticker]['vendas'][] = $mov; $diferencas['totais']['revolutvendas']++; } } // Verificar cada transação do CSV foreach ($transacoesAtuais as $t) { $linhaId = vistoIdLinha($t['ordem']); $tickerNormalizado = normalizarTicker($t['nomeAcao']); if (!isset($revolutPorTicker[$tickerNormalizado])) { // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'removertransacao', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'] ?? '', 'status' => 'OK' ]; continue; } $diferencas['removertransacao'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Ticker não encontrado no Revolut (normalizado: ' . $tickerNormalizado . ')' ]; continue; } $comprasTicker = $revolutPorTicker[$tickerNormalizado]['compras']; $vendasTicker = $revolutPorTicker[$tickerNormalizado]['vendas']; // ✅ PROCURAR COMPRA (tolerância: 0 dias, 1€) $compraEncontrada = null; foreach ($comprasTicker as $compra) { $diasDiff = abs(strtotime($compra['data']) - strtotime($t['dataCompra'])) / 86400; $custoDiff = abs($compra['valor'] - $t['custoInicial']); if ($diasDiff <= 0 && $custoDiff <= 1) { $compraEncontrada = $compra; break; } } // ✅ PROCURAR VENDA (tolerância: 0 dias, 1€) $vendaEncontrada = null; $temDataVendaCSV = !empty($t['dataVenda']); if ($temDataVendaCSV) { foreach ($vendasTicker as $venda) { $diasDiff = abs(strtotime($venda['data']) - strtotime($t['dataVenda'])) / 86400; $custoDiff = abs($venda['valor'] - $t['custoFinal']); if ($diasDiff <= 0 && $custoDiff <= 1) { $vendaEncontrada = $venda; break; } } } // Se não existe compra no Revolut e (não há venda no CSV ou também não existe venda no Revolut), // então esta linha do CSV muito provavelmente não corresponde a nada no extrato => remover. $naoExisteCompra = ($compraEncontrada === null); $naoExisteVenda = ($temDataVendaCSV && $vendaEncontrada === null); if ($naoExisteCompra && (!$temDataVendaCSV || $naoExisteVenda)) { $diferencas['removertransacao'][] = [ 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'motivo' => 'Compra e venda não encontradas no Revolut. Provável linha extra no CSV.' ]; continue; } // ✅ ANÃLISE DE DIFERENÇAS (DETALHADA) $diferencasCount = 0; $detalhes = []; if ($compraEncontrada) { // Data compra if ($compraEncontrada['data'] !== $t['dataCompra']) { $diferencasCount++; $detalhes[] = "Data Compra: {$t['dataCompra']} → {$compraEncontrada['data']}"; } // Quantidade if (abs($compraEncontrada['quantidade'] - $t['numAcoes']) > 0.00001) { $diferencasCount++; $detalhes[] = "Qtd: {$t['numAcoes']} → {$compraEncontrada['quantidade']}"; } // Custo compra if (abs($compraEncontrada['valor'] - $t['custoInicial']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Compra: {$t['custoInicial']} € → {$compraEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "COMPRA não encontrada no Revolut"; } if ($temDataVendaCSV) { if ($vendaEncontrada) { // Data venda if ($vendaEncontrada['data'] !== $t['dataVenda']) { $diferencasCount++; $detalhes[] = "Data Venda: {$t['dataVenda']} → {$vendaEncontrada['data']}"; } // Custo venda if (abs($vendaEncontrada['valor'] - $t['custoFinal']) > 0.01) { $diferencasCount++; $detalhes[] = "Custo Venda: {$t['custoFinal']} € → {$vendaEncontrada['valor']} €"; } } else { $diferencasCount++; $detalhes[] = "VENDA não encontrada no Revolut"; } } // ✅ RESULTADO POR LINHA if ($diferencasCount === 0) { // Match perfeito $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $item = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'dataCompra' => $t['dataCompra'], 'dataVenda' => $t['dataVenda'], 'diferencas' => $diferencasCount, 'detalhes' => implode(' | ', $detalhes), 'valoratualcompra' => $t['custoInicial'], 'valoratualvenda' => $t['custoFinal'], 'sugestaocompra' => null, 'sugestaovenda' => null ]; // Se esta linha já foi marcada como "Visto", passa a OK e não aparece como pendente if (vistoCheck($vistos, 'alterarlinha', $linhaId)) { $diferencas['duplicatasexatas'][] = [ 'id' => $linhaId, 'linha' => $t['ordem'], 'acao' => $t['nomeAcao'], 'data' => $t['dataCompra'], 'status' => 'OK' ]; } else { $diferencas['alterarlinha'][] = $item; } } // <-- ESTA chaveta é a que te falta (fecha o else do diferencasCount) } // fecha foreach ($transacoesAtuais as $t) return $diferencas; } // ========================== // NOVO: COMPARAR CAIXA // movimentos-caixa.csv <-> extrato-revolut.csv (CASH TOP-UP / CASH WITHDRAWAL / DIVIDEND / FEES) // ========================== function fnum_local($v): float { if ($v === null) return 0.0; $s = trim((string)$v); if ($s === '') return 0.0; $s = str_replace([' ', "\t"], '', $s); // Se vier "USD -1.25" ou "EUR 493.36" $s = preg_replace('/^[A-Z]{3}/', '', $s); $s = trim($s); // vírgulas para ponto $s = str_replace(',', '.', $s); $n = (float)$s; return is_finite($n) ? $n : 0.0; } function normCaixaTipo($tipo): string { $t = mb_strtolower(trim((string)$tipo), 'UTF-8'); // Fallback manual (caso iconv falhe ou não exista translit completo) $t = strtr($t, [ 'á'=>'a','à'=>'a','â'=>'a','ã'=>'a', 'é'=>'e','ê'=>'e', 'í'=>'i', 'ó'=>'o','ô'=>'o','õ'=>'o', 'ú'=>'u', 'ç'=>'c' ]); // Tentar translit (se funcionar, melhora ainda mais) $tt = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $t); if ($tt !== false && $tt !== null && $tt !== '') { $t = $tt; } $t = preg_replace('/[^a-z0-9]+/', ' ', (string)$t); // Depósito (apanha "deposito", "deposit", "top up", "cash top-up", etc.) if (strpos($t, 'depos') !== false || strpos($t, 'deposit') !== false || strpos($t, 'top up') !== false || strpos($t, 'topup') !== false || strpos($t, 'cash top up') !== false || strpos($t, 'cash topup') !== false) { return 'Depósito'; } if (strpos($t, 'levant') !== false || strpos($t, 'withdraw') !== false) return 'Levantamento'; if (strpos($t, 'divid') !== false || strpos($t, 'dividend') !== false) return 'Dividendo'; return 'Outros'; } function mapRevolutCashTypeToCaixaTipo(string $type): ?string { $t = strtoupper(trim($type)); if ($t === '') return null; // Tipos típicos vistos no extrato if (strpos($t, 'CASH TOP-UP') !== false) return 'Depósito'; if (strpos($t, 'CASH WITHDRAWAL') !== false) return 'Levantamento'; if (strpos($t, 'DIVIDEND') !== false) return 'Dividendo'; // Fees e afins if (strpos($t, 'FEE') !== false || strpos($t, 'TAX') !== false || strpos($t, 'COMMISSION') !== false) return 'Outros'; if (strpos($t, 'CUSTODY FEE') !== false) return 'Outros'; return null; // não é movimento de caixa que nos interesse aqui } function filtrarRevolutCaixa(array $revolutMovs): array { $out = []; foreach ($revolutMovs as $m) { $type = (string)($m['tipo'] ?? ''); $tipoCaixa = mapRevolutCashTypeToCaixaTipo($type); if ($tipoCaixa === null) continue; $data = (string)($m['data'] ?? ''); $moeda = strtoupper(trim((string)($m['moeda'] ?? ''))); $valor = (float)($m['valor'] ?? 0.0); $ticker = trim((string)($m['ticker'] ?? '')); $descricao = strtoupper(trim($type)); if ($ticker !== '' && strpos($descricao, 'DIVIDEND') !== false) { $descricao = $ticker . ' DIVIDEND'; } $out[] = [ 'data' => $data, 'tipo' => $tipoCaixa, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $descricao, ]; } return $out; } function lerMovimentosCaixaCSV(string $ficheiroCaixa): array { if (!file_exists($ficheiroCaixa)) return ['_erro' => 'movimentos-caixa.csv não encontrado.']; $fh = fopen($ficheiroCaixa, 'r'); if (!$fh) return ['_erro' => 'Não foi possível abrir movimentos-caixa.csv.']; $cab = fgetcsv($fh, 0, ','); // Ordem,Data,Tipo,Valor,Moeda,Descricao $rows = []; while (($r = fgetcsv($fh, 0, ',')) !== false) { if (count($r) < 6) continue; $ordem = trim((string)$r[0]); $data = substr(trim((string)$r[1]), 0, 10); $tipo = normCaixaTipo($r[2] ?? ''); $valor = fnum_local($r[3] ?? 0); $moeda = strtoupper(trim((string)($r[4] ?? ''))); $desc = trim((string)($r[5] ?? '')); if ($data === '' || strlen($data) < 10) continue; $rows[] = [ 'ordem' => $ordem, 'data' => $data, 'tipo' => $tipo, 'valor' => $valor, 'moeda' => $moeda, 'descricao' => $desc, ]; } fclose($fh); return $rows; } function compararCaixaComRevolut(array $revolutMovs, string $ficheiroCaixa): array { $revCaixa = filtrarRevolutCaixa($revolutMovs); $caixaCsv = lerMovimentosCaixaCSV($ficheiroCaixa); if (isset($caixaCsv['_erro'])) { return [ 'resumo' => ['duplicatas' => 0, 'alterar' => 0, 'adicionar' => 0, 'remover' => 0], 'detalhes' => ['duplicatasexatas' => [], 'alterarlinha' => [], 'adicionar' => [], 'remover' => []], 'aviso' => $caixaCsv['_erro'], ]; } // Vamos “consumir†linhas do CSV à medida que casam, para evitar reuso. $usado = array_fill(0, count($caixaCsv), false); $duplicatas = []; $alterar = []; $adicionar = []; $remover = []; // 1) Revolut -> procurar no movimentos-caixa.csv foreach ($revCaixa as $rc) { $matchIdx = null; $match = null; // Tentativa A: data + moeda + valor (tolerância) for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $c = $caixaCsv[$i]; if ($c['moeda'] !== $rc['moeda']) continue; $dias = abs(strtotime($c['data']) - strtotime($rc['data'])) / 86400; if ($dias > 0) continue; if (abs(((float)$c['valor']) - ((float)$rc['valor'])) > 0.01) continue; $matchIdx = $i; $match = $c; break; } if ($matchIdx === null) { $adicionar[] = [ 'origem' => 'Revolut', 'motivo' => 'Movimento de caixa não encontrado em movimentos-caixa.csv', 'sugestao' => $rc, ]; continue; } $usado[$matchIdx] = true; // Comparar tipo (e opcionalmente descrição) $diffs = []; if ($match['tipo'] !== $rc['tipo']) { $diffs[] = "Tipo: CSV={$match['tipo']} vs Revolut={$rc['tipo']}"; } if (count($diffs) === 0) { $duplicatas[] = [ 'data' => $rc['data'], 'tipo' => $rc['tipo'], 'valor' => $rc['valor'], 'moeda' => $rc['moeda'], 'status' => 'OK', ]; } else { $alterar[] = [ 'linha' => $match['ordem'], 'data' => $rc['data'], 'diferencas' => count($diffs), 'detalhes' => implode(' | ', $diffs), 'csv' => $match, 'revolut' => $rc, ]; } } // 2) Tudo o que ficou no CSV sem match -> remover/rever for ($i = 0; $i < count($caixaCsv); $i++) { if ($usado[$i]) continue; $remover[] = [ 'origem' => 'CSV', 'linha' => $caixaCsv[$i]['ordem'], 'motivo' => 'Movimento existe em movimentos-caixa.csv mas não aparece no extrato Revolut (tipos de caixa)', 'csv' => $caixaCsv[$i], ]; } return [ 'resumo' => [ 'duplicatas' => count($duplicatas), 'alterar' => count($alterar), 'adicionar' => count($adicionar), 'remover' => count($remover), ], 'detalhes' => [ 'duplicatasexatas' => $duplicatas, 'alterarlinha' => $alterar, 'adicionar' => $adicionar, 'remover' => $remover, ], ]; } $revolut = lerRevolut($ficheiroRevolut); if (isset($revolut['error'])) { echo json_encode(['ok' => false, 'error' => $revolut['error'], 'user' => getUserId()], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } // Normalizar tickers do Revolut para casar com normalizarTicker() foreach ($revolut as &$m) { if (isset($m['ticker']) && $m['ticker'] !== '') { $m['ticker'] = normalizarTicker($m['ticker']); } } unset($m); $revolut = filtrarPorAno($revolut, $anoFiltro); $transacoesAtuais = lerTransacoesAtuais($ficheiroTransacoes); $transacoesAtuais = filtrarPorAno($transacoesAtuais, $anoFiltro); $vistos = vistosLoad(); $diferencas = compararDados($revolut, $transacoesAtuais, $vistos); // --- NOVO: comparar CAIXA (movimentos-caixa.csv) com extrato-revolut.csv --- $caixaDiff = compararCaixaComRevolut($revolut, $ficheiroCaixa); echo json_encode([ 'ok' => true, 'ficheirorevolut' => basename($ficheiroRevolut), 'utilizador' => getUserId(), 'anofiltro' => $anoFiltro ? $anoFiltro : 'TODOS', 'dataverificacao' => date('Y-m-d H:i:s'), // (mantém o resumo/detalhes das AÇÕES como está no teu ficheiro) 'resumo' => [ 'duplicatas' => count($diferencas['duplicatasexatas'] ?? []), 'alterar' => count($diferencas['alterarlinha'] ?? []), 'adicionar' => count($diferencas['adicionartransacao'] ?? []), 'remover' => count($diferencas['removertransacao'] ?? []), ], 'detalhes' => $diferencas, // --- NOVO: resultados de CAIXA --- 'caixa' => $caixaDiff, ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; ======================================================================================== 🎉 EXPORTAÇÃO CONCLUÃDA! ========================================================================================