MetaQuotes Management Bridge - Dividend Support
Introduction
The MahiMarkets MTx Management Bridge is a Windows service designed to manage the configuration of a fleet of MetaTrader servers - both MT4 and MT5.
Please contact support@mahimarkets.com for any questions related to this document.
overview
Allows operators to apply dividends at a specific payout date and time with optional dry run.
In the csv input file the ticker symbol for the stock receiving the dividend and amount paid per share is specified.
For all the users having position in the stock it applies a positive or negative balance transaction when the dividend update runs.
The product is capable of running in a dry run mode where it emails a summary of what it would have done, if it was a real run, to double check all is working as intended.
Rollback is possible. If the job crashes in the middle of the update on next run it should continue from the point where it crashed.
Introduction
The dividend balance adjustment feature allows for periodic pay out and pay in of dividends for MT4 servers from a given CSV file.
The bridge associates every MetaTrader 4 server with an input directory which is scanned periodically and any CSV file found during the scan is processed. Dividend-related balance adjustments are applied to each respective MetaTrader 4 server and finally the bridge generates a report and sends a dividend balance adjustment summary email.
The dividend-related balance adjustment and rollback operations are idempotent. I.e. if they are run for a second time there will be no effect since the bridge keeps track of whether a certain dividend was already paid to a specific account for a specific date.
Input file structure
Input files for dividend adjustments are CSV files, and each row has the following structure:
Field | Description | Example |
instrument_filter | The dividend symbol filter. If specifying multiple symbols, they should be separated by a semicolon (;). Wildcard (*) and exclusion (!) are supported. | `US*0;!US30` - this will match all symbols starting with “US” and ending with “0”, and will exclude US30 |
dividend_date | The dividend date | 2020-10-10 |
dividend_long | Amount to be paid out/in for long position holders per unit of position held | 2 |
dividend_short | Amount to be paid out/in for short position holders per unit of position held | -1.5 |
dividend_currency | Dividend currency (the bridge will convert this currency to the deposit currency of each account before doing the balance adjustment) | USD |
tax | Percentage to be withheld for tax reasons (normalized value) | 0.1 (i.e. 10%) |
markup | Percentage to be withheld for markup reasons (normalized value) | 0.1 (i.e. 10%) |
user_group_filter | A filter specifying which groups and logins should be paid out/in for holding the current instrument | “demo*;!demoforex;!1001;999” - this filter will include all groups starting with "demo", except demoforex, also will exclude user 1001 and will include user 999 (regardless of group) |
rollback_flag | This fields should be set to “1” when doing a rollback transaction and should be “0” otherwise | 0 |
Dividend calculation
When paying a dividend for a particular symbol to a particular account, the bridge will query all open positions and will sum their volumes to produce an aggregated position. The volume of the aggregated position is then used as a basis for the following calculations.
The final amount to be payed or charged is calculated through the following formula:
`amount = dividend * volume * contract_size * exchange_rate`
Then markup is applied:
`amount = amount - abs(amount) * markup`
Then if the amount is positive a tax is applied:
`amount = amount - amount * tax`
For rollback transactions the amount is finally multiplied by -1.
`amount = amount * -1`
Where:
- amount - is the final amount to be payed or charged
- dividend - corresponds to the dividend_long or dividend_short fields of the input CSV file, depending whether the user holds a long or a short position
- volume - volume of the position being held in lots
- contract_size - the contract size of the symbol of the position being held
- exchange_rate - exchange rate used for converting from dividend currency to deposit currency
- markup - markup per the input CSV file
- tax - tax per the input CSV file
For short positions, charging an amount larger than the account balance will result in the account having a negative balance.
Position snapshotting
Before applying dividend-related balance adjustments the bridge will first gather all open positions of included users and will store the position details in a snapshot file. The snapshot doesn’t include all existing positions on the MT4 server, but only those which are related to the particular symbol, group, account, etc, filters. So when processing multiple input files during the same day, the bridge will generate a separate position snapshot per each input file.
In case there is a failure during the balance adjustment operation it is possible to re-run or rollback the operation in which case the bridge will query the positions from the snapshot file. Rerunning a balance adjustment which failed mid-way will ignore all the accounts already paid or charged by the previous run.
Currency conversion
In cases where the dividend currency differs from the deposit currency of the account being paid out (or charged), the bridge will perform currency conversion according to the exchange rate found on that particular MT4 server. In case there is no symbol containing both currencies as base and quote, the bridge will try to convert to USD first and then to deposit currency.
When converting from dividend currency to deposit currency, the bridge will use the best of the bid/ask price (from broker perspective). And when converting from dividend to report currency, the bridge will use the mid price.
If the bridge is not able to find the exchange rate for a specific balance adjustment, the transaction will be skipped and error will be generated in the email report.
Dry run
Similar to the swap update feature, the dividend-related balance adjustment can be performed in a “dry-run” mode. This means the balance adjustment operation will be “simulated” and a report will be generated without any actual change being applied to the remote MetaTrader 4 server.
Dry run mode is enabled by setting `DIVIDEND PAYOUT DRYRUN ENABLE` parameter to `Y` and `DRYRUN DIVIDEND PAYOUT PERIOD` to a cron expression specifying the desired schedule.
Rollback
Everytime a dividend-related balance adjustment is performed on a MetaTrader 4 server, the bridge will create a rollback file inside the rollback directory (see “DIVIDEND ROLLBACK DIR”
parameter in Parameters section). In case of any issue it is possible to revert the balance adjustment.
In order to perform a rollback please refer to the following steps:
- Open the rollback directory (by default it is `.\data\{SERVER}\dividend\rollback`)
- Select a subdirectory corresponding to the date/time you would like to rollback to
- Copy the CSV files into the input directory (by default it should be `.\data\{SERVER}\dividend\input`)
- Stop the bridge (from the Windows Services manager window) and reconfigure it to run after a short amount of time (by editing the `DIVIDEND PAYOUT UPDATE PERIOD` parameter) - e.g. after 5 minutes
- Start the bridge service and wait for the input directory to get scanned
- At this point the rollback should have taken place and an email should be generated in a few minute period
- Please edit `DIVIDEND PAYOUT UPDATE PERIOD` back to its previous value and restart the bridge again
Configuration
The configuration of the bridge is performed through an INI file. The “default” section of the INI file contains global parameters affecting the entire bridge. Also there are dedicated sections per each server which hold per-server parameters.
The name of a server configuration section should start either with “SERVER.MT4.” or “SERVERS.MT5.” depending on the version of the remote MetaTrader server being managed (see example below).
Parameters
Following is a list of all global configuration parameters:
Parameter | Description | Type | Default | Example |
MT TRACING ENABLED | Logs additional events (useful for troubleshooting and debugging) | Boolean | Y | N |
MT TRACING LOGS MAX DAYS TO KEEP | The bridge will keep the logs for this number of days | Integer | 14 | 30 |
EMAIL ADDRESS | Email address to receive email summary reports and alerts | Text | to@email.com | |
EMAIL FROM ADDRESS | Sender address of email reports and alerts | Text | from@email.com | |
EMAIL SMTP SERVER | SMTP server address | Text | smtp.my-server.com | |
EMAIL SMTP SERVER PORT | SMTP server port | Integer | 587 | |
EMAIL SMTP USER | SMTP username | Text | apikey | |
EMAIL SMTP PASSWORD | SMTP password | Text | mystrongpassword | |
REPORT CURRENCY | For certain reports the bridge will convert some fields to this currency to make the report more comprehensible | Text | USD | EUR |
The following parameters are supported in server sections:
Parameter | Description | Type | Derivable | Default | Example |
MT SERVER ADDRESS | Address (and port) of the remote MT4/MT5 server | Text | No | 127.0.0.1:443 | |
MT USER ID | MT4/MT5 manager user ID (needs administrative privilege) | Integer | No | 1000 | |
MT USER PASSWORD | MT4/MT5 user password | Text | No | mystrongpassword | |
SWAP UPDATE PERIOD | Schedule for performing regular swap updates | Text | Yes | 00 00 18 * * * | 00 00 18 * * * |
DRY RUN ENABLE | Enables the dry run feature | Boolean | Yes | N | Y |
DRY RUN SWAP UPDATE PERIOD | Schedule for performing updates in dry run mode (requires `DRY RUN ENABLE`=`Y`) | Text | Yes | 00 00 15 * * * | 00 00 15 * * * |
INPUT DIR | The bridge will scan this directory for CSV files with new swap values | Text | No | .\data\{SECTION}\swap\input | C:\tmp\different-input-dir |
ARCHIVE DIR | The bridge will copy CSV files here once processed | Text | No | .\data\{SECTION}\swap\archive | C:\tmp\myserver-archive |
REPORT DIR | The bridge will store individual swap update reports in this directory | Text | No | .\data\{SECTION}\swap\report | C:\tmp\myserver-report |
ROLLBACK DIR | The bridge will store rollback CSV files in this directory | Text | No | .\data\{SECTION}\swap\rollback | C:\tmp\myserver-rollback |
DIVIDEND INPUT DIR | The bridge will scan this directory for input dividend CSV files | Text | No | .\data\{SECTION}\dividend\input | C:\tmp\myserver-dividend-input |
DIVIDEND POSITION SNAPSHOT DIR | Before proceeding to dividend adjustments, the bridge will take a snapshot of all open positions and store it in a snapshot in this directory | Text | No | .\data\{SECTION}\dividend\snapshot | C:\tmp\myserver-dividend-snapshot |
DIVIDEND ARCHIVE DIR | The bridge will copy dividend CSV files here once processed | Text | No | .\data\{SECTION}\dividend\archive | C:\tmp\myserver-dividend-archive |
DIVIDEND REPORT DIR | The bridge will store individual dividend reports in this directory | Text | No | .\data\{SECTION}\dividend\report | C:\tmp\myserver-dividend-report |
DIVIDEND ROLLBACK DIR | The bridge will store dividend rollback CSV files in this directory | Text | No | .\data\{SECTION}\dividend\rollback | C:\tmp\myserver-dividend-rollback |
DIVIDEND PAYOUT PERIOD | Schedule for performing regular dividend adjustments | Text | Yes | 00 00 18 * * * | 00 00 18 * * * |
DIVIDEND PAYOUT DRYRUN ENABLE | Enables the dry run feature for dividend adjustment | Boolean | Yes | N | Y |
DRYRUN DIVIDEND PAYOUT PERIOD | Schedule for performing dividend adjustments in dry run mode (requires `DRY RUN ENABLE`=`Y`) | Text | Yes | 00 00 15 * * * | 00 00 15 * * * |
Also please note that parameter names are case insensitive, and any whitespace characters part of the name are ignored. Boolean-typed parameters can have either a “Y” or “N” value.
Example configuration file
[DEFAULT]
MT TRACING ENABLED=Y
MT TRACING LOGS MAX DAYS TO KEEP=14
EMAIL ADDRESS=email@company.com
EMAIL FROM ADDRESS=from@company.com
EMAIL SMTP PASSWORD=password
EMAIL SMTP SERVER=smtp.sendgrid.net
EMAIL SMTP SERVER PORT=587
EMAIL SMTP USER=apikey
REPORT CURRENCY=USD
[SERVERS.MT4.srv1]
MtServerAddress=127.0.0.1:443
MtUserId=101
MtUserPassword=password
SwapUpdatePeriod=00 00 18 * * *
DryRunEnable=1
DryRunSwapUpdatePeriod=00 00 15 * * *
DividendPayoutPeriod=00 30 19 * * *
DryRunDividendPayoutPeriod=00 00 19 * * *
DividendPayoutDryRunEnable=1
[SERVERS.MT5.srv2]
MtServerAddress=127.0.0.1:1443
MtUserId=101
MtUserPassword=password
SwapUpdatePeriod=00 00 18 * * *
DryRunEnable=1
DryRunSwapUpdatePeriod=00 00 15 * * *