Allow unspecfied outcome as input to sellshares

This commit is contained in:
Marshall Polaris 2022-07-31 23:38:45 -07:00
parent ae2e7dfe30
commit ff9a649c3c
2 changed files with 27 additions and 8 deletions

View File

@ -581,12 +581,12 @@ $ curl https://manifold.markets/api/v0/market/{marketId}/resolve -X POST \
### `POST /v0/market/[marketId]/sell`
Sells some quantity of shares in a market on behalf of the authorized user.
Sells some quantity of shares in a binary market on behalf of the authorized user.
Parameters:
- `outcome`: Required. One of `YES`, `NO`, or a `number` indicating the numeric
bucket ID, depending on the market type.
- `outcome`: Optional. One of `YES`, or `NO`. If you leave it off, and you only
own one kind of shares, you will sell that kind of shares.
- `shares`: Optional. The amount of shares to sell of the outcome given
above. If not provided, all the shares you own will be sold.

View File

@ -1,4 +1,4 @@
import { sumBy, uniq } from 'lodash'
import { mapValues, groupBy, sumBy, uniq } from 'lodash'
import * as admin from 'firebase-admin'
import { z } from 'zod'
@ -17,7 +17,7 @@ import { redeemShares } from './redeem-shares'
const bodySchema = z.object({
contractId: z.string(),
shares: z.number().optional(), // leave it out to sell all shares
outcome: z.enum(['YES', 'NO']),
outcome: z.enum(['YES', 'NO']).optional(), // leave it out to sell whichever you have
})
export const sellshares = newEndpoint({}, async (req, auth) => {
@ -46,9 +46,28 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
throw new APIError(400, 'Trading is closed.')
const prevLoanAmount = sumBy(userBets, (bet) => bet.loanAmount ?? 0)
const betsByOutcome = groupBy(userBets, (bet) => bet.outcome)
const sharesByOutcome = mapValues(betsByOutcome, (bets) =>
sumBy(bets, (b) => b.shares)
)
const outcomeBets = userBets.filter((bet) => bet.outcome == outcome)
const maxShares = sumBy(outcomeBets, (bet) => bet.shares)
let chosenOutcome: 'YES' | 'NO'
if (outcome != null) {
chosenOutcome = outcome
} else {
const nonzeroShares = Object.entries(sharesByOutcome).filter(
([_k, v]) => v
)
if (nonzeroShares.length > 1) {
throw new APIError(
400,
`You own multiple kinds of shares, but did not specify which to sell.`
)
}
chosenOutcome = nonzeroShares[0][0] as 'YES' | 'NO'
}
const maxShares = sharesByOutcome[chosenOutcome]
const sharesToSell = shares ?? maxShares
if (!floatingLesserEqual(sharesToSell, maxShares))
@ -63,7 +82,7 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
const { newBet, newPool, newP, fees, makers } = getCpmmSellBetInfo(
soldShares,
outcome,
chosenOutcome,
contract,
prevLoanAmount,
unfilledBets