swagger.yaml (10733B)
1 openapi: 3.0.3 2 info: 3 title: BTC/USD Prediction Game API 4 description: > 5 Serves sequential 1-minute BTC/USD candles from a randomly selected window 6 of real Bitstamp data. Clients place a directional prediction (long/short) 7 at a fixed future bar, advance the chart one candle at a time, and receive 8 the resolved profit/loss when the target bar is reached. 9 10 Profit formula: `gross_pct × (1 − fee_pct/100)² × 100` 11 where `gross_pct = (close − entry) / entry` for longs and 12 `(entry − close) / entry` for shorts. The notional position size is $100. 13 version: 1.0.0 14 15 servers: 16 - url: http://localhost:3000 17 18 paths: 19 /: 20 get: 21 summary: Serve the frontend 22 description: Returns the single-page HTML application. 23 responses: 24 '200': 25 description: HTML page 26 content: 27 text/html: 28 schema: 29 type: string 30 31 /api/session/new: 32 post: 33 summary: Start a new session 34 description: > 35 Picks a random starting position in the dataset (optionally constrained 36 to a year and/or month) and returns the first 100 candles of that window. 37 Any existing prediction on a previous session is not carried over — 38 sessions are independent. 39 requestBody: 40 required: true 41 content: 42 application/json: 43 schema: 44 $ref: '#/components/schemas/NewSessionRequest' 45 examples: 46 random: 47 summary: Fully random start 48 value: {} 49 year_only: 50 summary: Random start within 2021 51 value: { year: 2021 } 52 year_and_month: 53 summary: Random start within March 2020 54 value: { year: 2020, month: 3 } 55 responses: 56 '200': 57 description: Session created 58 content: 59 application/json: 60 schema: 61 $ref: '#/components/schemas/NewSessionResponse' 62 '400': 63 description: Fewer than 100 candles available for the requested period 64 content: 65 application/json: 66 schema: 67 $ref: '#/components/schemas/Error' 68 example: 69 error: not_enough_data 70 71 /api/next: 72 post: 73 summary: Advance by one candle 74 description: > 75 Moves the session forward by one candle and returns it. 76 If the session has an active prediction whose target bar is now reached 77 (or passed), the prediction is resolved and the result is included in the 78 response; the session's prediction slot is cleared. 79 requestBody: 80 required: true 81 content: 82 application/json: 83 schema: 84 $ref: '#/components/schemas/SessionIdBody' 85 responses: 86 '200': 87 description: Next candle (and optionally a resolved prediction) 88 content: 89 application/json: 90 schema: 91 $ref: '#/components/schemas/NextCandleResponse' 92 '404': 93 description: Session not found 94 content: 95 application/json: 96 schema: 97 $ref: '#/components/schemas/Error' 98 example: 99 error: session_not_found 100 '409': 101 description: No more candles available (end of dataset window) 102 content: 103 application/json: 104 schema: 105 $ref: '#/components/schemas/Error' 106 example: 107 error: end_of_data 108 109 /api/predict: 110 post: 111 summary: Place a prediction 112 description: > 113 Records a long or short prediction that resolves `bars_ahead` candles 114 from now. The entry price is the close of the current candle (server-authoritative). 115 Replaces any existing active prediction on the session. 116 requestBody: 117 required: true 118 content: 119 application/json: 120 schema: 121 $ref: '#/components/schemas/PredictRequest' 122 examples: 123 long_5_bars: 124 summary: Long prediction 5 bars ahead, 0.1% fee 125 value: 126 session_id: "550e8400-e29b-41d4-a716-446655440000" 127 bars_ahead: 5 128 direction: long 129 fee_pct: 0.10 130 short_20_bars: 131 summary: Short prediction 20 bars ahead, no fee 132 value: 133 session_id: "550e8400-e29b-41d4-a716-446655440000" 134 bars_ahead: 20 135 direction: short 136 fee_pct: 0.0 137 responses: 138 '200': 139 description: Prediction accepted; returns the server-side entry price 140 content: 141 application/json: 142 schema: 143 $ref: '#/components/schemas/PredictResponse' 144 '400': 145 description: bars_ahead is zero 146 content: 147 application/json: 148 schema: 149 $ref: '#/components/schemas/Error' 150 example: 151 error: bars_ahead_must_be_positive 152 '404': 153 description: Session not found 154 content: 155 application/json: 156 schema: 157 $ref: '#/components/schemas/Error' 158 example: 159 error: session_not_found 160 161 /api/predict/cancel: 162 post: 163 summary: Cancel the active prediction 164 description: Clears the active prediction on the session. No-op if there is none. 165 requestBody: 166 required: true 167 content: 168 application/json: 169 schema: 170 $ref: '#/components/schemas/SessionIdBody' 171 responses: 172 '200': 173 description: Prediction cleared 174 content: 175 application/json: 176 schema: 177 type: object 178 example: {} 179 '404': 180 description: Session not found 181 content: 182 application/json: 183 schema: 184 $ref: '#/components/schemas/Error' 185 example: 186 error: session_not_found 187 188 components: 189 schemas: 190 191 Candle: 192 type: object 193 required: [ts, open, high, low, close, volume] 194 properties: 195 ts: 196 type: integer 197 format: int64 198 description: Unix timestamp in seconds (UTC) 199 example: 1609459200 200 open: 201 type: number 202 format: double 203 example: 29300.50 204 high: 205 type: number 206 format: double 207 example: 29450.00 208 low: 209 type: number 210 format: double 211 example: 29280.10 212 close: 213 type: number 214 format: double 215 example: 29400.75 216 volume: 217 type: number 218 format: double 219 example: 12.345678 220 221 Direction: 222 type: string 223 enum: [long, short] 224 description: > 225 `long` — profit when close > entry; 226 `short` — profit when close < entry. 227 228 ResolvedPrediction: 229 type: object 230 required: [entry_price, close_price, direction, fee_pct, profit] 231 properties: 232 entry_price: 233 type: number 234 format: double 235 description: Close price at the time the prediction was placed 236 example: 29400.75 237 close_price: 238 type: number 239 format: double 240 description: Close price of the target candle 241 example: 29850.00 242 direction: 243 $ref: '#/components/schemas/Direction' 244 fee_pct: 245 type: number 246 format: double 247 description: Fee percentage that was applied 248 example: 0.10 249 profit: 250 type: number 251 format: double 252 description: > 253 Dollar P&L on a $100 notional position: 254 `gross_pct × (1 − fee_pct/100)² × 100` 255 example: 1.53 256 257 NewSessionRequest: 258 type: object 259 properties: 260 year: 261 type: integer 262 description: Constrain the start to this calendar year (2012–2026) 263 example: 2021 264 month: 265 type: integer 266 minimum: 1 267 maximum: 12 268 description: Constrain the start to this month within `year` (requires year) 269 example: 6 270 271 NewSessionResponse: 272 type: object 273 required: [session_id, candles] 274 properties: 275 session_id: 276 type: string 277 format: uuid 278 description: Opaque session identifier; include in all subsequent requests 279 example: "550e8400-e29b-41d4-a716-446655440000" 280 candles: 281 type: array 282 description: Initial 100 candles of the session window 283 items: 284 $ref: '#/components/schemas/Candle' 285 286 SessionIdBody: 287 type: object 288 required: [session_id] 289 properties: 290 session_id: 291 type: string 292 format: uuid 293 example: "550e8400-e29b-41d4-a716-446655440000" 294 295 NextCandleResponse: 296 type: object 297 required: [candle, resolved] 298 properties: 299 candle: 300 $ref: '#/components/schemas/Candle' 301 resolved: 302 description: > 303 Present when this candle reached (or passed) the prediction's target 304 bar; `null` otherwise. 305 oneOf: 306 - $ref: '#/components/schemas/ResolvedPrediction' 307 - type: 'null' 308 309 PredictRequest: 310 type: object 311 required: [session_id, bars_ahead, direction, fee_pct] 312 properties: 313 session_id: 314 type: string 315 format: uuid 316 example: "550e8400-e29b-41d4-a716-446655440000" 317 bars_ahead: 318 type: integer 319 format: int32 320 minimum: 1 321 description: How many candles from now the prediction should resolve 322 example: 10 323 direction: 324 $ref: '#/components/schemas/Direction' 325 fee_pct: 326 type: number 327 format: double 328 minimum: 0 329 maximum: 100 330 description: Round-trip fee percentage (applied on open and close) 331 example: 0.10 332 333 PredictResponse: 334 type: object 335 required: [entry_price] 336 properties: 337 entry_price: 338 type: number 339 format: double 340 description: Server-authoritative close price used as the entry for this prediction 341 example: 29400.75 342 343 Error: 344 type: object 345 required: [error] 346 properties: 347 error: 348 type: string 349 enum: 350 - not_enough_data 351 - session_not_found 352 - end_of_data 353 - bars_ahead_must_be_positive 354 example: session_not_found