Gr8/updateTrade.py

120 lines
4 KiB
Python
Raw Permalink Normal View History

2025-09-10 15:02:31 +03:00
import MetaTrader5 as mt5
import logging
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
import json
# -----------------------------
# Logging
# -----------------------------
logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s")
log = logging.getLogger()
# -----------------------------
# Load Config
# -----------------------------
def load_config(filepath="config.json"):
with open(filepath, "r") as f:
return json.load(f)
# -----------------------------
# Send Email
# -----------------------------
def send_email(subject, body, smtp_config):
recipients = smtp_config["recipient_email"]
if isinstance(recipients, str):
recipients = [recipients]
msg = MIMEMultipart()
msg["From"] = smtp_config["sender_email"]
msg["To"] = ", ".join(recipients)
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain"))
try:
with smtplib.SMTP(smtp_config["smtp_server"], smtp_config["smtp_port"]) as server:
server.starttls()
server.login(smtp_config["sender_email"], smtp_config["sender_password"])
server.send_message(msg)
log.info(f"Email sent to: {', '.join(recipients)}")
except Exception as e:
log.error(f"Error sending email: {e}")
# -----------------------------
# Update any position (buy/sell)
# -----------------------------
def update_position(position_ticket, sl_points=15, tp_points=15, smtp_config=None):
position = mt5.positions_get(ticket=position_ticket)
if not position:
log.error(f"Position {position_ticket} not found")
return
pos = position[0]
symbol_info = mt5.symbol_info(pos.symbol)
if not symbol_info:
log.error(f"Symbol info not found for {pos.symbol}")
return
tick = mt5.symbol_info_tick(pos.symbol)
if tick is None:
log.error(f"No tick data for {pos.symbol}")
return
point = symbol_info.point
# Determine prices based on buy/sell
if pos.type == mt5.ORDER_TYPE_BUY:
sl_price = tick.bid - sl_points * point # SL below current price
tp_price = tick.bid + tp_points * point # TP above current price
else: # SELL
sl_price = tick.ask + sl_points * point # SL above current price
tp_price = tick.ask - tp_points * point # TP below current price
request = {
"action": mt5.TRADE_ACTION_SLTP,
"position": position_ticket,
"symbol": pos.symbol,
"sl": sl_price,
"tp": tp_price,
"magic": pos.magic,
"comment": "Update SL/TP via Python",
}
result = mt5.order_send(request)
if result.retcode != mt5.TRADE_RETCODE_DONE:
log.error(f"Failed to update position {position_ticket}: {result.retcode}")
if smtp_config:
send_email(
subject=f"Failed to update position {position_ticket}",
body=f"Position update failed with code {result.retcode} for {pos.symbol}",
smtp_config=smtp_config
)
else:
log.info(f"Position {position_ticket} updated successfully: SL={sl_price}, TP={tp_price}")
if smtp_config:
send_email(
subject=f"Position {position_ticket} updated",
body=f"Updated position {position_ticket} ({pos.symbol})\nSL: {sl_price}\nTP: {tp_price}",
smtp_config=smtp_config
)
return result
# -----------------------------
# Example usage
# -----------------------------
if __name__ == "__main__":
config = load_config("config.json")
if not mt5.initialize():
log.error(f"MT5 initialize failed: {mt5.last_error()}")
quit()
log.info("Connected to MT5 terminal")
# Replace with actual position tickets
position_tickets = [53171689231, 557416536]
for ticket in position_tickets:
update_position(ticket, sl_points=150, tp_points=2000, smtp_config=config["email"])
mt5.shutdown()
log.info("MT5 shutdown complete")