|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectnet.commerce.zocalo.market.MarketMaker
public abstract class MarketMaker
A MarketMaker offers to buy and sell coupons for a particular claim. See Robin Hanson's paper on Scoring Rules for details. The price is determined by the history of past sales. Each time the MarketMaker (sometimes referred to as AMM) sells, the price increases, each time it buys, the price decreases. This MarketMaker uses an exponential rule to determine how much to change the price.
The market maker follows an exponential rule based on its current price, which means that when its current price (p) is changing to newP, the user pays log(newP/p) coupons on one side to get log((1 - newP) / (1 - p)) coupons on the other side. After each such transaction, the marketMaker moves the probability to newP. Notice that this is expressed in terms of trading coupons for coupons.
Since the user thinks in terms of paying money for coupons, we need to translate. The user uses |log((1 - newP) / (1 - p))| [which we call baseC] (times the cost of a coupon) in funds to buy baseC sets of coupons, and then trades those coupons on one side for |log(newProb/prob)| [which we call incrC] coupons on the other side. The net effect is that the user is down by baseC (* couponCost) in funds, and up by |incrC - baseC| [which we call totalC] coupons. The transaction actually happens by having the marketMaker accept the funds, buy the coupons, and make the trade. Notice that baseC and incrC have opposite signs appropriately reflecting the user's costs and gains, but we always transfer positive quantities.
We use this new terminology because the ratios apply to different steps for different transactions. The user may be buying or selling a single position. (In the binary case these are symmetrical, but not in the multi-outome case.) Complementary coupons (complementary sets in the multi-outcome case) can be used in the purchase instead of cash. I use "C" in these names because it's short, and it evokes "cost", "coupons", and "cash". None of these would be right, since each name sometimes refers to cost and other times to gain, and each applies to cash and coupons in different transactions.
The simplest case is the user providing funds in exchange for coupons. The user spends baseC in funds, and receives totalC in coupons (the AMM adds incrC in funds to the user's baseC to buy totalC sets from the bank, and keeps the unwanted coupons in its account.) The next simplest case is selling a position when the user already has sufficient coupons. The user provides totalC coupons and receives baseC in funds, which the AMM gets by combining the user's coupons with its own and turning them in to the bank for cash, of which it keeps incrC. If the user wants to sell and doesn't have coupons, it costs incrC, which earns totalC in complementary assets. In this case, the AMM contributes baseC in funds. So the ratios apply differently in buying and selling and sometimes refer to the user's contribution and sometimes the AMM's.
Traders can specify the size of a trade in terms of the target probability (or equivalently price), the maximum number of shares, or the maximum cost (a maximum cost is also imposed by the trader's budget.) We have to be able to compute newP from any of these choices, and find the most restrictive limit. We sometimes need to compute newP from incrC, baseC, or totalC.
Another item worth clarifying about the explanation above: I spoke in terms of "sets". For binary markets I would have said "pairs", which would have been reasonably clear. In the multi-outome case, the arithmetic works out that the user can specify any subset of the outcomes, and everything works out. If a claim has 5 possible outcomes (a, b, c, d, and e) and the user wants to buy a and c in preference to b, d, and e, then you add the probabilities for a and c to find p (the others add up to [1-p]) and follow the same procedure. The user pays baseC for baseC sets (which means baseC of each outcome), and then trades the baseC coupons of b, d, and e for incrC coupons of a and incrC of c. The user is out baseC in funds, and now has totalC of a and totalC of c. The market maker has spent incrC in funds and has totalC of b, d, and e. The bank has collected totalC in funds and issued totalC complete sets. The code currently only supports specifying one outcome to purchase, but that's mostly because the UI issues for specifying other combinations are complicated.
Field Summary | |
---|---|
static double |
EPSILON
|
Constructor Summary | |
---|---|
MarketMaker(Market market,
Quantity subsidy,
User owner)
|
Method Summary | |
---|---|
void |
addAllCoupons(java.util.Set couponsSet,
User user)
|
protected Quantity |
baseC(Position position,
Probability targetProbability)
The money price charged to move the probability from p to newP is |B * log((1 - newP)/(1 - p)| * couponCost |
Quantity |
buyOrSellUpToQuantity(Position position,
Price price,
Quantity quantity,
User user)
|
Quantity |
buyUpToQuantity(Position position,
Probability targetProbability,
Quantity maxQuantity,
User user)
buy from the marketMaker to make the probability reach TARGETPROBABILITY, and up to MAXQUANTITY total coupons, whichever is less. |
Quantity |
buyWithCostLimit(Position position,
Probability targetProbability,
Quantity costLimit,
User user)
purchase from the marketMaker up to a probability of TARGETPROBABILITY, and up to COSTLIMIT total funds, whichever is less. |
abstract Probability |
currentProbability(Position position)
|
Quantity |
getBeta()
Deprecated. |
Price |
maxPrice()
|
Accounts |
redeem(CouponBank couponBank)
return my accounts only if the requestor knows my market's couponBank. |
boolean |
roundedPriceEqualsRoundedProb(Position position,
Price price,
java.math.MathContext context)
|
Quantity |
sellHoldings(User user,
Position pos)
|
void |
setBeta(Quantity beta)
Deprecated. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final double EPSILON
Constructor Detail |
---|
public MarketMaker(Market market, Quantity subsidy, User owner)
Method Detail |
---|
public boolean roundedPriceEqualsRoundedProb(Position position, Price price, java.math.MathContext context)
public abstract Probability currentProbability(Position position)
public Quantity buyWithCostLimit(Position position, Probability targetProbability, Quantity costLimit, User user)
public Quantity buyOrSellUpToQuantity(Position position, Price price, Quantity quantity, User user)
public Quantity buyUpToQuantity(Position position, Probability targetProbability, Quantity maxQuantity, User user)
public Quantity sellHoldings(User user, Position pos)
public void addAllCoupons(java.util.Set couponsSet, User user)
protected Quantity baseC(Position position, Probability targetProbability)
public Accounts redeem(CouponBank couponBank)
public Quantity getBeta()
public void setBeta(Quantity beta)
public Price maxPrice()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |