209 lines
6.5 KiB
Python
209 lines
6.5 KiB
Python
# import MetaTrader5 as mt5
|
|
# import time
|
|
# import random
|
|
# import logging
|
|
|
|
# # -----------------------------
|
|
# # Logging
|
|
# # -----------------------------
|
|
# logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s")
|
|
# log = logging.getLogger()
|
|
|
|
# # -----------------------------
|
|
# # Parameters
|
|
# # -----------------------------
|
|
# SYMBOLS = ["XAUUSD", "US30", "USTEC", "EURUSD", "USDJPY"]
|
|
# LOT_SIZE = 0.01
|
|
# TRADE_DELAY = 2 # seconds before closing position
|
|
|
|
# # -----------------------------
|
|
# # Connect to MT5
|
|
# # -----------------------------
|
|
# if not mt5.initialize():
|
|
# log.error(f"MT5 initialize failed: {mt5.last_error()}")
|
|
# quit()
|
|
# log.info("Connected to MT5 terminal")
|
|
|
|
# # -----------------------------
|
|
# # Helper to open random trade
|
|
# # -----------------------------
|
|
# def open_random_trade():
|
|
# symbol = random.choice(SYMBOLS)
|
|
# symbol_info = mt5.symbol_info(symbol)
|
|
# if symbol_info is None:
|
|
# log.warning(f"{symbol} not found")
|
|
# return None
|
|
|
|
# if not symbol_info.visible:
|
|
# if not mt5.symbol_select(symbol, True):
|
|
# log.warning(f"Cannot select {symbol}")
|
|
# return None
|
|
|
|
# order_type = random.choice([mt5.ORDER_TYPE_BUY, mt5.ORDER_TYPE_SELL])
|
|
# tick = mt5.symbol_info_tick(symbol)
|
|
# price = tick.ask if order_type == mt5.ORDER_TYPE_BUY else tick.bid
|
|
|
|
# request = {
|
|
# "action": mt5.TRADE_ACTION_DEAL,
|
|
# "symbol": symbol,
|
|
# "volume": LOT_SIZE,
|
|
# "type": order_type,
|
|
# "price": price,
|
|
# "deviation": 50,
|
|
# "magic": 123456,
|
|
# "comment": "Random quick trade",
|
|
# "type_time": mt5.ORDER_TIME_GTC,
|
|
# "type_filling": mt5.ORDER_FILLING_RETURN,
|
|
# }
|
|
|
|
# result = mt5.order_send(request)
|
|
# if result.retcode != mt5.TRADE_RETCODE_DONE:
|
|
# log.error(f"Trade failed: {result.retcode}")
|
|
# return None
|
|
# log.info(f"Opened {'BUY' if order_type==mt5.ORDER_TYPE_BUY else 'SELL'} {symbol} @ {price}, Ticket={result.order}")
|
|
# return result.order
|
|
|
|
# # -----------------------------
|
|
# # Helper to close position
|
|
# # -----------------------------
|
|
# def close_position(ticket):
|
|
# positions = mt5.positions_get(ticket=ticket)
|
|
# if not positions:
|
|
# log.warning(f"Position {ticket} not found")
|
|
# return
|
|
# pos = positions[0]
|
|
# tick = mt5.symbol_info_tick(pos.symbol)
|
|
# price = tick.bid if pos.type == mt5.ORDER_TYPE_BUY else tick.ask
|
|
# close_request = {
|
|
# "action": mt5.TRADE_ACTION_DEAL,
|
|
# "symbol": pos.symbol,
|
|
# "volume": pos.volume,
|
|
# "type": mt5.ORDER_TYPE_SELL if pos.type==mt5.ORDER_TYPE_BUY else mt5.ORDER_TYPE_BUY,
|
|
# "position": ticket,
|
|
# "price": price,
|
|
# "deviation": 50,
|
|
# "magic": 123456,
|
|
# "comment": "Random trade close",
|
|
# "type_time": mt5.ORDER_TIME_GTC,
|
|
# "type_filling": mt5.ORDER_FILLING_RETURN,
|
|
# }
|
|
# result = mt5.order_send(close_request)
|
|
# if result.retcode != mt5.TRADE_RETCODE_DONE:
|
|
# log.error(f"Failed to close {ticket}: {result.retcode}")
|
|
# else:
|
|
# log.info(f"Closed Ticket={ticket} @ {price}")
|
|
|
|
# # -----------------------------
|
|
# # Main Loop
|
|
# # -----------------------------
|
|
# try:
|
|
# while True:
|
|
# ticket = open_random_trade()
|
|
# if ticket:
|
|
# time.sleep(TRADE_DELAY)
|
|
# close_position(ticket)
|
|
# time.sleep(1) # small delay between trades
|
|
# except KeyboardInterrupt:
|
|
# log.info("Stopped by user")
|
|
# finally:
|
|
# mt5.shutdown()
|
|
# log.info("MT5 connection closed")
|
|
|
|
|
|
import MetaTrader5 as mt5
|
|
import logging
|
|
import time
|
|
import random
|
|
|
|
# -----------------------------
|
|
# Logging
|
|
# -----------------------------
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s")
|
|
log = logging.getLogger()
|
|
|
|
# -----------------------------
|
|
# Initialize MT5
|
|
# -----------------------------
|
|
if not mt5.initialize():
|
|
log.error(f"MT5 initialize failed: {mt5.last_error()}")
|
|
quit()
|
|
log.info("Connected to MT5 terminal")
|
|
|
|
# -----------------------------
|
|
# Parameters
|
|
# -----------------------------
|
|
SYMBOLS = ["XAUUSD", "USDJPY", "US30", "USTEC"] # Add symbols you want to trade
|
|
LOT_SIZE = 0.01
|
|
DEVIATION = 20
|
|
MAGIC = 123456
|
|
TRADE_DELAY = 1 # seconds between trades
|
|
|
|
# -----------------------------
|
|
# Helper: Check if trade can be placed
|
|
# -----------------------------
|
|
def can_trade(symbol, lot_size):
|
|
info = mt5.symbol_info(symbol)
|
|
if not info:
|
|
log.warning(f"{symbol} not found")
|
|
return False, None
|
|
if not info.visible:
|
|
if not mt5.symbol_select(symbol, True):
|
|
log.warning(f"{symbol} cannot be added to Market Watch")
|
|
return False, None
|
|
if info.trade_mode != mt5.SYMBOL_TRADE_MODE_FULL:
|
|
log.warning(f"{symbol} not tradable in full mode")
|
|
return False, None
|
|
|
|
price = mt5.symbol_info_tick(symbol).ask
|
|
required_margin = mt5.order_calc_margin(mt5.ORDER_TYPE_BUY, symbol, lot_size, price)
|
|
account = mt5.account_info()
|
|
if required_margin > account.margin_free:
|
|
log.warning(f"Not enough margin for {symbol}: required {required_margin}, free {account.margin_free}")
|
|
return False, price
|
|
return True, price
|
|
|
|
# -----------------------------
|
|
# Place Market Order
|
|
# -----------------------------
|
|
def place_order(symbol, lot_size, order_type):
|
|
ok, price = can_trade(symbol, lot_size)
|
|
if not ok:
|
|
return None
|
|
|
|
request = {
|
|
"action": mt5.TRADE_ACTION_DEAL,
|
|
"symbol": symbol,
|
|
"volume": lot_size,
|
|
"type": order_type,
|
|
"price": price,
|
|
"deviation": DEVIATION,
|
|
"magic": MAGIC,
|
|
"comment": "Python HFT simulation",
|
|
"type_time": mt5.ORDER_TIME_GTC,
|
|
"type_filling": mt5.ORDER_FILLING_RETURN, # safer than FOK
|
|
}
|
|
|
|
result = mt5.order_send(request)
|
|
if result.retcode == mt5.TRADE_RETCODE_DONE:
|
|
log.info(f"Trade successful: {symbol} {['BUY','SELL'][order_type==mt5.ORDER_TYPE_SELL]} {lot_size} lots at {price}")
|
|
else:
|
|
log.error(f"Trade failed for {symbol}: {result.retcode}")
|
|
return result
|
|
|
|
# -----------------------------
|
|
# HFT Loop Example
|
|
# -----------------------------
|
|
try:
|
|
while True:
|
|
symbol = random.choice(SYMBOLS)
|
|
order_type = random.choice([mt5.ORDER_TYPE_BUY, mt5.ORDER_TYPE_SELL])
|
|
place_order(symbol, LOT_SIZE, order_type)
|
|
time.sleep(TRADE_DELAY)
|
|
except KeyboardInterrupt:
|
|
log.info("Stopping HFT simulation")
|
|
|
|
# -----------------------------
|
|
# Shutdown
|
|
# -----------------------------
|
|
mt5.shutdown()
|
|
log.info("MT5 shutdown complete")
|