avaialable from (https://rpubs.com/staszkiewicz/FM03_Price_Discovery)
Dynamic Market: Stock prices fluctuate constantly based on various factors like supply and demand, news, and economic indicators.
Order Book: A collection of buy and sell orders at different prices.
Price Discovery: The process of determining a fair market price through interaction of buy and sell orders.
library(quantmod)
## Ładowanie wymaganego pakietu: xts
## Ładowanie wymaganego pakietu: zoo
##
## Dołączanie pakietu: 'zoo'
## Następujące obiekty zostały zakryte z 'package:base':
##
## as.Date, as.Date.numeric
## Ładowanie wymaganego pakietu: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
We will assume that 5 buy orders were sent to the stocke exchange at prices of: 102,100, 99, 101, 97 the investors would like to buy respectively: 18,100, 200, 150, 50.
On the opposite side of the markets the different investors would like to buy the stock for 103, 105, 104, 102 the following quantity: 50, 100, 200, 150. First crease two data frames with the buy orders prices and corresponding quantities, the second frame with the sell orders.
buy_orders <- data.frame(price = c(102,100, 99, 101, 97), quantity = c(18,100, 200, 150, 50))
sell_orders <- data.frame(price = c(103, 105, 104, 102), quantity = c(50, 100, 200, 150))
buy_orders
## price quantity
## 1 102 18
## 2 100 100
## 3 99 200
## 4 101 150
## 5 97 50
sell_orders
## price quantity
## 1 103 50
## 2 105 100
## 3 104 200
## 4 102 150
Note our list are not arranged by the prices, as the orders comes with different prices and quantity. So we now need to arrange market by prices bid and ask
buy_orders <- buy_orders[order(buy_orders$price, decreasing = TRUE), ]
sell_orders <- sell_orders[order(sell_orders$price), ]
buy_orders
## price quantity
## 1 102 18
## 4 101 150
## 2 100 100
## 3 99 200
## 5 97 50
sell_orders
## price quantity
## 4 102 150
## 1 103 50
## 3 104 200
## 2 105 100
We need to check if the market can execute any orders, this means we need to have at least one price at winch there is demand and supply for. So let us check the highest buy price and the lowest sell price.
# Find the highest bid and lowest ask
highest_bid <- buy_orders$price[1]
lowest_ask <- sell_orders$price[1]
highest_bid
## [1] 102
lowest_ask
## [1] 102
Because the min sell is equal to max buy, we might execute the transaction at the strike price.
(highest_bid >= lowest_ask)
## [1] TRUE
But we need to establish the quantity.
# Determine the trade quantity
trade_quantity <- min(buy_orders$quantity[1], sell_orders$quantity[1])
trade_quantity
## [1] 18
At the price 102 we are able to transfer 18 shares. Now we have to update the new trade book after execution of the transactions. The matched orders will be sent to the CCP for clearance (usually +3d)
Match supply and demand and update trade book after execution of matched transactions
# Update orders
buy_orders$quantity[1] <- (buy_orders$quantity[1] - trade_quantity)
sell_orders$quantity[1] <- (sell_orders$quantity[1] - trade_quantity)
# Remove exhausted orders
# Remove exhausted orders
buy_orders <- buy_orders[buy_orders$quantity > 0, ]
sell_orders <- sell_orders[sell_orders$quantity > 0, ]
Show now the orders book buy oders
buy_orders
## price quantity
## 4 101 150
## 2 100 100
## 3 99 200
## 5 97 50
sells orders
sell_orders
## price quantity
## 4 102 132
## 1 103 50
## 3 104 200
## 2 105 100
Calculate the new market price
# Calculate the new price
new_price <- (highest_bid + lowest_ask) / 2
list(price = new_price, buy_orders = buy_orders, sell_orders = sell_orders)
## $price
## [1] 102
##
## $buy_orders
## price quantity
## 4 101 150
## 2 100 100
## 3 99 200
## 5 97 50
##
## $sell_orders
## price quantity
## 4 102 132
## 1 103 50
## 3 104 200
## 2 105 100
Below you have a full code check what the difference between the first one?
library(quantmod)
# Simulate a simple order book
buy_orders <- data.frame(price = c(100, 99, 98, 97), quantity = c(100, 200, 150, 50))
sell_orders <- data.frame(price = c(105, 104, 103, 102), quantity = c(50, 100, 200, 150))
# Function to process orders and determine price
process_orders <- function(buy_orders, sell_orders) {
# Sort orders by price
buy_orders <- buy_orders[order(buy_orders$price, decreasing = TRUE), ]
sell_orders <- sell_orders[order(sell_orders$price), ]
# Find the highest bid and lowest ask
highest_bid <- buy_orders$price[1]
lowest_ask <- sell_orders$price[1]
# If there's an overlap, execute trades and update orders
if (highest_bid >= lowest_ask) {
# Determine the trade quantity
trade_quantity <- min(buy_orders$quantity[1], sell_orders$quantity[1])
# Update orders
buy_orders$quantity[1] <- buy_orders$quantity[1] - trade_quantity
sell_orders$quantity[1] <- sell_orders$quantity[1] - trade_quantity
# Remove exhausted orders
buy_orders <- buy_orders[buy_orders$quantity > 0, ]
sell_orders <- sell_orders[sell_orders$quantity > 0, ]
# Calculate the new price
new_price <- (highest_bid + lowest_ask) / 2
return(list(price = new_price, buy_orders = buy_orders, sell_orders = sell_orders))
} else {
return(list(price = NA, buy_orders = buy_orders, sell_orders = sell_orders))
}
}
# Simulate multiple iterations
for (i in 1:10) {
result <- process_orders(buy_orders, sell_orders)
if (!is.na(result$price)) {
print(paste("Iteration", i, "Price:", result$price))
buy_orders <- result$buy_orders
sell_orders <- result$sell_orders
} else {
print("No trades executed.")
break
}
}
## [1] "No trades executed."
Now you might show the price discover in your reports for the Coca Cola assume the quantity bid and ask prices, please make sure the data in your reports are replicable.