up
This commit is contained in:
@@ -766,6 +766,8 @@ class mt5(Exchange, ImplicitAPI):
|
|||||||
|
|
||||||
timestamp = self.parse8601(self.safe_string(order, 'openTime'))
|
timestamp = self.parse8601(self.safe_string(order, 'openTime'))
|
||||||
last_trade_timestamp = self.parse8601(self.safe_string(order, 'closeTime'))
|
last_trade_timestamp = self.parse8601(self.safe_string(order, 'closeTime'))
|
||||||
|
if last_trade_timestamp is None:
|
||||||
|
last_trade_timestamp = timestamp
|
||||||
|
|
||||||
status = self.parse_order_status(self.safe_string(order, 'state'))
|
status = self.parse_order_status(self.safe_string(order, 'state'))
|
||||||
side = self.parse_order_side(self.safe_string(order, 'orderType'))
|
side = self.parse_order_side(self.safe_string(order, 'orderType'))
|
||||||
@@ -796,7 +798,7 @@ class mt5(Exchange, ImplicitAPI):
|
|||||||
|
|
||||||
return self.safe_order({
|
return self.safe_order({
|
||||||
'id': id,
|
'id': id,
|
||||||
'clientOrderId': None,
|
'clientOrderId': self.safe_string(order, 'comment'),
|
||||||
'datetime': self.iso8601(timestamp),
|
'datetime': self.iso8601(timestamp),
|
||||||
'timestamp': timestamp,
|
'timestamp': timestamp,
|
||||||
'lastTradeTimestamp': last_trade_timestamp,
|
'lastTradeTimestamp': last_trade_timestamp,
|
||||||
@@ -836,13 +838,22 @@ class mt5(Exchange, ImplicitAPI):
|
|||||||
|
|
||||||
def parse_order_status(self, status):
|
def parse_order_status(self, status):
|
||||||
statuses = {
|
statuses = {
|
||||||
'Started': 'open',
|
# MT5 状态 -> CCXT 标准状态
|
||||||
'Placed': 'open',
|
'Started': 'open', # 订单已开始
|
||||||
'Cancelled': 'canceled',
|
'Placed': 'open', # 订单已放置
|
||||||
'Partial': 'open',
|
'RequestAdding': 'pending', # 请求添加订单(待处理)
|
||||||
'Filled': 'closed',
|
'RequestModifying': 'pending', # 请求修改订单(待处理)
|
||||||
'Rejected': 'rejected',
|
'RequestCancelling': 'pending', # 请求取消订单(待处理)
|
||||||
'Expired': 'expired',
|
'Partial': 'open', # 订单部分成交(仍可继续成交)
|
||||||
|
'Filled': 'closed', # 订单完全成交
|
||||||
|
'Cancelled': 'canceled', # 订单已取消
|
||||||
|
'Rejected': 'rejected', # 订单被拒绝
|
||||||
|
'Expired': 'expired', # 订单已过期
|
||||||
|
# 备用映射
|
||||||
|
'New': 'open',
|
||||||
|
'Active': 'open',
|
||||||
|
'Done': 'closed',
|
||||||
|
'Canceled': 'canceled',
|
||||||
}
|
}
|
||||||
return self.safe_string(statuses, status, status)
|
return self.safe_string(statuses, status, status)
|
||||||
|
|
||||||
|
|||||||
25
ccxt/mt5.py
25
ccxt/mt5.py
@@ -803,7 +803,7 @@ class mt5(Exchange, ImplicitAPI):
|
|||||||
|
|
||||||
return self.safe_order({
|
return self.safe_order({
|
||||||
'id': id,
|
'id': id,
|
||||||
'clientOrderId': None,
|
'clientOrderId': self.safe_string(order, 'comment'),
|
||||||
'datetime': self.iso8601(timestamp),
|
'datetime': self.iso8601(timestamp),
|
||||||
'timestamp': timestamp,
|
'timestamp': timestamp,
|
||||||
'lastTradeTimestamp': last_trade_timestamp,
|
'lastTradeTimestamp': last_trade_timestamp,
|
||||||
@@ -835,13 +835,22 @@ class mt5(Exchange, ImplicitAPI):
|
|||||||
|
|
||||||
def parse_order_status(self, status):
|
def parse_order_status(self, status):
|
||||||
statuses = {
|
statuses = {
|
||||||
'Started': 'open',
|
# MT5 状态 -> CCXT 标准状态
|
||||||
'Placed': 'open',
|
'Started': 'open', # 订单已开始
|
||||||
'Cancelled': 'canceled',
|
'Placed': 'open', # 订单已放置
|
||||||
'Partial': 'open',
|
'RequestAdding': 'pending', # 请求添加订单(待处理)
|
||||||
'Filled': 'closed',
|
'RequestModifying': 'pending', # 请求修改订单(待处理)
|
||||||
'Rejected': 'rejected',
|
'RequestCancelling': 'pending', # 请求取消订单(待处理)
|
||||||
'Expired': 'expired',
|
'Partial': 'open', # 订单部分成交(仍可继续成交)
|
||||||
|
'Filled': 'closed', # 订单完全成交
|
||||||
|
'Cancelled': 'canceled', # 订单已取消
|
||||||
|
'Rejected': 'rejected', # 订单被拒绝
|
||||||
|
'Expired': 'expired', # 订单已过期
|
||||||
|
# 备用映射
|
||||||
|
'New': 'open',
|
||||||
|
'Active': 'open',
|
||||||
|
'Done': 'closed',
|
||||||
|
'Canceled': 'canceled',
|
||||||
}
|
}
|
||||||
return self.safe_string(statuses, status, status)
|
return self.safe_string(statuses, status, status)
|
||||||
|
|
||||||
|
|||||||
@@ -382,6 +382,7 @@ class mt5(mt5Parent):
|
|||||||
update_data = self.safe_value(data, 'update', {})
|
update_data = self.safe_value(data, 'update', {})
|
||||||
order_data = self.safe_value(update_data, 'order')
|
order_data = self.safe_value(update_data, 'order')
|
||||||
if order_data:
|
if order_data:
|
||||||
|
order_data['update_type'] = self.safe_value(update_data, 'type', None) # 这个字段可以判断是开仓还是平仓
|
||||||
order = self.parse_ws_order(order_data)
|
order = self.parse_ws_order(order_data)
|
||||||
if order:
|
if order:
|
||||||
# 使用简单的列表而不是 ArrayCacheBySymbolById
|
# 使用简单的列表而不是 ArrayCacheBySymbolById
|
||||||
@@ -601,7 +602,7 @@ class mt5(mt5Parent):
|
|||||||
"""解析单个订单数据"""
|
"""解析单个订单数据"""
|
||||||
if not order_data:
|
if not order_data:
|
||||||
return None
|
return None
|
||||||
|
# print("++++++",order_data)
|
||||||
try:
|
try:
|
||||||
symbol = self.safe_string(order_data, 'symbol')
|
symbol = self.safe_string(order_data, 'symbol')
|
||||||
if symbol and len(symbol) >= 6:
|
if symbol and len(symbol) >= 6:
|
||||||
@@ -621,17 +622,33 @@ class mt5(mt5Parent):
|
|||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
timestamp = self.milliseconds()
|
timestamp = self.milliseconds()
|
||||||
|
|
||||||
last_trade_timestamp = None
|
last_trade_timestamp = timestamp
|
||||||
if is_closed:
|
if is_closed:
|
||||||
last_trade_timestamp = self.parse8601(close_time)
|
last_trade_timestamp = self.parse8601(close_time)
|
||||||
|
|
||||||
|
mt5_order_type = self.safe_string(order_data, 'update_type', None)
|
||||||
|
|
||||||
amount = self.safe_number(order_data, 'lots', 0)
|
amount = self.safe_number(order_data, 'lots', 0)
|
||||||
filled = self.safe_number(order_data, 'closeLots', 0)
|
filled = self.safe_number(order_data, 'closeLots', 0)
|
||||||
|
price = self.safe_number(order_data, 'openPrice')
|
||||||
|
side = self.parse_order_side(self.safe_string(order_data, 'orderType'))
|
||||||
|
|
||||||
|
if mt5_order_type == 'MarketOpen':
|
||||||
|
amount = self.safe_number(order_data, 'lots', 0)
|
||||||
|
filled = self.safe_number(order_data, 'lots', 0)
|
||||||
|
elif mt5_order_type == 'MarketClose':
|
||||||
|
amount = self.safe_number(self.safe_dict(order_data, 'dealInternalIn', {}), 'lots', 0)
|
||||||
|
filled = self.safe_number(order_data, 'closeLots', 0)
|
||||||
|
price = self.safe_number(order_data, 'closePrice')
|
||||||
|
if side == 'buy':
|
||||||
|
side = 'sell'
|
||||||
|
else:
|
||||||
|
side = 'buy'
|
||||||
remaining = max(amount - filled, 0) if amount is not None and filled is not None else None
|
remaining = max(amount - filled, 0) if amount is not None and filled is not None else None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'id': self.safe_string(order_data, 'ticket'),
|
'id': self.safe_string(order_data, 'ticket'),
|
||||||
'clientOrderId': None,
|
'clientOrderId': self.safe_string(order_data, 'comment'),
|
||||||
'datetime': self.iso8601(timestamp),
|
'datetime': self.iso8601(timestamp),
|
||||||
'timestamp': timestamp,
|
'timestamp': timestamp,
|
||||||
'lastTradeTimestamp': last_trade_timestamp,
|
'lastTradeTimestamp': last_trade_timestamp,
|
||||||
@@ -641,8 +658,8 @@ class mt5(mt5Parent):
|
|||||||
'type': self.parse_order_type(self.safe_string(order_data, 'orderType')),
|
'type': self.parse_order_type(self.safe_string(order_data, 'orderType')),
|
||||||
'timeInForce': None,
|
'timeInForce': None,
|
||||||
'postOnly': None,
|
'postOnly': None,
|
||||||
'side': self.parse_order_side(self.safe_string(order_data, 'orderType')),
|
'side': side,
|
||||||
'price': self.safe_number(order_data, 'openPrice'),
|
'price': price,
|
||||||
'stopLossPrice': self.safe_number(order_data, 'stopLoss'),
|
'stopLossPrice': self.safe_number(order_data, 'stopLoss'),
|
||||||
'takeProfitPrice': self.safe_number(order_data, 'takeProfit'),
|
'takeProfitPrice': self.safe_number(order_data, 'takeProfit'),
|
||||||
'reduceOnly': None,
|
'reduceOnly': None,
|
||||||
|
|||||||
@@ -135,20 +135,19 @@ async def websocket_quick_test():
|
|||||||
async def order_listener():
|
async def order_listener():
|
||||||
while True:
|
while True:
|
||||||
# print("111111111")
|
# print("111111111")
|
||||||
res = await exchange.watch_ticker(symbol='BTCUSD')
|
res = await exchange.watch_orders()
|
||||||
logger.error("aaa")
|
|
||||||
logger.warning("bbb")
|
|
||||||
logger.debug("ccc")
|
|
||||||
print("===========================收到信息")
|
print("===========================收到信息")
|
||||||
print(res)
|
for order in res:
|
||||||
|
del order['info']
|
||||||
|
logger.info(f"📦 订单更新: {order}")
|
||||||
# for order in res:
|
# for order in res:
|
||||||
# logger.info(f"📦 订单更新: {order}")
|
# logger.info(f"📦 订单更新: {order}")
|
||||||
|
|
||||||
# 监听余额更新
|
# 监听余额更新
|
||||||
async def balance_listener():
|
# async def balance_listener():
|
||||||
balance = await exchange.watch_balance()
|
# balance = await exchange.watch_balance()
|
||||||
total = sum([v for v in balance['total'].values() if v is not None])
|
# total = sum([v for v in balance['total'].values() if v is not None])
|
||||||
logger.info(f"💰 余额更新: 总余额 {total:.2f}")
|
# logger.info(f"💰 余额更新: 总余额 {total:.2f}")
|
||||||
|
|
||||||
# 运行监听器
|
# 运行监听器
|
||||||
await asyncio.gather(
|
await asyncio.gather(
|
||||||
@@ -166,5 +165,5 @@ async def websocket_quick_test():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 运行快速测试
|
# 运行快速测试
|
||||||
asyncio.run(quick_order_test())
|
# asyncio.run(quick_order_test())
|
||||||
# asyncio.run(websocket_quick_test())
|
asyncio.run(websocket_quick_test())
|
||||||
Reference in New Issue
Block a user