Trading Port

Continuing the strategy port sub-series, we will now design the trading port.

  1. Market port.
  2. Trading port (this post).
  3. Other strategy ports.

In the modules and components post, we defined the trading port as a gateway to exchanges, managing a trading account, placing and canceling orders.

We will do as we did for the market port, that is, start with describing the domain model then proceed to defining the features supporting this representation of the world.

Domain model

Trading account

A trading account is a financial account maintained by an exchange or broker, that represents the funds they hold on behalf of the customer. The customer can use those to trade directly, or in the case of more sophisticated instruments, as a collateral securing repayment of leveraged positions.

As such, it has a more complex working than the usual deposit account. We shall use the following definitions, relevant to our trading project using accounts that support trading on margin:

Asset balances

The amount of each commodity and security owned by the customer. Barring blocked funds used as collateral, those are the amounts available for withdrawal.

Margin balance

The total value usable as a collateral for margin positions. It might differ from the total counter-value of asset balances, because not all assets might be usable as a collateral.

Open positions

On-going trades, where the asset was successfully sold (for short positions) or bought (for long positions) but not yet bought/sold back.

Used margin

Total counter-value currently blocked as a collateral to open positions.


Current counter-value of the account. That is, the total counter-value of asset balances plus/minus any unrealized profits/losses from open positions.

Margin level

Ratio of equity to used margin. This gives a measure of how exposed the account currently is to markets. When this number goes below a certain exchange-specific threshold, it will start forcefully closing loosing positions (a process known as liquidation).

In addition, an account is associated a list of orders, and a ledger that keeps track of all fund movements for legal and fiscal proceedings.

Anatomy of an order

Apart from deposits and withdrawals, which Cryptomate does not care about, all changes on a trading account are the results of executing orders.

Each order represents the intent of the account owner to buy or sell an asset for another. They come in two types:

  • A limit order has a fixed price, representing the worst price the owner wants to trade at. That is, highest price he wants to buy at, or lowest price he wants to sell at. Such an order goes to the order book if it has no counterparty when it is opened.
  • A market order has no fixed price, it requests an immediate trade, at whatever the best prices currently are.

In addition to their type, orders have a side (buy or sell), total volume to trade, expiration date and for margin trading, the leverage to use.

Once issued, the order follows the following life-cycle:

Order state diagram
Order state diagram.

Market orders follow the same state diagram, except they are executed instantly at the best possible value. This leaves no opportunity for cancelling or expiration, and it only remains if partially filled state while it is being processed.

During its life, an order will generate trades. Possibly zero if it gets cancelled, possibly many if it gets matched to a several smaller orders. The exact list of trades is usually of little value, but some aggregated statistics are commonly used, most notably:

Name Description
Executed volume How much was bought/sold so far.
Equals total volume on a closed order.
Cost How much was spent to buy/sell so far.
Average price Cost / executed volume.
Fee Total amount of fees paid for the trade so far.
Ever heard trading is a zero-sum game? Well, not so much.
Cancellation time Time at which the order was cancelled.
Close time Time at which the order got fully filled.
Order statistics.

Lastly, it is a common practice to match orders on the same market into positions. This logical grouping makes it possible to easily think about a position in terms of running profits and losses. As this grouping as actually related to a specific way of thinking about the strategy, it will not be handled at the trading port level.

Trading port features

As previously established, the purpose of the trading port is to abstract out all the details of connecting to a trading account and using it. That is:

  • Querying its status.
  • Placing and cancelling orders.
  • Subscribing to real-time events that affect account's orders.


Seen from client code, the trading port is straightforward:

  • Hand an account description to the trading engine.
  • Get an Account object back.
  • Use it to query its state, place or cancel orders.
  • Get notified of every order-related events through a callback.
  • Close the Account object when no longer needed.

Interface list

Assembling the features and objects described in previous sections, here is the full list of interfaces that, together, constitute the trading port:

Name Description
Account A valid, opened account on a trading platform.
AccountDescription Static data granting access to a trading account.
AccountEventHandler Callable that responds to events happening on an account.
Engine Main port entry point.
Order Buy/sell intent.
RuleSet Relevant trading rules for an Account.
Trade A single trade resulting from an order.
Trading port interfaces

For detailed specification of each interface, check their definition and inline documentation on GitHub. Again, due to the dynamic nature of python, not all interfaces need to appear as python types within the code.


That is it for the trading port. You will find the result on GitHub under the trading directory. In the next post, we will turn to the remaining ports of the strategy evaluator, which should be simpler.