mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-21 14:48:25 +00:00
PyMtApi5: implemented function SymbolInfoString; formatted code.
This commit is contained in:
@@ -38,6 +38,7 @@ class Mt5ApiApp:
|
||||
"SymbolIsSynchronized": self.process_symbol_is_synchronized,
|
||||
"SymbolInfoDouble": self.process_symbol_info_double,
|
||||
"SymbolInfoInteger": self.process_symbol_info_integer,
|
||||
"SymbolInfoString": self.process_symbol_info_string,
|
||||
}
|
||||
|
||||
def on_disconnect(self, error_msg=None):
|
||||
@@ -204,6 +205,16 @@ class Mt5ApiApp:
|
||||
result = mtapi.symbol_info_integer(symbol, prop_id)
|
||||
print(f"> SymbolInfoInteger: response = {result}")
|
||||
|
||||
def process_symbol_info_string(self, mtapi, parameters):
|
||||
pieces = parameters.split(" ", 1)
|
||||
if len(pieces) != 2 or not pieces[0] or not pieces[1]:
|
||||
print(f"! Invalid parameters for command SymbolInfoString: {parameters}")
|
||||
return
|
||||
symbol = pieces[0]
|
||||
prop_id = mt5enums.ENUM_SYMBOL_INFO_STRING(int(pieces[1]))
|
||||
result = mtapi.symbol_info_string(symbol, prop_id)
|
||||
print(f"> SymbolInfoString: response = {result}")
|
||||
|
||||
def mtapi_command_thread(self, mtapi):
|
||||
while mtapi.is_connected():
|
||||
filename = "client.cmd"
|
||||
|
||||
+56
-74
@@ -1,11 +1,12 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import asyncio
|
||||
from mt5enums import *
|
||||
from enum import IntEnum
|
||||
from threading import Lock, Thread
|
||||
from mtrpcclient import MtRpcClient
|
||||
|
||||
from mt5commandtype import Mt5CommandType
|
||||
from mt5enums import *
|
||||
from mtrpcclient import MtRpcClient
|
||||
|
||||
|
||||
class Mt5EventType(IntEnum):
|
||||
@@ -63,10 +64,12 @@ class MqlTradeTransaction:
|
||||
self.time_expiration = mql_trade_transaction_json["MtTimeExpiration"]
|
||||
|
||||
def __repr__(self):
|
||||
return (f"deal = {self.deal}, order = {self.order}, symbol = {self.symbol}, transaction_type = {self.transaction_type}, "
|
||||
return (
|
||||
f"deal = {self.deal}, order = {self.order}, symbol = {self.symbol}, transaction_type = {self.transaction_type}, "
|
||||
f"order_type = {self.order_type}, order_state = {self.order_state}, deal_type = {self.deal_type}, time_type = {self.time_type}, "
|
||||
f"price = {self.price}, price_trigger = {self.price_trigger}, price_sl = {self.price_sl}, price_tp = {self.price_tp}, volume = {self.volume}, "
|
||||
f"position = {self.position}, position_by = {self.position_by}, time_expiration = {self.time_expiration}")
|
||||
f"position = {self.position}, position_by = {self.position_by}, time_expiration = {self.time_expiration}"
|
||||
)
|
||||
|
||||
|
||||
class MqlTradeRequest:
|
||||
@@ -90,10 +93,12 @@ class MqlTradeRequest:
|
||||
# self.position_by = mql_trade_request_json["PositionBy"]
|
||||
|
||||
def __repr__(self):
|
||||
return (f"action = {self.action}, magic = {self.magic}, order = {self.order}, symbol = {self.symbol}, volume = {self.volume}, "
|
||||
return (
|
||||
f"action = {self.action}, magic = {self.magic}, order = {self.order}, symbol = {self.symbol}, volume = {self.volume}, "
|
||||
f"price = {self.price}, stop_limit = {self.stop_limit}, sl = {self.sl}, tp = {self.tp}, deviation = {self.deviation}, "
|
||||
f"order_type = {self.order_type}, type_filling = {self.type_filling}, type_time = {self.type_time}, expiration = {self.expiration}, "
|
||||
f"comment = {self.comment}")
|
||||
f"comment = {self.comment}"
|
||||
)
|
||||
|
||||
|
||||
class MqlTradeResult:
|
||||
@@ -109,8 +114,10 @@ class MqlTradeResult:
|
||||
self.request_id = mql_trade_result_json["Request_id"]
|
||||
|
||||
def __repr__(self):
|
||||
return (f"retcode = {self.retcode}, deal = {self.deal}, order = {self.order}, volume = {self.volume}, price = {self.price}, "
|
||||
f"bid = {self.bid}, ask = {self.ask}, comment = {self.comment}, request_id = {self.request_id}")
|
||||
return (
|
||||
f"retcode = {self.retcode}, deal = {self.deal}, order = {self.order}, volume = {self.volume}, price = {self.price}, "
|
||||
f"bid = {self.bid}, ask = {self.ask}, comment = {self.comment}, request_id = {self.request_id}"
|
||||
)
|
||||
|
||||
|
||||
class Mt5ApiClient:
|
||||
@@ -176,20 +183,17 @@ class Mt5ApiClient:
|
||||
# AccountInfoDouble
|
||||
def account_info_double(self, property_id: ENUM_ACCOUNT_INFO_DOUBLE):
|
||||
cmd_params = {"PropertyId": property_id}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.AccountInfoDouble, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.AccountInfoDouble, cmd_params)
|
||||
|
||||
# AccountInfoInteger
|
||||
def account_info_integer(self, property_id: ENUM_ACCOUNT_INFO_INTEGER):
|
||||
cmd_params = {"PropertyId": property_id}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.AccountInfoInteger, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.AccountInfoInteger, cmd_params)
|
||||
|
||||
# AccountInfoString
|
||||
def account_info_string(self, property_id: ENUM_ACCOUNT_INFO_STRING):
|
||||
cmd_params = {"PropertyId": property_id}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.AccountInfoString, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.AccountInfoString, cmd_params)
|
||||
|
||||
# Timeseries and Indicators Access
|
||||
|
||||
@@ -197,33 +201,27 @@ class Mt5ApiClient:
|
||||
def series_info_integer(self, symbol_name, timeframe: ENUM_TIMEFRAMES, prop_id: ENUM_SERIES_INFO_INTEGER):
|
||||
if symbol_name is None:
|
||||
symbol_name = ""
|
||||
cmd_params = {"Symbol": symbol_name,
|
||||
"Timeframe": timeframe, "PropId": prop_id}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.SeriesInfoInteger, cmd_params)
|
||||
cmd_params = {"Symbol": symbol_name, "Timeframe": timeframe, "PropId": prop_id}
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SeriesInfoInteger, cmd_params)
|
||||
|
||||
# Bars
|
||||
def bars(self, symbol_name, timeframe: ENUM_TIMEFRAMES):
|
||||
if symbol_name is None:
|
||||
symbol_name = ""
|
||||
cmd_params = {"Symbol": symbol_name, "Timeframe": timeframe}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.Bars, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.Bars, cmd_params)
|
||||
|
||||
# Bars (for a specified period)
|
||||
def bars_period(self, symbol_name, timeframe: ENUM_TIMEFRAMES, start_time: int, stop_time: int):
|
||||
if symbol_name is None:
|
||||
symbol_name = ""
|
||||
cmd_params = {"Symbol": symbol_name, "Timeframe": timeframe,
|
||||
"StartTime": start_time, "StopTime": stop_time}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.Bars2, cmd_params)
|
||||
cmd_params = {"Symbol": symbol_name, "Timeframe": timeframe, "StartTime": start_time, "StopTime": stop_time}
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.Bars2, cmd_params)
|
||||
|
||||
# BarsCalculated
|
||||
def bars_calculated(self, indicator_handle: int):
|
||||
cmd_params = {"IndicatorHandle": indicator_handle}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.BarsCalculated, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.BarsCalculated, cmd_params)
|
||||
|
||||
# CopyBuffer
|
||||
def copy_buffer(self):
|
||||
@@ -281,58 +279,57 @@ class Mt5ApiClient:
|
||||
pass
|
||||
|
||||
# IndicatorCreate
|
||||
def indicator_create(self, symbol: str, period: ENUM_TIMEFRAMES, indicator_type: ENUM_INDICATOR, parameters: list = []):
|
||||
def indicator_create(
|
||||
self, symbol: str, period: ENUM_TIMEFRAMES, indicator_type: ENUM_INDICATOR, parameters: list = []
|
||||
):
|
||||
cmd_params = {"Period": period, "IndicatorType": indicator_type}
|
||||
if symbol is not None:
|
||||
cmd_params["Symbol"] = symbol
|
||||
if len(parameters) != 0:
|
||||
cmd_params["Parameters"] = parameters
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.IndicatorCreate, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.IndicatorCreate, cmd_params)
|
||||
|
||||
# IndicatorRelease
|
||||
def indicator_release(self, indicator_handle: int):
|
||||
cmd_params = {"IndicatorHandle": indicator_handle}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.IndicatorRelease, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.IndicatorRelease, cmd_params)
|
||||
|
||||
# Market Info
|
||||
|
||||
# SymbolsTotal
|
||||
def symbols_total(self, selected: bool):
|
||||
cmd_params = {"Selected": selected}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.SymbolsTotal, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SymbolsTotal, cmd_params)
|
||||
|
||||
# SymbolName
|
||||
def symbol_name(self, pos: int, selected: bool):
|
||||
cmd_params = {"Pos": pos, "Selected": selected}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.SymbolName, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SymbolName, cmd_params)
|
||||
|
||||
# SymbolSelect
|
||||
def symbol_select(self, symbol_name: str, selected: bool):
|
||||
cmd_params = {"Symbol": symbol_name, "Selected": selected}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.SymbolSelect, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SymbolSelect, cmd_params)
|
||||
|
||||
# SymbolIsSynchronized
|
||||
def symbol_is_synchronized(self, symbol_name: str):
|
||||
cmd_params = {"Symbol": symbol_name}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.SymbolIsSynchronized, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SymbolIsSynchronized, cmd_params)
|
||||
|
||||
# SymbolInfoDouble
|
||||
def symbol_info_double(self, symbol_name: str, prop_id: ENUM_SYMBOL_INFO_DOUBLE):
|
||||
cmd_params = {"Symbol": symbol_name, "PropId": prop_id}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.SymbolInfoDouble, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SymbolInfoDouble, cmd_params)
|
||||
|
||||
# SymbolInfoInteger
|
||||
def symbol_info_integer(self, symbol_name: str, prop_id: ENUM_SYMBOL_INFO_INTEGER):
|
||||
cmd_params = {"Symbol": symbol_name, "PropId": prop_id}
|
||||
return self.__send_command(
|
||||
self.__get_default_expert(), Mt5CommandType.SymbolInfoInteger, cmd_params)
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SymbolInfoInteger, cmd_params)
|
||||
|
||||
# SymbolInfoString
|
||||
def symbol_info_string(self, symbol_name: str, prop_id: ENUM_SYMBOL_INFO_STRING):
|
||||
cmd_params = {"Symbol": symbol_name, "PropId": prop_id}
|
||||
return self.__send_command(self.__get_default_expert(), Mt5CommandType.SymbolInfoString, cmd_params)
|
||||
|
||||
# Private methods
|
||||
|
||||
@@ -355,18 +352,15 @@ class Mt5ApiClient:
|
||||
|
||||
def __send_command(self, expert_handle, command_type, payload=None):
|
||||
payload_json = None if payload is None else json.dumps(payload)
|
||||
response = self.__rpcclient.send_command(
|
||||
expert_handle, command_type, payload_json)
|
||||
response = self.__rpcclient.send_command(expert_handle, command_type, payload_json)
|
||||
if response is None:
|
||||
self.__logger.warning("Failed to send commad. Result is None")
|
||||
raise Exception("Failed to send commad. Result is None")
|
||||
response_json = json.loads(response)
|
||||
error_code = int(response_json["ErrorCode"])
|
||||
if error_code != 0:
|
||||
self.__logger.warning(
|
||||
f"send_command: ErrorCode = {response.ErrorCode}. {response.ErrorMessage}")
|
||||
raise Exception(
|
||||
f"Failed to send command: ErrorCode = {response.ErrorCode}. {response.ErrorMessage} ")
|
||||
self.__logger.warning(f"send_command: ErrorCode = {response.ErrorCode}. {response.ErrorMessage}")
|
||||
raise Exception(f"Failed to send command: ErrorCode = {response.ErrorCode}. {response.ErrorMessage} ")
|
||||
return response_json["Value"]
|
||||
|
||||
def __process_tick_event(self, payload):
|
||||
@@ -423,40 +417,31 @@ class Mt5ApiClient:
|
||||
|
||||
def __process_on_lock_tick(self, expert_handle, payload):
|
||||
# TODO: must be implemented
|
||||
self.__logger.warning(
|
||||
f"event type OnLockTicks is not supported. {expert_handle} - {payload}")
|
||||
self.__logger.warning(f"event type OnLockTicks is not supported. {expert_handle} - {payload}")
|
||||
|
||||
def __process_on_trade_transaction(self, expert_handle, payload):
|
||||
trade_transaction_json = json.loads(payload)
|
||||
trade_transaction = MqlTradeTransaction(
|
||||
trade_transaction_json["Trans"])
|
||||
trade_transaction = MqlTradeTransaction(trade_transaction_json["Trans"])
|
||||
trade_request = MqlTradeRequest(trade_transaction_json["Request"])
|
||||
trade_result = MqlTradeResult(trade_transaction_json["Result"])
|
||||
if self.__callback is not None:
|
||||
self.__callback.on_trade_transaction(
|
||||
expert_handle, trade_transaction, trade_request, trade_result)
|
||||
self.__callback.on_trade_transaction(expert_handle, trade_transaction, trade_request, trade_result)
|
||||
|
||||
# RPC event handlers
|
||||
|
||||
def mt_rpc_on_event(self, expert_handle, event_type, payload):
|
||||
self.__logger.debug(
|
||||
f"received event from {expert_handle}: {event_type}, {payload}")
|
||||
self.__logger.debug(f"received event from {expert_handle}: {event_type}, {payload}")
|
||||
mt_event_type = Mt5EventType(int(event_type))
|
||||
if mt_event_type == Mt5EventType.OnTick:
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_tick_event, payload)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_tick_event, payload)
|
||||
elif mt_event_type == Mt5EventType.OnBookEvent:
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_on_book_event, expert_handle, payload)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_on_book_event, expert_handle, payload)
|
||||
elif mt_event_type == Mt5EventType.OnLastTimeBar:
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_on_last_time_bar, expert_handle, payload)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_on_last_time_bar, expert_handle, payload)
|
||||
elif mt_event_type == Mt5EventType.OnLockTicks:
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_on_lock_tick, expert_handle, payload)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_on_lock_tick, expert_handle, payload)
|
||||
elif mt_event_type == Mt5EventType.OnTradeTransaction:
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_on_trade_transaction, expert_handle, payload)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_on_trade_transaction, expert_handle, payload)
|
||||
else:
|
||||
self.__logger.warning(f"received unsupported event {event_type}")
|
||||
|
||||
@@ -466,15 +451,12 @@ class Mt5ApiClient:
|
||||
|
||||
def mt_rpc_on_connection_failed(self, error_msg=None):
|
||||
self.__logger.info(f"connection failed: {error_msg}")
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_event_disconnect, error_msg)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_event_disconnect, error_msg)
|
||||
|
||||
def mt_rpc_on_expert_added(self, expert_handle):
|
||||
self.__logger.info(f"expert added: {expert_handle}")
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_expert_added, expert_handle)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_expert_added, expert_handle)
|
||||
|
||||
def mt_rpc_on_expert_removed(self, expert_handle):
|
||||
self.__logger.info(f"expert removed: {expert_handle}")
|
||||
self.__event_loop.call_soon_threadsafe(
|
||||
self.__process_expert_removed, expert_handle)
|
||||
self.__event_loop.call_soon_threadsafe(self.__process_expert_removed, expert_handle)
|
||||
|
||||
+53
-12
@@ -2,6 +2,7 @@ from enum import IntEnum
|
||||
|
||||
# Chart Timeframes
|
||||
|
||||
|
||||
class ENUM_TIMEFRAMES(IntEnum):
|
||||
PERIOD_CURRENT = 0
|
||||
PERIOD_M1 = 1
|
||||
@@ -29,6 +30,7 @@ class ENUM_TIMEFRAMES(IntEnum):
|
||||
|
||||
# Charts Properties
|
||||
|
||||
|
||||
class ENUM_CHART_PROPERTY_DOUBLE(IntEnum):
|
||||
CHART_SHIFT_SIZE = 3
|
||||
CHART_FIXED_POSITION = 41
|
||||
@@ -113,6 +115,7 @@ class ENUM_CHART_POSITION(IntEnum):
|
||||
|
||||
# Client Terminal Properties
|
||||
|
||||
|
||||
class ENUM_TERMINAL_INFO_INTEGER(IntEnum):
|
||||
TERMINAL_BUILD = 5
|
||||
TERMINAL_COMMUNITY_ACCOUNT = 23
|
||||
@@ -153,6 +156,7 @@ class ENUM_TERMINAL_INFO_STRING(IntEnum):
|
||||
|
||||
# Symbol Properties
|
||||
|
||||
|
||||
class ENUM_SYMBOL_INFO_INTEGER(IntEnum):
|
||||
SYMBOL_CUSTOM = 78
|
||||
SYMBOL_BACKGROUND_COLOR = 79
|
||||
@@ -324,6 +328,7 @@ class ENUM_SYMBOL_OPTION_MODE(IntEnum):
|
||||
|
||||
# Account Properties
|
||||
|
||||
|
||||
class ENUM_ACCOUNT_INFO_INTEGER(IntEnum):
|
||||
ACCOUNT_LOGIN = 0 # Account number
|
||||
ACCOUNT_TRADE_MODE = 32 # Account trade mode
|
||||
@@ -379,17 +384,23 @@ class ENUM_ACCOUNT_MARGIN_MODE(IntEnum):
|
||||
# Trade Constants:
|
||||
# History Database Properties
|
||||
|
||||
|
||||
class ENUM_SERIES_INFO_INTEGER(IntEnum):
|
||||
SERIES_BARS_COUNT = 0 # Bars count for the symbol-period for the current moment
|
||||
SERIES_FIRSTDATE = 1 # The very first date for the symbol-period for the current moment
|
||||
SERIES_LASTBAR_DATE = 5 # Open time of the last bar of the symbol-period
|
||||
SERIES_SERVER_FIRSTDATE = 2 # The very first date in the history of the symbol on the server regardless of the timeframe
|
||||
SERIES_TERMINAL_FIRSTDATE = 3 # The very first date in the history of the symbol in the client terminal, regardless of the timeframe
|
||||
SERIES_SERVER_FIRSTDATE = (
|
||||
2 # The very first date in the history of the symbol on the server regardless of the timeframe
|
||||
)
|
||||
SERIES_TERMINAL_FIRSTDATE = (
|
||||
3 # The very first date in the history of the symbol in the client terminal, regardless of the timeframe
|
||||
)
|
||||
SERIES_SYNCHRONIZED = 4 # S ymbol/period data synchronization flag for the current moment
|
||||
|
||||
|
||||
# Order Properties
|
||||
|
||||
|
||||
class ENUM_ORDER_PROPERTY_INTEGER(IntEnum):
|
||||
ORDER_TICKET = 22 # Order ticket. Unique number assigned to each order
|
||||
ORDER_TIME_SETUP = 1 # Order setup time
|
||||
@@ -431,8 +442,12 @@ class ENUM_ORDER_TYPE(IntEnum):
|
||||
ORDER_TYPE_SELL_LIMIT = 3 # Sell Limit pending order
|
||||
ORDER_TYPE_BUY_STOP = 4 # Buy Stop pending order
|
||||
ORDER_TYPE_SELL_STOP = 5 # Sell Stop pending order
|
||||
ORDER_TYPE_BUY_STOP_LIMIT = 6 # Upon reaching the order price, a pending Buy Limit order is places at the StopLimit price
|
||||
ORDER_TYPE_SELL_STOP_LIMIT = 7 # Upon reaching the order price, a pending Sell Limit order is places at the StopLimit price
|
||||
ORDER_TYPE_BUY_STOP_LIMIT = (
|
||||
6 # Upon reaching the order price, a pending Buy Limit order is places at the StopLimit price
|
||||
)
|
||||
ORDER_TYPE_SELL_STOP_LIMIT = (
|
||||
7 # Upon reaching the order price, a pending Sell Limit order is places at the StopLimit price
|
||||
)
|
||||
ORDER_TYPE_CLOSE_BY = 8 # Order to close a position by an opposite one
|
||||
|
||||
|
||||
@@ -474,6 +489,7 @@ class ENUM_ORDER_REASON(IntEnum):
|
||||
|
||||
# Position Properties
|
||||
|
||||
|
||||
class ENUM_POSITION_PROPERTY_INTEGER(IntEnum):
|
||||
POSITION_TICKET = 17 # Position ticket
|
||||
POSITION_TIME = 1 # Position open time
|
||||
@@ -508,14 +524,23 @@ class ENUM_POSITION_TYPE(IntEnum):
|
||||
|
||||
|
||||
class ENUM_POSITION_REASON(IntEnum):
|
||||
POSITION_REASON_CLIENT = 0 # The position was opened as a result of activation of an order placed from a desktop terminal
|
||||
POSITION_REASON_MOBILE = 1 # The position was opened as a result of activation of an order placed from a mobile application
|
||||
POSITION_REASON_WEB = 2 # The position was opened as a result of activation of an order placed from the web platform
|
||||
POSITION_REASON_EXPERT = 3 # The position was opened as a result of activation of an order placed from an MQL5 program
|
||||
POSITION_REASON_CLIENT = (
|
||||
0 # The position was opened as a result of activation of an order placed from a desktop terminal
|
||||
)
|
||||
POSITION_REASON_MOBILE = (
|
||||
1 # The position was opened as a result of activation of an order placed from a mobile application
|
||||
)
|
||||
POSITION_REASON_WEB = (
|
||||
2 # The position was opened as a result of activation of an order placed from the web platform
|
||||
)
|
||||
POSITION_REASON_EXPERT = (
|
||||
3 # The position was opened as a result of activation of an order placed from an MQL5 program
|
||||
)
|
||||
|
||||
|
||||
# Deal Properties
|
||||
|
||||
|
||||
class ENUM_DEAL_PROPERTY_INTEGER(IntEnum):
|
||||
DEAL_TICKET = 15 # Deal ticket. Unique number assigned to each deal
|
||||
DEAL_ORDER = 1 # Deal order number
|
||||
@@ -572,7 +597,9 @@ class ENUM_DEAL_ENTRY(IntEnum):
|
||||
|
||||
class ENUM_DEAL_REASON(IntEnum):
|
||||
DEAL_REASON_CLIENT = 0 # The deal was executed as a result of activation of an order placed from a desktop terminal
|
||||
DEAL_REASON_MOBILE = 1 # The deal was executed as a result of activation of an order placed from a mobile application
|
||||
DEAL_REASON_MOBILE = (
|
||||
1 # The deal was executed as a result of activation of an order placed from a mobile application
|
||||
)
|
||||
DEAL_REASON_WEB = 2 # The deal was executed as a result of activation of an order placed from the web platform
|
||||
DEAL_REASON_EXPERT = 3 # The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script
|
||||
DEAL_REASON_SL = 4 # The deal was executed as a result of Stop Loss activation
|
||||
@@ -585,6 +612,7 @@ class ENUM_DEAL_REASON(IntEnum):
|
||||
|
||||
# Trade Operation Types
|
||||
|
||||
|
||||
class ENUM_TRADE_REQUEST_ACTIONS(IntEnum):
|
||||
TRADE_ACTION_DEAL = 1 # Place a trade order for an immediate execution with the specified parameters (market order)
|
||||
TRADE_ACTION_PENDING = 5 # Place a trade order for the execution under specified conditions (pending order)
|
||||
@@ -596,15 +624,20 @@ class ENUM_TRADE_REQUEST_ACTIONS(IntEnum):
|
||||
|
||||
# Trade Transaction Types
|
||||
|
||||
|
||||
class ENUM_TRADE_TRANSACTION_TYPE(IntEnum):
|
||||
TRADE_TRANSACTION_ORDER_ADD = 0 # Adding a new open order
|
||||
TRADE_TRANSACTION_ORDER_UPDATE = 1 # Updating an open order. The updates include not only evident changes from the client terminal
|
||||
TRADE_TRANSACTION_ORDER_UPDATE = (
|
||||
1 # Updating an open order. The updates include not only evident changes from the client terminal
|
||||
)
|
||||
# or a trade server sides but also changes of an order state when setting it
|
||||
# (for example, transition from ORDER_STATE_STARTED to ORDER_STATE_PLACED or from ORDER_STATE_PLACED to ORDER_STATE_PARTIAL, etc.).
|
||||
TRADE_TRANSACTION_ORDER_DELETE = 2 # Removing an order from the list of the open ones. An order can be deleted from the open ones as a result of setting an appropriate request
|
||||
# or execution (filling) and moving to the history.
|
||||
TRADE_TRANSACTION_DEAL_ADD = 6 # Adding a deal to the history. The action is performed as a result of an order execution or performing operations with an account balance.
|
||||
TRADE_TRANSACTION_DEAL_UPDATE = 7 # Updating a deal in the history. There may be cases when a previously executed deal is changed on a server.
|
||||
TRADE_TRANSACTION_DEAL_UPDATE = (
|
||||
7 # Updating a deal in the history. There may be cases when a previously executed deal is changed on a server.
|
||||
)
|
||||
# For example, a deal has been changed in an external trading system (exchange) where it was previously transferred by a broker.
|
||||
TRADE_TRANSACTION_DEAL_DELETE = 8 # Deleting a deal from the history. There may be cases when a previously executed deal is deleted from a server.
|
||||
# For example, a deal has been deleted in an external trading system (exchange) where it was previously transferred by a broker.
|
||||
@@ -621,6 +654,7 @@ class ENUM_TRADE_TRANSACTION_TYPE(IntEnum):
|
||||
|
||||
# Trade Orders in Depth Of Market
|
||||
|
||||
|
||||
class ENUM_BOOK_TYPE(IntEnum):
|
||||
BOOK_TYPE_SELL = 1 # Sell order (Offer)
|
||||
BOOK_TYPE_BUY = 2 # Buy order (Bid)
|
||||
@@ -630,6 +664,7 @@ class ENUM_BOOK_TYPE(IntEnum):
|
||||
|
||||
# Object Types
|
||||
|
||||
|
||||
class ENUM_OBJECT(IntEnum):
|
||||
OBJ_VLINE = 0 # Vertical Line
|
||||
OBJ_HLINE = 1 # Horizontal Line
|
||||
@@ -679,6 +714,7 @@ class ENUM_OBJECT(IntEnum):
|
||||
|
||||
# Object Properties
|
||||
|
||||
|
||||
class ENUM_OBJECT_PROPERTY_DOUBLE(IntEnum):
|
||||
OBJPROP_PRICE = 9 # Price coordinate
|
||||
OBJPROP_LEVELVALUE = 204 # Level value
|
||||
@@ -692,7 +728,9 @@ class ENUM_OBJECT_PROPERTY_INTEGER(IntEnum):
|
||||
OBJPROP_STYLE = 1 # Style
|
||||
OBJPROP_WIDTH = 2 # Line thickness
|
||||
OBJPROP_BACK = 3 # Object in the background
|
||||
OBJPROP_ZORDER = 207 # Priority of a graphical object for receiving events of clicking on a chart (CHARTEVENT_CLICK).
|
||||
OBJPROP_ZORDER = (
|
||||
207 # Priority of a graphical object for receiving events of clicking on a chart (CHARTEVENT_CLICK).
|
||||
)
|
||||
# The default zero value is set when creating an object; the priority can be increased if necessary.
|
||||
# When objects are placed one atop another, only one of them with the highest priority will receive the CHARTEVENT_CLICK event.
|
||||
OBJPROP_FILL = 1031 # Fill an object with color (for OBJ_RECTANGLE, OBJ_TRIANGLE, OBJ_ELLIPSE, OBJ_CHANNEL, OBJ_STDDEVCHANNEL, OBJ_REGRESSION)
|
||||
@@ -765,6 +803,7 @@ class ENUM_ALIGN_MODE(IntEnum):
|
||||
|
||||
# Price Constants
|
||||
|
||||
|
||||
class ENUM_APPLIED_PRICE(IntEnum):
|
||||
PRICE_CLOSE = 1 # Close price
|
||||
PRICE_OPEN = 2 # Open price
|
||||
@@ -787,6 +826,7 @@ class ENUM_STO_PRICE(IntEnum):
|
||||
|
||||
# Smoothing Methods
|
||||
|
||||
|
||||
class ENUM_MA_METHOD(IntEnum):
|
||||
MODE_SMA = 0 # Simple averaging
|
||||
MODE_EMA = 1 # Exponential averaging
|
||||
@@ -796,6 +836,7 @@ class ENUM_MA_METHOD(IntEnum):
|
||||
|
||||
# Indicator constants
|
||||
|
||||
|
||||
class ENUM_INDICATOR(IntEnum):
|
||||
IND_AC = 5 # Accelerator Oscillator
|
||||
IND_AD = 6 # Accumulation/Distribution
|
||||
|
||||
+14
-11
@@ -9,6 +9,7 @@ from websockets.sync.client import connect as ws_connect
|
||||
class MtNotification(IntEnum):
|
||||
ClientReady = 0
|
||||
|
||||
|
||||
class MtMessageType(IntEnum):
|
||||
Command = 0
|
||||
Response = 1
|
||||
@@ -18,6 +19,7 @@ class MtMessageType(IntEnum):
|
||||
ExpertRemoved = 5
|
||||
Notification = 6
|
||||
|
||||
|
||||
class CommandTask:
|
||||
def __init__(self):
|
||||
self.locker = Lock()
|
||||
@@ -36,6 +38,7 @@ class CommandTask:
|
||||
with self.waiter:
|
||||
self.waiter.notify()
|
||||
|
||||
|
||||
class MtRpcClient:
|
||||
def __init__(self, callback=None):
|
||||
self.__logger = logging.getLogger(__name__)
|
||||
@@ -47,7 +50,7 @@ class MtRpcClient:
|
||||
|
||||
def connect(self, url):
|
||||
self.__logger.debug(f"connecting to {url}")
|
||||
self.__ws = ws_connect(url);
|
||||
self.__ws = ws_connect(url)
|
||||
self.__receive_thread = Thread(target=self.__receive_messages_thread)
|
||||
self.__receive_thread.start()
|
||||
|
||||
@@ -82,9 +85,9 @@ class MtRpcClient:
|
||||
|
||||
def __process_message(self, message):
|
||||
self.__logger.debug(f"process_message: {message}")
|
||||
pieces = message.split(';', 1)
|
||||
pieces = message.split(";", 1)
|
||||
if len(pieces) != 2 or not pieces[0] or not pieces[1]:
|
||||
self.__logger.warning("process_message: Invalid message format");
|
||||
self.__logger.warning("process_message: Invalid message format")
|
||||
return
|
||||
message_type = MtMessageType(int(pieces[0]))
|
||||
if message_type == MtMessageType.ExpertList:
|
||||
@@ -101,7 +104,7 @@ class MtRpcClient:
|
||||
self.__logger.warning(f"received unknown message type: {message_type}")
|
||||
|
||||
def __process_expert_list(self, payload):
|
||||
pieces = payload.split(',')
|
||||
pieces = payload.split(",")
|
||||
experts = list()
|
||||
for p in pieces:
|
||||
experts.append(int(p))
|
||||
@@ -111,17 +114,17 @@ class MtRpcClient:
|
||||
task.set_response(experts)
|
||||
|
||||
def __process_event(self, payload):
|
||||
pieces = payload.split(';', 2)
|
||||
pieces = payload.split(";", 2)
|
||||
if len(pieces) != 3 or not pieces[0] or not pieces[1] or not pieces[2]:
|
||||
self.__logger.warning("process_event: Invalid message format");
|
||||
self.__logger.warning("process_event: Invalid message format")
|
||||
return
|
||||
if self.__callback is not None:
|
||||
self.__callback.mt_rpc_on_event(int(pieces[0]), int(pieces[1]), pieces[2])
|
||||
|
||||
def __process_response(self, payload):
|
||||
pieces = payload.split(';', 2)
|
||||
pieces = payload.split(";", 2)
|
||||
if len(pieces) != 3 or not pieces[0] or not pieces[1] or not pieces[2]:
|
||||
self.__logger.warning("process_response: Invalid message format");
|
||||
self.__logger.warning("process_response: Invalid message format")
|
||||
return
|
||||
command_id = int(pieces[1])
|
||||
with self.__lock:
|
||||
@@ -159,6 +162,6 @@ class MtRpcClient:
|
||||
return f"{int(MtMessageType.Notification)};{notification_type}"
|
||||
|
||||
def __create_mt_command(self, expert_handle, command_id, command_type, payload):
|
||||
if (payload is None):
|
||||
return f"{MtMessageType.Command};{expert_handle};{command_id};{command_type}";
|
||||
return f"{MtMessageType.Command};{expert_handle};{command_id};{command_type};{payload}";
|
||||
if payload is None:
|
||||
return f"{MtMessageType.Command};{expert_handle};{command_id};{command_type}"
|
||||
return f"{MtMessageType.Command};{expert_handle};{command_id};{command_type};{payload}"
|
||||
|
||||
Reference in New Issue
Block a user