mtcli-risco 0.1.0__py3-none-any.whl → 1.0.0__py3-none-any.whl
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_risco/plugin.py +28 -3
- mtcli_risco/risco.py +51 -2
- {mtcli_risco-0.1.0.dist-info → mtcli_risco-1.0.0.dist-info}/METADATA +1 -1
- mtcli_risco-1.0.0.dist-info/RECORD +9 -0
- mtcli_risco-0.1.0.dist-info/RECORD +0 -9
- {mtcli_risco-0.1.0.dist-info → mtcli_risco-1.0.0.dist-info}/LICENSE +0 -0
- {mtcli_risco-0.1.0.dist-info → mtcli_risco-1.0.0.dist-info}/WHEEL +0 -0
- {mtcli_risco-0.1.0.dist-info → mtcli_risco-1.0.0.dist-info}/entry_points.txt +0 -0
mtcli_risco/plugin.py
CHANGED
|
@@ -5,7 +5,14 @@ from datetime import date
|
|
|
5
5
|
from mtcli.conecta import conectar, shutdown
|
|
6
6
|
from mtcli.logger import setup_logger
|
|
7
7
|
from .conf import LOSS_LIMIT, ARQUIVO_ESTADO
|
|
8
|
-
from .risco import
|
|
8
|
+
from .risco import (
|
|
9
|
+
carregar_estado,
|
|
10
|
+
salvar_estado,
|
|
11
|
+
risco_excedido,
|
|
12
|
+
encerrar_todas_posicoes,
|
|
13
|
+
cancelar_todas_ordens,
|
|
14
|
+
)
|
|
15
|
+
|
|
9
16
|
|
|
10
17
|
log = setup_logger()
|
|
11
18
|
|
|
@@ -18,10 +25,24 @@ log = setup_logger()
|
|
|
18
25
|
default=LOSS_LIMIT,
|
|
19
26
|
help="Limite de perda diária (ex: -500), default -180.00.",
|
|
20
27
|
)
|
|
21
|
-
|
|
28
|
+
@click.option(
|
|
29
|
+
"--status",
|
|
30
|
+
is_flag=True,
|
|
31
|
+
default=False,
|
|
32
|
+
help="Exibe o lucro total do dia atualizado e sai.",
|
|
33
|
+
)
|
|
34
|
+
def cli(limite, status):
|
|
22
35
|
"""Monitora e bloqueia ordens se o limite de prejuízo for atingido."""
|
|
23
36
|
conectar()
|
|
24
37
|
|
|
38
|
+
if status:
|
|
39
|
+
from .risco import calcular_lucro_total_dia
|
|
40
|
+
|
|
41
|
+
lucro = calcular_lucro_total_dia()
|
|
42
|
+
click.echo(f"Lucro total do dia (realizado + aberto): {lucro:.2f}")
|
|
43
|
+
shutdown()
|
|
44
|
+
return
|
|
45
|
+
|
|
25
46
|
estado = carregar_estado(ARQUIVO_ESTADO)
|
|
26
47
|
hoje = date.today()
|
|
27
48
|
|
|
@@ -35,7 +56,11 @@ def cli(limite):
|
|
|
35
56
|
return
|
|
36
57
|
|
|
37
58
|
if risco_excedido(limite):
|
|
38
|
-
click.echo(
|
|
59
|
+
click.echo(
|
|
60
|
+
f"🚫 Limite diário ({limite}) excedido. Encerrando posições e bloqueando novas ordens."
|
|
61
|
+
)
|
|
62
|
+
encerrar_todas_posicoes()
|
|
63
|
+
cancelar_todas_ordens()
|
|
39
64
|
salvar_estado(ARQUIVO_ESTADO, hoje, True)
|
|
40
65
|
else:
|
|
41
66
|
click.echo("Dentro do limite de risco.")
|
mtcli_risco/risco.py
CHANGED
|
@@ -48,12 +48,61 @@ def calcular_lucro_total_dia():
|
|
|
48
48
|
return total
|
|
49
49
|
|
|
50
50
|
|
|
51
|
+
def encerrar_todas_posicoes():
|
|
52
|
+
positions = mt5.positions_get()
|
|
53
|
+
if not positions:
|
|
54
|
+
log.info("Nenhuma posição aberta para fechar.")
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
for pos in positions:
|
|
58
|
+
tipo_oposto = (
|
|
59
|
+
mt5.ORDER_TYPE_SELL
|
|
60
|
+
if pos.type == mt5.ORDER_TYPE_BUY
|
|
61
|
+
else mt5.ORDER_TYPE_BUY
|
|
62
|
+
)
|
|
63
|
+
ordem_fechar = {
|
|
64
|
+
"action": mt5.TRADE_ACTION_DEAL,
|
|
65
|
+
"symbol": pos.symbol,
|
|
66
|
+
"volume": pos.volume,
|
|
67
|
+
"type": tipo_oposto,
|
|
68
|
+
"position": pos.ticket,
|
|
69
|
+
"deviation": 10,
|
|
70
|
+
"magic": 1000,
|
|
71
|
+
"comment": "Fechando posição por limite de risco",
|
|
72
|
+
}
|
|
73
|
+
resultado = mt5.order_send(ordem_fechar)
|
|
74
|
+
if resultado.retcode != mt5.TRADE_RETCODE_DONE:
|
|
75
|
+
log.error(f"Falha ao fechar posição {pos.ticket}: {resultado.retcode}")
|
|
76
|
+
else:
|
|
77
|
+
log.info(f"Posição {pos.ticket} fechada com sucesso.")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def cancelar_todas_ordens():
|
|
81
|
+
ordens = mt5.orders_get()
|
|
82
|
+
if not ordens:
|
|
83
|
+
log.info("Nenhuma ordem pendente para cancelar.")
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
for ordem in ordens:
|
|
87
|
+
resultado = mt5.order_delete(ordem.ticket)
|
|
88
|
+
if resultado.retcode != mt5.TRADE_RETCODE_DONE:
|
|
89
|
+
log.error(f"Falha ao cancelar ordem {ordem.ticket}: {resultado.retcode}")
|
|
90
|
+
else:
|
|
91
|
+
log.info(f"Ordem {ordem.ticket} cancelada com sucesso.")
|
|
92
|
+
|
|
93
|
+
|
|
51
94
|
def risco_excedido(limite):
|
|
52
|
-
"""Verifica se o prejuízo excedeu o limite permitido."""
|
|
53
95
|
conectar()
|
|
54
96
|
try:
|
|
55
97
|
total_lucro = calcular_lucro_total_dia()
|
|
56
|
-
|
|
98
|
+
if total_lucro <= limite:
|
|
99
|
+
log.warning(
|
|
100
|
+
"Limite de prejuízo excedido! Encerrando posições e cancelando ordens."
|
|
101
|
+
)
|
|
102
|
+
encerrar_todas_posicoes()
|
|
103
|
+
cancelar_todas_ordens()
|
|
104
|
+
return True
|
|
105
|
+
return False
|
|
57
106
|
except Exception as e:
|
|
58
107
|
log.error(f"Erro ao verificar risco: {e}")
|
|
59
108
|
return False
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
mtcli_risco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mtcli_risco/conf.py,sha256=nNQUfiQJ-LPzAqMAyDIHUxcjc8wxZ1yVnwJaSualhuk,294
|
|
3
|
+
mtcli_risco/plugin.py,sha256=h-9NkAwbaem9EHQ1LpXsxaP8OukP24GD1vsOl4Mr4qI,1865
|
|
4
|
+
mtcli_risco/risco.py,sha256=PaPRsGJQT9AcxRN39DcwjaFV5kAecLMYfuDND9K9NYY,3508
|
|
5
|
+
mtcli_risco-1.0.0.dist-info/entry_points.txt,sha256=pPmBNOystUidnZ4FoPta9-6sM9u7FCneA-4Cm2RMq4s,52
|
|
6
|
+
mtcli_risco-1.0.0.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
7
|
+
mtcli_risco-1.0.0.dist-info/METADATA,sha256=V9faC6QrCcOTiHlw76MCrPDMDaW-qLuurh0mI4xqLQc,2104
|
|
8
|
+
mtcli_risco-1.0.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
9
|
+
mtcli_risco-1.0.0.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
mtcli_risco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
mtcli_risco/conf.py,sha256=nNQUfiQJ-LPzAqMAyDIHUxcjc8wxZ1yVnwJaSualhuk,294
|
|
3
|
-
mtcli_risco/plugin.py,sha256=7dAmll-JM8D3n2mwrn7_GMedrTsZvHjj7FXQO86Bg6k,1297
|
|
4
|
-
mtcli_risco/risco.py,sha256=SrC72pdP4GwE9dNgIE9ZEUK7Bd1nK23SEQtJW6X6Iy4,1869
|
|
5
|
-
mtcli_risco-0.1.0.dist-info/entry_points.txt,sha256=pPmBNOystUidnZ4FoPta9-6sM9u7FCneA-4Cm2RMq4s,52
|
|
6
|
-
mtcli_risco-0.1.0.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
7
|
-
mtcli_risco-0.1.0.dist-info/METADATA,sha256=OltPrE78BoNXmt8K_59pSZVMsqykznKdFHuHMXAIGIo,2104
|
|
8
|
-
mtcli_risco-0.1.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
9
|
-
mtcli_risco-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|