Skip to content

Recommendations for Developers

This section provides general recommendations and solutions to common problems encountered by plugin developers.


Multithreading

Key aspects of working with threads:

  • Calls to Server API methods (e.g., the IMTServerAPI interface: Group, Symbol, etc.) are thread-safe. They can be invoked from different threads without additional synchronization.
  • Calls to object interface methods (e.g., IMTConGroup, IMTConSymbol, IMTConGateway, etc.) are NOT thread-safe. When accessing the same object from multiple threads, synchronization must be handled manually.
  • Sequential invocation of hooks and events is not guaranteed. Multiple hook or event handlers (even of the same type) may be triggered simultaneously, each in a separate thread. Therefore, your handlers must be thread-safe.
  • Synchronous calls from client-base events/hooks (e.g., IMTUserSink) to the trading database in plugins are forbidden. Violating this may cause deadlocks and server crashes.
  • Calls from trading events/hooks to the client database are allowed (all IMTServerAPI::User* methods, except those related to trading activity: UserAccountGet, UserDepositChange, UserDepositChangeRaw).
  • All plugin components must be implemented with thread safety in mind, except for calls to IMTServerAPI methods.

Interaction with Trading Server Threads

  • Do not interfere with server threads and do not use custom synchronization primitives that affect server threads (especially in hooks).
  • Data grouping for open orders and positions is done per client group, each using its own synchronization primitive.
  • Trading databases (orders, history, trades, positions) also use their own synchronization primitives.
  • In general, request processing follows a thread chain: initial check, routing, execution — with locking of the required client groups.
  • Incoming quotes, as well as symbol and group changes, are handled by a separate thread pool with corresponding locks.
  • Execution of trade requests from gateways is handled by a dedicated thread, in the order they arrive, with locking of the relevant groups.
  • Many events and hooks are invoked "under lock" — including group and/or trading database locks.

Interaction between trading and client databases is one-way only:
The trading database always accesses the client database, but never the other way around.

To avoid deadlocks:

  • Minimize direct and indirect access to data of other groups from hooks (e.g., fetching data from other orders/positions/accounts).
  • Minimize the use of custom synchronization primitives.
  • Do not attempt to explicitly control server threads (stop, synchronize, etc.).
  • In hooks and client-base events (e.g., IMTUserSink::OnUser, HookUser), API methods related to the trading database (e.g., IMTServerAPI::PositionGet) must not be called.
  • In IMTDealSink events, synchronous calls to methods for creating/modifying/deleting trades are allowed only for trades in the same group. For working with other groups, use asynchronous calls in a separate thread.

Memory Management

  • Plugins operate within the server’s address space; therefore, they must be memory-efficient and avoid excessive reallocation (fragmentation).
  • All interface objects are allocated via Create methods and released via Release.
  • If the API allocates memory (e.g., the IMTServerAPI::UserLogins function returns an array of clients), it must be freed using IMTServerAPI::Free.
  • Use IMTServerAPI::Allocate for memory allocation (paired with Free).

Working with Configuration and Data Interfaces

  • Methods like Add, Update, Delete, Clear for object interfaces modify only the local object. To apply changes to the server, call the corresponding Server API method.
  • For example, IMTConGroup::SymbolUpdate changes the symbol settings only in the local object. To send the changes to the server, call IMTServerAPI::GroupAdd.

Escaping Special Characters

  • When passing special characters (=, |, \, newline) in method parameters, they must be escaped with a backslash ().
  • If a backslash is not followed by a special character, it is interpreted as a regular character.

Examples:

Sent to server Interpreted as
\= =
|
(newline) (newline)
\ \