mtcli 3.7.0.dev0__tar.gz → 3.7.0.dev2__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.7.0.dev0 → mtcli-3.7.0.dev2}/PKG-INFO +1 -1
- mtcli-3.7.0.dev2/mtcli/plugin_loader.py +147 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/pyproject.toml +1 -1
- mtcli-3.7.0.dev0/mtcli/plugin_loader.py +0 -81
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/LICENSE +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/README.md +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/cli.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/commands/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/commands/bars.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/commands/conf.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/conecta.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/conf.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/config_registre.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/data/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/data/base.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/data/csv.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/data/mt5.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/database.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/domain/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/domain/timeframe.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/logger.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/marketdata/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/marketdata/tick_cache.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/marketdata/tick_repository.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/bar_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/bars_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/chart_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/conf_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/consecutive_bars_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/rates_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/signals_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/models/unconsecutive_bar_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/mt5_context.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugin.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugin_manager.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/exemplo.py-dist +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/cli.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/conf.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/models/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/models/model_media_movel.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/tests/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/tests/test_mm.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/media_movel/tests/test_model_media_movel.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/range_medio/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/range_medio/cli.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/range_medio/conf.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/range_medio/models/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/range_medio/models/average_range_model.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/range_medio/tests/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/range_medio/tests/test_rm.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/volume_medio/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/volume_medio/cli.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/volume_medio/conf.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/volume_medio/models/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/volume_medio/models/model_average_volume.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/volume_medio/tests/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/plugins/volume_medio/tests/test_vm.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/__init__.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/close_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/full_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/high_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/low_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/min_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/open_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/ranges_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/rates_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/vars_view.py +0 -0
- {mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/mtcli/views/volumes_view.py +0 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sistema de carregamento de plugins do mtcli.
|
|
3
|
+
|
|
4
|
+
Responsável por descobrir e registrar plugins externos
|
|
5
|
+
instalados via entry points.
|
|
6
|
+
|
|
7
|
+
Plugins devem declarar entry points no grupo:
|
|
8
|
+
|
|
9
|
+
mtcli.plugins
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from typing import Iterable, List
|
|
16
|
+
|
|
17
|
+
import click
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
from importlib.metadata import EntryPoint, entry_points
|
|
21
|
+
except ImportError: # pragma: no cover
|
|
22
|
+
from importlib_metadata import EntryPoint, entry_points
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
PLUGIN_GROUP = "mtcli.plugins"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def discover_plugins() -> Iterable[EntryPoint]:
|
|
31
|
+
"""
|
|
32
|
+
Descobre plugins registrados via entry points.
|
|
33
|
+
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
Iterable[EntryPoint]
|
|
37
|
+
Entry points encontrados no grupo ``mtcli.plugins``.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
|
|
42
|
+
# Python moderno
|
|
43
|
+
try:
|
|
44
|
+
return entry_points(group=PLUGIN_GROUP)
|
|
45
|
+
except TypeError:
|
|
46
|
+
# Compatibilidade Python antigo
|
|
47
|
+
eps = entry_points()
|
|
48
|
+
|
|
49
|
+
if hasattr(eps, "select"):
|
|
50
|
+
return eps.select(group=PLUGIN_GROUP)
|
|
51
|
+
|
|
52
|
+
return eps.get(PLUGIN_GROUP, [])
|
|
53
|
+
|
|
54
|
+
except Exception as exc: # pragma: no cover
|
|
55
|
+
logger.error("Erro ao descobrir plugins: %s", exc)
|
|
56
|
+
return []
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def register_plugin(cli: click.Group, ep: EntryPoint) -> None:
|
|
60
|
+
"""
|
|
61
|
+
Carrega e registra um plugin individual.
|
|
62
|
+
|
|
63
|
+
O plugin pode expor:
|
|
64
|
+
|
|
65
|
+
- função ``register(cli)``
|
|
66
|
+
- objeto ``click.Command``
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
cli : click.Group
|
|
71
|
+
CLI principal.
|
|
72
|
+
ep : EntryPoint
|
|
73
|
+
Entry point do plugin.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
plugin = ep.load()
|
|
77
|
+
|
|
78
|
+
if callable(plugin) and not isinstance(plugin, click.Command):
|
|
79
|
+
|
|
80
|
+
plugin(cli)
|
|
81
|
+
|
|
82
|
+
logger.debug(
|
|
83
|
+
"Plugin '%s' registrado via função register() (%s)",
|
|
84
|
+
ep.name,
|
|
85
|
+
ep.value,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
elif isinstance(plugin, click.Command):
|
|
89
|
+
|
|
90
|
+
cli.add_command(plugin)
|
|
91
|
+
|
|
92
|
+
logger.debug(
|
|
93
|
+
"Plugin '%s' registrado como comando Click (%s)",
|
|
94
|
+
ep.name,
|
|
95
|
+
ep.value,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
|
|
100
|
+
raise TypeError(
|
|
101
|
+
f"Plugin '{ep.name}' inválido: "
|
|
102
|
+
"não é click.Command nem função register(cli)"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def load_plugins(cli: click.Group) -> List[str]:
|
|
107
|
+
"""
|
|
108
|
+
Descobre e carrega todos os plugins instalados.
|
|
109
|
+
|
|
110
|
+
Parameters
|
|
111
|
+
----------
|
|
112
|
+
cli : click.Group
|
|
113
|
+
CLI principal do mtcli.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
list[str]
|
|
118
|
+
Lista de plugins carregados com sucesso.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
loaded: List[str] = []
|
|
122
|
+
seen = set()
|
|
123
|
+
|
|
124
|
+
for ep in discover_plugins():
|
|
125
|
+
|
|
126
|
+
if ep.name in seen:
|
|
127
|
+
logger.warning("Plugin duplicado ignorado: %s", ep.name)
|
|
128
|
+
continue
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
|
|
132
|
+
register_plugin(cli, ep)
|
|
133
|
+
|
|
134
|
+
seen.add(ep.name)
|
|
135
|
+
loaded.append(ep.name)
|
|
136
|
+
|
|
137
|
+
except Exception as exc:
|
|
138
|
+
|
|
139
|
+
logger.error(
|
|
140
|
+
"Falha ao carregar plugin '%s': %s",
|
|
141
|
+
ep.name,
|
|
142
|
+
exc,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
logger.info("Plugins carregados: %d", len(loaded))
|
|
146
|
+
|
|
147
|
+
return loaded
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Carregador de plugins do mtcli.
|
|
3
|
-
|
|
4
|
-
Responsável por descobrir e registrar plugins internos e externos
|
|
5
|
-
utilizando entry points.
|
|
6
|
-
|
|
7
|
-
Plugins podem expor:
|
|
8
|
-
|
|
9
|
-
1. função register(cli)
|
|
10
|
-
2. objeto click.Command
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
import logging
|
|
14
|
-
import click
|
|
15
|
-
|
|
16
|
-
try:
|
|
17
|
-
from importlib.metadata import entry_points
|
|
18
|
-
except ImportError: # pragma: no cover
|
|
19
|
-
from importlib_metadata import entry_points
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
logger = logging.getLogger(__name__)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def load_plugins(cli):
|
|
26
|
-
"""
|
|
27
|
-
Descobre e carrega plugins registrados via entry points.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
cli (click.Group): CLI principal.
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
try:
|
|
34
|
-
eps = entry_points()
|
|
35
|
-
|
|
36
|
-
plugins = (
|
|
37
|
-
eps.select(group="mtcli.plugins")
|
|
38
|
-
if hasattr(eps, "select")
|
|
39
|
-
else eps.get("mtcli.plugins", [])
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
except Exception as exc:
|
|
43
|
-
logger.error("Erro ao descobrir plugins: %s", exc)
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
loaded = set()
|
|
47
|
-
|
|
48
|
-
for ep in plugins:
|
|
49
|
-
|
|
50
|
-
if ep.name in loaded:
|
|
51
|
-
logger.warning("Plugin duplicado ignorado: %s", ep.name)
|
|
52
|
-
continue
|
|
53
|
-
|
|
54
|
-
try:
|
|
55
|
-
|
|
56
|
-
plugin = ep.load()
|
|
57
|
-
|
|
58
|
-
# função register(cli)
|
|
59
|
-
if callable(plugin) and not isinstance(plugin, click.Command):
|
|
60
|
-
plugin(cli)
|
|
61
|
-
|
|
62
|
-
# comando click direto
|
|
63
|
-
elif isinstance(plugin, click.Command):
|
|
64
|
-
cli.add_command(plugin)
|
|
65
|
-
|
|
66
|
-
else:
|
|
67
|
-
raise TypeError(
|
|
68
|
-
"Plugin não é comando Click nem função register(cli)"
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
loaded.add(ep.name)
|
|
72
|
-
|
|
73
|
-
logger.debug("Plugin carregado: %s", ep.name)
|
|
74
|
-
|
|
75
|
-
except Exception as exc:
|
|
76
|
-
|
|
77
|
-
logger.error(
|
|
78
|
-
"Falha ao carregar plugin '%s': %s",
|
|
79
|
-
ep.name,
|
|
80
|
-
exc,
|
|
81
|
-
)
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mtcli-3.7.0.dev0 → mtcli-3.7.0.dev2}/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.7.0.dev0 → mtcli-3.7.0.dev2}/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.7.0.dev0 → mtcli-3.7.0.dev2}/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
|