from datetime import datetime from time import sleep from pandas.plotting import register_matplotlib_converters import MetaTrader5 as mt5 if not mt5.initialize(): # mt5.initialize('C:/Program Files/MetaTrader 5/terminal.exe'): print("initialize() failed") mt5.shutdown() print(mt5.terminal_info()) print(mt5.version()) # mt5.login('41282', password='fquuiv2d', server='PMEX-Demo', ) # connect to the trade account without specifying a password and a server account = 41447 password = "aj3spdyp" # account = 41468 # password = "o3nfwqbm" authorized = mt5.login(account, password=password, server='PMEX-Demo') # the terminal database password is applied if connection data is set to be remembered if authorized: print("connected to account #{}".format(account)) else: print("failed to connect at account #{}, error code: {}".format(account, mt5.last_error())) price_of_each_step = 0.3 first_order_price_deviation = 0.4 stop_loss_price_deviation = 0.5 first_buy_order_lot_size = 10.0 # set to 10 second_buy_order_lot_size = 5.0 # set to 5 other_buy_order_lot_size = 2.0 # set to 2 first_sell_order_lot_size = 10.0 # set to 10 second_sell_order_lot_size = 5.0 # set to 5 other_sell_order_lot_size = 2.0 # set to 2 deviation = 20 # mt5 setting # ----------------------Program Vars------------------------------- # ----------------------DO NOT EDIT-------------------------------- # When either stop losses are executed then reset all orders buy_stop_loss_execution_price = 0 sell_stop_loss_execution_price = 0 first_buy_execution_price = 0 first_sell_execution_price = 0 first_buy_executed = False first_sell_executed = False first_buy_ticket_id = 0 first_sell_ticket_id = 0 open_position_buy_ticket_id = 0 open_position_sell_ticket_id = 0 def on_price_change_handler(current_price): # Update first_buy_executed and first_sell_stop_executed global first_buy_ticket_id global first_sell_ticket_id global open_position_buy_ticket_id global open_position_sell_ticket_id global highest_price global lowest_price is_first_buy_order_executed = False is_first_sell_order_executed = False if bool(first_buy_ticket_id): is_first_buy_order_executed = False if mt5.orders_get(ticket=first_buy_ticket_id) else True if bool(first_sell_ticket_id): is_first_sell_order_executed = False if mt5.orders_get(ticket=first_sell_ticket_id) else True if bool(first_buy_ticket_id): first_buy_ticket_id = 0 if is_first_buy_order_executed: delete_all_orders(type="sell") if bool(first_sell_ticket_id): first_sell_ticket_id = 0 if is_first_sell_order_executed: delete_all_orders(type="buy") open_positions = mt5.positions_get() buy_positions = [i for i in open_positions if i.type == 0] sell_positions = [i for i in open_positions if i.type == 1] if buy_positions: if not bool(open_position_buy_ticket_id): open_position_buy_ticket_id = buy_positions[0].ticket stop_loss = current_price - stop_loss_price_deviation change_stop_loss_all_orders(new_stop_loss_price=stop_loss, type='buy') else: # Maybe a position existed previously but the stop loss was hit, and its gone now if bool(open_position_buy_ticket_id): # If Buy Stop Loss order is executed(Price falls below buy_stop_loss_execution_price) open_position_buy_ticket_id = 0 # we set to position to null, if it existed highest_price = current_price lowest_price = current_price delete_and_rebuild_all_orders() sleep(1) if sell_positions: if not bool(open_position_sell_ticket_id): open_position_sell_ticket_id = sell_positions[0].ticket stop_loss = current_price + stop_loss_price_deviation change_stop_loss_all_orders(new_stop_loss_price=stop_loss, type='sell') else: # Maybe a position existed previously but the stop loss was hit, and its gone now if bool(open_position_sell_ticket_id): # If Sell Stop Loss order is executed(Price Increases above sell_stop_loss_execution_price) open_position_sell_ticket_id = 0 # we set to position to null, if it existed highest_price = current_price lowest_price = current_price delete_and_rebuild_all_orders() sleep(1) def on_highest_price_change_handler(current_price): stop_loss = current_price - stop_loss_price_deviation change_stop_loss_all_orders(stop_loss, type='buy') def on_lowest_price_change_handler(current_price): stop_loss = current_price + stop_loss_price_deviation change_stop_loss_all_orders(stop_loss, type='sell') def process_post_order_execution(result, lot, price): if not result: print(f"Failed to place order error code: {mt5.last_error()}") # mt5.shutdown() # quit() # check the execution result # print("1. order_send(): by {} {} lots at {} with deviation={} points".format(symbol, lot, price, deviation)) if result.retcode != mt5.TRADE_RETCODE_DONE: # print("2. order_send failed, retcode={}".format(result.retcode)) result_dict = result._asdict() for field in result_dict.keys(): # print(" {}={}".format(field, result_dict[field])) if field == "request": traderequest_dict = result_dict[field]._asdict() for tradereq_filed in traderequest_dict: # print(" traderequest: {}={}".format(tradereq_filed, traderequest_dict[tradereq_filed])) pass print("Don't shutdown() and quit") # mt5.shutdown() # quit() else: print("2. order_send done, ") print(" opened position with POSITION_TICKET={}".format(result.order)) def place_buy_stop_order(symbol, lot, price, stop_loss, is_first=False): request = { "action": mt5.TRADE_ACTION_PENDING, "symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_BUY_STOP, "price": price, "deviation": deviation, # "magic": 234000, "comment": "python script open", "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_RETURN, } # send a trading request result = mt5.order_send(request) if is_first: global first_buy_ticket_id first_buy_ticket_id = result.order process_post_order_execution(result, lot, price) def place_sell_stop_order(symbol, lot, price, stop_loss, is_first=False): request = { "action": mt5.TRADE_ACTION_PENDING, "symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_SELL_STOP, "price": price, "deviation": deviation, # "magic": 234000, "comment": "python script open", "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_RETURN, } # send a trading request result = mt5.order_send(request) if is_first: global first_sell_ticket_id first_sell_ticket_id = result.order process_post_order_execution(result, lot, price) def change_stop_loss_all_orders(new_stop_loss_price, type='buy'): # orders = mt5.orders_get(symbol=symbol) positions = mt5.positions_get(symbol=symbol) # type=4 is BUY Stop if positions is None: print(f"No Positions on {symbol}, error code={mt5.last_error()}") else: print(f"Total Positions on {symbol}:", len(positions)) # display all active orders for position in positions: request = { 'action': mt5.TRADE_ACTION_SLTP, "symbol": symbol, "volume": position.volume, 'price_open': position.price_open, 'sl': new_stop_loss_price, "comment": "python script modify", 'ticket': position.ticket, 'ENUM_ORDER_STATE': mt5.ORDER_FILLING_RETURN # Old Details # "price": order.price_open, } if position.type == 0 and type == 'buy': # request['action'] = mt5.POSITION_TYPE_BUY mt5.order_send(request) print( f"Modified Stop Loss on #{position.ticket}, Old Price: {position.sl} ---> New Price:{new_stop_loss_price}") elif position.type == 1 and type == 'sell': # request['action'] = mt5.POSITION_TYPE_SELL mt5.order_send(request) print( f"Modified Stop Loss on #{position.ticket}, Old Price: {position.sl} ---> New Price:{new_stop_loss_price}") def delete_all_orders(type='buy'): orders = mt5.orders_get(symbol=symbol) # type=4 is BUY Stop if orders is None: print(f"No orders on {symbol}, error code={mt5.last_error()}") else: print(f"Total orders on {symbol}:", len(orders)) # display all active orders for order in orders: request = { "action": mt5.TRADE_ACTION_REMOVE, 'order': order.ticket, "comment": "python script delete", } if order.type == 4 and type == 'buy': mt5.order_send(request) elif order.type != 4 and type == 'sell': mt5.order_send(request) print(f"Deleted #{order.ticket}") def place_list_of_orders(current_price, type='buy'): if type == "buy": first_order_price = current_price + first_order_price_deviation # (price_of_each_step * no_of_steps) second_order_price = first_order_price + price_of_each_step subsequent_order_price = second_order_price + price_of_each_step global first_buy_execution_price first_buy_execution_price = first_order_price stop_loss = first_order_price - stop_loss_price_deviation global buy_stop_loss_execution_price buy_stop_loss_execution_price = stop_loss else: first_order_price = current_price - first_order_price_deviation # (price_of_each_step * no_of_steps) second_order_price = first_order_price - price_of_each_step subsequent_order_price = second_order_price - price_of_each_step global first_sell_execution_price first_sell_execution_price = first_order_price stop_loss = first_order_price + stop_loss_price_deviation global sell_stop_loss_execution_price sell_stop_loss_execution_price = stop_loss # First Order if type == "buy": place_buy_stop_order(symbol, first_buy_order_lot_size, first_order_price, stop_loss, is_first=True) else: place_sell_stop_order(symbol, first_sell_order_lot_size, first_order_price, stop_loss, is_first=True) # Second Order if type == "buy": place_buy_stop_order(symbol, second_buy_order_lot_size, second_order_price, stop_loss) else: place_sell_stop_order(symbol, second_sell_order_lot_size, second_order_price, stop_loss) # Subsequent Orders for i in range(1, 10): if type == "buy": place_buy_stop_order(symbol, other_buy_order_lot_size, subsequent_order_price, stop_loss) subsequent_order_price += price_of_each_step else: place_sell_stop_order(symbol, other_sell_order_lot_size, subsequent_order_price, stop_loss) subsequent_order_price -= price_of_each_step def delete_and_rebuild_all_orders(): sleep(0.1) delete_all_orders(type='sell') sleep(0.2) delete_all_orders(type='buy') sleep(0.5) place_list_of_orders(current_price, type='buy') sleep(0.3) place_list_of_orders(current_price, type='sell') symbol = "GO1OZ-AU23" highest_price = 0 lowest_price = 0 no_of_orders = 0 print('Balance') o = 0 is_initial_operations_done = False while True: selected = mt5.symbol_select(symbol, True) if not selected: print(f"Failed to select {symbol}") mt5.shutdown() quit() symbol_info = mt5.symbol_info(symbol) if symbol_info is None: print(symbol, "not found, can not call order_check()") mt5.shutdown() quit() # if the symbol is unavailable in MarketWatch, add it if not symbol_info.visible: print(symbol, "is not visible, trying to switch on") if not mt5.symbol_select(symbol, True): print("symbol_select({}}) failed, exit", symbol) mt5.shutdown() quit() current_price = symbol_info.bid on_price_change_handler(current_price) if current_price > highest_price or not highest_price: highest_price = current_price print(f'Price to Sell at (First Order): {highest_price - first_order_price_deviation}') # Delete all sell orders at previous prices # and place new orders at latest price deviations if is_initial_operations_done: on_highest_price_change_handler(current_price) if current_price < lowest_price or not lowest_price: lowest_price = current_price print(f'Price to Buy at (First Order): {lowest_price + first_order_price_deviation}') # Delete all buy orders at previous prices # and place new orders at latest price deviations if is_initial_operations_done: on_lowest_price_change_handler(current_price) # Place orders even before the price touches the point # Keep Modifying the orders, by trailing the price if not is_initial_operations_done: delete_and_rebuild_all_orders() print(f"buy_stop_loss_execution_price: {buy_stop_loss_execution_price}") print(f"sell_stop_loss_execution_price: {sell_stop_loss_execution_price}") is_initial_operations_done = True # If Buy Stop Loss order is executed(Price falls below buy_stop_loss_execution_price) if current_price <= buy_stop_loss_execution_price: if first_buy_executed: highest_price = current_price lowest_price = current_price delete_and_rebuild_all_orders() sleep(1) first_buy_executed = False pass # If Sell Stop Loss order is executed(Price Increases above sell_stop_loss_execution_price) if current_price >= sell_stop_loss_execution_price: if first_sell_executed: highest_price = current_price lowest_price = current_price delete_and_rebuild_all_orders() sleep(1) first_sell_executed = False pass