TransactionFee¶
- class pams.TransactionFee(market)[source]¶
Transaction fee base class (ABC class).
It defines the transaction fees that the buyer and the seller pay at each execution in a market. All transaction fees should inherit this class and implement
compute_fees().A transaction fee is set by the “transactionFee” setting of a market group in the config, e.g.,
{"class": "ProportionalTransactionFee", "rate": 0.001}. The runner creates one instance for each market of the group and sets it tomarket.transaction_fee. Then, it callssetup()with the setting without “class”, right after the setup of the market. Without the setting,market.transaction_feeis None and no fees are charged.Because an instance is bound to its market,
compute_fees()only receives the execution: the price, the volume and the two orders. Everything else can be read throughself.market, e.g., the order books (self.market.buy_order_bookandself.market.sell_order_book), the prices, the time (self.market.get_time()), the simulator (self.market.simulator), the agents (self.market.simulator.id2agent) and the other markets (self.market.simulator.markets). An instance can also keep its own state, e.g., the cumulative volume of each agent for tiered fees.The market calls
compute_fees()once for each execution and records the fees inpams.logs.ExecutionLogasbuy_transaction_feeandsell_transaction_fee. The simulator subtracts them from the cash of the buyer and the seller. No agent receives them. Instead, the market adds both fees to the transaction fees that it collects in the time step, whichpams.Market.get_transaction_fee_revenues()returns for each time step andpams.Market.get_cumulative_transaction_fee_revenue()returns as the balance up to a time step. Negative fees (rebates) reduce them.When the market executes orders, which the runner asks it to do after each order or cancel while the market is running, it first matches the best buy and sell orders as long as their prices cross and determines one execution price for all the matched pairs. Then, it executes the pairs one by one in the order in which they were matched, and
compute_fees()is called for each pair before the volume of the pair is subtracted from its orders. At that moment:the two orders of the pair and the orders of the later pairs are still in the order books, and their volumes still include this pair and the later pairs (only the earlier pairs are subtracted), so the order books can still be crossed;
the earlier pairs of the same matching are already executed: their volumes are subtracted from their orders, the fully executed orders are removed from the order books, and the executed prices and volumes and the transaction fee revenue of the market include them;
the cash and the asset volumes of the agents do not include any pair of the matching yet, because the simulator updates them after all the pairs are executed.
Creating and setting up transaction fees does not draw random numbers from the pseudo random number generators of the runner or of the markets, and the built-in transaction fees draw none. Therefore, for the same seed, the prices and the executions are exactly the same with and without transaction fees, as long as the agents do not look at their cash (the built-in agents do not). If a transaction fee needs random numbers, create its own
random.Randominsetup().- abstract compute_fees(price, volume, buy_order, sell_order)[source]¶
Compute the transaction fees of an execution.
This is called by the market for each execution, before the executed volume is subtracted from the orders (see
TransactionFeefor the state of the market at that moment). You must implement this.- Parameters:
price (float) – executed price.
volume (int) – executed volume.
buy_order (
pams.order.Order) – buy order. Its volume still includes the executed volume.sell_order (
pams.order.Order) – sell order. Its volume still includes the executed volume.
- Returns:
transaction fees of the buyer and of the seller, which must be finite numbers. Negative fees are rebates, which are added to the cash.
- Return type:
Tuple[float, float]
- setup(settings, *args, **kwargs)[source]¶
Transaction fee setup. Usually be called from runner automatically.
It is called right after the setup of the market. By default, it does nothing.
- Parameters:
settings (Dict[str, Any]) – transaction fee configuration, i.e., the “transactionFee” setting of the market without “class”. Usually, automatically set from json config of simulator.
*args – not used.
**kwargs – not used.
- Return type:
None- Returns:
None