def open_sell(): global result_order_sell # establish connection to the MetaTrader 5 terminal if not mt5.initialize(): print("initialize() failed, error code =",mt5.last_error()) quit() # prepare the buy request structure symbol = "EURUSD" 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() lot = 0.01 point = mt5.symbol_info(symbol).point price = mt5.symbol_info_tick(symbol).bid deviation = 5 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_SELL, "price": price, "sl": price + sl_sell * point, "tp": price - tp_sell * point, "deviation": deviation, "magic": 234000, "comment": "python script open", "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_FOK, } # send a trading request result = mt5.order_send(request) # 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)) # request the result as a dictionary and display it element by element result_dict=result._asdict() for field in result_dict.keys(): print(" {}={}".format(field,result_dict[field])) # if this is a trading request structure, display it element by element as well if field=="request": traderequest_dict=result_dict[field]._asdict() for tradereq_filed in traderequest_dict: print(" traderequest: {}={}".format(tradereq_filed,traderequest_dict[tradereq_filed])) print("shutdown() and quit") mt5.shutdown() quit() print("2. order_send done, ", result) print(" sell opened position with POSITION_TICKET={}".format(result.order)) result_order_sell=result.order return(result_order_sell)
def order_send(self, request): result = mt5.order_send(request) return result
def half_risk(self, ticket=""): """Returns an order request that halves the initial risk of an open position Will have a ticket system implemented that will allow a position to be specified""" if ticket == "": for pos in mt5.positions_get(): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol tp = mt5.TradePosition(pos).tp sl = mt5.TradePosition(pos).sl order = mt5.TradePosition(pos).type price = mt5.TradePosition(pos).price_open if order == 0: # Buy diff = round(price - sl, 3) request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(sl + (diff / 2), 3), "tp": tp, "magic": self.magic, "comment": f"python half risk {symbol}" } if order == 1: # Sell diff = round(sl - price, 3) request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(sl - (diff / 2), 3), "tp": tp, "magic": self.magic, "comment": f"python half risk {symbol}" } result = mt5.order_send(request) else: position_id = int(ticket) pos = mt5.positions_get(ticket=position_id)[0] symbol = mt5.TradePosition(pos).symbol tp = mt5.TradePosition(pos).tp sl = mt5.TradePosition(pos).sl order = mt5.TradePosition(pos).type price = mt5.TradePosition(pos).price_open if order == 0: # Buy diff = round(price - sl, 3) request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(sl + (diff / 2), 3), "tp": tp, "magic": self.magic, "comment": f"python half risk {symbol}" } if order == 1: # Sell diff = round(sl - price, 3) request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(sl - (diff / 2), 3), "tp": tp, "magic": self.magic, "comment": f"python half risk {symbol}" } result = mt5.order_send(request) self.order_error_check(result)
def auto_be(self, ticket=""): """Returns an order request. Sets all open positions to break even + a few points to ensure no loss is taken""" if ticket == "": for pos in mt5.positions_get(): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol tp = mt5.TradePosition(pos).tp price = mt5.TradePosition(pos).price_open point = mt5.symbol_info(symbol).point order = mt5.TradePosition(pos).type if order == 1: request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(price - 5 * point, 3), "tp": tp, "magic": self.magic, "comment": f"python auto BE {symbol}" } elif order == 0: request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(price + 5 * point, 3), "tp": tp, "magic": self.magic, "comment": f"python auto BE {symbol}" } result = mt5.order_send(request) else: position_id = int(ticket) pos = mt5.positions_get(ticket=position_id)[0] symbol = mt5.TradePosition(pos).symbol tp = mt5.TradePosition(pos).tp order = mt5.TradePosition(pos).type price = mt5.TradePosition(pos).price_open point = mt5.symbol_info(symbol).point if order == 1: request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(price - 5 * point, 3), "tp": tp, "magic": self.magic, "comment": f"python auto BE {symbol}" } elif order == 0: request = { "action": mt5.TRADE_ACTION_SLTP, "symbol": symbol, "position": position_id, "sl": round(price + 5 * point, 3), "tp": tp, "magic": self.magic, "comment": f"python auto BE {symbol}" } result = mt5.order_send(request) self.order_error_check(result)
def enter_trades(symbol_and_sizes, pair_data, currency, timeframe, basket_direction, expire_after=3, suffix:str='.a') -> None: ''' Enter basket trades. expire_after is how many bars the order will live for ''' opposite = { 'buy': 'sell', 'sell': 'buy' } # Get the entry parameters for each symbol in the dict for symbol, lot_size in symbol_and_sizes.items(): # Reverse the trade direction if the currency is in ct pos direction = basket_direction if currency == symbol[:3] else opposite[basket_direction] print(symbol, direction, lot_size, ) atr = pair_data[symbol]['atr'][timeframe] info = mt5.symbol_info(symbol) # I dont trust pair_data to always have accurate prices so request them # Set the entry 1 ATR above current price if direction == 'buy': entry = info.ask + 0.5 * atr stop_loss = entry - 2 * atr take_profit = entry + 5 * atr type = mt5.ORDER_TYPE_BUY_STOP else: entry = info.bid - 0.5 * atr stop_loss = entry + 2 * atr take_profit = entry - 5 * atr type = mt5.ORDER_TYPE_SELL_STOP print('enter_trades() price:', float(round(entry, info.digits))) # Cancel orders after n bars if not filled expiry = info.time + (tf_to_sec[timeframe] * expire_after) if suffix: symbol = symbol.upper() + suffix request = { 'action': mt5.TRADE_ACTION_PENDING, 'symbol': symbol, 'volume': float(round(lot_size, 2)), # int will error 'price': float(round(entry, info.digits)), 'sl': float(round(stop_loss, info.digits)), 'tp': float(round(take_profit, info.digits)), 'deviation': 10, 'expiration': expiry, 'type': type, 'type_time': mt5.ORDER_TIME_SPECIFIED, 'type_filling': mt5.ORDER_FILLING_IOC, # Comments are how I keep track of all needed info about a trade's basket 'comment': f'{currency} {timeframe} {basket_direction}', } # send a trading request result = mt5.order_send(request) if result is not None: if result.retcode != mt5.TRADE_RETCODE_DONE: bot.send_message(chat_id=446051969, text=f'Entry failed: {symbol} {timeframe} {direction} {result.retcode}') print(f'~~~ order entry error {symbol} {result.retcode}') print(request['expiration']) else: bot.send_message(chat_id=446051969, text=f'Entry failed: {symbol} {timeframe} {direction}. "result" is None.') print(f'~~~ order entry error {symbol} "result" is none')
def order_send(request: dict): answer = Mt5.order_send(request) if answer.retcode != 10009: raise Exception("Mt5 return code is not 10009") return answer
"action": mt.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot_size, "type": mt.ORDER_TYPE_BUY, "price": current_price.ask, "sl": 0, "tp": 0, "deviation": deviation, "magic": 111, "comment": "Python Script BUY", "type_time": mt.ORDER_TIME_GTC, "type_filling": mt.ORDER_FILLING_RETURN, } # send request to platform order_result = mt.order_send(request) print('order result: ', order_result) # trade logic sell elif current_price.bid < sma: if not long_trades.empty: print('existing long trade') if num_open_trades == 0: # create sell request request = { "action": mt.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot_size, "type": mt.ORDER_TYPE_SELL,
def step(self, action, trade=False): """Take an action (buy/sell/hold) and computes the immediate reward. Args: action (numpy.array): Action to be taken, one-hot encoded. Returns: tuple: - observation (numpy.array): Agent's observation of the current environment. - reward (float) : Amount of reward returned after previous action. - done (bool): Whether the episode has ended, in which case further step() calls will return undefined results. - info (dict): Contains auxiliary diagnostic information (helpful for debugging, and sometimes learning). """ self._action = action self._iteration += 1 done = False info = {} if all(self._position != self._positions['flat']): reward = -self._time_fee self._current_pnl = 0 # establish connection to the MetaTrader 5 terminal if not mt5.initialize(): print("initialize() failed, error code =", mt5.last_error()) quit() # prepare the buy request structure symbol = "GBPUSD" 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() #------------------- instant_pnl = 0 reward = -self._time_fee if all(action == self._actions['buy']): reward -= self._trading_fee if all(self._position == self._positions['flat']): self._position = self._positions['long'] if trade: lot = 0.1 point = mt5.symbol_info(symbol).point price = mt5.symbol_info_tick(symbol).ask deviation = 20 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_BUY, "price": price, "deviation": deviation, "magic": 234000, "comment": "python script open", "type_time": mt5.ORDER_TIME_GTC, "type_filling": 1, } # send a trading request result = mt5.order_send(request) # 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)) # request the result as a dictionary and display it element by element result_dict = result._asdict() for field in result_dict.keys(): print(" {}={}".format(field, result_dict[field])) # if this is a trading request structure, display it element by element as well if field == "request": traderequest_dict = result_dict[field]._asdict( ) for tradereq_filed in traderequest_dict: print(" traderequest: {}={}".format( tradereq_filed, traderequest_dict[tradereq_filed])) print("2. order_send done, ", result) print(" opened position with POSITION_TICKET={}".format( result.order)) self._entry_price = self._price = self._tick_buy self.Buy_render = True elif all(self._position == self._positions['short']): self._exit_price = self._exit_price = self._tick_sell instant_pnl = round(self._entry_price, 5) - round( self._exit_price, 5) self._position = self._positions['flat'] self._entry_price = 0 if trade: position_id = result.order price = mt5.symbol_info_tick(symbol).bid deviation = 20 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_BUY, "position": position_id, "price": price, "deviation": deviation, "magic": 234000, "comment": "python script close", "type_time": mt5.ORDER_TIME_GTC, "type_filling": 1, } # send a trading request result = mt5.order_send(request) # check the execution result print( "3. close position #{}: sell {} {} lots at {} with deviation={} points" .format(position_id, symbol, lot, price, deviation)) if result.retcode != mt5.TRADE_RETCODE_DONE: print("4. order_send failed, retcode={}".format( result.retcode)) print(" result", result) else: print("4. position #{} closed, {}".format( position_id, result)) # request the result as a dictionary and display it element by element result_dict = result._asdict() for field in result_dict.keys(): print(" {}={}".format(field, result_dict[field])) # if this is a trading request structure, display it element by element as well if field == "request": traderequest_dict = result_dict[field]._asdict( ) for tradereq_filed in traderequest_dict: print(" traderequest: {}={}".format( tradereq_filed, traderequest_dict[tradereq_filed])) positions = mt5.positions_get( symbol="GBPUSD") if positions == None: print("No positions on GBPUSD, error code={}".format( mt5.last_error())) elif len(positions) > 0: print("Total positions on GBPUSD =", len(positions)) # display all open positions for position in positions: print(position) # get the list of positions on symbols whose names contain "*USD*" usd_positions = mt5.positions_get(group="*USD*") if usd_positions == None: print( "No positions with group=\"*USD*\", error code={}". format(mt5.last_error())) elif len(usd_positions) > 0: print("positions_get(group=\"*USD*\")={}".format( len(usd_positions))) # display these positions as a table using pandas.DataFrame df = pd.DataFrame( list(usd_positions), columns=usd_positions[0]._asdict().keys()) df['time'] = pd.to_datetime(df['time'], unit='s') df.drop([ 'time_update', 'time_msc', 'time_update_msc', 'external_id' ], axis=1, inplace=True) #print(df) instant_pnl = df['profit'][-1] # self.Buy_render = True if (instant_pnl > 0): self.TP_render = True else: self.SL_render = True elif all(action == self._actions['sell']): reward -= self._trading_fee if all(self._position == self._positions['flat']): self._position = self._positions['short'] self._entry_price = self._price = self._tick_sell self.Sell_render = True if trade: lot = 0.1 point = mt5.symbol_info(symbol).point price = mt5.symbol_info_tick(symbol).ask deviation = 20 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_SELL, "price": price, "deviation": deviation, "magic": 234000, "comment": "python script open", "type_time": mt5.ORDER_TIME_GTC, "type_filling": 1 } # send a trading request result = mt5.order_send(request) # 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)) # request the result as a dictionary and display it element by element result_dict = result._asdict() for field in result_dict.keys(): print(" {}={}".format(field, result_dict[field])) # if this is a trading request structure, display it element by element as well if field == "request": traderequest_dict = result_dict[field]._asdict( ) for tradereq_filed in traderequest_dict: print(" traderequest: {}={}".format( tradereq_filed, traderequest_dict[tradereq_filed])) print("2. order_send done, ", result) print(" opened position with POSITION_TICKET={}".format( result.order)) elif all(self._position == self._positions['long']): self._exit_price = self._tick_buy instant_pnl = round(self._exit_price, 5) - round( self._entry_price, 5) self._position = self._positions['flat'] self._entry_price = 0 if trade: position_id = result.order price = mt5.symbol_info_tick(symbol).bid deviation = 20 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_SELL, "position": position_id, "price": price, "deviation": deviation, "magic": 234000, "comment": "python script close", "type_time": mt5.ORDER_TIME_GTC, "type_filling": 1, } # send a trading request result = mt5.order_send(request) # check the execution result print( "3. close position #{}: sell {} {} lots at {} with deviation={} points" .format(position_id, symbol, lot, price, deviation)) if result.retcode != mt5.TRADE_RETCODE_DONE: print("4. order_send failed, retcode={}".format( result.retcode)) print(" result", result) else: print("4. position #{} closed, {}".format( position_id, result)) # request the result as a dictionary and display it element by element result_dict = result._asdict() for field in result_dict.keys(): print(" {}={}".format(field, result_dict[field])) # if this is a trading request structure, display it element by element as well if field == "request": traderequest_dict = result_dict[field]._asdict( ) for tradereq_filed in traderequest_dict: print(" traderequest: {}={}".format( tradereq_filed, traderequest_dict[tradereq_filed])) # shut down connection to the MetaTrader 5 terminal positions = mt5.positions_get(symbol="GBPUSD") if positions == None: print("No positions on GBPUSD, error code={}".format( mt5.last_error())) elif len(positions) > 0: print("Total positions on GBPUSD =", len(positions)) # display all open positions for position in positions: print(position) # get the list of positions on symbols whose names contain "*USD*" usd_positions = mt5.positions_get(group="*USD*") if usd_positions == None: print( "No positions with group=\"*USD*\", error code={}". format(mt5.last_error())) elif len(usd_positions) > 0: print("positions_get(group=\"*USD*\")={}".format( len(usd_positions))) # display these positions as a table using pandas.DataFrame df = pd.DataFrame( list(usd_positions), columns=usd_positions[0]._asdict().keys()) df['time'] = pd.to_datetime(df['time'], unit='s') df.drop([ 'time_update', 'time_msc', 'time_update_msc', 'external_id' ], axis=1, inplace=True) #print(df) instant_pnl = df['profit'][-1] # self.Sell_render = True if (instant_pnl > 0): self.TP_render = True else: self.SL_render = True else: self.Buy_render = self.Sell_render = False self.TP_render = self.SL_render = False usd_positions = mt5.positions_get(group="*USD*") reward += instant_pnl * 1000 self._total_pnl += instant_pnl * 10000 self._total_reward += reward try: self._prices_history.append(next(self._data_generator)) self._tick_sell, self._tick_buy, self.tick_mid, self.tick_rsi_14, self.tick_cci_14= \ self._prices_history[-1][:5] except StopIteration: done = True info['status'] = 'No more data.' # Game over logic if self._iteration >= self._episode_length: done = True info['status'] = 'Time out.' if reward <= self._max_lost: done = True info['status'] = 'Bankrupted.' if self._closed_plot: info['status'] = 'Closed plot' observation = self._get_observation() return observation, reward, done, info
def marketorder_trade_execution(self, PAIR, lot_size, TP, SL, POSITION): """ mql5 order types ENUM_ORDER_TYPE: ORDER_TYPE_BUY ; Market Buy order ORDER_TYPE_SELL : Market Sell order ORDER_TYPE_BUY_LIMIT : Buy Limit pending order ORDER_TYPE_SELL_LIMIT : Sell Limit pending order ORDER_TYPE_BUY_STOP : Buy Stop pending order ORDER_TYPE_SELL_STOP : Sell Stop pending order ORDER_TYPE_BUY_STOP_LIMIT : Upon reaching the order price, a pending Buy Limit order is placed at the StopLimit price ORDER_TYPE_SELL_STOP_LIMIT : Upon reaching the order price, a pending Sell Limit order is placed at the StopLimit price ORDER_TYPE_CLOSE_BY : Order to close a position by an opposite one """ point = mt5.symbol_info(PAIR).point if POSITION == 'LONG': order_type = mt5.ORDER_TYPE_BUY price = mt5.symbol_info_tick(PAIR).ask sl = np.double(price - SL * 10 * point) tp = np.double(price + TP * 10 * point) if self.TrailingStopOn == False: comment = 'TP' + str(TP) + ' SL' + str( SL) + ' ' + self.strategy_name + self.TimeFrame else: comment = 'TP' + str(TP) + ' TS' + str( SL) + ' ' + self.strategy_name + self.TimeFrame deviation = 5 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": PAIR, "volume": lot_size, "type": order_type, "price": price, "sl": np.double(sl), "tp": np.double(tp), "deviation": deviation, "magic": 234000, "comment": comment, "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_FOK, } self.login() self.result = mt5.order_send(request) if self.health_check(self.result._asdict()) == 'pass': print( "1. order_send(): by {} {} lots at {} with deviation={} points" .format(PAIR, lot_size, price, deviation)) elif POSITION == 'SHORT': order_type = mt5.ORDER_TYPE_SELL price = mt5.symbol_info_tick(PAIR).bid sl = np.double(price + SL * 10 * point) tp = np.double(price - TP * 10 * point) if self.TrailingStopOn == False: comment = 'TP' + str(TP) + ' SL' + str( SL) + ' ' + self.strategy_name + self.TimeFrame else: comment = 'TP' + str(TP) + ' TS' + str( SL) + ' ' + self.strategy_name + self.TimeFrame deviation = 5 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": PAIR, "volume": lot_size, "type": order_type, "price": price, "sl": np.double(sl), "tp": np.double(tp), "deviation": deviation, "magic": 234000, "comment": comment, "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_FOK, } self.login() self.result = mt5.order_send(request) if self.health_check(self.result._asdict()) == 'pass': print( "1. order_send(): by {} {} lots at {} with deviation={} points" .format(PAIR, lot_size, price, deviation)) elif POSITION == 'CLOSE': self.login() positions = mt5.positions_get() if positions is not None: for open_position in positions: if open_position.comment.find( self.strategy_name ) != -1 and open_position.comment.find( self.TimeFrame ) != -1 and PAIR == open_position.symbol: if open_position.order_type == 0: order_type = mt5.ORDER_TYPE_SELL price = mt5.symbol_info_tick( open_position.symbol).bid elif open_position.order_type == 1: order_type = mt5.ORDER_TYPE_BUY price = mt5.symbol_info_tick( open_position.symbol).ask comment = 'closed for ' + self.strategy_name + self.TimeFrame close_request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": open_position.symbol, "volume": open_position.volume, "type": order_type, "position": open_position.ticket, "price": price, "deviation": 5, "magic": 0, "comment": comment, "type_time": mt5.ORDER_TIME_GTC, # good till cancelled "type_filling": mt5.ORDER_FILLING_RETURN, } self.login() self.result = mt5.order_send(close_request) if self.health_check(self.result._asdict()) == 'pass': print( "1. order_send(): by {} {} lots at {} with deviation={} points" .format(PAIR, lot_size, price, deviation)) else: return else: raise ('POSITION TYPE IS INVALID FOR MARKET ORDERS!')
def open_position(self, pair: str, order_type: str, size: float, tp_distance: int = None, stop_distance: int = None, comment: str = ""): """Open a position on the connected current metatrader account Args: pair (str): The pair you want to exchange (EURUSD for instance) order_type (str): the type of order you want to place (BUY for instance) size (float): volume of the order tp_distance (int, optional): Number of pip before taking profit. Defaults to None. stop_distance (int, optional): Number of pip before stop loss. Defaults to None. comment (str, optional): A comment you want to put on your order. Defaults to empty """ symbol_info = mt5.symbol_info(pair) if symbol_info is None: print(pair, "not found") return if not symbol_info.visible: print(pair, "is not visible, trying to switch on") if not mt5.symbol_select(pair, True): print("symbol_select({}}) failed, exit", pair) return print(pair, "found!") point = symbol_info.point if (order_type == "BUY"): order = mt5.ORDER_TYPE_BUY price = mt5.symbol_info_tick(pair).ask if (stop_distance): sl = price - (stop_distance * point) if (tp_distance): tp = price + (tp_distance * point) if (order_type == "SELL"): order = mt5.ORDER_TYPE_SELL price = mt5.symbol_info_tick(pair).bid if (stop_distance): sl = price + (stop_distance * point) if (tp_distance): tp = price - (tp_distance * point) request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": pair, "volume": size, "type": order, "price": price, "sl": sl, "tp": tp, "magic": 234000, "comment": comment, "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_IOC, } result = mt5.order_send(request) print(result) if result.retcode != mt5.TRADE_RETCODE_DONE: print("Failed to send order :(") else: print("Order successfully placed!")
def avoid_multiple_positions(self, POSITION, PAIR): #THIS FUNCTION RESTRICTS THE BOT TO ONLY HAVE OPEN MAXPOSITION OF THE SAME INSTRUMENT PER STRATEGY #ALSO IT CLOSES AN EXISTING POSITION IF STRATEGY GIVES OPPOSITE OF ONGOING OPEN POSITION if POSITION == 'LONG': position_type = 0 elif POSITION == 'SHORT': position_type = 1 self.login() positions = mt5.positions_get() position_count = 0 for open_position in positions: if open_position.comment.find( self.strategy_name) != -1 and open_position.comment.find( self.TimeFrame) != -1: if open_position.symbol == PAIR: if (open_position.type == 0 and position_type == 1): #CLOSE A LONG POSITION BY OPPOSITE ORDER request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": open_position.symbol, "volume": open_position.volume, "type": mt5.ORDER_TYPE_SELL, "position": open_position.ticket, "price": mt5.symbol_info_tick(open_position.symbol).bid, "magic": open_position.magic, "comment": "close long pos", "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_FOK, } result = mt5.order_send(request) if self.health_check(self.result._asdict()) == 'pass': print(open_position.symbol, ' with vol: ', open_position.volume, ' LONG POSITION CLOSED!!! Strategy: ', self.strategy_name, ' on TIMEFRAME: ', self.TimeFrame) #print(result) elif (open_position.type == 1 and position_type == 0): #CLOSE A SHORT POSITION BY OPPOSITE ORDER request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": open_position.symbol, "volume": open_position.volume, "type": mt5.ORDER_TYPE_BUY, "position": open_position.ticket, "price": mt5.symbol_info_tick(open_position.symbol).ask, "magic": open_position.magic, "comment": "close short pos", "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_FOK, } result = mt5.order_send(request) if self.health_check(self.result._asdict()) == 'pass': print(open_position.symbol, ' with vol: ', open_position.volume, ' SHORT POSITION CLOSED!!! Strategy: ', self.strategy_name, ' on TIMEFRAME: ', self.TimeFrame) #print(result) else: position_count = position_count + 1 if position_count >= self.maxposition: action = 'block' else: action = 'noblock' return action
def simplestoploss(self, open_position): stoploss_limit = np.fromstring(open_position.comment[open_position.comment.find('TS') + 2]\ + open_position.comment[open_position.comment.find('TS') + 3], dtype=int, sep=' ') takeprofit_limit = np.fromstring(open_position.comment[open_position.comment.find('TP') + 2]\ + open_position.comment[open_position.comment.find('TP') + 3], dtype=int, sep=' ') order_type = open_position.type symbol = open_position.symbol current_price = open_position.price_current point = mt5.symbol_info(symbol).point order_timeframe = open_position.comment[open_position.comment. find(self.strategy_name) + 3:] #print(order_timeframe) past_data = MT5_DATAGENERATOR_v2(symbol, order_timeframe, 3) #print('current close: ', past_data['close'].iloc[1], ' previous close: ', past_data['close'].iloc[0]) if order_type == 0: #LONG ORDER if (past_data['close'].iloc[1] > past_data['close'].iloc[0]) and open_position.profit > 0: new_sl = np.double(open_position.price_current - stoploss_limit * 10 * point) print(open_position.symbol + ': new sl:', new_sl, ' old SL: ', open_position.sl) if new_sl > open_position.sl: tp = np.double(open_position.price_open + takeprofit_limit * 10 * point) request = { "action": mt5.TRADE_ACTION_SLTP, "position": open_position.ticket, "symbol": open_position.symbol, "sl": new_sl, "tp": tp, "magic": 123456 } result = mt5.order_send(request) if self.health_check(result._asdict()) == 'pass': print(open_position.symbol, ' SL Changed!!! Strategy: ', self.strategy_name, ' on TIMEFRAME: ', self.TimeFrame) #if result['retcode'] != mt5.TRADE_RETCODE_DONE: # print("2. order_send failed, retcode={}".format(result['retcode'])) elif order_type == 1: #SHORT ORDER if (past_data['close'].iloc[1] < past_data['close'].iloc[0]) and open_position.profit > 0: #print('change detected in ', open_position.symbol) new_sl = np.double(open_position.price_current + stoploss_limit * 10 * point) print(open_position.symbol + ': new sl:', new_sl, ' old SL: ', open_position.sl) if new_sl < open_position.sl: tp = np.double(open_position.price_open - takeprofit_limit * 10 * point) request = { "action": mt5.TRADE_ACTION_SLTP, "position": open_position.ticket, "symbol": open_position.symbol, "sl": new_sl, "tp": tp, "magic": 123456 } result = mt5.order_send(request) if self.health_check(result._asdict()) == 'pass': print(open_position.symbol, ' SL Changed!!! Strategy: ', self.strategy_name, ' on TIMEFRAME: ', self.TimeFrame) #print(result) else: raise Exception('Error in order_type')
def trade(): """Determine if we should trade and if so, send requests to MT5.""" utc_from, utc_to = get_dates() candles = get_data() current_buy_price, current_sell_price = get_current_prices() # calculate the % difference between the current price and the close price of the previous candle difference = (candles['close'][-1] - candles['close'][-2]) / candles['close'][-2] * 100 # used to check if a position has already been placed positions = mt5.positions_get(symbol=CRYPTO) orders = mt5.orders_get(symbol=CRYPTO) symbol_info = mt5.symbol_info(CRYPTO) # perform logic check if difference > PRICE_THRESHOLD: print(f'dif 1: {CRYPTO}, {difference}') # Pause for 8 seconds to ensure the increase is sustained time.sleep(8) # calculate the difference once again candles = mt5.copy_rates_range(CRYPTO, mt5.TIMEFRAME_M10, utc_from, utc_to) difference = (candles['close'][-1] - candles['close'][-2]) / candles['close'][-2] * 100 if difference > PRICE_THRESHOLD: print(f'dif 2: {CRYPTO}, {difference}') price = mt5.symbol_info_tick(CRYPTO).bid print( f'{CRYPTO} is up {str(difference)}% in the last 5 minutes opening BUY position.' ) # prepare the trade request if not mt5.initialize(): raise RuntimeError( f'MT5 initialize() failed with error code {mt5.last_error()}' ) # check that there are no open positions or orders if len(positions) == 0 and len(orders) < 1: if symbol_info is None: print(f'{CRYPTO} not found, can not call order_check()') mt5.shutdown() # if the symbol is unavailable in MarketWatch, add it if not symbol_info.visible: print(f'{CRYPTO} is not visible, trying to switch on') if not mt5.symbol_select(CRYPTO, True): print('symbol_select({}}) failed, exit', CRYPTO) #this represents 5% Equity. Minimum order is 0.01 BTC. Increase equity share if retcode = 10014 lot = float(round(((equity / 20) / current_buy_price), 2)) # define stop loss and take profit if ORDER_TYPE == BUY: sl = price - (price * STOP_LOSS) / 100 tp = price + (price * TAKE_PROFIT) / 100 else: sl = price + (price * STOP_LOSS) / 100 tp = price - (price * TAKE_PROFIT) / 100 request = { 'action': mt5.TRADE_ACTION_DEAL, 'symbol': CRYPTO, 'volume': lot, 'type': ORDER_TYPE, 'price': price, 'sl': sl, 'tp': tp, 'magic': 66, 'comment': 'python-buy', 'type_time': mt5.ORDER_TIME_GTC, 'type_filling': mt5.ORDER_FILLING_IOC, } # send a trading request result = mt5.order_send(request) # check the execution result print(f'1. order_send(): by {CRYPTO} {lot} lots at {price}') if result.retcode != mt5.TRADE_RETCODE_DONE: print(f'2. order_send failed, retcode={result.retcode}') #print the order result - anything else than retcode=10009 is an error in the trading request. print(f'2. order_send done, {result}') print( f' opened position with POSITION_TICKET={result.order}') else: print( f'BUY signal detected, but {CRYPTO} has {len(positions)} active trade' ) else: pass else: if orders or positions: print( 'Buying signal detected but there is already an active trade') else: print(f'difference is only: {str(difference)}% trying again...')
def get_order(symbol='EURUSD', side='long', lot=0.01, sl=100, tp=100, magic=101): # establish connection to the MetaTrader 5 terminal if not mt5.initialize(): print("initialize() failed, error code =", mt5.last_error()) quit() # prepare the buy request structure 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() point = mt5.symbol_info(symbol).point ask = mt5.symbol_info_tick(symbol).ask bid = mt5.symbol_info_tick(symbol).bid if side == 'long': price = ask stop_loss = price - sl * point take_profit = price + tp * point type_side = mt5.ORDER_TYPE_BUY elif side == 'short': price = bid stop_loss = price + sl * point take_profit = price - tp * point type_side = mt5.ORDER_TYPE_SELL deviation = 20 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot, "type": type_side, "price": price, "sl": stop_loss, "tp": take_profit, "deviation": deviation, "magic": magic, "comment": "python script open", "type_time": mt5.ORDER_TIME_GTC, #"type_filling": mt5.ORDER_FILLING_IOC, } # send a trading request result = mt5.order_send(request) # 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)) # request the result as a dictionary and display it element by element result_dict = result._asdict() #for field in result_dict.keys(): #print(" {}={}".format(field,result_dict[field])) # if this is a trading request structure, display it element by element as well # if field=="request": # traderequest_dict=result_dict[field]._asdict() # for tradereq_filed in traderequest_dict: # print(" traderequest: {}={}".format(tradereq_filed,traderequest_dict[tradereq_filed])) #print("shutdown() and quit") mt5.shutdown() #quit() #print("2. order_send done, ", result) #print(" opened position with POSITION_TICKET={}".format(result.order)) return result.order
def close_half(self, ticket=""): """Returns a order request that closes 50% of a selected position by volume ticket: the position ID that will be modified. (Currently not implemented) When ticket=1, it will close half of ALL currently open positions""" if ticket == "": # If no ticket specified, close half of all positions for pos in mt5.positions_get(): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol sell_vol = round(mt5.TradePosition(pos).volume / 2, 2) order = mt5.TradePosition(pos).type # TODO check if deviation needs to be in these requests if order == 0: price = mt5.symbol_info_tick(symbol).bid request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_SELL, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } if order == 1: price = mt5.symbol_info_tick(symbol).ask request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_BUY, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } result = mt5.order_send(request) else: for pos in mt5.positions_get(ticket=int(ticket)): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol sell_vol = round(mt5.TradePosition(pos).volume / 2, 2) order = mt5.TradePosition(pos).type if order == 0: price = mt5.symbol_info_tick(symbol).bid request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_SELL, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } if order == 1: price = mt5.symbol_info_tick(symbol).ask request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_BUY, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } result = mt5.order_send(request)
def get_closed(trade, symbol='EURUSD', side='long', lot=0.01, magic=102): # establish connection to the MetaTrader 5 terminal if not mt5.initialize(): print("initialize() failed, error code =", mt5.last_error()) quit() # prepare the buy request structure 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() # create a close request ask = mt5.symbol_info_tick(symbol).ask bid = mt5.symbol_info_tick(symbol).bid if side == 'short': price = ask type_side = mt5.ORDER_TYPE_BUY elif side == 'long': price = bid type_side = mt5.ORDER_TYPE_SELL deviation = 20 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "volume": lot, "type": type_side, "position": trade, "price": price, "deviation": deviation, "magic": 234000, "comment": "python script close", "type_time": mt5.ORDER_TIME_GTC, #"type_filling": mt5.ORDER_FILLING_RETURN, } # send a trading request result = mt5.order_send(request) # check the execution result #print("3. close position #{}: sell {} {} lots at {} with deviation={} points".format(trade,symbol,lot,price,deviation)); if result.retcode != mt5.TRADE_RETCODE_DONE: print("4. order_send failed, retcode={}".format(result.retcode)) #print(" result",result) else: #print("4. position #{} closed, {}".format(trade,result)) # request the result as a dictionary and display it element by element result_dict = result._asdict() # for field in result_dict.keys(): # #print(" {}={}".format(field,result_dict[field])) # # if this is a trading request structure, display it element by element as well # if field=="request": # traderequest_dict=result_dict[field]._asdict() # for tradereq_filed in traderequest_dict: # #print(" traderequest: {}={}".format(tradereq_filed,traderequest_dict[tradereq_filed])) # shut down connection to the MetaTrader 5 terminal mt5.shutdown()
def close_custom_pct(self, percent_close, ticket=""): """Returns an order request that closes a specified percentage of a specific position ticket: position ID When ticket=1, closes specified percentage of ALL currently open positions""" if ticket == "": # If no ticket specified, close half of all positions for pos in mt5.positions_get(): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol sell_vol = round( ((mt5.TradePosition(pos).volume / 100) * percent_close), 2) order = mt5.TradePosition(pos).type if order == 0: price = mt5.symbol_info_tick(symbol).bid request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_SELL, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } if order == 1: price = mt5.symbol_info_tick(symbol).ask request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_BUY, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } result = mt5.order_send(request) else: for pos in mt5.positions_get(ticket=int(ticket)): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol sell_vol = round( ((mt5.TradePosition(pos).volume / 100) * percent_close), 2) order = mt5.TradePosition(pos).type if order == 0: price = mt5.symbol_info_tick(symbol).bid request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_SELL, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } if order == 1: price = mt5.symbol_info_tick(symbol).ask request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_BUY, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } result = mt5.order_send(request) self.order_error_check(result)
"type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_RETURN, } request_sell = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol_2, "volume": lot, "type": mt5.ORDER_TYPE_SELL, "price": gbp_pr[i], "sl": gbp_pr[i] - 100 * point_2, "tp": gbp_pr[i] + 100 * point_2, "deviation": deviation, "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_RETURN, } result_buy = mt5.order_send(request_buy) result_sell = mt5.order_send(request_sell) if spread[i] <= rol[i]: request_buy = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol_2, "volume": lot, "type": mt5.ORDER_TYPE_BUY, "price": gbp_pr[i], "sl": gbp_pr[i] - 100 * point_2, "tp": gbp_pr[i] + 100 * point_2, "deviation": deviation, "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_RETURN, } request_sell = {
def close_custom_volume(self, vol, ticket=1): """Returns an order request that closes a position by a specified volume Currently not implemented within the GUI""" if ticket == 1: # If no ticket specified, close half of all positions for pos in mt5.positions_get(): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol sell_vol = round(vol, 2) order = mt5.TradePosition(pos).type if order == 0: price = mt5.symbol_info_tick(symbol).bid request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_SELL, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } if order == 1: price = mt5.symbol_info_tick(symbol).ask request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_BUY, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } result = mt5.order_send(request) else: for pos in mt5.positions_get(ticket=ticket): position_id = mt5.TradePosition(pos).ticket symbol = mt5.TradePosition(pos).symbol sell_vol = round(mt5.TradePosition(pos).volume / 2, 2) order = mt5.TradePosition(pos).type if order == 0: price = mt5.symbol_info_tick(symbol).bid request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_SELL, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } if order == 1: price = mt5.symbol_info_tick(symbol).ask request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": symbol, "position": position_id, "volume": sell_vol, "type": mt5.ORDER_TYPE_BUY, "price": price, "magic": self.magic, "comment": f"python close half {symbol}" } result = mt5.order_send(request)
"symbol": symbol, "volume": lot, "type": mt5.ORDER_TYPE_BUY_LIMIT, "price": entry, "stoplimit": entry, "sl": entry - 100 * point, "tp": entry + 100 * point, "deviation": deviation, "magic": 234000, "comment": "python script open", "type_time": mt5.ORDER_TIME_GTC, "type_filling": mt5.ORDER_FILLING_FOK, } # send a trading request result = mt5.order_send(request) # 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)) # request the result as a dictionary and display it element by element result_dict = result._asdict() for field in result_dict.keys(): print(" {}={}".format(field, result_dict[field])) # if this is a trading request structure, display it element by element as well if field == "request": traderequest_dict = result_dict[field]._asdict() for tradereq_filed in traderequest_dict: print(" traderequest: {}={}".format( tradereq_filed, traderequest_dict[tradereq_filed]))
def trade(): """Check if Musk mentioned bitcoin with positive sentiment and open a buy position if so""" what_musk_said = get_elons_tweet() tweet_sentiment = analyze_sentence() # used to check if a position has already been placed positions = mt5.positions_get(symbol=CRYPTO) orders = mt5.orders_get(symbol=CRYPTO) symbol_info = mt5.symbol_info(CRYPTO) price = mt5.symbol_info_tick(CRYPTO).bid # perform logic check if any(keyword in what_musk_said for keyword in keywords) and tweet_sentiment > 0: print(f'the madlad said it - buying some!') # prepare the trade request if not mt5.initialize(): raise RuntimeError(f'MT5 initialize() failed with error code {mt5.last_error()}') # check that there are no open positions or orders if len(positions) == 0 and len(orders) < 1: if symbol_info is None: print(f'{CRYPTO} not found, can not call order_check()') mt5.shutdown() # if the symbol is unavailable in MarketWatch, add it if not symbol_info.visible: print(f'{CRYPTO} is not visible, trying to switch on') if not mt5.symbol_select(CRYPTO, True): print('symbol_select({}}) failed, exit', CRYPTO) #this represents 5% Equity. Minimum order is 0.01 BTC. Increase equity share if retcode = 10014 lot = float(round(((equity / 5) / price), 2)) # define stop loss and take profit sl = price - (price * 5) / 100 tp = price + (price * 10) / 100 request = { 'action': mt5.TRADE_ACTION_DEAL, 'symbol': CRYPTO, 'volume': lot, 'type': mt5.ORDER_TYPE_BUY, 'price': price, 'sl': sl, 'tp': tp, 'magic': 66, 'comment': 'python-buy', 'type_time': mt5.ORDER_TIME_GTC, 'type_filling': mt5.ORDER_FILLING_IOC, } # send a trading request result = mt5.order_send(request) # check the execution result print(f'1. order_send(): by {CRYPTO} {lot} lots at {price}') if result.retcode != mt5.TRADE_RETCODE_DONE: print(f'2. order_send failed, retcode={result.retcode}') #print the order result - anything else than retcode=10009 is an error in the trading request. print(f'2. order_send done, {result}') print(f' opened position with POSITION_TICKET={result.order}') else: print(f'BUY signal detected, but {CRYPTO} has {len(positions)} active trade') else: print(f'He did not say it, he said: {what_musk_said} - OR sentiment was not positive')