Towards a unified exchange protocol
So far supported a total of 12 commands, STAT, STATJSON, BUY, SELL, CANCEL, WITHDRAW, DEPOSIT, PUSH, DIVIDEND, SPLIT, MKOPT and EXERCISE. The first 6 are general interest, usable for both BTC currency exchanges and BTC security exchanges. The last 5 are of particular interest, allowing the payment of dividends and the handling of options. PUSH may or may not be implemented.
Let's see them one at a time :
STAT requests a human-readable account statement. The exact implementation is left to each exchange.
STATJSON requests a complete account statement in JSON format, as follows :
- A header section, identified by the string "Header", and including such information as the exchange may consider useful, but at a minimum the account's name, identifier string or code ; the date of the STAT command ;
- A holdings section, identified by the string "Holdings", and containing a complete list of all the account's holdings. If the exchange uses full reserves for orders placed in the booki then such reserves should not be included in this section.
- If the exchange uses full reserves for orders placed in the book, a book section, identified by the string "Book", and containing a complete list of all the account's orders in the book, keyed by a unique identifier of the order.
- A trade history section, identified by the string "TradeHistory", and containing a complete list of all the account's trades either since the last request, or since the origin of the account, keyed by the unixtime of the order execution.
- Other fields, such as the exchange may find useful or expedient, and documents aside.
All fields should be terminated by a special md5 checksum, identified by the string "md5Checksum" and including the entirety of the section preceding with the exception of the header, which may be so terminated. All entities should be strings.
Sample output:
{
"Header":[
{"Name":"Mircea Popescu"},
{"DateTime":"Friday the 2nd of November 2012 at 10:43:26 PM"}
],
"Holdings":[
{"CxBTC":"530"},
{"md5Checksum":"487d7b1ac97de3441c19f7da818f8f57"}
],
"Book":[
{"3557099":{"MPSIC":"CxUSD", "BS":"B", "Quantity":"454", "Price":"470"}},
{"md5Checksum":"772283d08d132c153b15ed2b72029c81"}
],
"TradeHistory":[
{"1351895101":{"MPSIC":"CxEUR", "BS":"B", "Quantity":"35", "Price":"490"}},
{"md5Checksum":"13d2c0a077b954807e8ffcb4164fef1d"}
]
}
BUY|{MPSIC}|{quantity}|{price}|{expiry} and
SELL|{MPSIC}|{quantity}|{price}|{expiry}. Specification :
- MPSIC must be stated and be a valid MPSIC.
- Quantity must be stated and be a positive integer.
- Price may be absent in which case order should be executed at market. If price is given it must be a positive integer expressed in satoshi.
- Expiry may be absent in which case your order never expires. If expiry is given it must be a positive integer in unixtime format (seconds since epoch) and be after current server time.
For instance :
- BUY|CxUSD|100|19540|1351936223 is an order to buy 100 USD at a price of 0.00019450 BTC each to be executed before Sat, 03 Nov 2012 09:50:23 GMT
- SELL|CxEUR|50|22590|1353956215 is an order to sell 50 EUR at a price of 0.00022590 BTC each to be executed before Mon, 26 Nov 2012 18:56:55 GMT
- BUY|O.BTCUSD.C060T|300||1351936223 is an order to buy 300 BTC/USD options struck at 6 USD expiring Nov. the 30th at market price, to be executed before Sat, 03 Nov 2012 09:50:23 GMT
Note that BTC is the currency of all accounts, as such one does not buy or sell BTC (a meaningless concept). One buys or sells fiat currencies, shares, options and other securities in exchange for BTC. This is important.ii.
CANCEL|{order id} should allow the customer to cancel an order (provided the order was not executed yet). The customer must be able to retrieve the order id from a STATJSON. The customer may be able to retrieve the order id from a STAT.
WITHDRAW|{BTCaddress}|{Sum}. Specification :
- BTCaddress must be stated and must be a valid Bitcoin address.
- Sum must be stated, and it must respect the exchange's stated policies.iii
DEPOSIT|{Sum}. Specification :
- Sum must be stated, and it must respect the exchange's stated policies.iv
- The exchange may, at its own option, either :
- Respond with a valid BTC address where the customer may proceed to send the funds or
- Respond with a uniquely identifying sum the customer must send to a public or private BTC address the exchange controlsv or
- Not respond, but silently verify if the customer has sent to his privately issued BTC address the quoted sum.
It is very important that the exchange documents prominently the procedure it will follow.
This completes the list of basic commands, that are sufficient to run a BTC based currency exchange. Consequently, all exchanges that correctly implement these may hold themselves as following the BTC-UXP-B (Bitcoin Unified eXchange Protocol, Basic).
What follows are extended commands, which may or may not be implemented, according to each exchange's own policies.
PUSH|{MPSIC}|{CustomerCode}|{Quantity}. Specification :
- MPSIC must be stated and be a valid MPSIC.
- CustomerCode must be stated and must respect the exchange's own specification for account identification. The exchange may check if the destination exists before executing the PUSH.
- Quantity must be stated and be a positive integer. In the case the Quantity exceeds the holdings of the account the exchange may either discard the order or execute it up to the quantity actually available. If being executed up to the quantity actually available the exchange may cancel orders in the book.
The exchange may limit PUSH commands to only those accounts controlled by the same person or company.
DIVIDEND|{MPSIC}|{DividendToPay}|{NotionalFloat}. Specification :
- MPSIC must be stated and be a valid MPSIC.
- DividendToPay must be stated and be a positive integer equal to the satoshi value of the dividend being paid.
- NotionalFloat must be stated and be a positive integer equal to the total number of shares outstanding.
All exchanges that correctly implement BTC-UXP-B + DIVIDEND may hold themselves as following the BTC-UXP-S (Bitcoin Unified eXchange Protocol, Shares).
What follows are extended commands, which may or may not be implemented, according to each exchange's own policies.
SPLIT|{MPSIC}|{Sum}. Specification :
- MPSIC must be stated and be a valid MPSIC of an options contract.
- Sum must be stated and it must respect the exchange's stated policies.
The exchange should put the Sum in escrow and create as many CALL contracts of the specified strike and maturity as half the Sum allows, according to its own risk limitation policies, and create as many PUT contracts of the specified strike and maturity as half the Sum allows, according to its own risk limitation policies, and deposit these in the customer's account.
MKOPT|{MPSIC}|{Sum}. Specification :
- MPSIC must be stated and be a valid MPSIC of an options contract.
- Sum must be stated and it must respect the exchange's stated policies.
The exchange should put the Sum in escrow and create as many option contracts of the specified type, strike and maturity as the Sum allows, according to its own risk limitation policies, and deposit these in the customer's account.
EXERCISE|{MPSIC}|{Quantity}. Specification :
- MPSIC must be stated and be a valid MPSIC of an options contract.
- Quantity must be stated and it must be a positive integer. In the case the Quantity exceeds the holdings of the account the exchange may either discard the order or execute it up to the quantity actually available. If being executed up to the quantity actually available the exchange may cancel orders in the book.
All exchanges that correctly implement BTC-UXP-S + EXERCISE + at least one of SPLIT, MKOPT may hold themselves as following the BTC-UXP-A (Bitcoin Unified eXchange Protocol, All securities).
All this is mostly a draft, comments welcome.
———- Which is most likely a good idea. [↩]
- As detailed in the MPSIC specification, fractions of all currencies, such as CxmUSD or CxcEUR, representing mili USD (tenths of a cent) and centi EUR (eurocents) respectively are available should the exchanges wish to implement these. [↩]
- Exchanges may, for whatever reason and as long as they fully document them, institute any limitations as to the withdrawable amounts, their proper formatting etc. [↩]
- Exchanges may, for whatever reason and as long as they fully document them, institute any limitations as to the depositable amounts, their proper formatting etc. [↩]
- Such as for instance the exchange may allow only whole BTC deposits and then add an identifying code in decimals. [↩]
Saturday, 3 November 2012
Thanks for documenting the interface. However, I see following problematic points:
Before trying to create new standard, one should consider existing ones and make clear that they are inaccurate and why. You have mentioned FIX protocol yourself, why not use it instead?
Technical merits should be reasonably justified, for example you decided to use only a "everything is a string" subset of JSON and with embedded checksums. This adds additional effort necessary to emit/parse JSON data -> risk of bugs/incompatibilities that need to be outweighed by benefits, and more possible solutions considered.
There is no extension mechanism outlined, for example exchange may want to provide ability to buy/sell the same asset in litecoins.
Specification of BUY,SELL,CANCEL,EXERCISE,etc. return value is missing. I can from practice say it is very important for client to be able to reliably check how much items were actually accepted for the order, whether cancel was accepted and what was the exact result of exercise.
Above 2 points could easily be solved by adopting JSONRPC or similar existing protocol.
All dates should be specified as UTC or formatted with timezone.
And, on broader note, this interface should be adopted by multiple exchanges, much wanted function will be possiblity to move assets between them. Maybe it would be even beneficial in long term for MPEx to fund research in this direction.
Saturday, 3 November 2012
Well, mostly not use FIX because FIX is a mess. This thread on BTCtalk is related.
The "everything is a string" protects the protocol from the variable implementations of integers on different platforms. A string can be safely read by 8 bit, 16 bit, 32 bit and 64 bit platforms.
The perspective is quite intentionally BTC-centric. If someone wants to make a LTC-centric exchange they can either adapt the protocol or make a new one. This is BTC-UFX, not ???-UFX.
There are no return values for BUY/SELL etc because the execution side and the order relay side are independent. At the time the exchange accepts an order it does not yet know if/how it will be executed. This is as it should be.
The exchanges are free to use their own time. As long as they maintain the same timezones in their own STATJSON responses all is well.
Ideally exchanges would switch to at least asset-denomination that is compatible, for sure.
Monday, 5 November 2012
Please get rid of the unicode quotes: “” I was thinking it's obvious, but my subcontractor did indeed blindly copy them :/
Monday, 5 November 2012
Sadly wordpress automatically puts unicode quotes in. All quotes are to be simple quotes of course.