aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* service: add sell orders, event lifecycle and order book matchingKostya13 days10-104/+853
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Carry the order side from the context through risk, the trading mechanisms, fulfillment and settlement, so users can sell shares as well as buy them. The order book now matches priced limit orders from named users, rests any unfilled remainder, and prevents self-trades. In a binary market with minting enabled, a buy can also match a bid on the other option to mint a new YES/NO pair, and a sell can match an ask there to merge a pair back into the pool. LMSR gains a sell that refunds the cost difference from the pool. Add createEvent and openEvent to the catalog. Events start as DRAFT and only take the market maker's subsidy when they are opened, which fails if the market maker can't cover it. Add LocalAccountContext to expose user ledgers. Tighten the risk checks: reject orders from blocked accounts, on events that aren't ACTIVE, and at prices outside (0, d). Sells need enough unreserved shares; buys need enough balance to cover commission and cash already committed to resting bids. Settlement now cancels resting orders, pays out on shares still held rather than shares ever bought, sends order book commission to the market maker, and returns unused LMSR subsidy. Events also track per-user cash flow, so the event detail can list participants with their holdings, fees and P&L next to the order books.
* service: add ex-2 XML loader and carry order side through matchingKostya2026-09-069-8/+391
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Ex-2 documents declare users and their market-maker assignments next to the events, and the loader has to reject files that are schema-valid but logically inconsistent, which the v1 loader has no notion of. Add XMLLoaderV2, which checks the extension, unmarshals the document, runs it through XMLValidatorV2 and only then replaces the event and user repositories, so a rejected file leaves the previous catalog intact. The validator enforces unique positive event ids, non-empty names and descriptions, commission within 0..90 with a known type, at least two distinct options, a positive LMSR b or order-book d with non-negative initial inventory, unique user names, positive initial cash, and exactly one existing event per market-maker reference. Let EventMapperV2 take the resolved market maker's name so it lands on the domain event. Give Order a side and the placing user, and Trade the seller, so an order book can match a buyer against a seller. Keep the previous constructors, defaulting to a BUY with no user or seller, so existing LMSR call sites stay unchanged. Route LocalMatchingEngine through the mechanism's placeOrder with side, user and limit price instead of buy(), and have cancelOrder take the order to cancel. Also add an isBlocked query to User and Ledger for accounts that went negative.
* api: extend contexts and DTOs for order books and event creationKostya2026-09-069-3/+100
| | | | | | | | | | | | | | | | | | | | | | The desktop UI needs to create events, trade on both sides of an order book, and show who is participating in an event, none of which the api module could express so far. Add AccountContext for looking up ledger accounts by owner, and give CatalogContext an openEvent operation plus createEvent, taking either a CreateEventRequest or its fields spelled out. createEvent defaults to a "Not implemented" error so existing implementations keep compiling until they support it. Let GuessMarketContext.placeOrder take an explicit side, keeping the old signature as a default method that places a BUY so current callers are unaffected. Add OrderBookDTO and BookOrderDTO to describe per-option books with best bid, best ask and spread, and ParticipantDTO for a user's position, fees and P&L in an event. Carry the order books and participants on EventDetailDTO and the market maker's name on EventSummaryDTO.
* ex-2: add invalid-input fixtures and wire ui-desktop to the serviceKostya2026-09-0614-3/+510
| | | | | | | | | | | | | | | | | | | | | The ex-2 loader has to reject documents that are schema-valid but logically broken, and so far only error-2.xml and error-3.xml exercised that path. Add one fixture per validation rule under test-data/ex-2/invalid, each a copy of small.xml with a single defect described in a leading comment: a non-.xml extension, a duplicate event id, commission outside 0..90 on either side, a duplicate user name, zero or negative initial cash, a market maker referencing an unknown event, and an event with no market maker or with two. Teach LedgerMapper to map individual LedgerEntry records to LedgerEntryDTO, renaming id to seq and time to at and rendering the timestamp through InstantOptions.humanize, so callers can show a ledger history rather than only the account summary. Make ui-desktop depend on api and service in the build tooling and in its Eclipse classpath, since the desktop UI now talks to the service layer directly, and put lib/openjfx on java.library.path for the test run so tests touching JavaFX can load its native libraries.
* catalog: add generated v3 JAXB binding and ex-2 test dataKostya2026-09-0613-0/+1026
| | | | | | | | | | | | | | | | | | | | The ex-2 schema describes a nested Guess-Market/GM-events document in which every event carries its pricing mechanism inline, as either a GM-LMSR element holding the liquidity parameter b or a GM-order-book element holding the allow-mint, initial and d attributes, instead of naming a mechanism and passing its parameters separately. Add the xjc-generated classes for that schema under catalog.model.v3, along with the fixtures the loader will be tested against: small.xml with two events, one per mechanism, multiple.xml with four, and two negative cases -- error-2.xml, where a market maker is funded with zero initial cash, and error-3.xml, where a market maker points at event id 12, which no event declares -- so the cross-reference and funding checks have something to reject. The binding covers the GM-events subtree only. The GM-users half of the document and the per-event id element are not bound yet, so nothing reads these classes so far.
* openjfx: ship native libraries so the desktop UI can launch on WindowsKostya2026-08-2364-4/+8
| | | | | | | | | | | | | | | | lib/openjfx held only the JavaFX API jars, with no Prism/Glass native libraries backing them. At startup JavaFX tried the d3d then sw rendering pipelines and both failed to load, since NativeLibLoader had no native code to find, crashing before any window opened. Bump the jars to 25.0.4 to match the target JDK and add the matching native DLLs alongside them. Drop the web/media/swt/swing jars and their natives (including the 92MB jfxwebkit.dll) since ui-desktop never references those modules. Update package.sh to also stage *.dll files when copying runtime libs into build/dist, and point java.library.path at lib/openjfx in the generated run-*.bat so the natives are found at launch.
* Merge branch 'master' of localhost:/srv/git/guess-marketKostya2026-08-230-0/+0
|\
| * api: move AccountDTO into model.ledger as LedgerDTOKostya2026-08-231-3/+2
| | | | | | | | | | | | Relocate the account record out of the api package into model.ledger, alongside LedgerEntryDTO, and rename it to LedgerDTO so the ledger DTOs live together under one package.
* | model: relocate market DTOs out of the flat api packageKostya2026-08-2316-78/+118
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Move AccountDTO/MarketDTO/MarketStateDTO/PurchaseReceiptDTO/TradeRowDTO out of the catch-all api package into model.market (and LedgerDTO into model.ledger), matching the existing model.event convention so DTOs live next to the domain they describe rather than in the interface package. Relocate LedgerMapper from mapper.v2 to infrastructure.adapter to match the module's established package layout, and update all call sites and imports accordingly. Also register the ui-desktop module in the build tooling: add it to MODULES, add openjfx to the shipped runtime libs, and generalize package.sh so each executable module (ui-console, ui-desktop) gets its own Main-Class/Class-Path manifest and run script instead of special-casing ui-console. Fold long Class-Path manifest lines at 72 bytes per the JAR spec, since adding ui-desktop's dependencies pushed the line past the limit.
* | Add MapStruct LedgerMapper and wire annotation processing into build.shKostya2026-08-203-2/+117
|/ | | | | build.sh now passes -processorpath/-s so MapStruct's generated impl compiles alongside hand-written sources.
* Move CommissionTiming and MechanismType into model.event packageKostya2026-08-2017-25/+26
| | | | | Groups them with the other event-domain enums instead of the general api package, and updates all call sites accordingly.
* Add MapStruct jars to service moduleKostya2026-08-203-0/+2
| | | | | | lib/*/*.jar is auto-globbed onto the build classpath, so this makes mapstruct available for future DTO<->domain mappers without any build script changes.
* Add dotfiles to .gitignoreKostya2026-08-201-0/+2
|
* Add JaCoCo coverage reporting to test.shKostya2026-08-204-2/+20
| | | | | | Vendor jacocoagent.jar/jacococli.jar under lib/jacoco/ (excluded from the shipped classpath), attach the agent during test runs, and generate an HTML+XML report into build/coverage after tests pass.
* Simplify .gitignore1.0Kostya2026-08-181-6/+0
|
* Break down purchase receipts by cost/commission, harden XML validation and ↵Kostya2026-08-1818-76/+608
| | | | | | | | | state I/O Adds a full pre-load validation pass for GM XML seeds (ids, names, options, commission, LMSR liquidity), replaces IO.print with System.out, and surfaces detailed error messages across load/save commands instead of generic failures.
* Wire event ledger movements, show winning market by name, seed LMSR subsidyKostya2026-08-1812-22/+64
| | | | | | | | | | | | | - Event ledger now grows on purchase and shrinks on payout, mirroring the exact amounts moved on the buyer's ledger (it previously had a Ledger object that nothing ever wrote to). - Settlement and event-detail views now show the winning market's display name instead of its raw key; event details are viewable for settled events too (the picker previously excluded anything not ACTIVE). - LMSR events seed their ledger with a SUBSIDY entry for the market maker's worst-case loss (b * ln(outcomes)), reusing the existing cost() function rather than recomputing the formula.
* Fix menu wording and reprint prompt on retryKostya2026-08-184-4/+5
| | | | | | Rename "option"/"but order" wording to "market"/"buy order", add a blank line before the command prompt, and reprint the prompt text on readInt() retries instead of leaving the user without context.
* Harden console path input against crashesKostya2026-08-184-8/+20
| | | | | | | | | Menu.start() runs command.execute() with no surrounding try/catch, so an unchecked InvalidPathException from Path.of() on bad user input crashed the whole console loop. Centralize path parsing in InputProcessor.readPath(), which now validates and reprompts instead of throwing, and strips a surrounding pair of quotes so pasted/quoted paths still work.
* Add XML schema validation, split build scripts by module, rename ↵Kostya2026-08-1828-199/+573
| | | | | | | | | BuyMenuCommand to PlaceOrderMenuCommand Introduces XMLValidatorV1 and deserializer/adapter classes for events, ledgers, markets, users, and trading mechanisms. Replaces the monolithic build.bat/run.sh scripts with per-module tools (_util.sh, build.sh, package.sh, test.sh) that compile in dependency order.
* Replace order matching with risk/matching/fulfillment/settlement pipelineKostya2026-08-1784-2200/+2133
| | | | | | | | | Move XML loading infrastructure and models under service/catalog, and split order execution into a real pipeline: RiskEngine checks the order, MatchingEngine matches it, FulfillmentContext books the resulting trades, and SettlementContext resolves winning markets. GuessMarketContext.buyShares becomes placeOrder(price, quantity), and TradingMechanism.buy now returns matched trades directly instead of a single TradeExecution.
* Split DTOs into api/model, extract order matching into service/matchingKostya2026-08-1639-297/+227
| | | | | | | Moves Event/Ledger DTOs out of the flat api package into api/model/{event,ledger}, and moves LocalCatalogContext and order matching logic into dedicated service/catalog and service/matching packages, replacing TradingOperation/TradingOperationImpl.
* Rename Option/Account to Market/Ledger, add Result-based error handlingKostya2026-08-1638-250/+477
| | | | | | Split GuessMarketContext into a separate CatalogContext for read-only event listing, wrap fallible operations in Result<T> instead of throwing, and wire load/save of events and users through a JSON Wrapper.
* Implement LMSR and order-book trading logic, wire MarketContext facade and ↵Kostya2026-08-1529-114/+600
| | | | | | | | | | | new menu commands Fill in the previously stubbed cost/pricing math for both trading mechanisms, and give OrderBookTradingMechanism an actual matching engine with resting bid/ask books. Fold EventRepository/UserRepository access into a single MarketContext used by LocalGuessMarketContext, and move the repository package under infrastructure. Add Buy/EventDetails/LoadState/ SaveState/SettleEvent console commands and wire them into App/Menu.
* Switch TradingMechanism quantities to int, add yes/no and select promptsKostya2026-08-144-6/+35
| | | | | | | | | TradingMechanism's q/quantity params move from long/long[] to int/int[] to match the rest of the domain (Trade.quantity, Option counts, etc. are already int). Add InputProcessor.readYesNo and readSelect for upcoming menu commands that need a confirm prompt or a pick-from-list prompt.
* Collapse console I/O interfaces into InputProcessor, drop unneeded atomicsKostya2026-08-1413-120/+63
| | | | | | | | | | | InputProvider/OutputProvider each had one implementation and no test exercised the seam, so fold Console{Input,Output}Provider straight into InputProcessor and update Menu/MenuCommand call sites accordingly. Account and Event both use AtomicInteger for a ledger/trade id counter that's only ever touched next to a plain, non-thread-safe ArrayList add in the same method - the atomic bought no real thread-safety. Swapped both to plain int with ++.
* Implement in-memory repositories, XML load validation, and menu exit/list ↵Kostya2026-08-1421-61/+359
| | | | | | | | | | | | | | commands - Add generic Repository<T> interface; EventRepository/UserRepository extend it - Implement InMemoryEventRepository/InMemoryUserRepository backed by ArrayList - Rename XMLLoader to XMLLoaderV1, add LoadValidator and mapper/v2 package - Add OrderBookTradingMechanism - Add User(String, int) convenience constructor - Add ListEventsMenuCommand and ExitMenuCommand, isExit() on MenuCommand - Menu now sizes selection range by max command index and exits on isExit() - LoadFileMenuCommand reports validation issues on failed loads - Untrack test-data/ and config.properties from .gitignore
* Move mapper/provider infra into v1 packages, add repository write methodsKostya2026-08-149-18/+83
| | | | | Correct Mapper's generic parameter order to <TModel, TDomain> and stub addEvent/addUser on the Event/User repositories.
* Move IO providers into io package, add InputProcessor, implement menu loop ↵Kostya2026-08-149-24/+116
| | | | | | | and file load command Wires InputProcessor into the console menu's selection loop and the load-file command's prompt handling, replacing the unimplemented stub.
* Wire buyShares and menu commands, replace factory interfaces with DIKostya2026-08-1421-64/+211
| | | | | | | | Implement LocalGuessMarketContext.buyShares/loadEvents via a new TradingOperation and Loader, backed by in-memory repositories. Replace the ConsoleInputProviderFactory/ConsoleOutputProviderFactory pattern with picocontainer-injected providers, and drive the menu from a list of MenuCommand implementations instead of a hardcoded printout.
* Add ledgered credit/debit to Account and trade recording to EventKostya2026-08-146-26/+67
| | | | | | | Drops AccountType (accounts no longer need to self-identify), gives Account credit()/debit() that append LedgerEntry rows, adds Event.recordTrade()/tradeVolumeOf()/getCommission(), and implements LocalGuessMarketContext.listEvents() via the repository.
* Implement LMSR mechanism and Event/Account accessors, wire EventMapperV1Kostya2026-08-144-2/+176
| | | | | | Adds LmsrTradingMechanism, exposes Event/Account getters plus Event.toEventSummary() for DTO conversion, and implements EventMapperV1.toDomain() to build Event from the legacy XML model.
* Wire EventRepository into LocalGuessMarketContext, add mapper/provider infra ↵Kostya2026-08-148-5/+49
| | | | | | | and tests Removes the placeholder Mapper interface in favor of concrete mapper/provider implementations, fixes Menu.stop() to no-op instead of throwing.
* Add legacy XML model bindings, mapper infra, and normalize account balanceKostya2026-08-1328-4/+2277
| | | | | Rename repositories package to repository, add MarketAction domain type, and round Account.initialBalance through BigDecimalOptions.toMoney.
* Add domain model, repositories, and trading mechanism interfaces to service ↵Kostya2026-08-1311-0/+197
| | | | | | | module Introduces Account/Event/Trade/User/Option/LedgerEntry domain types plus EventRepository/UserRepository and TradingMechanism abstractions.
* Remove engine moduleKostya2026-08-1314-995/+0
| | | | | | Superseded by the service module's GuessMarketContext implementation; the JAXB model, TradingMechanism interface, and its LMSR/order-book stubs had no remaining callers.
* Add service module with stubbed LocalGuessMarketContextKostya2026-08-139-75/+170
| | | | | | | | | | GuessMarketContext gained a richer surface (loadEvents/listEvents/ buyShares/closeEvent/account/save-restoreState) backed by new EventDetailDTO, MarketStateDTO, OptionStateDTO and PurchaseReceiptDTO. The old engine-module provider implemented the previous shape and is removed; market.guess.service.LocalGuessMarketContext replaces it as a stub, each method throwing UnsupportedOperationException pending a real implementation.
* Replace EventDTO with richer EventSummaryDTO/TradeRowDTO view modelsKostya2026-08-138-30/+30
| | | | | | | Introduce MechanismType and rename CommissionChargeType to CommissionTiming to better describe LMSR vs order-book events. LocalGuessMarketContext.GetAllEventsAsync is stubbed pending the new mapping.
* Move I/O provider abstraction to ui-console, add ledger/account/problem DTOsKostya2026-08-1318-50/+47
| | | | | | | | InputProvider/OutputProvider were api-layer types only ever implemented by the console UI; relocate them there. Drop the unused GuessMarketEngine/LocalGuessMarketService pair, flesh out LoadResultDTO with success/failure variants, and make LocalGuessMarketContext.LoadAsync report real outcomes instead of an empty placeholder.
* Vendor Mockito 5.23.0 dependenciesKostya2026-08-135-0/+0
|
* Move engine contracts to api module, add I/O provider abstraction and ↵Kostya2026-08-1032-31/+1115
| | | | | | | | | | | PicoContainer wiring Relocates GuessMarketEngine/GuessMarketContext into market.guess.api so engine and ui-console depend on a shared contract instead of engine internals, and makes context loading async (CompletableFuture). Adds InputProvider/OutputProvider interfaces with console implementations, wires the console app's Menu through a PicoContainer, and adds the generated model classes plus vendored picocontainer jar needed to build it.
* flatten modules to repo root, vendor deps, repair Eclipse build pathsKostya2026-08-0994-124/+155
| | | | | | | | | | | | | | | | | | | | | | | Move api, engine, ui-console and ui-desktop out of modules/ up to the repo root and drop the empty exception project (GuessMarketException now lives in api). Vendor gson, jaxb, okhttp, openjfx and tomcat under lib/, and group the JUnit standalone jar into lib/junit/ alongside them. Rewrite every .classpath: drop the copy-pasted optional="true" that was masking real build path errors, point the library entries at ../lib/, and put the JUnit jar on the test source folders so the placeholder AppTest classes compile. ui-desktop: take the JavaFX jars off the modulepath (there is no module-info.java, so module="true" left the packages unresolvable) and add a Launcher that calls Application.launch, avoiding the "JavaFX runtime components are missing" check without VM arguments. engine: add LocalGuessMarketService and the GuessMarketContext provider interface, and give GuessMarketException the no-arg and cause constructors they need.
* consolidate modules, add more infraKostya2026-08-0912-29/+97
|
* wireframeKostya2026-08-0633-25/+309
|
* template initial commitKostya2026-08-0612-0/+232