Markets
Right now I've got the markets coded and trading. You can put an offer on a market. (There may be a hundred other offers already there... each with their own terms and limits.)
You'll always get the lowest price on the market if you're buying, or the highest price if you're selling. (As long as there are offers within your range.)
Your offer may trade many times before it is done, and against multiple other offers on the market. After each trade, OTCron will drop a receipt into the respective inboxes for the 4 asset accounts involved. (A trade involves, say, a buyer and seller bitcoin acct, and a buyer and seller WoW gold account. That's 4 asset accounts total, with each Nym controlling two accounts.)
When your offer has completed its terms, OTCron then removes it from the market.
You can configure your offer as a "day order" (date range) and/or as a "stop order" (only activate onto the market when price reaches X level) and/or as a "limit order" (only allow trades at a certain price point) and/or as a "fill-or-kill order" (each trade against a given offer must occur in minimum increments.)
OT Markets also support market granularity, meaning that the price of wheat on the 5000 bushel market might be cheaper, per bushel, than the price of the same wheat on the 10 bushel market. This means that traders would be able to profit by purchasing in bulk and then breaking up the wheat to be sold in smaller chunks (on smaller granularity markets.)
You could also use the markets for trading currency baskets (since OT supports baskets).
Since each asset type on OT is based on a currency contract, you could even issue futures contracts and other options, and use OT for trading futures on markets, or baskets of futures, etc etc.
Current drawbacks: (1) OT is very new and has not been tested with users in the real world. The version is v0.44 as I write this. I'm very proud of it, but it is brand spanking new, so you have to take that into account. (2), the keysize is still restricted to 1024. Since the software is still experimental, I haven't added any other keysizes yet, but that will be necessary if you are using it for real trades, FYI. I am very supportive of any developers using the OT API.
Here's the issue market offer API call:
// -------------------------------------------------- /// ISSUE MARKET OFFER /// void // Notice the return value is void. Use OT_API_PopMessageBuffer() to check for server replies. OT_API_issueMarketOffer (const char * SERVER_ID,// The OT API uses the server ID to look up the connect info from the server contract. const char * USER_ID, // UserID (NymID) is a hash of the public key. ServerID (above) is a hash of server contract. // ------------------------------------------- const char * ASSET_TYPE_ID, // Perhaps this is the wheat market. const char * ASSET_ACCT_ID, // This is my wheat account. // ------------------------------------------- const char * CURRENCY_TYPE_ID, // Perhaps I'm buying the wheat with rubles. const char * CURRENCY_ACCT_ID, // This is my ruble account. // ------------------------------------------- const char * MARKET_SCALE, // Defaults to minimum of 1. Market granularity. const char * MINIMUM_INCREMENT, // This will be multiplied by the Scale. Min 1. const char * TOTAL_ASSETS_ON_OFFER, // Total assets available for sale or purchase. Will be multiplied by minimum increment. const char * PRICE_LIMIT, // Per Minimum Increment... int bBuyingOrSelling); // Actually OT_BOOL. SELLING == OT_TRUE (1), BUYING == OT_FALSE (0).
For all you web guys, the "const char *" means that parameter is passed as a string.
FOR THOSE FASCINATED WITH TRIPLE-ENTRY ACCOUNTING.
(A description of the improvements made to receipts in the latest release of OT.)
Warning: boring accounting details below...
-- finalReceipt and basketReceipt are powerful additions to OT's receipt system, which bring OT's recurring transactions, basket currencies, and markets fully into compliance with the doctrine of "destruction of account history".
BACKGROUND (using chequeReceipt as an example):
In order to perform any transaction, the OT client must use a transaction number. These numbers are signed-for ON EVERY SINGLE RECEIPT -- until they are closed.
For example, if you write a cheque, #47, then the #47 will appear on every receipt going into the future, for every transaction that you do, until that transaction #47 is closed.
When will it be closed? When the cheque is cashed, the chequeReceipt #47 will appear in your inbox. YOU must accept it, before #47 will be closed -- which removes it from your inbox, AND signs-off on the latest account balance.
You see, since your balance is CHANGED whenever a cheque you wrote CLEARS, the server is thus forced to keep a copy of that chequeReceipt in your inbox, in order to prove the current balance, since that cheque has your signature on it. (The current balance, FYI, is your last signed balance, which the server already has on the most recent receipt, minus the amount of the cheque, which also features #47 -- a valid number -- and YOUR SIGNATURE.)
Once you sign to accept the chequeReceipt, it disappears from your inbox, the latest balance is signed, and #47 disappears forever from your list of "Issued Transaction Numbers". (That is, you no longer have to sign for #47 on any of your future receipts, since #47 is now CLOSED.)
IN SUM: "To perform a transaction, you must burn up one of your transaction numbers. And you need to sign for those in advance before you can use them. AND you need to CONTINUE signing, on into the future, for any transaction number that has been used, UNTIL YOU FINALLY SIGN TO CLOSE it."
NOW LET'S examine the latest updates to OT:
FINAL RECEIPT and BASKET RECEIPT All of the above still holds true; chequeReceipt still operates exactly the same, as do the receipts for transfers, withdrawals, deposits, etc. Those are the same.
===> But, for Markets…. (and other recurring transactions...)
-- When Alice places an offer on a market, the server saves a copy of her signed offer. BUT THIS TIME, THREE transaction numbers are provided instead of one: an opening number, and a closing number for EACH asset account, of which there are two. (She is buying bushels of wheat in return for dollars. Therefore she has a WHEAT account and a DOLLAR account.)
-- As various trades process on the market over time (against her market offer), marketReceipts will appear in Alice's inbox for her wheat account, and her inbox for her dollar account. Each marketReceipt contains a copy of Alice's ORIGINAL market offer, as well as an UPDATED VERSION (showing the changes to her account balances as a result of each trade.)
-- Remember that Alice has to sign for these 3 transaction numbers on ALL of her future receipts, until they are closed out. Let's say the numbers are #9, #10, and #11.
-- marketReceipts will continue to appear in Alice's inboxes over time, which she can remove by signing to accept them. This allows the server to prove the latest balance for each account (as caused by each trade and proven by each receipt.) So far, this much is similar to when you sign for a normal chequeReceipt.
-- But now Alice cannot cancel her market offer! Because what if new marketReceipts are popping into her inbox from new trades so quickly, that she is unable to do a new balance agreement before a new one comes in? If she cannot sign a proper balance agreement, then she cannot perform the transaction necessary to cancel the trading (nor can she close out the numbers from her receipts, and out of her inbox!) She's trapped.
===> THIS IS WHY there are now THREE transaction numbers for a market offer (say #9, #10 and #11): Because when the "Cancel Market Offer" message is sent, it requires no balance agreement at all! Instead, these actions occur:
- Transaction #9 is permanently closed, and will not appear on any future receipts.
- Transaction #10 appears as a FINAL RECEIPT in Alice's WHEAT inbox (in reference to #9.)
- Transaction #11 appears as a FINAL RECEIPT in Alice's DOLLAR inbox (in reference to #9.)
===> Trans#'s 10 and 11 stay open. (For now.)
===> The finalReceipts in each inbox prove when the offer was officially closed. (Whether by Alice, or by some other natural expiration. This is where smart contracts will figure big, in the future.)
===> Alice's "last signed receipt" shows her inbox contents, and the same receipt no longer shows #9 signed out -- she's not responsible for number 9 anymore. Thus any marketReceipt appearing AFTER would automatically be INVALID. (No NEW balance changes are permitted, related to #9.)
===> This means that new marketReceipts can never be dumped onto Alice AFTER she has closed a market offer (or payment plan.)
From there, Alice can accept the various receipts in her inbox at her LEISURE--the trading has been stopped, no more recurring transactions can occur, and the finalReceipt proves this.
THE TRICK IS: #10 and #11 are still open, and they REFER to #9. In order to finally CLOSE those finalReceipts for #10 and #11, which both refer to #9 -- OT requires Alice to ALSO close any other marketReceipts present in those inboxes, that ALSO refer to #9. (That is, the finalReceipt cannot be removed until those related receipts are also removed.)
===> This way, OT is guaranteed that all of Alice's WHEAT balance changes (shown in the marketReceipts in the wheat inbox) will be signed-for by the client and CLOSED OUT properly before finalReceipt#10 itself is closed out.
===> Similarly, all of Alice's DOLLAR balance changes (shown in the marketReceipts for her dollar inbox) will also be signed for by the client and CLOSED OUT properly before finalReceipt #11 itself is finally closed.
===> Thus, by the time the finalReceipts #10 and #11 are finally closed, ALL RECEIPTS will have been closed related to this market offer, and all balances have been agreed, for Alice's wheat account AND her dollar account.
I find this very interesting because it takes the concept of "Destruction of Account History" as pioneered by Bill St. Clair and Patrick Chkoreff, and adapts it to * recurring transactions * such as market offers and PAYMENT PLANS.
This innovation is unique to OT, as far as I know.
The same concept has also now been adapted for OT's BASKET CURRENCIES.
When you exchange into a [dollar/gold/bitcoin] basket, you must actually supply your dollar account, your gold account, and your bitcoin account, so that OT can remove the the appropriate amount of dollars, gold, and bitcoins from those accounts, in order to credit you with the new basket units during the exchange.
The OT client will now provide 4 transaction numbers in order to perform the exchange:
9. The main basket account's basketReceipt
10. The dollar account's basketReceipt
11. The gold account's basketReceipt
12. The bitcoin account's basketReceipt
When the exchange occurs, the client does NOT have to sign any balance agreements. Instead, a basketReceipt is dropped into EACH INBOX, and the balance agreements can be signed later, whenever the client wants to finally close out those receipts.
OTHERWISE, THE CLIENT WOULD HAVE TO PROVIDE a full balance agreement for every single account, all at once, in order to perform the exchange! The server would also have to verify all 4 of these balance agreements in order to process it!
That would be unwieldy. What if there were 10 asset accounts in the basket, or 50? Must I perform 50 balance agreements in order to do a single transaction?
INSTEAD, THINGS ARE EASY: a basketReceipt is simply dropped into the inbox for each constituent account, and the user can close those receipts later, the same as he would close a chequeReceipt or transferReceipt, signing the new balance at that time.
I find this very interesting because it takes the concept of "Destruction of Account History" and adapts it to BASKET CURRENCIES.
This means:
===> finalReceipt means that OT can perform transactions that PROCESS REPEATEDLY OVER TIME, even hundreds of times, yet it maintains the secure paradigm of "destruction of account history."
===> basketReceipt means that OT can perform transactions that process across ANY NUMBER OF ASSET ACCOUNTS -- even dozens of asset accounts in a single transaction -- yet it still maintains the secure paradigm of "destruction of account history."
===> This means that a new transaction type involving MULTIPLE TRADES can be processed based on STANDING OFFERS, WITHOUT forcing a signature from each client at each stop along the way.
This is awesome IMO!
I'm sure you can see where I'm going with all of this...
**** RIPPLE ****
The latest changes to receipts are what will make it possible to eventually add RIPPLE CREDIT LINES and RIPPLE FLOWS to OT!
Of course that will require a whole other set of code, which I will have to get around to at some point when I can afford it, but it will someday become possible to extend "credit lines" between Nyms, and then have "Ripple Markets" where payments can flow p2p between the various credit lines.
This is made possible by the new receipt code, since instead of having to sign for each individual transaction during a "Ripple Flow", credit lines will involve STANDING OFFERS, which will process according to their terms as long as the transaction stays open! (The same way as marketReceipts do now -- until the credit line is closed, and the "finalReceipt" is thrown.)
So this release gets us closer to using OT as Ripple, although more would still need to be coded, such as the CreditLine object itself, and the RippleMarket, etc.
In case you guys find any of this Ripple stuff interesting, I've attached some of my notes below. It will probably be months before any of this actually gets coded, but you might enjoy the thoughts recorded.
Happy September! And remember, the time is short.
Your friend,
-Fellow Traveler
PS NEED VOLUNTEERS: iOS client, Mac client, Google Native Chrome, Android client, Windows client, QT client, Bitcoin integration, Bittorrent integration, TAHOE-LAFS integration, Freenet integration, i2p integration, mixminion integration, Tor integration, Firefox integration, Thunderbird integration...
Ripple Notes
The only change necessary for OT to have built in Ripple is to make possible to execute various trades atomically.
Alice, Bob, Timón, and FT issue each one their own digital currency.
The denomination is not very important, because it will only affect the exchange rate, that users will have to set manually anyway.
1) Alice issues aUSDs that are accepted by her and Bob, because they're friends.
Bob issues bUSDs that are accepted by him, Alice and Timón.
Bob usually buys bread to Timón for bitcoins, and Timón sometimes accepts bUSDs.
Timón issues tHours that Bob accepts, because with them he can buy bUSDs (to settle debts with Timón) and bread.
FT issues fOz's (ounces of silver) that really keeps at home and that Timón accepts because he knows FT accepts 1 Oz per hour of programming labor.
2) Now FT wants to buy a box full of apples from Alice, that see sells for 80 aUSDs.
Let's see the market: Alice buys up to 100 bUSDs for aUSDs at a 1:1 rate Bob buys up to 100 aUSDs for bUSDs at a 1:1 rate Bob buys up to 10 tHours for bUSDs at a 1:10 rate Timón buys up to 2.5 fOz's for tHours at a 1:4 rate
The balances don't change, they're just putting an offer in the market. For example.
Alice buys up to 100 bUSDs for aUSDs at a 1:1 rate Would be like an offer like this: user=alice buying=bUSD, selling=aUSD, price=1, amount=100
3) So FT could sell 2 fOz's for 8 tHours. Then sell 8 tHours for 80 bUSDs. Then sell 80 bUSDs for 80 aUSDs. Then sell 80 aUSDs for a box full of apples.
The payment described in 3 should be atomic.
Balances before the transaction:
aUSD | bUSD | tHours | fSLV | |
Alice | 10,000 | 0 | 0 | 0 |
Bob | 0 | 10,000 | 0 | 0 |
Timón | 0 | 0 | 1,000 | 0 |
FellowTraveller | 0 | 0 | 0 | 500 |
Balances after the transaction:
aUSD | bUSD | tHours | fSLV | |
Alice | 10,000 | 80 | 0 | 0 |
Bob | 0 | 9,920 | 8 | 0 |
Timón | 0 | 0 | 992 | 2 |
FellowTraveller | 0 | 0 | 0 | 498 |
If you want it step by step, here it is (but remember we want it to occur atomically).
FT sells 2 fOz's for 8 tHours.
aUSD | bUSD | tHours | fSLV | |
Alice | 10,000 | 0 | 0 | 0 |
Bob | 0 | 10,000 | 0 | 0 |
Timón | 0 | 0 | 992 | 2 |
FellowTraveller | 0 | 0 | 8 | 498 |
Then sell 8 tHours for 80 bUSDs.
aUSD | bUSD | tHours | fSLV | |
Alice 10,000 | 0 | 0 | 0 | |
Bob | 0 | 9,920 | 8 | 0 |
Timón | 0 | 0 | 992 | 2 |
FellowTraveller | 0 | 80 | 0 | 498 |
Then sell 80 bUSDs for 80 aUSDs.
aUSD | bUSD | tHours | fSLV | |
Alice | 9,920 | 80 | 0 | 0 |
Bob | 0 | 9,920 | 8 | 0 |
Timón | 0 | 0 | 992 | 2 |
FellowTraveller | 80 | 0 | 0 | 498 |
Then sell 80 aUSDs for a box full of apples.
aUSD | bUSD | tHours | fSLV | |
Alice | 10,000 | 80 | 0 | 0 |
Bob | 0 | 9,920 | 8 | 0 |
Timón | 0 | 0 | 992 | 2 |
FellowTraveller | 0 | 0 | 0 | 498 |
Q: WHAT IS A CREDIT LINE?
A: Alice opening a bUSD account and putting an offer "I buy up to 100 bUSD for aUSDs" is the equivalent of giving credit to Bob.
Q: Would Alice and Bob see that there are actually two currencies (aUSD and bUSD) or would the UI be such that they only need to see them as "dollars", and they see that they are willing to accept dollars from each other?
A: They could see separately:
-How many dollars they have issued in total (how much they owe).
-How many dollars their neighbors have of their currency (how much they owe by user)
-How many dollars they have from their neighbors (how much each user owes them)
-How many dollars they have from other people in total (how much people owe them)
And the same for each denomination.
Alice opening a bUSD account and putting an offer "I buy up to 100 bUSD for aUSDs" is the equivalent of giving credit to Bob.
In the example, Bob never has aUSDs so he doesn't need an aUSD account.
For the credit line to become two-ways, Bob would need to open an aUSD and place an offer "I buy up to X aUSD for bUSDs".
Potential UI sequence:
- ALICE clicks "Give Credit to,” and then she selects "BOB" from a list.
- BOB logs in the next day, with a message "Alice has extended credit to you in the amount of $100 USD. Do you accept?" (This means that some sort of message will be sent via the internal OT message system, to facilitate this notification.)
- When Bob clicks yes, then the software checks to see if Bob has already issued his own $bUSD currency. If not, then Bob's currency bUSD is automatically issued at this time. (Bob's "credit line" object will need to manage his issuer accounts for various currencies,as well as manage a list of his credit lines to and from other people, as well as his asset accounts from those people, as well as his bUSD internal asset account, as well as his Ripple market offers. This OTCreditLine object would need to be written.)
- Alice's offer is created on the new aUSD/bUSD market: "I buy up to 100 bUSD for aUSDs at X:Y rate". (This could probably be done using a modified version of the existing OT market code, to enable to atomic transactions. This modified version would be specially for Ripple, due to the atomic-multi-step transactions.)
- This means that aUSDs, Alice's own USD currency must ALSO be issued at this time, if they haven't been already.
- This means that Y aUSDs (from X:Y) must actually be issued into existence by Alice at this same time. That is, not only is the currency in existence, but say, 100 units of that currency are actually transferred at this time from Alice's aUSD issuer acct, leaving it at -100, to Alice's aUSD credit line account leaving it at +$100, so that they are actually available to fill her bUSD market offer, should a "Ripple path" transaction occur.
(This means Alice has an internal account balance of $100 aUSD.)
Unlike Bob's silver account, which is private to him, and unlike Bob's gold account, which is private to him, Alice can actually SEE the contents of Bob's aUSD account! Because that shows her how much USD that she owes to Bob. This is unlike the normal OT accounts, where you are not shown other people's balances.
On Alice's "Credit Lines" page, she would have a list of currencies (Dollars, Bitcoins, Silver, etc.) When she clicks on a currency, say dollars, the details appear on the right:
Details: a list of credit lines. Bob, Carol, Donald, Edward, etc.
Alice's "total dollars owed" is the absolute value of her aUSD issuer account. So if her aUSD issuer account has -$2000, then she owes $2000 to all of her various friends (in TOTAL.)
For Bob, Carol, Edward, etc, she sees THEIR balances in aUSD:
ALICE OWES THEM | |
Bob | $A 0 |
Carol | $A 1000 |
Donald | $A 500 |
Edward | $A 500 |
- She also sees HER balances in bUSD/cUSD/dUSD/eUSD:
ALICE OWES | THEY OWE ALICE | |
Bob | $A 0 | $0 bUSD |
Carol | $A 1000 | $877 cUSD |
Donald | $A 500 | $142 dUSD |
Edward | $A 500 | $905 eUSD |
Total owed BY Alice: $2000 Total owed TO Alice: $1924
Net: Alice owes $76.
- Alice should also see the CURRENT STATUS of her MARKET OFFERS. Above we only see the account balances (what is owed both ways) but we don't see what people are willing to CONVERT.
Let's say Alice and Bob are willing to convert $100 both ways (for each other):
Alice: OFFER: "I buy up to 100 bUSD for aUSDs"
Alice: INTERNAL: $100 aUSD
(To trade $100, this means Alice has an internal account balance of $100 aUSD at least, and -$100 of her aUSD issuer account matches to this. Her market offers trade against this account.)
Bob: OFFER: "I buy up to 100 aUSD for bUSDs"
Bob: INTERNAL: $100 bUSD
(This means Bob has an internal account balance of $100 bUSD at least, and -$100 of his bUSD issuer account matches to this. His market offers trade against this account.)
- THEREFORE our total picture now looks like this:
ALICE OWES | THEY OWE ALICE | |
Bob: | $A 0 | $0 bUSD |
Carol: | $A 1000 | $877 cUSD |
Donald: | $A 500 | $142 dUSD |
Edward: | $A 500 | $905 eUSD |
Total owed BY Alice: $2000
Total owed TO Alice: $1924
Net: Alice owes $76.
Alice: OFFER: "I buy up to 100 bUSD for aUSDs"
Alice: INTERNAL: $100 aUSD
Bob: OFFER: "I buy up to 100 aUSD for bUSDs"
Bob: INTERNAL: $100 bUSD
- Let's say a "Ripple" flows through and she converts HALF OF the bUSD she's willing to convert. How does our picture CHANGE?
ALICE OWES | THEY OWE ALICE | |
Bob: | $A 0 | $50 bUSD * |
Carol: | $A 1000 | $877 cUSD |
Donald: | $A 500 | $142 dUSD |
Edward: | $A 500 | $905 eUSD |
Total owed BY Alice: $2000
Total owed TO Alice: $1974
Net: Alice owes $26.
Alice: OFFER: "I buy up to 50 bUSD for aUSDs"
Alice: INTERNAL: $50 aUSD
Bob: OFFER: "I buy up to 100 aUSD for bUSDs"
Bob: INTERNAL: $100 bUSD
QUESTION: Should Bob be able to see how much is LEFT on Alice's offer?
That is: "Alice's bUSD acct contains $50, which you owe to her, and there is still $50 left on her total credit line to you (of $100.)"
NEXT QUESTION: How does this model ever CONVERT one currency to another?
SO FAR, the creation of a CREDIT LINE has only resulted in two-way USD relationships, or two-way Gold relationships, etc.
NOTHING in the above example shows where Alice converts Dollars to Gold, or Dollars to Bitcoin.
FOR EXAMPLE, Let's say Alice extends GOLD credit to Bob…
Even if Bob reciprocates, then they have 100g gold relationship both ways, complete with Alice's offer to buy bGold using aGold, and Bob's offer to buy aGold using bGold.
STILL this doesn't explain how dollars get converted into gold, EVEN THOUGH ALICE AND BOB BOTH DEAL IN DOLLARS AND BOTH DEAL IN GOLD.
===> It's not ENOUGH for Alice and Bob to handle both gold and dollars, and to extend credit to each other in gold and dollars. ON TOP OF THIS, Alice must also be willing to convert gold into dollars, and dollars into gold, AND THIS HAS NOTHING TO DO WITH HER CREDIT RELATIONSHIPS TO BOB OR TO ANYONE ELSE. Rather, it has more to do with her market judgments of the various currencies.
===>Therefore, there still needs to be ANOTHER page, where Alice can set up her CONVERSION RATIOS between gold=>dollars and dollars=>gold, and BTC=>dollars and dollars=>BTC, etc.
It seems to me that the "Ripple path" mechanism would need to make use of markets that included offers for the credit lines, as well as offers for the currency conversion, before it could operate properly.