如何正确关闭已打开的订单? 发送订单时不能将票号传递给“位置”

问题描述

我想开单,没问题,但是如果我想关闭这个订单,我需要票号,票我不能手动写,开单后会给出。

documentation,我得到了这个:

enter image description here

但是除了 0 之外我不能传递任何东西给 printf("%c %c %c %c %c",k1,k2,k3,k4,k5); (第 20 行),否则它不会打开订单。

同时,如果 position = 0,它将打开一个订单,我将从 "position": 0 获得一个持仓单,然后我必须手动将其复制并粘贴到收盘时的 result.order 中下单功能,就像关闭订单一样。

那么,有没有一种方法可以不用在每次打开订单后手动复制票号并将其粘贴到关闭功能中?或者提前为打开和关闭订单写一张独特的票?

先谢谢你!

position

解决方法

你的问题有两个部分,我将分别解决。

为什么我不能传递位置值
您在帖子中提到在初始请求中不能输入除 "position": 0 以外的任何内容。正如您已经发现的那样,API 文档指出

位置票。在更改和关闭头寸时填写它以明确识别。通常与开仓订单的票号相同。

这意味着如果您已经有一个票证并且需要修改它,您需要输入一个值。 API 文档在提供的示例中实际上是这样做的。

我将在此处包含一些片段,但我建议您查看 order_send 文档页面上提供的示例。

request = {
    "action": mt5.TRADE_ACTION_DEAL,"symbol": symbol,"volume": lot,"type": mt5.ORDER_TYPE_BUY,"price": price,"sl": price - 100 * point,"tp": price + 100 * point,"deviation": deviation,"magic": 234000,"comment": "python script open","type_time": mt5.ORDER_TIME_GTC,"type_filling": mt5.ORDER_FILLING_RETURN,}

正如您在此处看到的,position 字段未填写。这是因为它是第一个请求,没有什么可修改的,因为还没有交易请求。

关闭请求 dict 如下所示

position_id = result.order

request={
    "action": mt5.TRADE_ACTION_DEAL,"type": mt5.ORDER_TYPE_SELL,"position": position_id,"comment": "python script close",}

在请求中,您可以看到两件事。第一个是填写 position 字段,因为我们现在正在对原始请求进行修改。您可以在这里看到的第二件事是 position_id 取自初始请求的响应。 position_id 是响应的 order 字段。此结构的文档在 here 中可用。

如何在不手动复制订单号的情况下调整代码以关闭它?
根据您的评论,我认为这就是您要寻找的。​​p>

例如,order_send 函数已经显示了如何完成此操作。

您需要做的最重要的事情是将 buy() 函数响应中的 position_id 传递给 close() 函数。

还需要注意的是,在您的原始代码中,magic 字段对于购买请求设置为 234000,对于关闭请求设置为 0。在阅读文档时,它没有明确提到这需要相同。但是,由于在他们提供的示例中是相同的,我也在下面的代码中将其更改为相同。

import MetaTrader5 as mt5

if not mt5.initialize():
    print("initialize() failed,error code =",mt5.last_error())
    quit()

symbol = "EURUSD"
lot = 0.1
point = mt5.symbol_info(symbol).point
price = mt5.symbol_info_tick(symbol).ask
deviation = 20


def buy():
    request = {
        "action": mt5.TRADE_ACTION_DEAL,"type_filling": mt5.ORDER_FILLING_IOC,}
    # send a trading request
    result = mt5.order_send(request)

    # check the execution result
    print("2. order_send done,",result)
    position_id = result.order
    print(position_id)

    mt5.shutdown()
    return position_id


def close(position_id):
    close_request = {"action": mt5.TRADE_ACTION_DEAL,"comment": "python script op",}
    # send a close request
    result = mt5.order_send(close_request)
    print(result)


pos_id = buy()
close(pos_id)

,

我找到了一种方法(硬编码),可能有点让人不知所措,但这是我能想到的唯一方法。我会发布答案;也许它对某人有用。

所以我想要买卖特定订单的功能;主要问题是票号,所以我创建了购买/打开订单、关闭订单、获取票号(仓位/订单的唯一编号)和幻数(给 EA 的确切编号)和一个功能来做我需要的(见上文),我将我的幻数与所有打开的订单进行比较。如果有匹配的,它会抓取票号并用它来关闭订单。

import time
import MetaTrader5 as mt5

def init():
    if not mt5.initialize():
        print("initialize() failed,mt5.last_error())
        quit()


# prepare the buy request structure
lott = 0.15
symboll = "EURUSD"

deviation = 20
magic = 987654321

def buy():
    # establish connection to the MetaTrader 5 terminal
    init()
    
    symbol = symboll
    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 = lott
    point = mt5.symbol_info(symbol).point
    price = mt5.symbol_info_tick(symbol).ask
    
    request = {
        "action": mt5.TRADE_ACTION_DEAL,"sl": price - 1000 * point,"tp": price + 1000 * point,"magic": magic,}
    
    # 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))
    print("   sleep 2 seconds before closing position #{}".format(result.order))


def close(ticket_no):
    init()
    symbol = symboll
    symbol_info = mt5.symbol_info(symbol)
    lot = lott
    # create a close request
    position_id=ticket_no
    price=mt5.symbol_info_tick(symbol).bid
    deviation=20
    request={
        "action": mt5.TRADE_ACTION_DEAL,}
    # 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,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,traderequest_dict[tradereq_filed]))
    
    # shut down connection to the MetaTrader 5 terminal
    mt5.shutdown()
    quit()


def get_ticket_no():
    init()
    symbol = symboll
    symbol_info = mt5.symbol_info(symbol)
    
    positions=mt5.positions_get(symbol=symbol)
    if positions==None:
        print("No positions on EURUSD,error code={}".format(mt5.last_error()))
    elif len(positions)>0:
        print("Total positions on EURUSD =",len(positions))
        # display all open positions
        for position in positions:
            print(position)

    # get the list of positions on symbols whose names contain "*EUR*"
    symmbol_positions=mt5.positions_get()
    if symmbol_positions==None:
        print("No positions with group=\"*EUR*\",error code={}".format(mt5.last_error()))    
    elif len(symmbol_positions)>0:
        lst = list(symmbol_positions)
        ticket_no = lst[0][0] # get the ticket number
        magic_no = lst[0][6] # get the magic number
        print(f'{ticket_no=}')
        print(f'{magic_no=}')
        return ticket_no

    # shut down connection to the MetaTrader 5 terminal
    mt5.shutdown()
    quit()


def get_magic_no():
    init()
    symbol = symboll
    symbol_info = mt5.symbol_info(symbol)
    
    positions=mt5.positions_get(symbol=symbol)
    if positions==None:
        print("No positions on EURUSD,error code={}".format(mt5.last_error()))    
    elif len(symmbol_positions)>0:
        lst = list(symmbol_positions)
        ticket_no = lst[0][0] # get the ticket number
        magic_no = lst[0][6] # get the magic number
        print(f'{ticket_no=}')
        print(f'{magic_no=}')
        return magic_no

    # shut down connection to the MetaTrader 5 terminal
    mt5.shutdown()
    quit()
    

def close_order():
    if get_magic_no() == magic:
        close(get_ticket_no())
    else:
        print("Order not found!")
    
    
buy()
time.sleep(2)
close_order()