- Features
- Design Choices
- Local Deployment
- Contributing
- Api Documentation
- Results & Data From Simulations
A server side implementation for a stock market and stock trading simulator. Users can create accounts and trade stocks using paper money with the goal of increasing their profits and outperforming other accounts, while keeping track of market activity to best plan for price trajectories
All stock prices, news, earnings etc. are completely simulated and are not reflective of real world market activity.
Default stock data, such as the name, ticker symbol, market cap and sector are based on real world companies
- The market date is tracked on intervals that can be altered. The default "day" is 24 intervals of 10 seconds, and 30 "days" is a month
- The date is formatted as month/day/year
- Stock prices change after each 10 second interval, and certain stock events can happen at the end of each day
- There are 3 market types; Bear, Bull and Normal. Bear markets occur if the average stock price falls 10% in a month, while bull markets happen if prices rise 10% monthly. Normal market conditions cover all scenarios in between
- Stock prices change on an interval (10 seconds)
- Stock prices change based on three factors: market cap, momentum, and volatility
- Market Cap: Large and small cap stocks experience higher movement, in an upward or downward trajectory
- Momentum: When stock prices rise for 3 days, they experience positive momentum, while they experience negative momentum if they fall for 3 days
- Volatility: Each stock is judged on whether it is volatile or not. This is an unchangeable boolean value, and is based on the nature of the real world company. Volatile stocks receive a slight increase in movement each time their prices change
- At the end of each day, there is a chance that a specific stock will release a news story, which will have a large effect on their price
- Positive news, such as buyouts, will increase the stocks by around price 10%
- Negative news, such as lawsuits or management shakeups will decrease stock price by around 10%
- Bankruptcies will occur if a stock price dips below $1, where a buyout will occur and the stocks price will reset back to the default
- Stocks release earnings reports on the first day of every 3rd month (3rd, 6th, 9th, 12th)
- Earnings reports effect stock prices and optimism, and are also affected by previous optimism
- Index funds track the average price of a specific category of stocks
- These cannot be traded, but only serve to estimate the total market trajectory
I am currently in the process of migrating the current backend server to multiple microservices. The three microservices will be:
- Stock Market API
- Trading API
- Trading Bots
Here are the main justifications for doing this:
-
Learn microservices & gain experience building applications that talk to other services
-
Implement Spring Security, but isolate its features only to the trading API. The market is a publically available API, and so its endpoints do not require any authorization/authentication. Likewise, the trading bot service has no endpoints, and so requires minimal security measures, at least in the context of APIs. This means Spring Security is only relevant for 1/3 functions
-
Although this is a simulation, and there are no plans for deployment, the idea here is that each of the 3 services would be seperate "companies." The trading API acts a brokerage firm, the market API simulated a countries stock market, and the trading bot service acts a quant firm that interacts with its domestic market through publically-unavailable bots. Seperating the server into these 3 services means that it more closely follows the goal of having 3 seperate "companies" that all work together to build a stock market simulation
To run locally, first ensure that Docker Desktop & Maven is downloaded to your system. Then run the following commands:
- Stock Market Service will run on http://localhost:8000
- Stock Trading Service will run on http://localhost:8010
- git clone https://github.com/Jackson-Wozniak/Stock-Market-Simulation.git
- docker-compose up
To update docker-compose after changes to code, run:
- docker-compose up --build
To remove created containers after you are done, run:
- docker-compose down
Stock Market Service API Docs (click to expand)
Market
{
"date": String,
"trajectory": String,
"lastMonthPrice": double
}
StockSummary
{
"ticker" : String,
"companyName" : String,
"price" : double,
"lastDayPrice" : double,
"percentChange" : double
}
Stock
{
"ticker" : String,
"companyName" : String,
"sector" : String,
"marketCap" : String,
"price" : double,
"lastDayPrice" : double,
"momentum" : integer,
"momentumStreakInDays" : integer,
"volatileStock" : String,
"investorRating" : String
}
DetailedStock
{
}
StockPriceHistory
[
{
"marketDate": ZonedDateTime,
"price": double
}
]
News
{
"event": String,
"dateReleased": ZonedDateTime
}
EarningsReport
{
"estimatedEPS": double,
"actualEPS": double,
"reportMessage": String,
"dateOfRelease": ZonedDateTime
}
SimulatedStock
[
{
"MM/DD/YYYY": double
},
]
IndexFund
{
"name": String,
"price": double,
"fundTracking": String
}
GET
/api/v1/market
200 OK -> Market
GET
/api/v1/market/sim/price_history?days={String}&stocks={int}
200 OK -> List[SimulatedStock]
GET
/api/v1/stocks/{ticker}
200 OK -> StockSummary
GET
/api/v1/stocks
200 OK -> List[StockSummary]
GET
/api/v1/stocks/detailed
200 OK -> List[Stock]
GET
/api/v1/stocks/marketCap/{String}
200 OK -> List[Stock]
GET
/api/v1/stocks/sector/{String}
200 OK -> List[Stock]
GET
/api/v1/stocks/price/{ticker}
200 OK -> double
GET
/api/v1/stocks/random
200 OK -> Stock
GET
/api/v1/stocks/history/{ticker}
200 OK -> List[StockPriceHistory]
GET
/api/v1/news/{ticker}
200 OK -> List[News]
GET
/api/v1/news/
200 OK -> List[News]
GET
/api/v1/earnings/{ticker}
200 OK -> List[EarningsReport]
GET
/api/v1/earnings
200 OK -> List[EarningsReport]
GET
/api/v1/earnings/date/{String}
200 OK -> List[EarningsReport]
GET
/api/v1/funds
200 OK -> List[IndexFund]
GET
/api/v1/funds/total-market
200 OK -> IndexFund
GET
/api/v1/funds/cap
200 OK -> List[IndexFund]
GET
/api/v1/funds/cap/{String}
200 OK -> IndexFund
GET
/api/v1/funds/sector
200 OK -> List[IndexFund]
GET
/api/v1/funds/sector/{String}
200 OK -> IndexFund
GET
/api/v1/funds/volatility
200 OK -> List[IndexFund]
GET
/api/v1/funds/volatility/{String}
200 OK -> IndexFund
Below is a chart that uses the market simulation endpoint with 100 stocks over 30 days to display price changes. The simulation is seperate from that actual market as it does not retrieve stock info from the database, but uses the same price change formula to re-enact the real market simulation
The current calculation method is as followed:
NP = P + (P * R) + (P * (R * V)) + (M * PR)
NP = New Price
P -> Original Price
R -> Random Number. For these simulations the number weres -.0015 to .0015 and -.002 to .002
V -> Volatility of the stock. Values of 0 to 4
M -> Momentum of the stock. Values of -2 to 2
PR -> Positive random number up to .002
A common way to randomly simulate stock data is the model of Geometric Brownian Motion. An example of this can be seen below, with the same price and duration as my simulations:
Using the log-parser python script, this chart shows the duration of each market interval (aka how long it takes for the program to change prices and save them to the database)
Y-Axis shows the number of times the market advanced intervals, with the X-Axis being the time range of that interval
*NOTE: In the future there could be a system that acts as a cache in order to avoid stocks being queried/saved each cycle. One way to do this may be to have a StockManager that acts as an intermediary between the service classes and repository classes, that keeps the stocks in memory and only saves/queries at the end of the trading day. If there is a better system please to propose the idea by opening a GitHub issue, I would like to hear better systems for this use-case