mtcli 3.5.0.dev2__tar.gz → 3.5.0.dev3__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.
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/PKG-INFO +1 -1
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/marketdata/tick_repository.py +42 -26
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/pyproject.toml +1 -1
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/LICENSE +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/README.md +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/commands/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/commands/bars.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/commands/conf.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/commands/logs.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/conecta.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/conf.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/data/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/data/base.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/data/csv.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/data/mt5.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/database.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/domain/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/domain/timeframe.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/logger.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/marketdata/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/marketdata/tick_cache.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/bar_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/bars_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/chart_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/conf_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/consecutive_bars_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/rates_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/signals_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/models/unconsecutive_bar_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/mt.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/mt5_context.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugin.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/command.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/conf.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/models/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/models/model_media_movel.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/tests/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/tests/test_mm.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/tests/test_model_media_movel.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/command.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/conf.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/models/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/models/average_range_model.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/tests/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/tests/test_rm.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/command.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/conf.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/models/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/models/model_average_volume.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/tests/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/tests/test_vm.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/__init__.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/close_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/full_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/high_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/low_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/min_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/open_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/ranges_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/rates_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/vars_view.py +0 -0
- {mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/views/volumes_view.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
TickRepository
|
|
2
|
+
TickRepository profissional com:
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
4
|
+
- Paginação automática
|
|
5
|
+
- Sincronização incremental robusta
|
|
6
|
+
- Integração com mt5_conexao
|
|
7
|
+
- Proteção contra loops infinitos
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
import MetaTrader5 as mt5
|
|
@@ -17,56 +17,72 @@ from mtcli.mt5_context import mt5_conexao
|
|
|
17
17
|
|
|
18
18
|
class TickRepository:
|
|
19
19
|
|
|
20
|
+
BATCH_SIZE = 200000 # tamanho seguro por lote
|
|
21
|
+
|
|
20
22
|
def __init__(self):
|
|
21
23
|
self.conn = get_connection()
|
|
22
24
|
self.cache = TickCache()
|
|
23
25
|
|
|
24
26
|
# ============================================================
|
|
25
|
-
# SINCRONIZAÇÃO
|
|
27
|
+
# SINCRONIZAÇÃO COM PAGINAÇÃO
|
|
26
28
|
# ============================================================
|
|
27
29
|
|
|
28
30
|
def sync(self, symbol: str, days_back: int = 1):
|
|
29
31
|
"""
|
|
30
|
-
Sincroniza banco com MT5.
|
|
32
|
+
Sincroniza banco com MT5 usando paginação.
|
|
31
33
|
|
|
32
|
-
Busca
|
|
34
|
+
Busca todos os ticks disponíveis desde o último timestamp.
|
|
33
35
|
"""
|
|
34
36
|
|
|
37
|
+
total_inserted = 0
|
|
38
|
+
|
|
35
39
|
with mt5_conexao():
|
|
36
40
|
|
|
37
41
|
last_time = self._get_last_tick_time(symbol)
|
|
38
42
|
|
|
39
43
|
if last_time:
|
|
40
|
-
start = datetime.fromtimestamp(last_time)
|
|
44
|
+
start = datetime.fromtimestamp(last_time + 1)
|
|
41
45
|
else:
|
|
42
46
|
start = datetime.now() - timedelta(days=days_back)
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
while True:
|
|
49
|
+
|
|
50
|
+
ticks = mt5.copy_ticks_from(
|
|
51
|
+
symbol,
|
|
52
|
+
start,
|
|
53
|
+
self.BATCH_SIZE,
|
|
54
|
+
mt5.COPY_TICKS_ALL,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
if ticks is None or len(ticks) == 0:
|
|
58
|
+
break
|
|
59
|
+
|
|
60
|
+
inserted = self._insert_ticks(symbol, ticks)
|
|
61
|
+
total_inserted += inserted
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
return 0
|
|
63
|
+
self.cache.add_many(ticks)
|
|
53
64
|
|
|
54
|
-
|
|
55
|
-
|
|
65
|
+
# Atualiza início para próximo tick
|
|
66
|
+
ultimo_timestamp = int(ticks[-1]["time"])
|
|
67
|
+
novo_start = datetime.fromtimestamp(ultimo_timestamp + 1)
|
|
56
68
|
|
|
57
|
-
|
|
69
|
+
# Proteção contra loop infinito
|
|
70
|
+
if novo_start <= start:
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
start = novo_start
|
|
74
|
+
|
|
75
|
+
# Se retornou menos que o batch, acabou histórico
|
|
76
|
+
if len(ticks) < self.BATCH_SIZE:
|
|
77
|
+
break
|
|
78
|
+
|
|
79
|
+
return total_inserted
|
|
58
80
|
|
|
59
81
|
# ============================================================
|
|
60
82
|
# INSERÇÃO
|
|
61
83
|
# ============================================================
|
|
62
84
|
|
|
63
85
|
def _insert_ticks(self, symbol, ticks):
|
|
64
|
-
"""
|
|
65
|
-
Insere ticks no SQLite.
|
|
66
|
-
|
|
67
|
-
O retorno do MT5 é numpy structured array.
|
|
68
|
-
Acesso deve ser por campo: t["time"], t["last"], etc.
|
|
69
|
-
"""
|
|
70
86
|
|
|
71
87
|
cursor = self.conn.cursor()
|
|
72
88
|
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/media_movel/tests/test_model_media_movel.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/range_medio/models/average_range_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mtcli-3.5.0.dev2 → mtcli-3.5.0.dev3}/mtcli/plugins/volume_medio/models/model_average_volume.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|