manifold/common/sell-bet.ts
James Grugett 80ae551ca9
🧾 Limit orders! (#495)
* Simple limit order UI

* Update bet schema

* Restrict bet panel / bet row to only CPMMBinaryContracts (all binary DPM are resolved)

* Limit orders partway implemented

* Update follow leaderboard copy

* Change cpmm code to take some state instead of whole contract

* Write more of matching algorithm

* Fill in more of placebet

* Use client side contract search for emulator

* More correct matching

* Merge branch 'main' into limit-orders

* Some cleanup

* Listen for unfilled bets in bet panel. Calculate how the probability moves based on open limit orders.

* Simpler switching between bet & limit bet.

* Render your open bets (unfilled limit orders)

* Cancel bet endpoint.

* Fix build error

* Rename open bets to limit bets. Tweak payout calculation

* Limit probability selector to 1-99

* Deduct user balance only on each fill. Store orderAmount of bet. Timestamp of fills.

* Use floating equal to check if have shares

* Add limit order switcher to mobile bet dialog

* Support limit orders on numeric markets

* Allow CORS exception for Vercel deployments

* Remove console.logs

* Update user balance by new bet amount

* Tweak vercel cors

* Try another regexp for vercel cors

* Test another vercel regex

* Slight notifications refactor

* Fix docs edit link (#624)

* Fix docs edit link

* Update github links

* Small groups UX changes

* Groups UX on mobile

* Leaderboards => Rankings on groups

* Unused vars

* create: remove automatic setting of log scale

* Use react-query to cache notifications (#625)

* Use react-query to cache notifications

* Fix imports

* Cleanup

* Limit unseen notifs query

* Catch the bounced query

* Don't use interval

* Unused var

* Avoid flash of page nav

* Give notification question priority & 2 lines

* Right justify timestamps

* Rewording

* Margin

* Simplify error msg

* Be explicit about limit for unseen notifs

* Pass limit > 0

* Remove category filters

* Remove category selector references

* Track notification clicks

* Analyze tab usage

* Bold more on new group chats

* Add API route for listing a bets by user (#567)

* Add API route for getting a user's bets

* Refactor bets API to use /bets

* Update /markets to use zod validation

* Update docs

* Clone missing indexes from firestore

* Minor notif spacing adjustments

* Enable tipping on group chats w/ notif (#629)

* Tweak cors regex for vercel

* Your limit bets

* Implement selling shares

* Merge branch 'main' into limit-orders

* Fix lint

* Move binary search to util file

* Add note that there might be closed form

* Add tooltip to explain limit probability

* Tweak

* Cancel your limit orders if you run out of money

* Don't show amount error in probability input

* Require limit prob to be >= .1% and <= 99.9%

* Fix focus input bug

* Simplify mobile betting dialog

* Move mobile limit bets list into bet dialog.

* Small fixes to existing sell shares client

* Lint

* Refactor useSaveShares to actually read from localStorage, use less bug-prone interface.

* Fix NaN error

* Remove TODO

* Simple bet fill notification

* Tweak wording

* Sort limit bets by limit prob

* Padding on limit bets

* Match header size

Co-authored-by: Ian Philips <iansphilips@gmail.com>
Co-authored-by: ahalekelly <ahalekelly@gmail.com>
Co-authored-by: mantikoros <sgrugett@gmail.com>
Co-authored-by: Ben Congdon <ben@congdon.dev>
Co-authored-by: Austin Chen <akrolsmir@gmail.com>
2022-07-10 13:05:44 -05:00

136 lines
2.9 KiB
TypeScript

import { Bet, LimitBet } from './bet'
import {
calculateDpmShareValue,
deductDpmFees,
getDpmOutcomeProbability,
} from './calculate-dpm'
import { calculateCpmmSale, getCpmmProbability } from './calculate-cpmm'
import { CPMMContract, DPMContract } from './contract'
import { DPM_CREATOR_FEE, DPM_PLATFORM_FEE, Fees } from './fees'
import { sumBy } from 'lodash'
export type CandidateBet<T extends Bet> = Omit<T, 'id' | 'userId'>
export const getSellBetInfo = (bet: Bet, contract: DPMContract) => {
const { pool, totalShares, totalBets } = contract
const { id: betId, amount, shares, outcome } = bet
const adjShareValue = calculateDpmShareValue(contract, bet)
const newPool = { ...pool, [outcome]: pool[outcome] - adjShareValue }
const newTotalShares = {
...totalShares,
[outcome]: totalShares[outcome] - shares,
}
const newTotalBets = { ...totalBets, [outcome]: totalBets[outcome] - amount }
const probBefore = getDpmOutcomeProbability(totalShares, outcome)
const probAfter = getDpmOutcomeProbability(newTotalShares, outcome)
const profit = adjShareValue - amount
const creatorFee = DPM_CREATOR_FEE * Math.max(0, profit)
const platformFee = DPM_PLATFORM_FEE * Math.max(0, profit)
const fees: Fees = {
creatorFee,
platformFee,
liquidityFee: 0,
}
const saleAmount = deductDpmFees(amount, adjShareValue)
console.log(
'SELL M$',
amount,
outcome,
'for M$',
saleAmount,
'creator fee: M$',
creatorFee
)
const newBet: CandidateBet<Bet> = {
contractId: contract.id,
amount: -adjShareValue,
shares: -shares,
outcome,
probBefore,
probAfter,
createdTime: Date.now(),
sale: {
amount: saleAmount,
betId,
},
fees,
}
return {
newBet,
newPool,
newTotalShares,
newTotalBets,
fees,
}
}
export const getCpmmSellBetInfo = (
shares: number,
outcome: 'YES' | 'NO',
contract: CPMMContract,
prevLoanAmount: number,
unfilledBets: LimitBet[]
) => {
const { pool, p } = contract
const { saleValue, cpmmState, fees, makers, takers } = calculateCpmmSale(
contract,
shares,
outcome,
unfilledBets
)
const loanPaid = Math.min(prevLoanAmount, saleValue)
const probBefore = getCpmmProbability(pool, p)
const probAfter = getCpmmProbability(cpmmState.pool, cpmmState.p)
const takerAmount = sumBy(takers, 'amount')
const takerShares = sumBy(takers, 'shares')
console.log(
'SELL M$',
shares,
outcome,
'for M$',
saleValue,
'creator fee: M$',
fees.creatorFee
)
const newBet: CandidateBet<Bet> = {
contractId: contract.id,
amount: takerAmount,
shares: takerShares,
outcome,
probBefore,
probAfter,
createdTime: Date.now(),
loanAmount: -loanPaid,
fees,
fills: takers,
isFilled: true,
isCancelled: false,
orderAmount: takerAmount,
}
return {
newBet,
newPool: cpmmState.pool,
newP: cpmmState.p,
fees,
makers,
takers,
}
}