PyMtApi5: started implementation MtApi client MT5 for python3

This commit is contained in:
Vyacheslav Demidyuk
2025-01-15 18:31:56 +02:00
parent 6b3d54b9d5
commit 04d2f2e189
5 changed files with 1924 additions and 0 deletions
+203
View File
@@ -0,0 +1,203 @@
import logging
import signal
import sys
import time
import os
import os.path
import mt5enums
from functools import partial
from mt5apiclient import Mt5ApiClient
from threading import Thread
logger = logging.getLogger(__name__)
def signal_handler(mtapi, _, __):
if mtapi.is_connected():
mtapi.disconnect()
class Mt5ApiApp:
def __init__(self, address, port):
self.__address = address
self.__port = port
def on_disconnect(self, error_msg=None):
if error_msg is not None:
print(f"> Disconnected with error: {error_msg}")
else:
print("> Normal disconnected")
os.kill(os.getpid(), signal.SIGINT)
def on_quote_update(self, quote):
print(f"> update quote: {quote}")
def on_quote_added(self, quote):
print(f"> added quote: {quote}")
def on_quote_removed(self, quote):
print(f"> removed quote: {quote}")
def on_book_event(self, expert_handle, symbol):
print(f"> received book event: {expert_handle} - {symbol}")
def on_last_time_bar(self, expert_handle, instrument, rates):
print(
f"> received last time bar event: {expert_handle} - {instrument}, {rates}")
def on_trade_transaction(self, expert_handle, trade_transaction, trade_request, trade_result):
print(
f"> received trade transaction event: {expert_handle} - {trade_transaction}, {trade_request}, {trade_result}")
def process_command(self, mtapi, command):
pieces = command.split(' ', 1)
if len(pieces) != 2 or not pieces[0] or not pieces[1]:
print(f"! Invalid command format: {command}")
return
if pieces[0] == "AccountInfoDouble":
self.process_account_info_double(mtapi, pieces[1])
elif pieces[0] == "AccountInfoInteger":
self.process_account_info_integer(mtapi, pieces[1])
elif pieces[0] == "AccountInfoString":
self.process_account_info_string(mtapi, pieces[1])
elif pieces[0] == "SeriesInfoInteger":
self.process_series_info_integer(mtapi, pieces[1])
elif pieces[0] == "Bars":
self.process_bars(mtapi, pieces[1])
elif pieces[0] == "BarsPeriod":
self.process_bars_period(mtapi, pieces[1])
elif pieces[0] == "BarsCalculated":
self.process_bars_calculated(mtapi, pieces[1])
elif pieces[0] == "IndicatorCreate":
self.process_indicator_create(mtapi, pieces[1])
elif pieces[0] == "IndicatorRelease":
self.process_indicator_release(mtapi, pieces[1])
elif pieces[0] == "SymbolsTotal":
self.process_symbols_total(mtapi, pieces[1])
else:
print(f"! Unknown command: {pieces[0]}")
def process_account_info_double(self, mtapi, parameters):
property_id = mt5enums.ENUM_ACCOUNT_INFO_DOUBLE(int(parameters))
result = mtapi.account_info_double(property_id)
print(f"> AccountInfoDouble {property_id}: result = {result}")
def process_account_info_integer(self, mtapi, parameters):
property_id = mt5enums.ENUM_ACCOUNT_INFO_INTEGER(int(parameters))
value = mtapi.account_info_integer(property_id)
print(f"> AccountInfoInteger {property_id}: response = {value}")
def process_account_info_string(self, mtapi, parameters):
property_id = mt5enums.ENUM_ACCOUNT_INFO_STRING(int(parameters))
result = mtapi.account_info_string(property_id)
print(f"> AccountInfoString {property_id}: result = {result}")
def process_series_info_integer(self, mtpapi, parameters):
pieces = parameters.split(' ', 2)
if len(pieces) != 3 or not pieces[0] or not pieces[1] or not pieces[2]:
print(f"! Invalid parameters for command SeriesInfoInteger: {parameters}")
return
timeframe = mt5enums.ENUM_TIMEFRAMES(int(pieces[1]))
prop_id = mt5enums.ENUM_SERIES_INFO_INTEGER(int(pieces[2]))
result = mtpapi.series_info_integer(pieces[0], timeframe, prop_id)
print(f"> SeriesInfoInteger: result = {result}")
def process_bars(self, mtpapi, parameters):
pieces = parameters.split(' ', 1)
if len(pieces) != 2 or not pieces[0] or not pieces[1]:
print(f"! Invalid parameters for command Bars: {parameters}")
return
timeframe = mt5enums.ENUM_TIMEFRAMES(int(pieces[1]))
result = mtpapi.bars(pieces[0], timeframe)
print(f"> Bars: result = {result}")
def process_bars_period(self, mtpapi, parameters):
pieces = parameters.split(' ', 3)
if len(pieces) != 4 or not pieces[0] or not pieces[1] or not pieces[2] or not pieces[3]:
print(f"! Invalid parameters for command BarsPeriod: {parameters}")
return
timeframe = mt5enums.ENUM_TIMEFRAMES(int(pieces[1]))
start_time = int(pieces[2])
stop_time = int(pieces[3])
result = mtpapi.bars_period(pieces[0], timeframe, start_time, stop_time)
print(f"> Bars: result = {result}")
def process_bars_calculated(self, mtpapi, parameters):
if not parameters:
print(f"! Invalid parameters for command BarsCalculated: {parameters}")
return
indicator_handle = int(parameters)
result = mtpapi.bars_calculated(indicator_handle)
print(f"> BarsCalculated: result = {result}")
def process_indicator_create(self, mtpapi, parameters):
pieces = parameters.split(' ')
if len(pieces) != 3 or not pieces[0] or not pieces[1] or not pieces[2]:
print(f"! Invalid parameters for command IndicatorCreate: {parameters}")
return
timeframe = mt5enums.ENUM_TIMEFRAMES(int(pieces[1]))
indicator_type = mt5enums.ENUM_INDICATOR(int(pieces[2]))
result = mtpapi.indicator_create(pieces[0], timeframe, indicator_type)
print(f"> IndicatorCreate: result = {result}")
def process_indicator_release(self, mtpapi, parameters):
if not parameters:
print(f"! Invalid parameters for command IndicatorRelease: {parameters}")
return
indicator_handle = int(parameters)
result = mtpapi.indicator_release(indicator_handle)
print(f"> IndicatorRelease: response = {result}")
def process_symbols_total(self, mtpapi, parameters):
if not parameters or len(parameters) == 0:
print(f"! Invalid parameters for command SymbolsTotal: {parameters}")
return
parameters = parameters[:len(parameters) - 1]
selected = parameters == "True"
result = mtpapi.symbols_total(selected)
print(f"> SymbolsTotal: response = {result}")
def mtapi_command_thread(self, mtapi):
while mtapi.is_connected():
filename = "client.cmd"
if os.path.isfile(filename):
f = open("client.cmd", "r")
command = f.read()
f.close()
os.remove(filename)
self.process_command(mtapi, command)
time.sleep(0.5)
def run(self):
with Mt5ApiClient(self.__address, self.__port, self) as mtapi:
print(f"> Connected to {self.__address}:{self.__port}")
signal.signal(signal.SIGINT, partial(signal_handler, mtapi))
quotes = mtapi.get_quotes()
print(f"> quotes: {quotes}")
command_thread = Thread(
target=self.mtapi_command_thread, args=(mtapi,))
command_thread.start()
while mtapi.is_connected():
signal.pause()
command_thread.join()
def main():
logging.basicConfig(filename='client.log',
filemode='w', level=logging.DEBUG)
logger.info('Started')
args_num = len(sys.argv)
if args_num != 3:
print("Incorrect arguments. For using input:\n\tclient <address> <port>")
exit(1)
address = sys.argv[1]
port = int(sys.argv[2])
app = Mt5ApiApp(address, port)
app.run()
if __name__ == "__main__":
main()
+450
View File
@@ -0,0 +1,450 @@
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
class Mt5EventType(IntEnum):
OnTradeTransaction = 1
OnBookEvent = 2
OnTick = 3
OnLastTimeBar = 4
OnLockTicks = 5
class Mt5Quote:
def __init__(self, quote_json):
self.instrument = quote_json["Instrument"]
self.expert_handle = quote_json["ExpertHandle"]
self.bid = quote_json["Tick"]["Bid"]
self.ask = quote_json["Tick"]["Ask"]
self.volume = quote_json["Tick"]["Volume"]
def __repr__(self):
return f"{self.expert_handle}-{self.instrument}: Bid = {self.bid}, Ask = {self.ask}, Volume = {self.volume}"
class MqlRates:
def __init__(self, mql_rates_json):
self.time = mql_rates_json["mt_time"]
self.open = mql_rates_json["open"]
self.high = mql_rates_json["high"]
self.low = mql_rates_json["low"]
self.close = mql_rates_json["close"]
self.tick_volume = mql_rates_json["tick_volume"]
self.spread = mql_rates_json["spread"]
self.real_volume = mql_rates_json["real_volume"]
def __repr__(self):
return f"time = {self.time}, open = {self.open}, high = {self.high}, low = {self.low}, close = {self.close}, tick_volume = {self.tick_volume}, spread = {self.spread}, real_volume = {self.real_volume}"
class MqlTradeTransaction:
def __init__(self, mql_trade_transaction_json):
self.deal = mql_trade_transaction_json["Deal"]
self.order = mql_trade_transaction_json["Order"]
self.symbol = mql_trade_transaction_json["Symbol"]
self.transaction_type = mql_trade_transaction_json["Type"]
self.order_type = mql_trade_transaction_json["OrderType"]
self.order_state = mql_trade_transaction_json["OrderState"]
self.deal_type = mql_trade_transaction_json["DealType"]
self.time_type = mql_trade_transaction_json["TimeType"]
self.price = mql_trade_transaction_json["Price"]
self.price_trigger = mql_trade_transaction_json["PriceTrigger"]
self.price_sl = mql_trade_transaction_json["PriceSl"]
self.price_tp = mql_trade_transaction_json["PriceTp"]
self.volume = mql_trade_transaction_json["Volume"]
self.position = mql_trade_transaction_json["Position"]
self.position_by = mql_trade_transaction_json["PositionBy"]
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}, "
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}")
class MqlTradeRequest:
def __init__(self, mql_trade_request_json):
self.action = mql_trade_request_json["Action"]
self.magic = mql_trade_request_json["Magic"]
self.order = mql_trade_request_json["Order"]
self.symbol = mql_trade_request_json["Symbol"]
self.volume = mql_trade_request_json["Volume"]
self.price = mql_trade_request_json["Price"]
self.stop_limit = mql_trade_request_json["Stoplimit"]
self.sl = mql_trade_request_json["Sl"]
self.tp = mql_trade_request_json["Tp"]
self.deviation = mql_trade_request_json["Deviation"]
self.order_type = mql_trade_request_json["Type"]
self.type_filling = mql_trade_request_json["Type_filling"]
self.type_time = mql_trade_request_json["Type_time"]
self.expiration = mql_trade_request_json["MtExpiration"]
self.comment = mql_trade_request_json["Comment"]
# self.position = mql_trade_request_json["Position"]
# 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}, "
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}")
class MqlTradeResult:
def __init__(self, mql_trade_result_json):
self.retcode = mql_trade_result_json["Retcode"]
self.deal = mql_trade_result_json["Deal"]
self.order = mql_trade_result_json["Order"]
self.volume = mql_trade_result_json["Volume"]
self.price = mql_trade_result_json["Price"]
self.bid = mql_trade_result_json["Bid"]
self.ask = mql_trade_result_json["Ask"]
self.comment = mql_trade_result_json["Comment"]
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}")
class Mt5ApiClient:
def __init__(self, address, port, callback=None):
self.__address = address
self.__port = port
self.__callback = callback
self.__logger = logging.getLogger(__name__)
self.__rpcclient = MtRpcClient(self)
self.__is_connected = False
self.__quotes = dict()
self.__experts = list()
self.__lock = Lock()
def __enter__(self):
self.connect()
return self
def __exit__(self, *_):
self.disconnect()
def connect(self):
self.__logger.info(f"Connecting to {self.__address}:{self.__port}")
url = f"ws://{self.__address}:{self.__port}"
self.__rpcclient.connect(url)
experts = self.__rpcclient.request_expert_list()
if experts is None:
self.__rpcclient.disconnect()
raise Exception("Failed to load expert list")
self.__logger.info(f"loaded exerts {self.__experts}")
for expert_handle in experts:
quote = self.__get_quote(expert_handle)
if quote is not None:
self.__experts.append(expert_handle)
self.__quotes[expert_handle] = quote
self.__logger.info(f"loaded quotes {self.__quotes}")
# TODO: send backtesting ready
self.__event_loop = asyncio.new_event_loop()
self.__event_thread = Thread(target=self.__event_thread_func)
self.__event_thread.start()
self.__is_connected = True
def disconnect(self):
self.__rpcclient.disconnect()
self.__event_loop.call_soon_threadsafe(self.__event_loop.stop)
self.__event_thread.join()
self.__quotes.clear()
self.__experts.clear()
def is_connected(self):
with self.__lock:
return self.__is_connected
def get_quotes(self):
with self.__lock:
return list(self.__quotes.values())
def is_testing(self):
return False
# Account Information functions
# 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)
# 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)
# 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)
# Timeseries and Indicators Access
# SeriesInfoInteger
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)
# 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)
# 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)
# 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)
# CopyBuffer
def copy_buffer(self):
# TODO
pass
# CopyRates
def copy_rates(self):
# TODO
pass
# CopyTime
def copy_time(self):
# TODO
pass
# Copy Open
def copy_open(self):
# TODO
pass
# Copy High
def copy_high(self):
# TODO
pass
# CopyLow
def copy_low(self):
# TODO
pass
# CopyClose
def copy_close(self):
# TODO
pass
# CopyTickVolume
def copy_tick_volume(self):
# TODO
pass
# CopyRealVolume
def copy_real_volume(self):
# TODO
pass
# CopySpread
def copy_spread(self):
# TODO
pass
# CopyTicks
def copy_ticks(self):
# TODO
pass
# IndicatorCreate
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)
# 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)
# 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)
# Private methods
def __event_thread_func(self):
self.__logger.debug(f"__event_thread started")
asyncio.set_event_loop(self.__event_loop)
self.__event_loop.run_forever()
self.__logger.debug(f"__event_thread stopped")
def __get_quote(self, expert_handle):
response = self.__send_command(expert_handle, Mt5CommandType.GetQuote)
quote = Mt5Quote(response) if response is not None else None
return quote
def __get_default_expert(self):
with self.__lock:
if len(self.__experts) > 0:
return self.__experts[0]
return 0
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)
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} ")
return response_json["Value"]
def __process_tick_event(self, payload):
quote_json = json.loads(payload)
if quote_json is not None:
quote = Mt5Quote(quote_json)
with self.__lock:
self.__quotes[quote.expert_handle] = quote
if self.__callback is not None:
self.__callback.on_quote_update(quote)
def __process_event_disconnect(self, error_msg=None):
with self.__lock:
self.__is_connected = False
if self.__callback is not None:
self.__callback.on_disconnect(error_msg)
def __process_expert_added(self, expert_handle):
quote = self.__get_quote(expert_handle)
if quote is not None:
with self.__lock:
self.__quotes[expert_handle] = quote
self.__experts.append(expert_handle)
if self.__callback is not None:
self.__callback.on_quote_added(quote)
def __process_expert_removed(self, expert_handle):
quote = None
with self.__lock:
self.__experts.remove(expert_handle)
if expert_handle in self.__quotes:
quote = self.__quotes.pop(expert_handle)
if quote is not None and self.__callback is not None:
self.__callback.on_quote_removed(quote)
def __process_on_book_event(self, expert_handle, payload):
book_event_json = json.loads(payload)
if book_event_json is None:
self.__logger.error("Failed to parse book event json")
return
symbol = book_event_json["Symbol"]
if self.__callback is not None:
self.__callback.on_book_event(expert_handle, symbol)
def __process_on_last_time_bar(self, expert_handle, payload):
last_time_bar_event_json = json.loads(payload)
if last_time_bar_event_json is None:
self.__logger.error("Failed to parse last time bar event json")
return
instrument = last_time_bar_event_json["Instrument"]
rates = MqlRates(last_time_bar_event_json["Rates"])
if self.__callback is not None:
self.__callback.on_last_time_bar(expert_handle, instrument, rates)
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}")
def __process_on_trade_transaction(self, expert_handle, payload):
trade_transaction_json = json.loads(payload)
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)
# 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}")
mt_event_type = Mt5EventType(int(event_type))
if mt_event_type == Mt5EventType.OnTick:
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)
elif mt_event_type == Mt5EventType.OnLastTimeBar:
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)
elif mt_event_type == Mt5EventType.OnTradeTransaction:
self.__event_loop.call_soon_threadsafe(
self.__process_on_trade_transaction, expert_handle, payload)
else:
self.__logger.warning(f"received unsupported event {event_type}")
def mt_rcp_on_disconnect(self):
self.__logger.info("normal disconnected")
self.__event_loop.call_soon_threadsafe(self.__process_event_disconnect)
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)
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)
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)
+254
View File
@@ -0,0 +1,254 @@
from enum import IntEnum
class Mt5CommandType(IntEnum):
# NoCommand = 0
GetQuote = 1
#trade operations
OrderCalcMargin = 2
OrderCalcProfit = 3
PositionsTotal = 6
PositionGetSymbol = 7
PositionSelect = 8
PositionGetDouble = 9
PositionGetInteger = 10
PositionGetString = 11
PositionGetTicket = 4
OrdersTotal = 12
OrderGetTicket = 13
OrderSelect = 14
OrderGetDouble = 15
OrderGetInteger = 16
OrderGetString = 17
HistorySelect = 18
HistorySelectByPosition = 19
HistoryOrderSelect = 20
HistoryOrdersTotal = 21
HistoryOrderGetTicket = 22
HistoryOrderGetDouble = 23
HistoryOrderGetInteger = 24
HistoryOrderGetString = 25
HistoryDealSelect = 26
HistoryDealsTotal = 27
HistoryDealGetTicket = 28
HistoryDealGetDouble = 29
HistoryDealGetInteger = 30
HistoryDealGetString = 31
#Account Information
AccountInfoDouble = 32
AccountInfoInteger = 33
AccountInfoString = 34
#Access to Timeseries and Indicator Data
SeriesInfoInteger = 35
Bars = 36
Bars2 = 1036
BarsCalculated = 37
IndicatorCreate = 38
IndicatorRelease = 39
CopyBuffer = 40
CopyBuffer1 = 1040
CopyBuffer2 = 1140
CopyRates = 41
CopyRates1 = 1041
CopyRates2 = 1141
CopyTime = 42
CopyTime1 = 1042
CopyTime2 = 1142
CopyOpen = 43
CopyOpen1 = 1043
CopyOpen2 = 1143
CopyHigh = 44
CopyHigh1 = 1044
CopyHigh2 = 1144
CopyLow = 45
CopyLow1 = 1045
CopyLow2 = 1145
CopyClose = 46
CopyClose1 = 1046
CopyClose2 = 1146
CopyTickVolume = 47
CopyTickVolume1 = 1047
CopyTickVolume2 = 1147
CopyRealVolume = 48
CopyRealVolume1 = 1048
CopyRealVolume2 = 1148
CopySpread = 49
CopySpread1 = 1049
CopySpread2 = 1149
#Market Information
SymbolsTotal = 50
SymbolName = 51
SymbolSelect = 52
SymbolIsSynchronized = 53
SymbolInfoDouble = 54
SymbolInfoInteger = 55
SymbolInfoString = 56
SymbolInfoString2 = 1056
SymbolInfoTick = 57
SymbolInfoSessionQuote = 58
SymbolInfoSessionTrade = 59
MarketBookAdd = 60
MarketBookRelease = 61
MarketBookGet = 62
OrderCloseAll = 63
#CTrade
PositionClose = 64
PositionOpen = 65
PositionOpen2 = 1065
PositionModify = 6066
PositionClosePartial_bySymbol = 6067
PositionClosePartial_byTicket = 6068
#Backtesting
BacktestingReady = 66
IsTesting = 67
PositionSelectByTicket = 69
ObjectCreate = 70
ObjectName = 71
ObjectDelete = 72
ObjectsDeleteAll = 73
ObjectFind = 74
ObjectGetTimeByValue = 75
ObjectGetValueByTime = 76
ObjectMove = 77
ObjectsTotal = 78
ObjectGetDouble = 79
ObjectGetInteger = 80
ObjectGetString = 81
ObjectSetDouble = 82
ObjectSetInteger = 83
ObjectSetString = 84
iAC = 88
iAD = 89
iADX = 90
iADXWilder = 91
iAlligator = 92
iAMA = 93
iAO = 94
iATR = 95
iBearsPower = 96
iBands = 97
iBullsPower = 98
iCCI = 99
iChaikin = 100
iCustom = 101
iDEMA = 102
iDeMarker = 103
iEnvelopes = 104
iForce = 105
iFractals = 106
iFrAMA = 107
iGator = 108
iIchimoku = 109
iBWMFI = 110
iMomentum = 111
iMFI = 112
iMA = 113
iOsMA = 114
iMACD = 115
iOBV = 116
iSAR = 117
iRSI = 118
iRVI = 119
iStdDev = 120
iStochastic = 121
iTEMA = 122
iTriX = 123
iWPR = 124
iVIDyA = 125
iVolumes = 126
#Date and Time
TimeCurrent = 127
TimeTradeServer = 128
TimeLocal = 129
TimeGMT = 130
#Chart Operations
ChartId = 206
ChartRedraw = 207
ChartApplyTemplate = 236
ChartSaveTemplate = 237
ChartWindowFind = 238
ChartTimePriceToXY = 239
ChartXYToTimePrice = 240
ChartOpen = 241
ChartFirst = 242
ChartNext = 243
ChartClose = 244
ChartSymbol = 245
ChartPeriod = 246
ChartSetDouble = 247
ChartSetInteger = 248
ChartSetString = 249
ChartGetDouble = 250
ChartGetInteger = 251
ChartGetString = 252
ChartNavigate = 253
ChartIndicatorDelete = 254
ChartIndicatorName = 255
ChartIndicatorsTotal = 256
ChartWindowOnDropped = 257
ChartPriceOnDropped = 258
ChartTimeOnDropped = 259
ChartXOnDropped = 260
ChartYOnDropped = 261
ChartSetSymbolPeriod = 262
ChartScreenShot = 263
ChartIndicatorAdd = 280
ChartIndicatorGet = 281
# Terminal Operations
TerminalCompany = 68
TerminalName = 69
TerminalPath = 70
#Checkup
GetLastError = 132
TerminalInfoString = 153
TerminalInfoInteger = 204
TerminalInfoDouble = 205
#Common Functions
Alert = 136
Comment = 137
GetTickCount = 138
GetMicrosecondCount = 139
MessageBox = 140
PeriodSeconds = 141
PlaySound = 142
Print = 68
ResetLastError = 143
SendNotification = 144
SendMail = 145
#Global Variables
GlobalVariableCheck = 146
GlobalVariableTime = 147
GlobalVariableDel = 148
GlobalVariableGet = 149
GlobalVariableName = 150
GlobalVariableSet = 151
GlobalVariablesFlush = 152
GlobalVariableTemp = 154
GlobalVariableSetOnCondition = 156
GlobalVariablesDeleteAll = 157
GlobalVariablesTotal = 158
UnlockTicks = 159
PositionCloseAll = 160
TesterStop = 161
CopyTicks = 300
OrderSend = 301
OrderSendAsync = 302
OrderCheck = 303
Buy = 304
Sell = 305
+855
View File
@@ -0,0 +1,855 @@
from enum import IntEnum
# Chart Timeframes
class ENUM_TIMEFRAMES(IntEnum):
PERIOD_CURRENT = 0
PERIOD_M1 = 1
PERIOD_M2 = 2
PERIOD_M3 = 3
PERIOD_M4 = 4
PERIOD_M5 = 5
PERIOD_M6 = 6
PERIOD_M10 = 10
PERIOD_M12 = 12
PERIOD_M15 = 15
PERIOD_M20 = 20
PERIOD_M30 = 30
PERIOD_H1 = 16385
PERIOD_H2 = 16386
PERIOD_H3 = 16387
PERIOD_H4 = 16388
PERIOD_H6 = 16390
PERIOD_H8 = 16392
PERIOD_H12 = 1639
PERIOD_D1 = 16408
PERIOD_W1 = 32769
PERIOD_MN1 = 49153
# Charts Properties
class ENUM_CHART_PROPERTY_DOUBLE(IntEnum):
CHART_SHIFT_SIZE = 3
CHART_FIXED_POSITION = 41
CHART_FIXED_MAX = 8
CHART_FIXED_MIN = 9
CHART_POINTS_PER_BAR = 11
CHART_PRICE_MIN = 108
CHART_PRICE_MAX = 109
class ENUM_CHART_PROPERTY_INTEGER(IntEnum):
CHART_SHOW = 46
CHART_IS_OBJECT = 111
CHART_BRING_TO_TOP = 35
CHART_CONTEXT_MENU = 50
CHART_CROSSHAIR_TOOL = 49
CHART_MOUSE_SCROLL = 42
CHART_EVENT_MOUSE_WHEEL = 48
CHART_EVENT_MOUSE_MOVE = 40
CHART_EVENT_OBJECT_CREATE = 38
CHART_EVENT_OBJECT_DELETE = 39
CHART_MODE = 0
CHART_FOREGROUND = 1
CHART_SHIFT = 2
CHART_AUTOSCROLL = 4
CHART_KEYBOARD_CONTROL = 47
CHART_QUICK_NAVIGATION = 45
CHART_SCALE = 5
CHART_SCALEFIX = 6
CHART_SCALEFIX_11 = 7
CHART_SCALE_PT_PER_BAR = 10
CHART_SHOW_OHLC = 12
CHART_SHOW_BID_LINE = 13
CHART_SHOW_ASK_LINE = 14
CHART_SHOW_LAST_LINE = 15
CHART_SHOW_PERIOD_SEP = 16
CHART_SHOW_GRID = 17
CHART_SHOW_VOLUMES = 18
CHART_SHOW_OBJECT_DESCR = 19
CHART_VISIBLE_BARS = 100
CHART_WINDOWS_TOTAL = 101
CHART_WINDOW_IS_VISIBLE = 102
CHART_WINDOW_HANDLE = 103
CHART_WINDOW_YDISTANCE = 110
CHART_FIRST_VISIBLE_BAR = 104
CHART_WIDTH_IN_BARS = 105
CHART_WIDTH_IN_PIXELS = 106
CHART_HEIGHT_IN_PIXELS = 107
CHART_COLOR_BACKGROUND = 21
CHART_COLOR_FOREGROUND = 22
CHART_COLOR_GRID = 23
CHART_COLOR_VOLUME = 24
CHART_COLOR_CHART_UP = 25
CHART_COLOR_CHART_DOWN = 26
CHART_COLOR_CHART_LINE = 27
CHART_COLOR_CANDLE_BULL = 28
CHART_COLOR_CANDLE_BEAR = 29
CHART_COLOR_BID = 30
CHART_COLOR_ASK = 31
CHART_COLOR_LAST = 32
CHART_COLOR_STOP_LEVEL = 33
CHART_SHOW_TRADE_LEVELS = 34
CHART_DRAG_TRADE_LEVELS = 43
CHART_SHOW_DATE_SCALE = 36
CHART_SHOW_PRICE_SCALE = 37
CHART_SHOW_ONE_CLICK = 44
CHART_IS_MAXIMIZED = 115
CHART_IS_MINIMIZED = 116
class ENUM_CHART_PROPERTY_STRING(IntEnum):
CHART_COMMENT = 20
CHART_EXPERT_NAME = 113
CHART_SCRIPT_NAME = 114
class ENUM_CHART_POSITION(IntEnum):
CHART_BEGIN = 0 # Chart beginning (the oldest prices)
CHART_CURRENT_POS = 1 # Current position
CHART_END = 2 # Chart end (the latest prices)
#Client Terminal Properties
class ENUM_TERMINAL_INFO_INTEGER(IntEnum):
TERMINAL_BUILD = 5
TERMINAL_COMMUNITY_ACCOUNT = 23
TERMINAL_COMMUNITY_CONNECTION = 24
TERMINAL_CONNECTED = 6
TERMINAL_DLLS_ALLOWED = 7
TERMINAL_TRADE_ALLOWED = 8
TERMINAL_EMAIL_ENABLED = 9
TERMINAL_FTP_ENABLED = 10
TERMINAL_NOTIFICATIONS_ENABLED = 26
TERMINAL_MAXBARS = 11
TERMINAL_MQID = 22
TERMINAL_CODEPAGE = 12
TERMINAL_CPU_CORES = 21
TERMINAL_DISK_SPACE = 20
TERMINAL_MEMORY_PHYSICAL = 14
TERMINAL_MEMORY_TOTAL = 15
TERMINAL_MEMORY_AVAILABLE = 16
TERMINAL_MEMORY_USED = 17
TERMINAL_X64 = 18
TERMINAL_OPENCL_SUPPORT = 19
TERMINAL_SCREEN_DPI = 27
TERMINAL_PING_LAST = 29
class ENUM_TERMINAL_INFO_DOUBLE(IntEnum):
TERMINAL_COMMUNITY_BALANCE = 25
class ENUM_TERMINAL_INFO_STRING(IntEnum):
TERMINAL_LANGUAGE = 13
TERMINAL_COMPANY = 0
TERMINAL_NAME = 1
TERMINAL_PATH = 2
TERMINAL_DATA_PATH = 3
TERMINAL_COMMONDATA_PATH = 4
# Symbol Properties
class ENUM_SYMBOL_INFO_INTEGER(IntEnum):
SYMBOL_CUSTOM = 78
SYMBOL_BACKGROUND_COLOR = 79
SYMBOL_CHART_MODE = 80
SYMBOL_SELECT = 0
SYMBOL_VISIBLE = 76
SYMBOL_SESSION_DEALS = 56
SYMBOL_SESSION_BUY_ORDERS = 60
SYMBOL_SESSION_SELL_ORDERS = 62
SYMBOL_VOLUME = 10
SYMBOL_VOLUMEHIGH = 11
SYMBOL_VOLUMELOW = 12
SYMBOL_TIME = 15
SYMBOL_DIGITS = 17
SYMBOL_SPREAD_FLOAT = 41
SYMBOL_SPREAD = 18
SYMBOL_TICKS_BOOKDEPTH = 25
SYMBOL_TRADE_CALC_MODE = 29
SYMBOL_TRADE_MODE = 30
SYMBOL_START_TIME = 51
SYMBOL_EXPIRATION_TIME = 52
SYMBOL_TRADE_STOPS_LEVEL = 31
SYMBOL_TRADE_FREEZE_LEVEL = 32
SYMBOL_TRADE_EXEMODE = 33
SYMBOL_SWAP_MODE = 37
SYMBOL_SWAP_ROLLOVER3DAYS = 40
SYMBOL_MARGIN_HEDGED_USE_LEG = 82
SYMBOL_EXPIRATION_MODE = 49
SYMBOL_FILLING_MODE = 50
SYMBOL_ORDER_MODE = 71
SYMBOL_ORDER_GTC_MODE = 81
SYMBOL_ORDER_CLOSEBY = 64
SYMBOL_OPTION_MODE = 75
SYMBOL_OPTION_RIGHT = 74
class ENUM_SYMBOL_INFO_DOUBLE(IntEnum):
SYMBOL_BID = 1
SYMBOL_BIDHIGH = 2
SYMBOL_BIDLOW = 3
SYMBOL_ASK = 4
SYMBOL_ASKHIGH = 5
SYMBOL_ASKLOW = 6
SYMBOL_LAST = 7
SYMBOL_LASTHIGH = 8
SYMBOL_LASTLOW = 9
SYMBOL_VOLUME_REAL = 10
SYMBOL_VOLUMEHIGH_REAL = 11
SYMBOL_VOLUMELOW_REAL = 12
SYMBOL_OPTION_STRIKE = 72
SYMBOL_POINT = 16
SYMBOL_TRADE_TICK_VALUE = 26
SYMBOL_TRADE_TICK_VALUE_PROFIT = 53
SYMBOL_TRADE_TICK_VALUE_LOSS = 54
SYMBOL_TRADE_TICK_SIZE = 27
SYMBOL_TRADE_CONTRACT_SIZE = 28
SYMBOL_TRADE_ACCRUED_INTEREST = 87
SYMBOL_TRADE_FACE_VALUE = 86
SYMBOL_TRADE_LIQUIDITY_RATE = 85
SYMBOL_VOLUME_MIN = 34
SYMBOL_VOLUME_MAX = 35
SYMBOL_VOLUME_STEP = 36
SYMBOL_VOLUME_LIMIT = 55
SYMBOL_SWAP_LONG = 38
SYMBOL_SWAP_SHORT = 39
SYMBOL_MARGIN_INITIAL = 42
SYMBOL_MARGIN_MAINTENANCE = 43
SYMBOL_MARGIN_LONG = 44 # FIXME: Undocumented!
SYMBOL_MARGIN_SHORT = 45 # FIXME: Undocumented!
SYMBOL_MARGIN_LIMIT = 46 # FIXME: Undocumented!
SYMBOL_MARGIN_STOP = 47 # FIXME: Undocumented!
SYMBOL_MARGIN_STOPLIMIT = 48 # FIXME: Undocumented!
SYMBOL_SESSION_VOLUME = 57
SYMBOL_SESSION_TURNOVER = 58
SYMBOL_SESSION_INTEREST = 59
SYMBOL_SESSION_BUY_ORDERS_VOLUME = 61
SYMBOL_SESSION_SELL_ORDERS_VOLUME = 63
SYMBOL_SESSION_OPEN = 64
SYMBOL_SESSION_CLOSE = 65
SYMBOL_SESSION_AW = 66
SYMBOL_SESSION_PRICE_SETTLEMENT = 67
SYMBOL_SESSION_PRICE_LIMIT_MIN = 68
SYMBOL_SESSION_PRICE_LIMIT_MAX = 69
SYMBOL_MARGIN_HEDGED = 77
class ENUM_SYMBOL_INFO_STRING(IntEnum):
SYMBOL_BASIS = 73
SYMBOL_CURRENCY_BASE = 22
SYMBOL_CURRENCY_PROFIT = 23
SYMBOL_CURRENCY_MARGIN = 24
SYMBOL_BANK = 19
SYMBOL_DESCRIPTION = 20
SYMBOL_FORMULA = 84
SYMBOL_PAGE = 83
SYMBOL_ISIN = 70
SYMBOL_PATH = 21
class ENUM_SYMBOL_CHART_MODE(IntEnum):
SYMBOL_CHART_MODE_BID = 0
SYMBOL_CHART_MODE_LAST = 1
class ENUM_SYMBOL_ORDER_GTC_MODE(IntEnum):
SYMBOL_ORDERS_GTC = 0
SYMBOL_ORDERS_DAILY = 1
SYMBOL_ORDERS_DAILY_EXCLUDING_STOPS = 2
class ENUM_SYMBOL_CALC_MODE(IntEnum):
SYMBOL_CALC_MODE_FOREX = 0
SYMBOL_CALC_MODE_FUTURES = 1
SYMBOL_CALC_MODE_CFD = 2
SYMBOL_CALC_MODE_CFDINDEX = 3
SYMBOL_CALC_MODE_CFDLEVERAGE = 4
SYMBOL_CALC_MODE_EXCH_STOCKS = 32
SYMBOL_CALC_MODE_EXCH_FUTURES = 33
SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS = 34
SYMBOL_CALC_MODE_SERV_COLLATERAL = 64
class ENUM_SYMBOL_TRADE_MODE(IntEnum):
SYMBOL_TRADE_MODE_DISABLED = 0
SYMBOL_TRADE_MODE_LONGONLY = 1
SYMBOL_TRADE_MODE_SHORTONLY = 2
SYMBOL_TRADE_MODE_CLOSEONLY = 3
SYMBOL_TRADE_MODE_FULL = 4
class ENUM_SYMBOL_TRADE_EXECUTION(IntEnum):
SYMBOL_TRADE_EXECUTION_REQUEST = 0
SYMBOL_TRADE_EXECUTION_INSTANT = 1
SYMBOL_TRADE_EXECUTION_MARKET = 2
SYMBOL_TRADE_EXECUTION_EXCHANGE = 3
class ENUM_SYMBOL_SWAP_MODE(IntEnum):
SYMBOL_SWAP_MODE_DISABLED = 0
SYMBOL_SWAP_MODE_POINTS = 1
SYMBOL_SWAP_MODE_CURRENCY_SYMBOL = 2
SYMBOL_SWAP_MODE_CURRENCY_MARGIN = 3
SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT = 4
SYMBOL_SWAP_MODE_INTEREST_CURRENT = 5
SYMBOL_SWAP_MODE_INTEREST_OPEN = 6
SYMBOL_SWAP_MODE_REOPEN_CURRENT = 7
SYMBOL_SWAP_MODE_REOPEN_BID = 8
class ENUM_DAY_OF_WEEK(IntEnum):
SUNDAY = 0
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
class ENUM_SYMBOL_OPTION_RIGHT(IntEnum):
SYMBOL_OPTION_RIGHT_CALL = 0
SYMBOL_OPTION_RIGHT_PUT = 1
class ENUM_SYMBOL_OPTION_MODE(IntEnum):
SYMBOL_OPTION_MODE_EUROPEAN = 0
SYMBOL_OPTION_MODE_AMERICAN = 1
# Account Properties
class ENUM_ACCOUNT_INFO_INTEGER(IntEnum):
ACCOUNT_LOGIN = 0 # Account number
ACCOUNT_TRADE_MODE = 32 # Account trade mode
ACCOUNT_LEVERAGE = 35 # Account leverage
ACCOUNT_LIMIT_ORDERS = 47 # Maximum allowed number of active pending orders
ACCOUNT_MARGIN_SO_MODE = 44 # Mode for setting the minimal allowed margin
ACCOUNT_TRADE_ALLOWED = 33 # Allowed trade for the current account
ACCOUNT_TRADE_EXPERT = 34 # Allowed trade for an Expert Advisor
ACCOUNT_MARGIN_MODE = 53 # Margin calculation mode
class ENUM_ACCOUNT_INFO_DOUBLE(IntEnum):
ACCOUNT_BALANCE = 37 # Account balance in the deposit currency
ACCOUNT_CREDIT = 38 # Account credit in the deposit currency
ACCOUNT_PROFIT = 39 # Current profit of an account in the deposit currency
ACCOUNT_EQUITY = 40 # Account equity in the deposit currency
ACCOUNT_MARGIN = 41 # Account margin used in the deposit currency
ACCOUNT_MARGIN_FREE = 42 # Free margin of an account in the deposit currency
ACCOUNT_MARGIN_LEVEL = 43 # Account margin level in percents
ACCOUNT_MARGIN_SO_CALL = 45 # Margin call level
ACCOUNT_MARGIN_SO_SO = 46 # Margin stop out level
ACCOUNT_MARGIN_INITIAL = 48 # Initial margin
ACCOUNT_MARGIN_MAINTENANCE = 49 # Maintenance margin
ACCOUNT_ASSETS = 50 # The current assets of an account
ACCOUNT_LIABILITIES = 51 # The current liabilities on an account
ACCOUNT_COMMISSION_BLOCKED = 52 # The current blocked commission amount on an account
class ENUM_ACCOUNT_INFO_STRING(IntEnum):
ACCOUNT_NAME = 1 # Client name
ACCOUNT_SERVER = 3 # Trade server name
ACCOUNT_CURRENCY = 36 # Account currency
ACCOUNT_COMPANY = 2 # Name of a company that serves the account
class ENUM_ACCOUNT_TRADE_MODE(IntEnum):
ACCOUNT_TRADE_MODE_DEMO = 0 # Demo account
ACCOUNT_TRADE_MODE_CONTEST = 1 # Contest account
ACCOUNT_TRADE_MODE_REAL = 2 # Real account
class ENUM_ACCOUNT_STOPOUT_MODE(IntEnum):
ACCOUNT_STOPOUT_MODE_PERCENT = 0 # Account stop out mode in percents
ACCOUNT_STOPOUT_MODE_MONEY = 1 # Account stop out mode in money
class ENUM_ACCOUNT_MARGIN_MODE(IntEnum):
ACCOUNT_MARGIN_MODE_RETAIL_NETTING = 0 # Used for the OTC markets to interpret positions in the "netting" mode
ACCOUNT_MARGIN_MODE_EXCHANGE = 1 # Used for the exchange markets
ACCOUNT_MARGIN_MODE_RETAIL_HEDGING = 2 # Used for the exchange markets where individual positions are possible
# 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_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
ORDER_TYPE = 4 # Order type
ORDER_STATE = 14 # Order state
ORDER_TIME_EXPIRATION = 2 # Order expiration time
ORDER_TIME_DONE = 3 # Order execution or cancellation time
ORDER_TIME_SETUP_MSC = 18 # The time of placing an order for execution in milliseconds since 01.01.1970
ORDER_TIME_DONE_MSC = 19 # Order execution/cancellation time in milliseconds since 01.01.1970
ORDER_TYPE_FILLING = 5 # Order filling type
ORDER_TYPE_TIME = 6 # Order lifetime
ORDER_MAGIC = 15 # ID of an Expert Advisor that has placed the order (designed to ensure that each Expert Advisor places its own unique number)
ORDER_REASON = 23 # The reason or source for placing an order
ORDER_POSITION_ID = 17 # Position identifier that is set to an order as soon as it is executed.
# Each executed order results in a deal that opens or modifies an already existing position. The identifier of exactly this position is set to the executed order at this moment.
ORDER_POSITION_BY_ID = 21 # Identifier of an opposite position used for closing by order ORDER_TYPE_CLOSE_BY
class ENUM_ORDER_PROPERTY_DOUBLE(IntEnum):
ORDER_VOLUME_INITIAL = 7 # Order initial volume
ORDER_VOLUME_CURRENT = 8 # Order current volume
ORDER_PRICE_OPEN = 9 # Price specified in the order
ORDER_SL = 12 # Stop Loss value
ORDER_TP = 13 # Take Profit value
ORDER_PRICE_CURRENT = 10 # The current price of the order symbol
ORDER_PRICE_STOPLIMIT = 11 #The Limit order price for the StopLimit order
class ENUM_ORDER_PROPERTY_STRING(IntEnum):
ORDER_SYMBOL = 0 # Symbol of the order
ORDER_COMMENT = 16 # Order comment
ORDER_EXTERNAL_ID = 20 # Order identifier in an external trading system (on the Exchange)
class ENUM_ORDER_TYPE(IntEnum):
ORDER_TYPE_BUY = 0 # Market Buy order
ORDER_TYPE_SELL = 1 # Market Sell order
ORDER_TYPE_BUY_LIMIT = 2 # Buy Limit pending order
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_CLOSE_BY = 8 # Order to close a position by an opposite one
class ENUM_ORDER_STATE(IntEnum):
ORDER_STATE_STARTED = 0 # Order checked, but not yet accepted by broker
ORDER_STATE_PLACED = 1 # Order accepted
ORDER_STATE_CANCELED = 2 # Order canceled by client
ORDER_STATE_PARTIAL = 3 # Order partially executed
ORDER_STATE_FILLED = 4 # Order fully executed
ORDER_STATE_REJECTED = 5 # Order rejected
ORDER_STATE_EXPIRED = 6 # Order expired
ORDER_STATE_REQUEST_ADD = 7 # Order is being registered (placing to the trading system)
ORDER_STATE_REQUEST_MODIFY = 8 # Order is being modified (changing its parameters)
ORDER_STATE_REQUEST_CANCEL = 9 # Order is being deleted (deleting from the trading system)
class ENUM_ORDER_TYPE_FILLING(IntEnum):
ORDER_FILLING_FOK = 0
ORDER_FILLING_IOC = 1
ORDER_FILLING_RETURN = 2
class ENUM_ORDER_TYPE_TIME(IntEnum):
ORDER_TIME_GTC = 0
ORDER_TIME_DAY = 1
ORDER_TIME_SPECIFIED = 2
ORDER_TIME_SPECIFIED_DAY = 3
class ENUM_ORDER_REASON(IntEnum):
ORDER_REASON_CLIENT = 0 # The order was placed from a desktop terminal
ORDER_REASON_MOBILE = 1 # The order was placed from a mobile application
ORDER_REASON_WEB = 2 # The order was placed from a web platform
ORDER_REASON_EXPERT = 3 # The order was placed from an MQL5-program, i.e. by an Expert Advisor or a script
ORDER_REASON_SL = 4 # The order was placed as a result of Stop Loss activation
ORDER_REASON_TP = 5 # The order was placed as a result of Take Profit activation
ORDER_REASON_SO = 6 # The order was placed as a result of the Stop Out event
# Position Properties
class ENUM_POSITION_PROPERTY_INTEGER(IntEnum):
POSITION_TICKET = 17 # Position ticket
POSITION_TIME = 1 # Position open time
POSITION_TIME_MSC = 14 # Position opening time in milliseconds since 01.01.1970
POSITION_TIME_UPDATE = 15 # Position changing time in seconds since 01.01.1970
POSITION_TIME_UPDATE_MSC = 16 # Position changing time in milliseconds since 01.01.1970
POSITION_TYPE = 2 # Position type
POSITION_MAGIC = 12 # Position magic number
POSITION_IDENTIFIER = 13 # Position identifier is a unique number that is assigned to every newly opened position
# and doesn't change during the entire lifetime of the position. Position turnover doesn't change its identifier.
POSITION_REASON = 18 # The reason for opening a position
class ENUM_POSITION_PROPERTY_DOUBLE(IntEnum):
POSITION_VOLUME = 3 # Position volume
POSITION_PRICE_OPEN = 4 # Position open price
POSITION_SL = 6 # Stop Loss level of opened position
POSITION_TP = 7 # Take Profit level of opened position
POSITION_PRICE_CURRENT = 5 # Current price of the position symbol
POSITION_SWAP = 9 # Cumulative swap
POSITION_PROFIT = 10 # Current profit
class ENUM_POSITION_PROPERTY_STRING(IntEnum):
POSITION_SYMBOL = 0 # Symbol of the position
POSITION_COMMENT = 11 # Position comment
class ENUM_POSITION_TYPE(IntEnum):
POSITION_TYPE_BUY = 0 # Buy
POSITION_TYPE_SELL = 1 # Sell
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
# 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
DEAL_TIME = 2 # Deal time
DEAL_TIME_MSC = 13 # The time of a deal execution in milliseconds since 01.01.1970
DEAL_TYPE = 3 # Deal type
DEAL_ENTRY = 4 # Deal entry - entry in, entry out, reverse
DEAL_MAGIC = 11 # Deal magic number
DEAL_REASON = 16 # The reason or source for deal execution
DEAL_POSITION_ID = 12 # Identifier of a position
class ENUM_DEAL_PROPERTY_DOUBLE(IntEnum):
DEAL_VOLUME = 5 # Deal volume
DEAL_PRICE = 6 # Deal price
DEAL_COMMISSION = 7 # Deal commission
DEAL_SWAP = 8 # Cumulative swap on close
DEAL_PROFIT = 9 # Deal profit
class ENUM_DEAL_PROPERTY_STRING(IntEnum):
DEAL_SYMBOL = 0 # Deal symbol
DEAL_COMMENT = 10 # Deal comment
DEAL_EXTERNAL_ID = 14 # Deal identifier in an external trading system (on the Exchange)
class ENUM_DEAL_TYPE(IntEnum):
DEAL_TYPE_BUY = 0 # Buy
DEAL_TYPE_SELL = 1 # Sell
DEAL_TYPE_BALANCE = 2 # Balance
DEAL_TYPE_CREDIT = 3 # Credit
DEAL_TYPE_CHARGE = 4 # Additional charge
DEAL_TYPE_CORRECTION = 5 # Correction
DEAL_TYPE_BONUS = 6 # Bonus
DEAL_TYPE_COMMISSION = 7 # Additional commission
DEAL_TYPE_COMMISSION_DAILY = 8 # Daily commission
DEAL_TYPE_COMMISSION_MONTHLY = 9 # Monthly commission
DEAL_TYPE_COMMISSION_AGENT_DAILY = 10 # Daily agent commission
DEAL_TYPE_COMMISSION_AGENT_MONTHLY = 11 # Monthly agent commission
DEAL_TYPE_INTEREST = 12 # Interest rate
DEAL_TYPE_BUY_CANCELED = 13 # Canceled buy deal
DEAL_TYPE_SELL_CANCELED = 14 # Canceled sell deal
DEAL_DIVIDEND = 15 # Dividend operations
DEAL_DIVIDEND_FRANKED = 16 # Franked (non-taxable) dividend operations
DEAL_TAX = 17 # Tax charges
class ENUM_DEAL_ENTRY(IntEnum):
DEAL_ENTRY_IN = 0 # Entry in
DEAL_ENTRY_OUT = 1 # Entry out
DEAL_ENTRY_INOUT = 2 # Reverse
DEAL_ENTRY_STATE = 255 # Close a position by an opposite one
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_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
DEAL_REASON_TP = 5 # The deal was executed as a result of Take Profit activation
DEAL_REASON_SO = 6 # The deal was executed as a result of the Stop Out event
DEAL_REASON_ROLLOVER = 7 # The deal was executed due to a rollover
DEAL_REASON_VMARGIN = 8 # The deal was executed after charging the variation margin
DEAL_REASON_SPLIT = 9 # The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement
# 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)
TRADE_ACTION_SLTP = 6 # Modify Stop Loss and Take Profit values of an opened position
TRADE_ACTION_MODIFY = 7 # Modify the parameters of the order placed previously
TRADE_ACTION_REMOVE = 8 # Delete the pending order placed previously
TRADE_ACTION_CLOSE_BY = 10 # Close a position by an opposite one
# 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
# 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.
# 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.
TRADE_TRANSACTION_HISTORY_ADD = 3 # Adding an order to the history as a result of execution or cancellation.
TRADE_TRANSACTION_HISTORY_UPDATE = 4 # Changing an order located in the orders history. This type is provided for enhancing functionality on a trade server side.
TRADE_TRANSACTION_HISTORY_DELETE = 5 # Deleting an order from the orders history. This type is provided for enhancing functionality on a trade server side.
TRADE_TRANSACTION_POSITION = 9 # Changing a position not related to a deal execution. This type of transaction shows that a position has been changed on a trade server side.
# Position volume, open price, Stop Loss and Take Profit levels can be changed. Data on changes are submitted in MqlTradeTransaction structure via OnTradeTransaction handler.
# Position change (adding, changing or closing), as a result of a deal execution, does not lead to the occurrence of TRADE_TRANSACTION_POSITION transaction.
TRADE_TRANSACTION_REQUEST = 10 # Notification of the fact that a trade request has been processed by a server and processing result has been received.
# Only type field (trade transaction type) must be analyzed for such transactions in MqlTradeTransaction structure.
# The second and third parameters of OnTradeTransaction (request and result) must be analyzed for additional data.
# 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)
BOOK_TYPE_SELL_MARKET = 3 # Sell order by Market
BOOK_TYPE_BUY_MARKET = 4 # Buy order by Market
# Object Types
class ENUM_OBJECT(IntEnum):
OBJ_VLINE = 0 # Vertical Line
OBJ_HLINE = 1 # Horizontal Line
OBJ_TREND = 2 # Trend Line
OBJ_TRENDBYANGLE = 3 # Trend Line By Angle
OBJ_CYCLES = 4 # Cycle Lines
OBJ_ARROWED_LINE = 108 # Arrowed Line
OBJ_CHANNEL = 5 # Equidistant Channel
OBJ_STDDEVCHANNEL = 6 # Standard Deviation Channel
OBJ_REGRESSION = 7 # Linear Regression Channel
OBJ_PITCHFORK = 8 # Andrews’ Pitchfork
OBJ_GANNLINE = 9 # Gann Line
OBJ_GANNFAN = 10 # Gann Fan
OBJ_GANNGRID = 11 # Gann Grid
OBJ_FIBO = 12 # Fibonacci Retracement
OBJ_FIBOTIMES = 13 # Fibonacci Time Zones
OBJ_FIBOFAN = 14 # Fibonacci Fan
OBJ_FIBOARC = 15 # Fibonacci Arcs
OBJ_FIBOCHANNEL = 16 # Fibonacci Channel
OBJ_EXPANSION = 17 # Fibonacci Expansion
OBJ_ELLIOTWAVE5 = 18 # Elliott Motive Wave
OBJ_ELLIOTWAVE3 = 19 # Elliott Correction Wave
OBJ_RECTANGLE = 20 # Rectangle
OBJ_TRIANGLE = 21 # Triangle
OBJ_ELLIPSE = 22 # Ellipse
OBJ_ARROW_THUMB_UP = 23 # Thumbs Up
OBJ_ARROW_THUMB_DOWN = 24 # Thumbs Down
OBJ_ARROW_UP = 25 # Arrow Up
OBJ_ARROW_DOWN = 26 # Arrow Down
OBJ_ARROW_STOP = 27 # Stop Sign
OBJ_ARROW_CHECK = 28 # Check Sign
OBJ_ARROW_LEFT_PRICE = 29 # Left Price Label
OBJ_ARROW_RIGHT_PRICE = 30 # Right Price Label
OBJ_ARROW_BUY = 31 # Buy Sign
OBJ_ARROW_SELL = 32 # Sell Sign
OBJ_ARROW = 100 # Arrow
OBJ_TEXT = 101 # Text
OBJ_LABEL = 102 # Label
OBJ_BUTTON = 103 # Button
OBJ_CHART = 104 # Chart
OBJ_BITMAP = 105 # Bitmap
OBJ_BITMAP_LABEL = 106 # Bitmap Label
OBJ_EDIT = 107 # Edit
OBJ_EVENT = 109 # The "Event" object corresponding to an event in the economic calendar
OBJ_RECTANGLE_LABEL = 110 # The "Rectangle label" object for creating and designing the custom graphical interface.
# Object Properties
class ENUM_OBJECT_PROPERTY_DOUBLE(IntEnum):
OBJPROP_PRICE = 9 # Price coordinate
OBJPROP_LEVELVALUE = 204 # Level value
OBJPROP_SCALE = 1006 # Scale (properties of Gann objects and Fibonacci Arcs)
OBJPROP_ANGLE = 1007 # Angle. For the objects with no angle specified, created from a program, the value is equal to EMPTY_VALUE
OBJPROP_DEVIATION = 1010 # Deviation for the Standard Deviation Channel
class ENUM_OBJECT_PROPERTY_INTEGER(IntEnum):
OBJPROP_COLOR = 0 # Color
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).
# 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)
OBJPROP_HIDDEN = 208 # Prohibit showing of the name of a graphical object in the list of objects from the terminal menu "Charts" - "Objects" - "List of objects".
# The true value allows to hide an object from the list. By default, true is set to the objects that display calendar events,
# trading history and to the objects created from MQL5 programs. To see such graphical objects and access their properties, click on the "All" button in the "List of objects" window.
OBJPROP_SELECTED = 4 # Object is selected
OBJPROP_READONLY = 1028 # Ability to edit text in the Edit object
OBJPROP_TYPE = 7 # Object type
OBJPROP_TIME = 8 # Time coordinate
OBJPROP_SELECTABLE = 10 # Object availability
OBJPROP_CREATETIME = 11 # Time of object creation
OBJPROP_LEVELS = 200 # Number of levels
OBJPROP_LEVELCOLOR = 201 # Color of the line-level
OBJPROP_LEVELSTYLE = 202 # Style of the line-level
OBJPROP_LEVELWIDTH = 203 # Thickness of the line-level
OBJPROP_ALIGN = 1036 # Horizontal text alignment in the "Edit" object (OBJ_EDIT)
OBJPROP_FONTSIZE = 1002 # Font size
OBJPROP_RAY_LEFT = 1003 # Ray goes to the left
OBJPROP_RAY_RIGHT = 1004 # Ray goes to the right
OBJPROP_RAY = 1032 # A vertical line goes through all the windows of a chart
OBJPROP_ELLIPSE = 1005 # Showing the full ellipse of the Fibonacci Arc object (OBJ_FIBOARC)
OBJPROP_ARROWCODE = 1008 # Arrow code for the Arrow object
OBJPROP_TIMEFRAMES = 12 # Visibility of an object at timeframes
OBJPROP_ANCHOR = 1011 # Location of the anchor point of a graphical object
OBJPROP_XDISTANCE = 1012 # The distance in pixels along the X axis from the binding corner
OBJPROP_YDISTANCE = 1013 # The distance in pixels along the Y axis from the binding corner
OBJPROP_DIRECTION = 1014 # Trend of the Gann object
OBJPROP_DEGREE = 1015 # Level of the Elliott Wave Marking
OBJPROP_DRAWLINES = 1016 # Displaying lines for marking the Elliott Wave
OBJPROP_STATE = 1018 # Button state (pressed / depressed)
OBJPROP_CHART_ID = 1030 # ID of the "Chart" object (OBJ_CHART). It allows working with the properties of this object like with a normal chart using the functions described in Chart Operations, but there some exceptions.
OBJPROP_XSIZE = 1019 # The object's width along the X axis in pixels. Specified for OBJ_LABEL (read only), OBJ_BUTTON, OBJ_CHART, OBJ_BITMAP, OBJ_BITMAP_LABEL, OBJ_EDIT, OBJ_RECTANGLE_LABEL objects.
OBJPROP_YSIZE = 1020 # The object's height along the Y axis in pixels. Specified for OBJ_LABEL (read only), OBJ_BUTTON, OBJ_CHART, OBJ_BITMAP, OBJ_BITMAP_LABEL, OBJ_EDIT, OBJ_RECTANGLE_LABEL objects.
OBJPROP_XOFFSET = 1033 # The X coordinate of the upper left corner of the rectangular visible area in the graphical objects "Bitmap Label" and "Bitmap" (OBJ_BITMAP_LABEL and OBJ_BITMAP).
# The value is set in pixels relative to the upper left corner of the original image.
OBJPROP_YOFFSET = 1034 # The Y coordinate of the upper left corner of the rectangular visible area in the graphical objects "Bitmap Label" and "Bitmap" (OBJ_BITMAP_LABEL and OBJ_BITMAP).
# The value is set in pixels relative to the upper left corner of the original image.
OBJPROP_PERIOD = 1022 # Timeframe for the Chart object
OBJPROP_DATE_SCALE = 1023 # Displaying the time scale for the Chart object
OBJPROP_PRICE_SCALE = 1024 # Displaying the price scale for the Chart object
OBJPROP_CHART_SCALE = 1027 # The scale for the Chart object
OBJPROP_BGCOLOR = 1025 # The background color for OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL
OBJPROP_CORNER = 1026 # The corner of the chart to link a graphical object
OBJPROP_BORDER_TYPE = 1029 # Border type for the "Rectangle label" object
OBJPROP_BORDER_COLOR = 1035 # Border color for the OBJ_EDIT and OBJ_BUTTON objects
class ENUM_OBJECT_PROPERTY_STRING(IntEnum):
OBJPROP_NAME = 5 # Object name
OBJPROP_TEXT = 6 # Description of the object (the text contained in the object)
OBJPROP_TOOLTIP = 206 # The text of a tooltip. If the property is not set, then the tooltip generated automatically by the terminal is shown. A tooltip can be disabled by setting the "\n" (line feed) value to it
OBJPROP_LEVELTEXT = 205 # Level description
OBJPROP_FONT = 1001 # Font
OBJPROP_BMPFILE = 1017 # The name of BMP-file for Bitmap Label.
OBJPROP_SYMBOL = 1021 # Symbol for the Chart object
class ENUM_BORDER_TYPE(IntEnum):
BORDER_FLAT = 0 # Flat form
BORDER_RAISED = 1 # Prominent form
BORDER_SUNKEN = 2 # Concave form
class ENUM_ALIGN_MODE(IntEnum):
ALIGN_LEFT = 1 # Left alignment
ALIGN_CENTER = 2 # Centered (only for the Edit object)
ALIGN_RIGHT = 0 # Right alignment
# Price Constants
class ENUM_APPLIED_PRICE(IntEnum):
PRICE_CLOSE = 1 # Close price
PRICE_OPEN = 2 # Open price
PRICE_HIGH = 3 # The maximum price for the period
PRICE_LOW = 4 # The minimum price for the period
PRICE_MEDIAN = 5 # Median price, (high + low)/2
PRICE_TYPICAL = 6 # Typical price, (high + low + close)/3
PRICE_WEIGHTED = 7 # Average price, (high + low + close + close)/4
class ENUM_APPLIED_VOLUME(IntEnum):
VOLUME_TICK = 0 # Tick volume
VOLUME_REAL = 1 # Trade volume
class ENUM_STO_PRICE(IntEnum):
STO_LOWHIGH = 0 # Calculation is based on Low/High prices
STO_CLOSECLOSE = 1 # Calculation is based on Close/Close prices
# Smoothing Methods
class ENUM_MA_METHOD(IntEnum):
MODE_SMA = 0 # Simple averaging
MODE_EMA = 1 # Exponential averaging
MODE_SMMA = 2 # Smoothed averaging
MODE_LWMA = 3 # Linear-weighted averaging
# Indicator constants
class ENUM_INDICATOR(IntEnum):
IND_AC = 5 # Accelerator Oscillator
IND_AD = 6 # Accumulation/Distribution
IND_ADX = 8 # Average Directional Index
IND_ADXW = 9 # ADX by Welles Wilder
IND_ALLIGATOR = 7 # Alligator
IND_AMA = 40 # Adaptive Moving Average
IND_AO = 11 # Awesome Oscillator
IND_ATR = 10 # Average True Range
IND_BANDS = 13 # Bollinger Bands®
IND_BEARS = 12 # Bears Power
IND_BULLS = 14 # Bulls Power
IND_BWMFI = 22 # Market Facilitation Index
IND_CCI = 15 # Commodity Channel Index
IND_CHAIKIN = 41 # Chaikin Oscillator
IND_CUSTOM = 43 # Custom indicator
IND_DEMA = 36 # Double Exponential Moving Average
IND_DEMARKER = 16 # DeMarker
IND_ENVELOPES = 17 # Envelopes
IND_FORCE = 18 # Force Index
IND_FRACTALS = 19 # Fractals
IND_FRAMA = 39 # Fractal Adaptive Moving Average
IND_GATOR = 20 # Gator Oscillator
IND_ICHIMOKU = 21 # Ichimoku Kinko Hyo
IND_MA = 26 # Moving Average
IND_MACD = 23 # MACD
IND_MFI = 25 # Money Flow Index
IND_MOMENTUM = 24 # Momentum
IND_OBV = 28 # On Balance Volume
IND_OSMA = 27 # OsMA
IND_RSI = 30 # Relative Strength Index
IND_RVI = 31 # Relative Vigor Index
IND_SAR = 29 # Parabolic SAR
IND_STDDEV = 32 # Standard Deviation
IND_STOCHASTIC = 33 # Stochastic Oscillator
IND_TEMA = 37 # Triple Exponential Moving Average
IND_TRIX = 38 # Triple Exponential Moving Averages Oscillator
IND_VIDYA = 42 # Variable Index Dynamic Average
IND_VOLUMES = 34 # Volumes
IND_WPR = 35 # Williams' Percent Ranges
class ENUM_DATATYPE(IntEnum):
TYPE_BOOL = 1
TYPE_CHAR = 2
TYPE_UCHAR = 3
TYPE_SHORT = 4
TYPE_USHORT = 5
TYPE_COLOR = 6
TYPE_INT = 7
TYPE_UINT = 8
TYPE_DATETIME = 9
TYPE_LONG = 10
TYPE_ULONG = 11
TYPE_FLOAT = 12
TYPE_DOUBLE = 13
TYPE_STRING = 14
+162
View File
@@ -0,0 +1,162 @@
import websockets
from websockets.sync.client import connect as ws_connect
from threading import Thread, Lock, Condition
import logging
from enum import IntEnum
class MtNotification(IntEnum):
ClientReady = 0
class MtMessageType(IntEnum):
Command = 0
Response = 1
Event = 2
ExpertList = 3
ExpertAdded = 4
ExpertRemoved = 5
Notification = 6
class CommandTask:
def __init__(self):
self.locker = Lock()
self.waiter = Condition()
self.response = None
def wait_response(self, time):
with self.waiter:
self.waiter.wait(time)
with self.locker:
return self.response
def set_response(self, response):
with self.locker:
self.response = response
with self.waiter:
self.waiter.notify()
class MtRpcClient:
def __init__(self, callback=None):
self.__logger = logging.getLogger(__name__)
self.__callback = callback
self.__notification_tasks = dict()
self.__tasks = dict()
self.__next_command_id = 0
self.__lock = Lock()
def connect(self, url):
self.__logger.debug(f"connecting to {url}")
self.__ws = ws_connect(url);
self.__receive_thread = Thread(target = self.__receive_messages_thread)
self.__receive_thread.start()
def disconnect(self):
self.__ws.close()
self.__receive_thread.join()
self.__logger.debug("disconnected")
def request_expert_list(self):
task = CommandTask()
with self.__lock:
self.__notification_tasks[MtNotification.ClientReady] = task
self.__ws.send(self.__create_notification(MtNotification.ClientReady))
response = task.wait_response(10)
with self.__lock:
self.__notification_tasks.pop(MtNotification.ClientReady)
return response
def send_command(self, expert_handle, command_type, payload = None):
command_id = self.__next_command_id
self.__next_command_id += 1
task = CommandTask()
with self.__lock:
self.__tasks[command_id] = task
self.__ws.send(self.__create_mt_command(expert_handle, command_id, command_type, payload))
response = task.wait_response(10)
with self.__lock:
self.__tasks.pop(command_id)
return response
# Private methods
def __process_message(self, message):
self.__logger.debug(f"process_message: {message}")
pieces = message.split(';', 1)
if len(pieces) != 2 or not pieces[0] or not pieces[1]:
self.__logger.warning("process_message: Invalid message format");
return
message_type = MtMessageType(int(pieces[0]))
if message_type == MtMessageType.ExpertList:
self.__process_expert_list(pieces[1])
elif message_type == MtMessageType.Event:
self.__process_event(pieces[1])
elif message_type == MtMessageType.Response:
self.__process_response(pieces[1])
elif message_type == MtMessageType.ExpertAdded:
self.__process_expert_added(pieces[1])
elif message_type == MtMessageType.ExpertRemoved:
self.__process_expert_removed(pieces[1])
else:
self.__logger.warning(f"received unknown message type: {message_type}")
def __process_expert_list(self, payload):
pieces = payload.split(',')
experts = list()
for p in pieces:
experts.append(int(p))
with self.__lock:
task = self.__notification_tasks.get(MtNotification.ClientReady)
if task is not None:
task.set_response(experts)
def __process_event(self, payload):
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");
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)
if len(pieces) != 3 or not pieces[0] or not pieces[1] or not pieces[2]:
self.__logger.warning("process_response: Invalid message format");
return
command_id = int(pieces[1])
with self.__lock:
task = self.__tasks.get(command_id)
if task is not None:
task.set_response(pieces[2])
def __process_expert_added(self, payload):
if self.__callback is not None:
self.__callback.mt_rpc_on_expert_added(int(payload))
def __process_expert_removed(self, payload):
if self.__callback is not None:
self.__callback.mt_rpc_on_expert_removed(int(payload))
def __receive_messages_thread(self):
self.__logger.debug("started receive_messages thread")
while True:
try:
message = self.__ws.recv()
self.__process_message(message)
except websockets.exceptions.ConnectionClosed:
self.__logger.info("Connection closed")
if self.__callback is not None:
self.__callback.mt_rcp_on_disconnect()
break
except Exception as e:
self.__logger.error(e)
if self.__callback is not None:
self.__callback.mt_rpc_on_connection_failed(str(e))
break
self.__logger.debug("function receive_messages finished")
def __create_notification(self, notification_type):
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}";