mtcli-risco 0.1.0__tar.gz → 1.0.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mtcli-risco
3
- Version: 0.1.0
3
+ Version: 1.0.0
4
4
  Summary: Plugin do mtcli
5
5
  License: GPL-3.0
6
6
  Author: Valmir França da Silva
@@ -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 carregar_estado, salvar_estado, risco_excedido
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
- def cli(limite):
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(f"🚫 Limite diário ({limite}) excedido. Bloqueando novas ordens.")
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.")
@@ -0,0 +1,110 @@
1
+ """Lógica do plugin risco."""
2
+
3
+ import MetaTrader5 as mt5
4
+ import json
5
+ import os
6
+ from datetime import date, datetime, time
7
+ from mtcli.conecta import conectar, shutdown
8
+ from mtcli.logger import setup_logger
9
+
10
+ log = setup_logger()
11
+
12
+
13
+ def carregar_estado(arquivo_estado):
14
+ """Carrega o estado do controle de risco."""
15
+ if os.path.exists(arquivo_estado):
16
+ with open(arquivo_estado, "r") as f:
17
+ log.info(f"Carregando dados do arquivo {arquivo_estado}")
18
+ return json.load(f)
19
+ return {"data": None, "bloqueado": False}
20
+
21
+
22
+ def salvar_estado(arquivo_estado, data, bloqueado):
23
+ """Salva o estado do controle de risco."""
24
+ with open(arquivo_estado, "w") as f:
25
+ json.dump({"data": data.isoformat(), "bloqueado": bloqueado}, f)
26
+ log.info(f"Salvando o estado: data {data} bloqueado {bloqueado}")
27
+
28
+
29
+ def calcular_lucro_total_dia():
30
+ """Calcula o lucro total do dia."""
31
+ hoje = datetime.now().date()
32
+ inicio = datetime.combine(hoje, time(0, 0))
33
+ fim = datetime.combine(hoje, time(23, 59))
34
+
35
+ deals = mt5.history_deals_get(inicio, fim)
36
+ lucro_realizado = 0.0
37
+
38
+ if deals is not None:
39
+ lucro_realizado = sum(deal.profit for deal in deals if deal.type in (1, 2))
40
+
41
+ info = mt5.account_info()
42
+ lucro_aberto = info.profit if info else 0.0
43
+
44
+ total = lucro_realizado + lucro_aberto
45
+ log.info(
46
+ f"Lucro realizado: {lucro_realizado}, lucro aberto: {lucro_aberto}, total: {total}"
47
+ )
48
+ return total
49
+
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
+
94
+ def risco_excedido(limite):
95
+ conectar()
96
+ try:
97
+ total_lucro = calcular_lucro_total_dia()
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
106
+ except Exception as e:
107
+ log.error(f"Erro ao verificar risco: {e}")
108
+ return False
109
+ finally:
110
+ shutdown()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mtcli-risco"
3
- version = "0.1.0"
3
+ version = "1.0.0"
4
4
  description = "Plugin do mtcli"
5
5
  authors = [
6
6
  {name = "Valmir França da Silva",email = "vfranca3@gmail.com"}
@@ -1,61 +0,0 @@
1
- """Lógica do plugin risco."""
2
-
3
- import MetaTrader5 as mt5
4
- import json
5
- import os
6
- from datetime import date, datetime, time
7
- from mtcli.conecta import conectar, shutdown
8
- from mtcli.logger import setup_logger
9
-
10
- log = setup_logger()
11
-
12
-
13
- def carregar_estado(arquivo_estado):
14
- """Carrega o estado do controle de risco."""
15
- if os.path.exists(arquivo_estado):
16
- with open(arquivo_estado, "r") as f:
17
- log.info(f"Carregando dados do arquivo {arquivo_estado}")
18
- return json.load(f)
19
- return {"data": None, "bloqueado": False}
20
-
21
-
22
- def salvar_estado(arquivo_estado, data, bloqueado):
23
- """Salva o estado do controle de risco."""
24
- with open(arquivo_estado, "w") as f:
25
- json.dump({"data": data.isoformat(), "bloqueado": bloqueado}, f)
26
- log.info(f"Salvando o estado: data {data} bloqueado {bloqueado}")
27
-
28
-
29
- def calcular_lucro_total_dia():
30
- """Calcula o lucro total do dia."""
31
- hoje = datetime.now().date()
32
- inicio = datetime.combine(hoje, time(0, 0))
33
- fim = datetime.combine(hoje, time(23, 59))
34
-
35
- deals = mt5.history_deals_get(inicio, fim)
36
- lucro_realizado = 0.0
37
-
38
- if deals is not None:
39
- lucro_realizado = sum(deal.profit for deal in deals if deal.type in (1, 2))
40
-
41
- info = mt5.account_info()
42
- lucro_aberto = info.profit if info else 0.0
43
-
44
- total = lucro_realizado + lucro_aberto
45
- log.info(
46
- f"Lucro realizado: {lucro_realizado}, lucro aberto: {lucro_aberto}, total: {total}"
47
- )
48
- return total
49
-
50
-
51
- def risco_excedido(limite):
52
- """Verifica se o prejuízo excedeu o limite permitido."""
53
- conectar()
54
- try:
55
- total_lucro = calcular_lucro_total_dia()
56
- return total_lucro <= limite
57
- except Exception as e:
58
- log.error(f"Erro ao verificar risco: {e}")
59
- return False
60
- finally:
61
- shutdown()
File without changes
File without changes