Skip to content

Latest commit

 

History

History
executable file
·
141 lines (100 loc) · 6.72 KB

README.md

File metadata and controls

executable file
·
141 lines (100 loc) · 6.72 KB

Super Simple Stock Market

Super Simple Stock Market (SSSM) is an object-oriented system designed to run trading in a fictitious Global Beverage Corporation Exchange stock market. Besides recording trades for common and preferred stock, SSSM is able to calculate both stock specific metrics (such as Dividend Yield and P/E Ratio) and index metrics (such as Volume Weighted Stock Price and a GBCE specific All Share Index).

Restrictions and assumptions

  • Prices will be given in a single unspecified currency with 100 subunits
  • Minimum stock price is 0.01
  • Minimum fixed dividend is 1%
  • No fractional shares
  • P/E Ratio is based on past performance (i.e., on last dividend paid)
  • Timestamps are given in machine time (i.e., Instant); the system is not timezone aware
  • Trades represent committed orders and all prices are final
  • Trades will not be evicted from history (i.e., history can contain trades older than 5 minutes)
  • Trades are written to the history more often than metrics are computed (i.e., system is optimized for writes)
  • Since no trades are evicted and data is held in memory the system will not be submitted to unreasonable load
  • SSSM is a single threaded system

Design guidelines

1. Immutable model

Stocks and Trades are immutable by design. The system at this stage is not multithreaded but immutability comes with highly desirable characteristics such as side effect free programming and simple reasoning about the code.

Mutable collections are still used sparingly and isolated (e.g., for trades history).

2. Composition vs Inheritance

Preferred and common stocks are types of stock (IS-A relationship). Fixed dividend is exclusive to preferred stocks and dividend yield is dependent on the stock type. It would be possible to design the model relying in a type discriminator (e.g, StockType enum). A mix of composition and delegation could be used to model dynamic swappable behaviour. In the lack of such requirements, inheritance seems like a natural way to design the model respecting SOLID Open/Closed principle. Special care is taken to follow the Liskov Substitution Principle, plus encapsulation and patterns such as static factory methods are used to hide implementation details from the API.

Class Diagram - Stocks

On the other end of the spectrum, it would not make much sense to apply inheritance for different types of Trade since in SSSM all trades behave the same. A TradeIndicator enum discriminator is used instead.

Class Diagram - Trades

3. Services and Data

In accordance with Domain-driven design practices a StockMarketService class provides the required methods for calculating Volume Weighted Stock price and the GBCE specific All Share Index.

The data itself is written and retrieved using an in-memory implementation of StockRepository. Internally, a MultiMap stores trades for each kind of stock.

Class Diagram - Service and Repository

Finally, a geometric mean summary Collector is implemented as an alternative for a private or public static utility method in order to comply with the Simple responsibility principle.

4. Accuracy trumps speed

Decimal values are represented with BigDecimal instead of types like double and long.

Precision and rounding policies:

  • Internal computations use a precision of 30 digits
  • The fractional part of monetary values are scaled to the second digit
  • The fractional part of percentage values are scaled to the fifth digit

ROUND_HALF_EVEN policy is used for rounding.

5. Some libraries, no containers

It is certainly possible to design a production quality toy project. On the other hand, it is hard to ignore that a large enterprise project may call for a different toolset than a self-contained exercise.

Tools such as Spring Boot are able to bootstrap a production grade application with all the bells and whistles in a matter of minutes. Still, I feel that overengineering a toy project to emulate enterprise architecture defeats the purpose of the exercise. Thus, while I'm fully aware of the benefits that IoC containers, a bean validation framework etc could bring to the project, I've chosen to stick with a basic clean design.

This does not mean ignoring tools altogether:

  • Lombok is used to reduce boilerplate code
  • Guava brings that extra level of expressiveness with custom collections, preconditions etc to the project.
  • SLF4J is used as lightweight logging facade loosely coupled to a java.util.logging implementation.

6. Testing

A suite of TestNG unit tests with AssertJ assertions is provided. Surefire reports can be generated with:

mvn test

While Spock was initially considered, this project is still too small and a complex BDD framework would be an overkill. For the same reason, automatic coverage, load and acceptance tests were not implemented for this version of the software.

How to build

In order to build the project Maven 3 and Oracle JDK 8 are required. The project can be built with:

mvn clean install

Super Simple Stock Market itself is IDE agnostic. Some IDEs may require extra configuration in order to play well with Lombok.