mtcli 3.8.0.dev8__tar.gz → 3.8.0.dev9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/PKG-INFO +1 -1
  2. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/database.py +1 -1
  3. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/marketdata/tick_repository.py +2 -3
  4. mtcli-3.8.0.dev9/mtcli/migrations/007_deduplicate_ticks_and_add_unique_index.py +91 -0
  5. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/pyproject.toml +1 -1
  6. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/LICENSE +0 -0
  7. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/README.md +0 -0
  8. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/__init__.py +0 -0
  9. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/__main__.py +0 -0
  10. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/cli.py +0 -0
  11. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/cli_dev.py +0 -0
  12. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/commands/__init__.py +0 -0
  13. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/commands/bars.py +0 -0
  14. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/commands/conf.py +0 -0
  15. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/commands/doctor.py +0 -0
  16. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/commands/ticks.py +0 -0
  17. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/commands_dev/__init__.py +0 -0
  18. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/commands_dev/migrate.py +0 -0
  19. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/conecta.py +0 -0
  20. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/conf.py +0 -0
  21. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/config_registre.py +0 -0
  22. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/data/__init__.py +0 -0
  23. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/data/base.py +0 -0
  24. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/data/csv.py +0 -0
  25. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/data/mt5.py +0 -0
  26. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/domain/__init__.py +0 -0
  27. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/domain/timeframe.py +0 -0
  28. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/logger.py +0 -0
  29. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/marketdata/__init__.py +0 -0
  30. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/marketdata/tick_cache.py +0 -0
  31. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/marketdata/tick_engine.py +0 -0
  32. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/001_initial_schema.py +0 -0
  33. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/002_ticks_time_msc.py +0 -0
  34. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/003_optimize_ticks_without_rowid.py +0 -0
  35. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/004_ticks_pk_time_msc.py +0 -0
  36. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/005_tick_price_compression.py +0 -0
  37. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/006_add_index_ticks_symbol_time.py +0 -0
  38. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/__init__.py +0 -0
  39. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/__main__.py +0 -0
  40. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/migrations/runner.py +0 -0
  41. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/__init__.py +0 -0
  42. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/bar_model.py +0 -0
  43. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/bars_model.py +0 -0
  44. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/chart_model.py +0 -0
  45. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/conf_model.py +0 -0
  46. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/consecutive_bars_model.py +0 -0
  47. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/rates_model.py +0 -0
  48. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/signals_model.py +0 -0
  49. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/models/unconsecutive_bar_model.py +0 -0
  50. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/mt5_context.py +0 -0
  51. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugin.py +0 -0
  52. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugin_loader.py +0 -0
  53. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugin_manager.py +0 -0
  54. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/__init__.py +0 -0
  55. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/exemplo.py-dist +0 -0
  56. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/__init__.py +0 -0
  57. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/cli.py +0 -0
  58. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/conf.py +0 -0
  59. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/models/__init__.py +0 -0
  60. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/models/model_media_movel.py +0 -0
  61. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/tests/__init__.py +0 -0
  62. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/tests/test_mm.py +0 -0
  63. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/media_movel/tests/test_model_media_movel.py +0 -0
  64. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/range_medio/__init__.py +0 -0
  65. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/range_medio/cli.py +0 -0
  66. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/range_medio/conf.py +0 -0
  67. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/range_medio/models/__init__.py +0 -0
  68. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/range_medio/models/average_range_model.py +0 -0
  69. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/range_medio/tests/__init__.py +0 -0
  70. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/range_medio/tests/test_rm.py +0 -0
  71. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/volume_medio/__init__.py +0 -0
  72. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/volume_medio/cli.py +0 -0
  73. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/volume_medio/conf.py +0 -0
  74. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/volume_medio/models/__init__.py +0 -0
  75. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/volume_medio/models/model_average_volume.py +0 -0
  76. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/volume_medio/tests/__init__.py +0 -0
  77. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/plugins/volume_medio/tests/test_vm.py +0 -0
  78. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/__init__.py +0 -0
  79. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/close_view.py +0 -0
  80. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/full_view.py +0 -0
  81. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/high_view.py +0 -0
  82. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/low_view.py +0 -0
  83. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/min_view.py +0 -0
  84. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/open_view.py +0 -0
  85. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/ranges_view.py +0 -0
  86. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/rates_view.py +0 -0
  87. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/vars_view.py +0 -0
  88. {mtcli-3.8.0.dev8 → mtcli-3.8.0.dev9}/mtcli/views/volumes_view.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mtcli
