- Published on
Royal Stock Exchange(RSE) - Seeding Stock Market data in SQL - Part 2
- Authors
- Name
- Loi Tran
- @PrimeTimeTrann
Royal Stock Exchange(RSE) - Seeding Stock Market data in SQL - Part 2
It's always a good idea to have some reasonable dummy data for testing.
I always find it useful to create a script to run on my machine in order to not only generate data which I can query, but to help in the process of actually building/understanding my db schema.
An app at scale will need custom SQL queries without an ORM eventually. It's not a waste of time to write a few to populate our DB before diving into an ORM, defining classes, or adding migration headaches to our list of problems.
Steps
Start off by wiping my db clean/dropping tables.
DROP TABLE IF EXISTS Users; DROP TABLE IF EXISTS Stocks; DROP TABLE IF EXISTS Orders; DROP TABLE IF EXISTS Prices;
Next I define the
Users
table and add a few users.CREATE TABLE Users ( Id INT PRIMARY KEY IDENTITY(1, 1), FName VARCHAR(255) NOT NULL, LName VARCHAR(255) NOT NULL, ); INSERT INTO Users (FName, LName) VALUES ('Loi', 'Tran'), ('Tai', 'Tran'), ('Thao', 'Tran'), ('Hieu', 'Tran'), ('Doug', 'Tran');
Now
Stocks
&Orders
since we're building a stock exchange.CREATE TABLE Orders ( Expires DATETIME, UserId INT NOT NULL, Shares INT NOT NULL, OrderableId INT NOT NULL, StopPrice DECIMAL(10, 2), Type VARCHAR(20) NOT NULL, LimitPrice DECIMAL(10, 2), Status VARCHAR(20) NOT NULL, Id INT PRIMARY KEY IDENTITY(1, 1), OrderType VARCHAR(10) NOT NULL CHECK (OrderType IN ('Buy', 'Sell')), OrderableType VARCHAR(10) NOT NULL CHECK (OrderableType IN ('Stock', 'Option', 'Bond')) ); CREATE TABLE Stocks ( Id INT PRIMARY KEY IDENTITY(1, 1), Name NVARCHAR(30), Price DECIMAL(18, 2), Quantity INT, Symbol NVARCHAR(20) ); INSERT INTO Stocks (Name, Price, Quantity, Symbol) VALUES ('AT&T', 15.81, 75, 'T'), ('Coinbase', 64.21, 100, 'COIN'), ('Bank of America', 28.5, 100, 'BAC'); INSERT INTO Orders (UserId, OrderableId, OrderableType, Status, Type, StopPrice, LimitPrice, Shares, Expires, OrderType) VALUES (1, 1, 'Stock', 'Filled', 'Buy', NULL, 100.00, 10, '2023-05-31 12:00:00', 'Buy'), (2, 2, 'Option', 'Non-filled', 'Limit', NULL, 50.00, 5, '2023-06-01 15:30:00', 'Buy'), (1, 3, 'Bond', 'Cancelled', 'Stop Loss', 70.00, NULL, 8, '2023-06-02 10:45:00', 'Buy');
Most importantly,
Prices
for tracking prices over time which'll be displayed as candlesticks in a chart.- Define
Prices
. - Define variables which we'll update for each time series item.
- Run a loop which creates a
Price
item and inserts it into the db.
CREATE TABLE Prices ( Id INT PRIMARY KEY IDENTITY(1, 1), StockId INT NOT NULL, TransactionCount INT NOT NULL, DateOfAggregation DATETIME NOT NULL, o DECIMAL(18, 2) NOT NULL, -- open l DECIMAL(18, 2) NOT NULL, -- lo h DECIMAL(18, 2) NOT NULL, -- hi c DECIMAL(18, 2) NOT NULL, -- close v DECIMAL(18, 2) NOT NULL, -- volume vwa DECIMAL(18, 2) NOT NULL -- volume weighted average ); DECLARE @count INT = 0; DECLARE @weekAgo DATETIME = GETDATE() - 7; DECLARE @price DECIMAL(10, 2) = 27.00; DECLARE @open DECIMAL(10, 2) = @price; DECLARE @lo DECIMAL(10, 2) = 0.0; DECLARE @hi DECIMAL(10, 2) = 0.0; DECLARE @close DECIMAL(10, 2) = 0.0; WHILE @count < 30 BEGIN SET @price = @price -0.10 + (RAND() * (.10 - (-0.10))); SET @close = @price; SET @lo = @price -0.05 + (RAND() * (-0.1)); SET @hi = @price -0.05 + (RAND() * (.1)); INSERT INTO Prices ( StockId, TransactionCount, DateOfAggregation, o, l, v, h, c, vwa ) VALUES ( 1, 100, @weekAgo, @open, CASE WHEN @open < @lo THEN @open ELSE @lo END, 1000, CASE WHEN @close > @hi THEN @close ELSE @hi END, @close, 140 ); SET @open = @close; SET @count = @count + 1; SET @weekAgo = DATEADD(HOUR, 1, @weekAgo); END;
- Define
Now we've got some data. Yay