mtcli-renko 1.1.0.dev1__tar.gz → 1.1.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.1.0.dev1 → mtcli_renko-1.1.0.dev2}/PKG-INFO +1 -1
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/commands/renko.py +12 -4
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/conf.py +5 -0
- mtcli_renko-1.1.0.dev2/mtcli_renko/controllers/renko_controller.py +105 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/models/renko_model.py +47 -71
- mtcli_renko-1.1.0.dev2/mtcli_renko/views/renko_view.py +75 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/pyproject.toml +1 -1
- mtcli_renko-1.1.0.dev1/mtcli_renko/controllers/renko_controller.py +0 -66
- mtcli_renko-1.1.0.dev1/mtcli_renko/views/renko_view.py +0 -37
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/LICENSE +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/README.md +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/__init__.py +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/commands/__init__.py +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/controllers/__init__.py +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/domain/__init__.py +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/domain/timeframe.py +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/models/__init__.py +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/plugin.py +0 -0
- {mtcli_renko-1.1.0.dev1 → mtcli_renko-1.1.0.dev2}/mtcli_renko/views/__init__.py +0 -0
|
@@ -8,7 +8,7 @@ from ..controllers.renko_controller import RenkoController
|
|
|
8
8
|
from ..views.renko_view import exibir_renko
|
|
9
9
|
from ..domain.timeframe import Timeframe
|
|
10
10
|
from mtcli.logger import setup_logger
|
|
11
|
-
from ..conf import SYMBOL, BRICK, PERIOD, BARS, DATA_MODE, MAX_TICKS
|
|
11
|
+
from ..conf import SYMBOL, BRICK, PERIOD, BARS, DATA_MODE, MAX_TICKS, TICK_STYLE
|
|
12
12
|
|
|
13
13
|
log = setup_logger(__name__)
|
|
14
14
|
|
|
@@ -43,7 +43,13 @@ log = setup_logger(__name__)
|
|
|
43
43
|
default=MAX_TICKS,
|
|
44
44
|
show_default=True,
|
|
45
45
|
type=int,
|
|
46
|
-
|
|
46
|
+
)
|
|
47
|
+
@click.option(
|
|
48
|
+
"--tick-style",
|
|
49
|
+
type=click.Choice(["estrutural", "hibrido", "agressivo"], case_sensitive=False),
|
|
50
|
+
default=TICK_STYLE,
|
|
51
|
+
show_default=True,
|
|
52
|
+
help="Define como tratar brick em formação no modo tick.",
|
|
47
53
|
)
|
|
48
54
|
def renko(
|
|
49
55
|
symbol,
|
|
@@ -55,6 +61,7 @@ def renko(
|
|
|
55
61
|
ancorar_abertura,
|
|
56
62
|
data_mode,
|
|
57
63
|
max_ticks,
|
|
64
|
+
tick_style,
|
|
58
65
|
):
|
|
59
66
|
|
|
60
67
|
try:
|
|
@@ -71,7 +78,8 @@ def renko(
|
|
|
71
78
|
ancorar_abertura,
|
|
72
79
|
data_mode,
|
|
73
80
|
max_ticks,
|
|
81
|
+
tick_style,
|
|
74
82
|
)
|
|
75
83
|
|
|
76
|
-
|
|
77
|
-
exibir_renko(
|
|
84
|
+
resultado = controller.executar()
|
|
85
|
+
exibir_renko(resultado, numerar=numerar)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Renko controller.
|
|
3
|
+
|
|
4
|
+
Responsável por:
|
|
5
|
+
- Orquestrar obtenção de dados (candle ou tick)
|
|
6
|
+
- Chamar o model
|
|
7
|
+
- Aplicar estilo de saída no modo tick
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from ..models.renko_model import RenkoModel
|
|
11
|
+
from mtcli.logger import setup_logger
|
|
12
|
+
|
|
13
|
+
log = setup_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RenkoController:
|
|
17
|
+
"""
|
|
18
|
+
Controller principal do Renko.
|
|
19
|
+
|
|
20
|
+
:param symbol: ativo (ex: WINJ26)
|
|
21
|
+
:param brick_size: tamanho do brick
|
|
22
|
+
:param timeframe: timeframe MT5 (para candle)
|
|
23
|
+
:param quantidade: número de candles
|
|
24
|
+
:param modo: simples ou classico
|
|
25
|
+
:param ancorar_abertura: ancora na abertura da sessão
|
|
26
|
+
:param data_mode: candle ou tick
|
|
27
|
+
:param max_ticks: quantidade máxima de ticks
|
|
28
|
+
:param tick_style: estrutural | hibrido | agressivo
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
symbol,
|
|
34
|
+
brick_size,
|
|
35
|
+
timeframe,
|
|
36
|
+
quantidade,
|
|
37
|
+
modo="simples",
|
|
38
|
+
ancorar_abertura=False,
|
|
39
|
+
data_mode="candle",
|
|
40
|
+
max_ticks=3000,
|
|
41
|
+
tick_style="hibrido",
|
|
42
|
+
):
|
|
43
|
+
self.model = RenkoModel(symbol, brick_size)
|
|
44
|
+
self.timeframe = timeframe
|
|
45
|
+
self.quantidade = quantidade
|
|
46
|
+
self.modo = modo
|
|
47
|
+
self.ancorar_abertura = ancorar_abertura
|
|
48
|
+
self.data_mode = data_mode
|
|
49
|
+
self.max_ticks = max_ticks
|
|
50
|
+
self.tick_style = tick_style
|
|
51
|
+
|
|
52
|
+
def executar(self):
|
|
53
|
+
"""
|
|
54
|
+
Executa construção do Renko conforme modo configurado.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
# =========================
|
|
58
|
+
# MODO TICK
|
|
59
|
+
# =========================
|
|
60
|
+
if self.data_mode == "tick":
|
|
61
|
+
|
|
62
|
+
ticks = self.model.obter_ticks(
|
|
63
|
+
timeframe=self.timeframe,
|
|
64
|
+
max_ticks=self.max_ticks,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# 🔒 Correção definitiva do erro numpy
|
|
68
|
+
if ticks is None or len(ticks) == 0:
|
|
69
|
+
return []
|
|
70
|
+
|
|
71
|
+
resultado = self.model.construir_renko_ticks(ticks)
|
|
72
|
+
|
|
73
|
+
# =========================
|
|
74
|
+
# Aplicar estilo de tick
|
|
75
|
+
# =========================
|
|
76
|
+
|
|
77
|
+
# Estrutural → somente confirmados
|
|
78
|
+
if self.tick_style == "estrutural":
|
|
79
|
+
return resultado.confirmados
|
|
80
|
+
|
|
81
|
+
# Agressivo → confirmados + parcial como válido
|
|
82
|
+
if self.tick_style == "agressivo":
|
|
83
|
+
if resultado.em_formacao:
|
|
84
|
+
return resultado.confirmados + [resultado.em_formacao]
|
|
85
|
+
return resultado.confirmados
|
|
86
|
+
|
|
87
|
+
# Híbrido (default) → retorna objeto completo
|
|
88
|
+
return resultado
|
|
89
|
+
|
|
90
|
+
# =========================
|
|
91
|
+
# MODO CANDLE
|
|
92
|
+
# =========================
|
|
93
|
+
rates = self.model.obter_rates(
|
|
94
|
+
self.timeframe,
|
|
95
|
+
self.quantidade,
|
|
96
|
+
ancorar_abertura=self.ancorar_abertura,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
if rates is None or len(rates) == 0:
|
|
100
|
+
return []
|
|
101
|
+
|
|
102
|
+
return self.model.construir_renko(
|
|
103
|
+
rates,
|
|
104
|
+
modo=self.modo,
|
|
105
|
+
)
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Renko model institucional profissional.
|
|
3
3
|
|
|
4
|
-
✔
|
|
5
|
-
✔ Tick mode
|
|
4
|
+
✔ Candle mode determinístico
|
|
5
|
+
✔ Tick mode híbrido (confirmados + em formação)
|
|
6
|
+
✔ Estrutura estável
|
|
6
7
|
✔ Compatível com controller atual
|
|
7
|
-
✔ Seguro para numpy arrays
|
|
8
|
-
✔ Funciona em mercado aberto e fechado
|
|
9
8
|
"""
|
|
10
9
|
|
|
11
10
|
from dataclasses import dataclass
|
|
12
|
-
from typing import List, Optional
|
|
11
|
+
from typing import List, Optional, NamedTuple
|
|
13
12
|
from datetime import datetime
|
|
14
13
|
|
|
15
14
|
import MetaTrader5 as mt5
|
|
@@ -22,7 +21,7 @@ log = setup_logger(__name__)
|
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
# ==========================================================
|
|
25
|
-
# DATA
|
|
24
|
+
# DATA STRUCTURES
|
|
26
25
|
# ==========================================================
|
|
27
26
|
|
|
28
27
|
@dataclass
|
|
@@ -32,6 +31,11 @@ class RenkoBrick:
|
|
|
32
31
|
close: float
|
|
33
32
|
|
|
34
33
|
|
|
34
|
+
class RenkoResult(NamedTuple):
|
|
35
|
+
confirmados: List[RenkoBrick]
|
|
36
|
+
em_formacao: Optional[RenkoBrick]
|
|
37
|
+
|
|
38
|
+
|
|
35
39
|
# ==========================================================
|
|
36
40
|
# MODEL
|
|
37
41
|
# ==========================================================
|
|
@@ -86,10 +90,6 @@ class RenkoModel:
|
|
|
86
90
|
|
|
87
91
|
return rates or []
|
|
88
92
|
|
|
89
|
-
# -------------------------
|
|
90
|
-
# Ancorado no último pregão
|
|
91
|
-
# -------------------------
|
|
92
|
-
|
|
93
93
|
data_pregao = self._ultimo_pregao_data(timeframe)
|
|
94
94
|
|
|
95
95
|
if data_pregao is None:
|
|
@@ -118,7 +118,7 @@ class RenkoModel:
|
|
|
118
118
|
return filtrado[-quantidade:]
|
|
119
119
|
|
|
120
120
|
# ======================================================
|
|
121
|
-
# TICKS
|
|
121
|
+
# TICKS
|
|
122
122
|
# ======================================================
|
|
123
123
|
|
|
124
124
|
def obter_ticks(self, timeframe, max_ticks=5000):
|
|
@@ -150,7 +150,6 @@ class RenkoModel:
|
|
|
150
150
|
if ticks is None or len(ticks) == 0:
|
|
151
151
|
return []
|
|
152
152
|
|
|
153
|
-
# 🔥 Pegar apenas os ticks mais recentes
|
|
154
153
|
if len(ticks) > max_ticks:
|
|
155
154
|
ticks = ticks[-max_ticks:]
|
|
156
155
|
|
|
@@ -160,86 +159,41 @@ class RenkoModel:
|
|
|
160
159
|
# CONSTRUÇÃO RENKO (CANDLE)
|
|
161
160
|
# ======================================================
|
|
162
161
|
|
|
163
|
-
def construir_renko(
|
|
164
|
-
self,
|
|
165
|
-
rates,
|
|
166
|
-
modo="simples",
|
|
167
|
-
) -> List[RenkoBrick]:
|
|
162
|
+
def construir_renko(self, rates, modo="simples") -> List[RenkoBrick]:
|
|
168
163
|
|
|
169
164
|
if rates is None or len(rates) < 2:
|
|
170
165
|
return []
|
|
171
166
|
|
|
172
167
|
bricks: List[RenkoBrick] = []
|
|
173
|
-
|
|
174
168
|
last_price = float(rates[0]["open"])
|
|
175
|
-
direction: Optional[str] = None
|
|
176
169
|
|
|
177
170
|
for rate in rates[1:]:
|
|
178
171
|
|
|
179
172
|
high = float(rate["high"])
|
|
180
173
|
low = float(rate["low"])
|
|
181
174
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
bricks.append(RenkoBrick("down", last_price, novo))
|
|
192
|
-
last_price = novo
|
|
193
|
-
|
|
194
|
-
elif modo == "classico":
|
|
195
|
-
|
|
196
|
-
if direction in (None, "up"):
|
|
197
|
-
|
|
198
|
-
while high - last_price >= self.brick_size:
|
|
199
|
-
novo = last_price + self.brick_size
|
|
200
|
-
bricks.append(RenkoBrick("up", last_price, novo))
|
|
201
|
-
last_price = novo
|
|
202
|
-
direction = "up"
|
|
203
|
-
|
|
204
|
-
if (
|
|
205
|
-
direction == "up"
|
|
206
|
-
and last_price - low >= 2 * self.brick_size
|
|
207
|
-
):
|
|
208
|
-
novo = last_price - self.brick_size
|
|
209
|
-
bricks.append(RenkoBrick("down", last_price, novo))
|
|
210
|
-
last_price = novo
|
|
211
|
-
direction = "down"
|
|
212
|
-
|
|
213
|
-
if direction in (None, "down"):
|
|
214
|
-
|
|
215
|
-
while last_price - low >= self.brick_size:
|
|
216
|
-
novo = last_price - self.brick_size
|
|
217
|
-
bricks.append(RenkoBrick("down", last_price, novo))
|
|
218
|
-
last_price = novo
|
|
219
|
-
direction = "down"
|
|
220
|
-
|
|
221
|
-
if (
|
|
222
|
-
direction == "down"
|
|
223
|
-
and high - last_price >= 2 * self.brick_size
|
|
224
|
-
):
|
|
225
|
-
novo = last_price + self.brick_size
|
|
226
|
-
bricks.append(RenkoBrick("up", last_price, novo))
|
|
227
|
-
last_price = novo
|
|
228
|
-
direction = "up"
|
|
175
|
+
while high - last_price >= self.brick_size:
|
|
176
|
+
novo = last_price + self.brick_size
|
|
177
|
+
bricks.append(RenkoBrick("up", last_price, novo))
|
|
178
|
+
last_price = novo
|
|
179
|
+
|
|
180
|
+
while last_price - low >= self.brick_size:
|
|
181
|
+
novo = last_price - self.brick_size
|
|
182
|
+
bricks.append(RenkoBrick("down", last_price, novo))
|
|
183
|
+
last_price = novo
|
|
229
184
|
|
|
230
185
|
return bricks
|
|
231
186
|
|
|
232
187
|
# ======================================================
|
|
233
|
-
# CONSTRUÇÃO RENKO (TICK)
|
|
188
|
+
# CONSTRUÇÃO RENKO (TICK HÍBRIDO)
|
|
234
189
|
# ======================================================
|
|
235
190
|
|
|
236
|
-
def construir_renko_ticks(self, ticks
|
|
191
|
+
def construir_renko_ticks(self, ticks) -> RenkoResult:
|
|
237
192
|
|
|
238
193
|
if ticks is None or len(ticks) < 2:
|
|
239
|
-
return []
|
|
194
|
+
return RenkoResult([], None)
|
|
240
195
|
|
|
241
196
|
bricks: List[RenkoBrick] = []
|
|
242
|
-
|
|
243
197
|
last_price = float(ticks[0]["last"])
|
|
244
198
|
|
|
245
199
|
for tick in ticks[1:]:
|
|
@@ -256,4 +210,26 @@ class RenkoModel:
|
|
|
256
210
|
bricks.append(RenkoBrick("down", last_price, novo))
|
|
257
211
|
last_price = novo
|
|
258
212
|
|
|
259
|
-
|
|
213
|
+
# ----------------------------
|
|
214
|
+
# Brick em formação
|
|
215
|
+
# ----------------------------
|
|
216
|
+
|
|
217
|
+
ultimo_preco = float(ticks[-1]["last"])
|
|
218
|
+
diferenca = ultimo_preco - last_price
|
|
219
|
+
|
|
220
|
+
em_formacao = None
|
|
221
|
+
|
|
222
|
+
if abs(diferenca) > 0:
|
|
223
|
+
|
|
224
|
+
direcao = "up" if diferenca > 0 else "down"
|
|
225
|
+
|
|
226
|
+
em_formacao = RenkoBrick(
|
|
227
|
+
direction=direcao,
|
|
228
|
+
open=last_price,
|
|
229
|
+
close=ultimo_preco,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
return RenkoResult(
|
|
233
|
+
confirmados=bricks,
|
|
234
|
+
em_formacao=em_formacao,
|
|
235
|
+
)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Renko view acessível.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from ..conf import DIGITS
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def exibir_renko(resultado, numerar: bool = False):
|
|
10
|
+
|
|
11
|
+
if not resultado:
|
|
12
|
+
click.echo("Nenhum bloco Renko gerado.")
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
# Lista simples (estrutural ou agressivo)
|
|
16
|
+
if isinstance(resultado, list):
|
|
17
|
+
|
|
18
|
+
click.echo("=== GRAFICO RENKO ===")
|
|
19
|
+
click.echo(f"Total de blocos: {len(resultado)}")
|
|
20
|
+
click.echo()
|
|
21
|
+
|
|
22
|
+
for i, brick in enumerate(resultado, start=1):
|
|
23
|
+
|
|
24
|
+
if numerar:
|
|
25
|
+
linha = (
|
|
26
|
+
f"{i} "
|
|
27
|
+
f"{brick.direction.upper()} "
|
|
28
|
+
f"{brick.open:.{DIGITS}f} "
|
|
29
|
+
f"{brick.close:.{DIGITS}f}"
|
|
30
|
+
)
|
|
31
|
+
else:
|
|
32
|
+
linha = (
|
|
33
|
+
f"{brick.direction.upper()} "
|
|
34
|
+
f"{brick.open:.{DIGITS}f} "
|
|
35
|
+
f"{brick.close:.{DIGITS}f}"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
click.echo(linha)
|
|
39
|
+
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
# Híbrido
|
|
43
|
+
confirmados = resultado.confirmados
|
|
44
|
+
em_formacao = resultado.em_formacao
|
|
45
|
+
|
|
46
|
+
click.echo("=== GRAFICO RENKO ===")
|
|
47
|
+
click.echo(f"Blocos confirmados: {len(confirmados)}")
|
|
48
|
+
click.echo()
|
|
49
|
+
|
|
50
|
+
for i, brick in enumerate(confirmados, start=1):
|
|
51
|
+
|
|
52
|
+
if numerar:
|
|
53
|
+
linha = (
|
|
54
|
+
f"{i} "
|
|
55
|
+
f"{brick.direction.upper()} "
|
|
56
|
+
f"{brick.open:.{DIGITS}f} "
|
|
57
|
+
f"{brick.close:.{DIGITS}f}"
|
|
58
|
+
)
|
|
59
|
+
else:
|
|
60
|
+
linha = (
|
|
61
|
+
f"{brick.direction.upper()} "
|
|
62
|
+
f"{brick.open:.{DIGITS}f} "
|
|
63
|
+
f"{brick.close:.{DIGITS}f}"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
click.echo(linha)
|
|
67
|
+
|
|
68
|
+
if em_formacao:
|
|
69
|
+
click.echo()
|
|
70
|
+
click.echo("EM FORMACAO:")
|
|
71
|
+
click.echo(
|
|
72
|
+
f"{em_formacao.direction.upper()} "
|
|
73
|
+
f"{em_formacao.open:.{DIGITS}f} "
|
|
74
|
+
f"{em_formacao.close:.{DIGITS}f}"
|
|
75
|
+
)
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Renko controller.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from ..models.renko_model import RenkoModel
|
|
6
|
-
from mtcli.logger import setup_logger
|
|
7
|
-
|
|
8
|
-
log = setup_logger(__name__)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class RenkoController:
|
|
12
|
-
|
|
13
|
-
def __init__(
|
|
14
|
-
self,
|
|
15
|
-
symbol,
|
|
16
|
-
brick_size,
|
|
17
|
-
timeframe,
|
|
18
|
-
quantidade,
|
|
19
|
-
modo="simples",
|
|
20
|
-
ancorar_abertura=False,
|
|
21
|
-
data_mode="candle",
|
|
22
|
-
max_ticks=3000,
|
|
23
|
-
):
|
|
24
|
-
self.model = RenkoModel(symbol, brick_size)
|
|
25
|
-
self.timeframe = timeframe
|
|
26
|
-
self.quantidade = quantidade
|
|
27
|
-
self.modo = modo
|
|
28
|
-
self.ancorar_abertura = ancorar_abertura
|
|
29
|
-
self.data_mode = data_mode
|
|
30
|
-
self.max_ticks = max_ticks
|
|
31
|
-
|
|
32
|
-
def executar(self):
|
|
33
|
-
|
|
34
|
-
# -------------------------------------------------
|
|
35
|
-
# TICK MODE
|
|
36
|
-
# -------------------------------------------------
|
|
37
|
-
|
|
38
|
-
if self.data_mode == "tick":
|
|
39
|
-
|
|
40
|
-
ticks = self.model.obter_ticks(
|
|
41
|
-
timeframe=self.timeframe,
|
|
42
|
-
max_ticks=self.max_ticks,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
if ticks is None or len(ticks) == 0:
|
|
46
|
-
return []
|
|
47
|
-
|
|
48
|
-
return self.model.construir_renko_ticks(ticks)
|
|
49
|
-
|
|
50
|
-
# -------------------------------------------------
|
|
51
|
-
# CANDLE MODE
|
|
52
|
-
# -------------------------------------------------
|
|
53
|
-
|
|
54
|
-
rates = self.model.obter_rates(
|
|
55
|
-
self.timeframe,
|
|
56
|
-
self.quantidade,
|
|
57
|
-
ancorar_abertura=self.ancorar_abertura,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
if rates is None or len(rates) == 0:
|
|
61
|
-
return []
|
|
62
|
-
|
|
63
|
-
return self.model.construir_renko(
|
|
64
|
-
rates,
|
|
65
|
-
modo=self.modo,
|
|
66
|
-
)
|
|
@@ -1,37 +0,0 @@
|
|
|
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
|
-
if not bricks:
|
|
14
|
-
click.echo("Nenhum bloco Renko gerado.")
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
click.echo("=== GRAFICO RENKO ===")
|
|
18
|
-
click.echo(f"Total de blocos: {len(bricks)}")
|
|
19
|
-
click.echo()
|
|
20
|
-
|
|
21
|
-
for i, brick in enumerate(bricks, start=1):
|
|
22
|
-
|
|
23
|
-
if numerar:
|
|
24
|
-
linha = (
|
|
25
|
-
f"{i} "
|
|
26
|
-
f"{brick.direction.upper()} "
|
|
27
|
-
f"{brick.open:.{DIGITS}f} "
|
|
28
|
-
f"{brick.close:.{DIGITS}f}"
|
|
29
|
-
)
|
|
30
|
-
else:
|
|
31
|
-
linha = (
|
|
32
|
-
f"{brick.direction.upper()} "
|
|
33
|
-
f"{brick.open:.{DIGITS}f} "
|
|
34
|
-
f"{brick.close:.{DIGITS}f}"
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
click.echo(linha)
|
|
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
|