diff --git a/activity_diagram.puml b/activity_diagram.puml new file mode 100644 index 0000000..56a746f --- /dev/null +++ b/activity_diagram.puml @@ -0,0 +1,38 @@ +@startuml ActivityDiagram +!define START #90EE90 +!define END #FFB6C6 +!define DECISION #FFFFE6 +!define ACTION #E6F2FF + +title Stock Trading Game - Purchase Transaction Activity Diagram + +start +:Player initiates purchase request; +:Exchange.buy() called with symbol and quantity; + +if (Symbol valid and stock exists?) then (No) + :Throw IllegalArgumentException; + end +else (Yes) + :Get Stock from exchange; + :Create Share with current market price; +endif + +:Create Purchase transaction; + +if (Player has sufficient funds?) then (No) + :Throw IllegalStateException; + end +else (Yes) + :Deduct purchase cost from player money; + :Add share to portfolio; + :Record transaction in archive; + :Mark transaction as committed; +endif + +:Exchange notifies all observers; +:UI updates with new portfolio state; + +stop + +@enduml diff --git a/class_diagram.puml b/class_diagram.puml new file mode 100644 index 0000000..494288f --- /dev/null +++ b/class_diagram.puml @@ -0,0 +1,202 @@ +@startuml ClassDiagram +!define ABSTRACT_COLOR #FFE6E6 +!define INTERFACE_COLOR #E6F2FF +!define ENUM_COLOR #FFFFE6 + +skinparam backgroundColor #FFFFFF +skinparam classBackgroundColor #FFFFFF +skinparam classBorderColor #333333 + +package Model { + + ' Enums + enum PlayerStatus #FFFFE6 { + NOVICE + INVESTOR + SPECULATOR + -- + getDisplayName(): String + } + + ' Interfaces + interface ExchangeObserver #E6F2FF { + onExchangeUpdated(exchange: Exchange): void + } + + ' Core Model Classes + class Player { + - name: String + - startingMoney: BigDecimal + - money: BigDecimal + - portfolio: Portfolio + - transactionArchive: TransactionArchive + -- + + Player(name: String, startingMoney: BigDecimal) + + getName(): String + + getMoney(): BigDecimal + + addMoney(amount: BigDecimal): void + + withdrawMoney(amount: BigDecimal): void + + getPortfolio(): Portfolio + + getTransactionArchive(): TransactionArchive + + getStatus(): PlayerStatus + } + + class Stock { + - symbol: String + - company: String + - prices: List + -- + + Stock(symbol: String, company: String, salesPrice: BigDecimal) + + getSymbol(): String + + getCompany(): String + + getSalesPrice(): BigDecimal + + addNewSalesPrice(price: BigDecimal): void + + getHistoricalPrices(): List + + getHighestPrice(): BigDecimal + + getLowestPrice(): BigDecimal + + getLatestPriceChange(): BigDecimal + } + + class Share { + - stock: Stock + - quantity: BigDecimal + - purchasePrice: BigDecimal + -- + + Share(stock: Stock, quantity: BigDecimal, purchasePrice: BigDecimal) + + getStock(): Stock + + getQuantity(): BigDecimal + + getPurchasePrice(): BigDecimal + } + + class Portfolio { + - shares: List + -- + + Portfolio() + + addShare(share: Share): boolean + + removeShare(share: Share): boolean + + getShares(): List + + getShares(symbol: String): List + + contains(share: Share): boolean + + getNetWorth(): BigDecimal + } + + class Exchange { + - name: String + - week: int + - stockMap: Map + - observers: List + - random: Random + -- + + Exchange(name: String, stocks: List) + + addObserver(observer: ExchangeObserver): void + + removeObserver(observer: ExchangeObserver): void + - notifyObservers(): void + + getName(): String + + getWeek(): int + + hasStock(symbol: String): boolean + + getStock(symbol: String): Stock + + findStocks(searchTerm: String): List + + buy(symbol: String, quantity: BigDecimal, player: Player): Transaction + + sell(share: Share, player: Player): Transaction + + sell(originalShare: Share, sellQuantity: BigDecimal, player: Player): Transaction + + advance(): void + + getGainers(limit: int): List + + getLosers(limit: int): List + } + + ' Transaction Hierarchy + abstract class Transaction #FFE6E6 { + # share: Share + # week: int + # calculator: TransactionCalculator + # committed: boolean + -- + # Transaction(share: Share, week: int, calculator: TransactionCalculator) + + getShare(): Share + + getWeek(): int + + getCalculator(): TransactionCalculator + + isCommitted(): boolean + + commit(player: Player): void {abstract} + } + + class Purchase { + -- + + Purchase(share: Share, week: int) + + commit(player: Player): void + } + + class Sale { + -- + + Sale(share: Share, week: int) + + commit(player: Player): void + } + + class TransactionArchive { + - transactions: List + -- + + TransactionArchive() + + add(transaction: Transaction): boolean + + isEmpty(): boolean + + getTransactions(week: int): List + + getPurchase(week: int): List + + getSale(week: int): List + + getAllTransactions(): List + + countDistinctWeeks(): int + } + + ' Calculator Classes + interface TransactionCalculator #E6F2FF { + calculateTotal(): BigDecimal + } + + class PurchaseCalculator { + - share: Share + -- + + PurchaseCalculator(share: Share) + + calculateTotal(): BigDecimal + } + + class SaleCalculator { + - share: Share + -- + + SaleCalculator(share: Share) + + calculateTotal(): BigDecimal + } + + class TransactionFactory { + -- + + {static} createPurchase(share: Share, week: int): Purchase + + {static} createSale(share: Share, week: int): Sale + } + + ' Relationships + Player --> Portfolio : "has" + Player --> TransactionArchive : "has" + Player --> PlayerStatus : "has" + + Portfolio --> Share : "contains *" + + Share --> Stock : "references" + + Exchange --> Stock : "manages *" + Exchange --> ExchangeObserver : "notifies *" + Exchange --> Transaction : "creates" + + Transaction --> Share : "trades" + Transaction --> TransactionCalculator : "uses" + + Purchase --|> Transaction : "extends" + Sale --|> Transaction : "extends" + + PurchaseCalculator ..|> TransactionCalculator : "implements" + SaleCalculator ..|> TransactionCalculator : "implements" + + TransactionFactory --> Purchase : "creates" + TransactionFactory --> Sale : "creates" + + TransactionArchive --> Transaction : "stores *" + TransactionArchive --> Purchase : "retrieves" + TransactionArchive --> Sale : "retrieves" +} + +@enduml diff --git a/sequence_diagram.puml b/sequence_diagram.puml new file mode 100644 index 0000000..1cf9a93 --- /dev/null +++ b/sequence_diagram.puml @@ -0,0 +1,101 @@ +@startuml SequenceDiagram +title Stock Trading Game - Buy Stock Transaction Sequence + +actor User as user +participant "View" as view +participant "Exchange" as exchange +participant "Stock" as stock +participant "Share" as share +participant "Purchase" as purchase +participant "Player" as player +participant "Portfolio" as portfolio +participant "PurchaseCalculator" as calc +participant "TransactionArchive" as archive +participant "Observer" as observer + +user -> view: Click Buy Button +activate view +view -> exchange: buy(symbol, quantity, player) +activate exchange + +exchange -> exchange: Validate inputs +exchange -> stock: getStock(symbol) +activate stock +stock --> exchange: Stock object +deactivate stock + +exchange -> exchange: Check if stock exists + +exchange -> stock: getSalesPrice() +activate stock +stock --> exchange: BigDecimal price +deactivate stock + +exchange -> share: new Share(stock, quantity, price) +activate share +share --> exchange: Share instance +deactivate share + +exchange -> purchase: new Purchase(share, week) +activate purchase +purchase -> calc: new PurchaseCalculator(share) +activate calc +calc --> purchase: Calculator instance +deactivate calc +purchase --> exchange: Purchase instance +deactivate purchase + +exchange -> purchase: commit(player) +activate purchase + +purchase -> calc: calculateTotal() +activate calc +calc --> purchase: BigDecimal total cost +deactivate calc + +purchase -> player: getMoney() +activate player +player --> purchase: BigDecimal current money +deactivate player + +alt Sufficient Funds + purchase -> player: withdrawMoney(cost) + activate player + player -> player: Subtract from balance + deactivate player + + purchase -> portfolio: addShare(share) + activate portfolio + portfolio -> portfolio: Add share to list + portfolio --> purchase: true + deactivate portfolio + + purchase -> archive: add(this) + activate archive + archive -> archive: Add transaction to list + archive --> purchase: true + deactivate archive + + purchase -> purchase: committed = true + purchase --> exchange: void + +else Insufficient Funds + purchase --> exchange: throw IllegalStateException +end + +deactivate purchase + +exchange -> observer: notifyObservers() +activate observer +observer -> observer: Update UI state +observer --> exchange: void +deactivate observer + +exchange --> view: Transaction completed +deactivate exchange + +view -> view: Refresh display +view --> user: Show updated portfolio +deactivate view + +@enduml