Simulating a stock market: Company

For the 0.1.3 update of Delicate Stocks, I’ve decided to scrap the old system of company value being based on an average of 2 perlin noises to an actual market with simulated customers and asset - liability based company valuation.

Values/Variables of the algorithmn
combal: The company’s balance / spendable value
liability: The company’s liabilities
assets: The value of all of the company’s assets
eco: The economic status (between 1 and 0.5, perlin noise based)
popularity: The popularity of the product
supply: The amount of unsold product
costproduction: avg. cost to make 1 product
price: The sale price of each product

CustomerData:
  need: The customer's want of the product
  income: The customer's income
  bal: The customer's balance

newfactorycost: the cost to make a new factory
lastprice: the last price
clock: a clock that controls the rate of the market server-wide
demand: The demand of the product

Code:

local clock = game.ReplicatedStorage.clock


local crash = script.crash
local rocket = script.rocket

local customerdata = {}
local supply = 200
local demand = 0
local price = 1
local costproduction = .7

local stocks = game.ReplicatedStorage.Stocks

local compbal = stocks.bal
local liability = stocks.liability
local assets = stocks.assetvalue

local popularity = 0

local eco = 1
local x = 1.1

local lastprice = 1
local change = 0

local supplychange = 0

local production = 
	{
		{amount = 1, cost = costproduction}
	}

local newfactorycost = 150

local function GenerateCustomerData()
	for c=1, 5000 do
		customerdata[c] = 
			{
				need = (math.random(1,100)+30)/100,
				bal = 25 + math.random(1,25),
				income = math.random(2,5)
			}
	end
end

local function fixprice()
	lastprice = price
	price*= (supply+demand-supplychange)/supply
	change = (price-lastprice)/lastprice
end
local function RunCustomers()
	for _, customer in pairs(customerdata) do
		customer.bal += customer.income*eco
		customer.need += 1
		if math.random(1,35) < customer.need+popularity then
			if customer.need > 2 then
				customer.need-= 2
			else
				customer.need-= 1
			end
			if supply > 1 and customer.bal > price then
				supply-=1
				customer.bal-=price
				compbal.Value+=price
				popularity+=1/2500
				else demand +=1
			end
		end
	end
end

local function produce()
	for _, factory in pairs(production) do
		compbal.Value -= factory.cost*(1-eco)
		liability.Value += factory.cost*(1-eco)
		supply+= factory.amount
	end
	if demand > 1 and compbal.Value> newfactorycost then
		compbal.Value -= newfactorycost
		liability.Value -= newfactorycost
		assets.Value += newfactorycost
		table.insert(production,
			{cost=1,amount=math.random(60,90)/100}
		)
	end
	if assets.Value < liability.Value and #production > 1 then
		production[1] = nil
	end
end


GenerateCustomerData()

clock.Event:Connect(function()
	local ran = math.random(1,15)
	if ran == 12 then
		popularity+= 10
	end
	assets.Value = (supply * costproduction) + compbal.Value
	fixprice()
	RunCustomers()
	fixprice()
	produce()
	demand = 0
	popularity*= .9
	local noise = math.noise(x/10,0,0)
	local crash = math.random(1,250)
	local c = 0
	x+=1
	if crash == 142 then
		c = .2
	end
	eco = (((noise+1)/2)/2)+.5 - c
end)

I’m not an expert at this, so if anyone who has a greater knowledge of markets sees this, please correct me on any miscalculations/flaws!

1 Like

I’m back 6 months later, and for anyone wondering I’ve completely scrapped the system mentioned above.

My new system works like this:

local function RunCustomers()
	local trueprice = stock.price.Value * (1+tax.Value/100)
	local desireability = ((wealthValue*avgPercent) / trueprice)^2
	
	local WhomKnow = math.floor(sims * (comp.popularity.Value) / 100)
	local possiblyBuying = WhomKnow * (0.25 * desireability)
	
	local product = comp.supply.Value
	
	local defBuying = math.min(possiblyBuying, product)
	
	local totalSpent = (comp.price.Value * defBuying) / sims
	wealthValue -= totalSpent
	comp.balance.Value += comp.price.Value * defBuying
	comp.supply.Value -= defBuying
end

Variable sims hold the amount of customers in the simulation, which for my case is 1,000,000
avgPercent is the set percent that average customers would spent their wealth on the product.
popularity is a number between 0 and 100, it represents the percentage of people that know about the product
desirability is how close the product price is to the price that the customers prefer to buy at. if this is above 1, the price is lower than the desirability, if it’s below 1 then the price is higher than the desirability, the desirability acts as a boost for determining buyers.

comp.supply.Value is simply the amount of product (int) that the company sells
wealthValue is a number representing the average wealth for each sim.

This system was made in a span of 7 minutes and its not ideal, I’m going to add s&d alongside other factors to further calculate the customers.

1 Like