mtcli 3.8.0.dev3__tar.gz → 3.8.0.dev4__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 (80) hide show
  1. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/PKG-INFO +1 -1
  2. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/cli.py +0 -13
  3. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/database.py +14 -32
  4. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/marketdata/tick_repository.py +14 -23
  5. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/marketdata/tick_streamer.py +0 -13
  6. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/pyproject.toml +1 -1
  7. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/LICENSE +0 -0
  8. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/README.md +0 -0
  9. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/__init__.py +0 -0
  10. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/commands/__init__.py +0 -0
  11. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/commands/bars.py +0 -0
  12. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/commands/conf.py +0 -0
  13. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/commands/doctor.py +0 -0
  14. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/commands/migrate.py +0 -0
  15. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/conecta.py +0 -0
  16. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/conf.py +0 -0
  17. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/config_registre.py +0 -0
  18. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/data/__init__.py +0 -0
  19. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/data/base.py +0 -0
  20. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/data/csv.py +0 -0
  21. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/data/mt5.py +0 -0
  22. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/domain/__init__.py +0 -0
  23. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/domain/timeframe.py +0 -0
  24. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/logger.py +0 -0
  25. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/marketdata/__init__.py +0 -0
  26. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/marketdata/tick_cache.py +0 -0
  27. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/marketdata/tick_engine.py +0 -0
  28. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/migrations/001_initial_schema.py +0 -0
  29. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/migrations/002_ticks_time_msc.py +0 -0
  30. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/migrations/003_optimize_ticks_without_rowid.py +0 -0
  31. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/migrations/__init__.py +0 -0
  32. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/migrations/runner.py +0 -0
  33. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/__init__.py +0 -0
  34. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/bar_model.py +0 -0
  35. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/bars_model.py +0 -0
  36. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/chart_model.py +0 -0
  37. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/conf_model.py +0 -0
  38. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/consecutive_bars_model.py +0 -0
  39. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/rates_model.py +0 -0
  40. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/signals_model.py +0 -0
  41. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/models/unconsecutive_bar_model.py +0 -0
  42. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/mt5_context.py +0 -0
  43. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugin.py +0 -0
  44. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugin_loader.py +0 -0
  45. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugin_manager.py +0 -0
  46. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/__init__.py +0 -0
  47. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/exemplo.py-dist +0 -0
  48. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/__init__.py +0 -0
  49. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/cli.py +0 -0
  50. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/conf.py +0 -0
  51. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/models/__init__.py +0 -0
  52. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/models/model_media_movel.py +0 -0
  53. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/tests/__init__.py +0 -0
  54. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/tests/test_mm.py +0 -0
  55. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/media_movel/tests/test_model_media_movel.py +0 -0
  56. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/range_medio/__init__.py +0 -0
  57. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/range_medio/cli.py +0 -0
  58. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/range_medio/conf.py +0 -0
  59. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/range_medio/models/__init__.py +0 -0
  60. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/range_medio/models/average_range_model.py +0 -0
  61. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/range_medio/tests/__init__.py +0 -0
  62. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/range_medio/tests/test_rm.py +0 -0
  63. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/volume_medio/__init__.py +0 -0
  64. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/volume_medio/cli.py +0 -0
  65. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/volume_medio/conf.py +0 -0
  66. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/volume_medio/models/__init__.py +0 -0
  67. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/volume_medio/models/model_average_volume.py +0 -0
  68. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/volume_medio/tests/__init__.py +0 -0
  69. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/plugins/volume_medio/tests/test_vm.py +0 -0
  70. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/__init__.py +0 -0
  71. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/close_view.py +0 -0
  72. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/full_view.py +0 -0
  73. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/high_view.py +0 -0
  74. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/low_view.py +0 -0
  75. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/min_view.py +0 -0
  76. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/open_view.py +0 -0
  77. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/ranges_view.py +0 -0
  78. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/rates_view.py +0 -0
  79. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/mtcli/views/vars_view.py +0 -0
  80. {mtcli-3.8.0.dev3 → mtcli-3.8.0.dev4}/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.dev3
3
+ Version: 3.8.0.dev4
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
@@ -21,13 +21,6 @@ _tick_streamer = None
21
21
 
22
22
 
23
23
  def start_tick_capture():
24
- """
25
- Inicia captura contínua de ticks em background.
26
-
27
- O símbolo deve ser definido via variável:
28
-
29
- MTCLI_SYMBOL=WINJ26
30
- """
31
24
 
32
25
  global _tick_streamer
33
26
 
@@ -65,9 +58,6 @@ def start_tick_capture():
65
58
  @click.version_option(package_name="mtcli")
66
59
  @click.pass_context
67
60
  def mt(ctx):
68
- """
69
- CLI principal do mtcli.
70
- """
71
61
 
72
62
  start_tick_capture()
73
63
 
@@ -87,9 +77,6 @@ logger.info("Plugins carregados: %s", loaded_plugins)
87
77
 
88
78
  @mt.command(name="plugins")
89
79
  def list_plugins():
90
- """
91
- Lista os plugins carregados.
92
- """
93
80
 
94
81
  if not loaded_plugins:
95
82
  click.echo("Nenhum plugin carregado.")
@@ -15,28 +15,23 @@ from pathlib import Path
15
15
  from datetime import datetime
16
16
  from .conf import DB_NAME
17
17
 
18
+
18
19
  DB_PATH = Path.home() / ".mtcli" / DB_NAME
19
20
  BACKUP_DIR = Path.home() / ".mtcli" / "backups"
20
21
 
22
+ _connection = None
23
+
21
24
 
22
25
  def get_connection():
23
26
  """
24
- Cria ou retorna uma conexão SQLite otimizada para ingestão
25
- contínua de ticks de mercado.
26
-
27
- Configurações aplicadas:
27
+ Retorna conexão singleton SQLite otimizada para ingestão
28
+ contínua de ticks.
29
+ """
28
30
 
29
- - WAL (Write Ahead Logging)
30
- - synchronous=NORMAL
31
- - temp_store em memória
32
- - mmap para leitura rápida
33
- - cache expandido
31
+ global _connection
34
32
 
35
- Returns
36
- -------
37
- sqlite3.Connection
38
- Conexão ativa com o banco SQLite.
39
- """
33
+ if _connection:
34
+ return _connection
40
35
 
41
36
  DB_PATH.parent.mkdir(parents=True, exist_ok=True)
42
37
  BACKUP_DIR.mkdir(parents=True, exist_ok=True)
@@ -50,6 +45,9 @@ def get_connection():
50
45
  conn.execute("PRAGMA cache_size=-200000")
51
46
  conn.execute("PRAGMA journal_size_limit=67108864")
52
47
 
48
+ # checkpoint automático
49
+ conn.execute("PRAGMA wal_autocheckpoint=1000")
50
+
53
51
  conn.execute("""
54
52
  CREATE TABLE IF NOT EXISTS schema_migrations(
55
53
  version INTEGER PRIMARY KEY,
@@ -59,22 +57,9 @@ def get_connection():
59
57
 
60
58
  conn.commit()
61
59
 
62
- return conn
63
-
60
+ _connection = conn
64
61
 
65
- # ==========================================================
66
- # CHECKPOINT
67
- # ==========================================================
68
-
69
- def wal_checkpoint(conn):
70
- """
71
- Executa checkpoint do WAL.
72
-
73
- Move os dados do arquivo `.wal` para o banco principal
74
- e reduz seu tamanho.
75
- """
76
-
77
- conn.execute("PRAGMA wal_checkpoint(TRUNCATE)")
62
+ return conn
78
63
 
79
64
 
80
65
  # ==========================================================
@@ -84,9 +69,6 @@ def wal_checkpoint(conn):
84
69
  def backup_database(conn):
85
70
  """
86
71
  Realiza backup diário seguro do banco SQLite.
87
-
88
- O backup utiliza a API nativa do SQLite,
89
- permitindo cópia consistente mesmo com o banco em uso.
90
72
  """
91
73
 
92
74
  now = datetime.now().strftime("%Y%m%d")
@@ -5,13 +5,13 @@ Responsável por:
5
5
 
6
6
  - Persistir ticks no SQLite
7
7
  - Sincronizar histórico inicial
8
- - Consultas rápidas para engines (Renko etc)
8
+ - Consultas rápidas para engines
9
9
  """
10
10
 
11
11
  import MetaTrader5 as mt5
12
12
  from datetime import datetime, timedelta
13
13
 
14
- from ..database import get_connection, wal_checkpoint, backup_database
14
+ from ..database import get_connection, backup_database
15
15
  from .tick_cache import TickCache
16
16
  from mtcli.mt5_context import mt5_conexao
17
17
 
@@ -25,7 +25,6 @@ class TickRepository:
25
25
  self.conn = get_connection()
26
26
  self.cache = TickCache()
27
27
 
28
- self.insert_counter = 0
29
28
  self.last_backup_day = None
30
29
 
31
30
  # ==========================================================
@@ -33,9 +32,6 @@ class TickRepository:
33
32
  # ==========================================================
34
33
 
35
34
  def sync(self, symbol: str, days_back: int = 1):
36
- """
37
- Sincroniza histórico de ticks a partir do broker.
38
- """
39
35
 
40
36
  total_inserted = 0
41
37
 
@@ -84,6 +80,8 @@ class TickRepository:
84
80
  self.conn.rollback()
85
81
  raise
86
82
 
83
+ self._daily_backup()
84
+
87
85
  return total_inserted
88
86
 
89
87
  # ==========================================================
@@ -119,23 +117,7 @@ class TickRepository:
119
117
  data,
120
118
  )
121
119
 
122
- inserted = len(data)
123
-
124
- self.insert_counter += inserted
125
-
126
- if self.insert_counter >= 200000:
127
-
128
- wal_checkpoint(self.conn)
129
- self.insert_counter = 0
130
-
131
- today = datetime.now().date()
132
-
133
- if self.last_backup_day != today:
134
-
135
- backup_database(self.conn)
136
- self.last_backup_day = today
137
-
138
- return inserted
120
+ return len(data)
139
121
 
140
122
  # ==========================================================
141
123
  # CONSULTAS
@@ -199,3 +181,12 @@ class TickRepository:
199
181
  result = cursor.fetchone()
200
182
 
201
183
  return result[0] if result and result[0] else None
184
+
185
+ def _daily_backup(self):
186
+
187
+ today = datetime.now().date()
188
+
189
+ if self.last_backup_day != today:
190
+
191
+ backup_database(self.conn)
192
+ self.last_backup_day = today
@@ -1,10 +1,5 @@
1
1
  """
2
2
  Captura contínua de ticks.
3
-
4
- Objetivo:
5
-
6
- - eliminar dependência do histórico do broker
7
- - manter histórico próprio
8
3
  """
9
4
 
10
5
  import time
@@ -21,13 +16,9 @@ class TickStreamer:
21
16
 
22
17
  self.symbol = symbol
23
18
  self.repo = TickRepository()
24
-
25
19
  self.running = False
26
20
 
27
21
  def start(self):
28
- """
29
- Inicia captura contínua de ticks.
30
- """
31
22
 
32
23
  self.running = True
33
24
 
@@ -69,7 +60,3 @@ class TickStreamer:
69
60
  self.repo.conn.rollback()
70
61
 
71
62
  start = int(ticks[-1]["time_msc"]) + 1
72
-
73
- def stop(self):
74
-
75
- self.running = False
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mtcli"
3
- version = "3.8.0.dev3"
3
+ version = "3.8.0.dev4"
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