mtcli-renko 1.0.0.dev0__tar.gz → 1.0.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_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/PKG-INFO +1 -1
- mtcli_renko-1.0.0.dev2/mtcli_renko/commands/renko.py +82 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/conf.py +14 -4
- mtcli_renko-1.0.0.dev2/mtcli_renko/domain/timeframe.py +87 -0
- mtcli_renko-1.0.0.dev2/mtcli_renko/views/__init__.py +0 -0
- mtcli_renko-1.0.0.dev2/mtcli_renko/views/renko_view.py +43 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/pyproject.toml +1 -1
- mtcli_renko-1.0.0.dev0/mtcli_renko/commands/renko.py +0 -24
- mtcli_renko-1.0.0.dev0/mtcli_renko/views/renko_view.py +0 -28
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/LICENSE +0 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/README.md +0 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/__init__.py +0 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/commands/__init__.py +0 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/controllers/__init__.py +0 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/controllers/renko_controller.py +0 -0
- {mtcli_renko-1.0.0.dev0/mtcli_renko/models → mtcli_renko-1.0.0.dev2/mtcli_renko/domain}/__init__.py +0 -0
- {mtcli_renko-1.0.0.dev0/mtcli_renko/views → mtcli_renko-1.0.0.dev2/mtcli_renko/models}/__init__.py +0 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/models/renko_model.py +0 -0
- {mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/plugin.py +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Comando CLI para geração de gráfico Renko.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from ..controllers.renko_controller import RenkoController
|
|
8
|
+
from ..views.renko_view import exibir_renko
|
|
9
|
+
from ..domain.timeframe import Timeframe
|
|
10
|
+
from mtcli.logger import setup_logger
|
|
11
|
+
from ..conf import (
|
|
12
|
+
SYMBOL,
|
|
13
|
+
BRICK,
|
|
14
|
+
PERIOD,
|
|
15
|
+
BARS
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
log = setup_logger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.command()
|
|
22
|
+
@click.version_option(package_name="mtcli-renko")
|
|
23
|
+
@click.option(
|
|
24
|
+
"--symbol",
|
|
25
|
+
"-s",
|
|
26
|
+
default=SYMBOL,
|
|
27
|
+
show_default=True,
|
|
28
|
+
help="Ativo (ex: WINJ26)",
|
|
29
|
+
)
|
|
30
|
+
@click.option(
|
|
31
|
+
"--brick",
|
|
32
|
+
"-b",
|
|
33
|
+
default=BRICK,
|
|
34
|
+
show_default=True,
|
|
35
|
+
type=float,
|
|
36
|
+
help="Tamanho do brick em pontos",
|
|
37
|
+
)
|
|
38
|
+
@click.option(
|
|
39
|
+
"--timeframe",
|
|
40
|
+
"-t",
|
|
41
|
+
default=PERIOD,
|
|
42
|
+
show_default=True,
|
|
43
|
+
help=f"Timeframe ({', '.join(Timeframe.valid_labels())})",
|
|
44
|
+
)
|
|
45
|
+
@click.option(
|
|
46
|
+
"--bars",
|
|
47
|
+
"-n",
|
|
48
|
+
default=BARS,
|
|
49
|
+
show_default=True,
|
|
50
|
+
help="Quantidade de candles para cálculo",
|
|
51
|
+
)
|
|
52
|
+
@click.option(
|
|
53
|
+
"--numerar/--no-numerar",
|
|
54
|
+
default=False,
|
|
55
|
+
show_default=True,
|
|
56
|
+
help="Exibir numeração das linhas",
|
|
57
|
+
)
|
|
58
|
+
def renko(symbol, brick, timeframe, bars, numerar):
|
|
59
|
+
"""
|
|
60
|
+
Gera gráfico Renko em modo texto (screen reader friendly).
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
tf_enum = Timeframe.from_string(timeframe)
|
|
65
|
+
except ValueError as e:
|
|
66
|
+
raise click.BadParameter(str(e))
|
|
67
|
+
|
|
68
|
+
log.info(
|
|
69
|
+
f"[Renko CLI] symbol={symbol} | brick={brick} | "
|
|
70
|
+
f"timeframe={tf_enum.label} | bars={bars} | "
|
|
71
|
+
f"numerar={numerar}"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
controller = RenkoController(
|
|
75
|
+
symbol,
|
|
76
|
+
brick,
|
|
77
|
+
tf_enum.mt5_const,
|
|
78
|
+
bars,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
bricks = controller.executar()
|
|
82
|
+
exibir_renko(bricks, numerar=numerar)
|
|
@@ -53,10 +53,20 @@ SYMBOL = os.getenv(
|
|
|
53
53
|
|
|
54
54
|
BRICK = float(os.getenv(
|
|
55
55
|
"BRICK",
|
|
56
|
-
_get_config_value("RENKO", "brick",
|
|
56
|
+
_get_config_value("RENKO", "brick", 50)
|
|
57
57
|
))
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
_get_config_value("
|
|
59
|
+
PERIOD = os.getenv(
|
|
60
|
+
"PERIOD",
|
|
61
|
+
_get_config_value("RENKO", "period", "M5")
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
BARS = int(os.getenv(
|
|
65
|
+
"BARS",
|
|
66
|
+
_get_config_value("RENKO", "bars", 500)
|
|
67
|
+
))
|
|
68
|
+
|
|
69
|
+
DIGITS = int(os.getenv(
|
|
70
|
+
"DIGITS",
|
|
71
|
+
_get_config_value("RENKO", "digits", 2)
|
|
62
72
|
))
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enum de Timeframes suportados pelo MTCLI Renko.
|
|
3
|
+
|
|
4
|
+
Fornece:
|
|
5
|
+
- Conversão amigável (m5, 5m, h1, 1h)
|
|
6
|
+
- Mapeamento para constante MT5
|
|
7
|
+
- Lista de valores válidos para CLI
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from enum import Enum
|
|
11
|
+
import MetaTrader5 as mt5
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Timeframe(Enum):
|
|
15
|
+
"""
|
|
16
|
+
Representa timeframes suportados pelo MT5.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
M1 = ("m1", mt5.TIMEFRAME_M1)
|
|
20
|
+
M2 = ("m2", mt5.TIMEFRAME_M2)
|
|
21
|
+
M3 = ("m3", mt5.TIMEFRAME_M3)
|
|
22
|
+
M4 = ("m4", mt5.TIMEFRAME_M4)
|
|
23
|
+
M5 = ("m5", mt5.TIMEFRAME_M5)
|
|
24
|
+
M10 = ("m10", mt5.TIMEFRAME_M10)
|
|
25
|
+
M15 = ("m15", mt5.TIMEFRAME_M15)
|
|
26
|
+
M30 = ("m30", mt5.TIMEFRAME_M30)
|
|
27
|
+
|
|
28
|
+
H1 = ("h1", mt5.TIMEFRAME_H1)
|
|
29
|
+
H2 = ("h2", mt5.TIMEFRAME_H2)
|
|
30
|
+
H3 = ("h3", mt5.TIMEFRAME_H3)
|
|
31
|
+
H4 = ("h4", mt5.TIMEFRAME_H4)
|
|
32
|
+
H6 = ("h6", mt5.TIMEFRAME_H6)
|
|
33
|
+
H8 = ("h8", mt5.TIMEFRAME_H8)
|
|
34
|
+
H12 = ("h12", mt5.TIMEFRAME_H12)
|
|
35
|
+
|
|
36
|
+
D1 = ("d1", mt5.TIMEFRAME_D1)
|
|
37
|
+
W1 = ("w1", mt5.TIMEFRAME_W1)
|
|
38
|
+
MN1 = ("mn1", mt5.TIMEFRAME_MN1)
|
|
39
|
+
|
|
40
|
+
def __init__(self, label: str, mt5_const: int):
|
|
41
|
+
self.label = label
|
|
42
|
+
self.mt5_const = mt5_const
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def from_string(cls, value: str) -> "Timeframe":
|
|
46
|
+
"""
|
|
47
|
+
Converte string amigável para Enum Timeframe.
|
|
48
|
+
|
|
49
|
+
Aceita:
|
|
50
|
+
m5, 5m
|
|
51
|
+
h1, 1h
|
|
52
|
+
d1, 1d
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
value = value.strip().lower()
|
|
56
|
+
|
|
57
|
+
# Aliases humanos
|
|
58
|
+
aliases = {
|
|
59
|
+
"1m": "m1",
|
|
60
|
+
"5m": "m5",
|
|
61
|
+
"15m": "m15",
|
|
62
|
+
"30m": "m30",
|
|
63
|
+
"1h": "h1",
|
|
64
|
+
"4h": "h4",
|
|
65
|
+
"1d": "d1",
|
|
66
|
+
"1w": "w1",
|
|
67
|
+
"1mo": "mn1",
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if value in aliases:
|
|
71
|
+
value = aliases[value]
|
|
72
|
+
|
|
73
|
+
for tf in cls:
|
|
74
|
+
if tf.label == value:
|
|
75
|
+
return tf
|
|
76
|
+
|
|
77
|
+
raise ValueError(
|
|
78
|
+
f"Timeframe inválido: {value}. "
|
|
79
|
+
f"Use: {', '.join(cls.valid_labels())}"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def valid_labels(cls):
|
|
84
|
+
"""
|
|
85
|
+
Retorna lista de labels válidos.
|
|
86
|
+
"""
|
|
87
|
+
return [tf.label for tf in cls]
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Renko view.
|
|
3
|
+
|
|
4
|
+
Saída textual acessível para leitores de tela.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
from ..conf import DIGITS
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def exibir_renko(bricks, numerar: bool = False):
|
|
12
|
+
"""
|
|
13
|
+
Exibe blocos Renko em formato textual linear.
|
|
14
|
+
|
|
15
|
+
:param bricks: lista de RenkoBrick
|
|
16
|
+
:param numerar: se True, exibe índice das linhas
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
if not bricks:
|
|
20
|
+
click.echo("Nenhum bloco Renko gerado.")
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
click.echo("=== GRAFICO RENKO ===")
|
|
24
|
+
click.echo(f"Total de blocos: {len(bricks)}")
|
|
25
|
+
click.echo()
|
|
26
|
+
|
|
27
|
+
for i, brick in enumerate(bricks, start=1):
|
|
28
|
+
|
|
29
|
+
if numerar:
|
|
30
|
+
linha = (
|
|
31
|
+
f"{i} "
|
|
32
|
+
f"{brick.direction.upper()} "
|
|
33
|
+
f"{brick.open:.{DIGITS}f} "
|
|
34
|
+
f"{brick.close:.{DIGITS}f}"
|
|
35
|
+
)
|
|
36
|
+
else:
|
|
37
|
+
linha = (
|
|
38
|
+
f"{brick.direction.upper()} "
|
|
39
|
+
f"{brick.open:.{DIGITS}f} "
|
|
40
|
+
f"{brick.close:.{DIGITS}f}"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
click.echo(linha)
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Comando CLI para geração de gráfico Renko.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import click
|
|
6
|
-
from ..controllers.renko_controller import RenkoController
|
|
7
|
-
from ..views.renko_view import exibir_renko
|
|
8
|
-
import MetaTrader5 as mt5
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@click.command()
|
|
12
|
-
@click.option("--symbol", "-s", required=True)
|
|
13
|
-
@click.option("--brick", "-b", required=True, type=float)
|
|
14
|
-
@click.option("--timeframe", "-t", default=mt5.TIMEFRAME_M5)
|
|
15
|
-
@click.option("--bars", "-n", default=500)
|
|
16
|
-
def renko(symbol, brick, timeframe, bars):
|
|
17
|
-
"""
|
|
18
|
-
Gera gráfico Renko em modo texto.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
controller = RenkoController(symbol, brick, timeframe, bars)
|
|
22
|
-
bricks = controller.executar()
|
|
23
|
-
|
|
24
|
-
exibir_renko(bricks)
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Renko view.
|
|
3
|
-
|
|
4
|
-
Saída textual acessível para leitores de tela.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
def exibir_renko(bricks):
|
|
8
|
-
"""
|
|
9
|
-
Exibe blocos Renko em formato textual linear.
|
|
10
|
-
|
|
11
|
-
:param bricks: lista de RenkoBrick
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
if not bricks:
|
|
15
|
-
print("Nenhum bloco Renko gerado.")
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
print("=== GRAFICO RENKO ===")
|
|
19
|
-
print(f"Total de blocos: {len(bricks)}")
|
|
20
|
-
print()
|
|
21
|
-
|
|
22
|
-
for i, brick in enumerate(bricks, start=1):
|
|
23
|
-
print(
|
|
24
|
-
f"{i} "
|
|
25
|
-
f"{brick.direction.upper()} "
|
|
26
|
-
f"{brick.open:.0f} "
|
|
27
|
-
f"{brick.close:.0f}"
|
|
28
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mtcli_renko-1.0.0.dev0 → mtcli_renko-1.0.0.dev2}/mtcli_renko/controllers/renko_controller.py
RENAMED
|
File without changes
|
{mtcli_renko-1.0.0.dev0/mtcli_renko/models → mtcli_renko-1.0.0.dev2/mtcli_renko/domain}/__init__.py
RENAMED
|
File without changes
|
{mtcli_renko-1.0.0.dev0/mtcli_renko/views → mtcli_renko-1.0.0.dev2/mtcli_renko/models}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|