3
- Version: 3.8.0.dev8
3
+ Version: 3.8.0.dev9
4
4
  Summary: Aplicativo CLI para exibir gráficos do MetaTrader 5 screen reader friendly
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -41,7 +41,7 @@ def get_connection():
41
41
  conn.execute("PRAGMA journal_mode=WAL")
42
42
  conn.execute("PRAGMA synchronous=NORMAL")
43
43
  conn.execute("PRAGMA temp_store=MEMORY")
44
- conn.execute("PRAGMA mmap_size=268435456")
44
+ conn.execute("PRAGMA mmap_size=30000000000")
45
45
  conn.execute("PRAGMA cache_size=-200000")
46
46
  conn.execute("PRAGMA journal_size_limit=67108864")
47
47
  conn.execute("PRAGMA read_uncommitted = TRUE")
@@ -114,7 +114,7 @@ class TickRepository:
114
114
 
115
115
  cursor.executemany(
116
116
  """
117
- INSERT INTO ticks(
117
+ INSERT OR IGNORE INTO ticks(
118
118
  symbol,
119
119
  time_msc,
120
120
  bid,
@@ -124,12 +124,11 @@ class TickRepository:
124
124
  flags
125
125
  )
126
126
  VALUES (?,?,?,?,?,?,?)
127
- ON CONFLICT(symbol,time_msc) DO NOTHING
128
127
  """,
129
128
  data,
130
129
  )
131
130
 
132
- return len(data)
131
+ return cursor.rowcount
133
132
 
134
133
  # ==========================================================
135
134
  # CONSULTAS
@@ -0,0 +1,91 @@
1
+ """
2
+ Migration 007
3
+
4
+ Objetivo
5
+ --------
6
+
7
+ 1. Remover registros duplicados da tabela `ticks`
8
+ 2. Criar índice UNIQUE para evitar duplicação futura
9
+
10
+ Critério de unicidade adotado:
11
+
12
+ (symbol, time_msc)
13
+
14
+ Estratégia
15
+ ----------
16
+
17
+ 1. Criar tabela temporária com SELECT DISTINCT
18
+ 2. Copiar dados únicos
19
+ 3. Substituir tabela original
20
+ 4. Criar índice UNIQUE
21
+
22
+ Essa estratégia é muito mais rápida do que DELETE em tabelas grandes.
23
+ """
24
+
25
+ from sqlite3 import Connection
26
+
27
+
28
+ def upgrade(conn: Connection) -> None:
29
+ cursor = conn.cursor()
30
+
31
+ # ---------------------------------------------------------
32
+ # 1 - criar nova tabela sem duplicados
33
+ # ---------------------------------------------------------
34
+
35
+ cursor.execute(
36
+ """
37
+ CREATE TABLE IF NOT EXISTS ticks_new AS
38
+ SELECT DISTINCT *
39
+ FROM ticks
40
+ """
41
+ )
42
+
43
+ # ---------------------------------------------------------
44
+ # 2 - remover tabela antiga
45
+ # ---------------------------------------------------------
46
+
47
+ cursor.execute("DROP TABLE ticks")
48
+
49
+ # ---------------------------------------------------------
50
+ # 3 - renomear tabela nova
51
+ # ---------------------------------------------------------
52
+
53
+ cursor.execute("ALTER TABLE ticks_new RENAME TO ticks")
54
+
55
+ # ---------------------------------------------------------
56
+ # 4 - recriar índice de performance existente
57
+ # ---------------------------------------------------------
58
+
59
+ cursor.execute(
60
+ """
61
+ CREATE INDEX IF NOT EXISTS idx_ticks_symbol_time
62
+ ON ticks(symbol, time_msc)
63
+ """
64
+ )
65
+
66
+ # ---------------------------------------------------------
67
+ # 5 - criar índice UNIQUE
68
+ # ---------------------------------------------------------
69
+
70
+ cursor.execute(
71
+ """
72
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_ticks_unique
73
+ ON ticks(symbol, time_msc)
74
+ """
75
+ )
76
+
77
+ conn.commit()
78
+
79
+
80
+ def downgrade(conn: Connection) -> None:
81
+ cursor = conn.cursor()
82
+
83
+ # Remove índice UNIQUE caso exista rollback
84
+
85
+ cursor.execute(
86
+ """
87
+ DROP INDEX IF EXISTS idx_ticks_unique
88
+ """
89
+ )
90
+
91
+ conn.commit()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mtcli"
3
- version = "3.8.0.dev8"
3
+ version = "3.8.0.dev9"
4
4
  description = "Aplicativo CLI para exibir gráficos do MetaTrader 5 screen reader friendly"
5
5
  authors = [
6
6
  {name = "Valmir França",email = "vfranca3@gmail.com"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes