Small Stock Market Simulation

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Small Stock Market Simulation

Post by KristopherWindsor »

I just made this today, and it's not too fun to play, so it is therefore an "experimental" project. :-)

To play, use the up and down arrow keys to select a stock or stock index, then press the Space Bar to buy or sell it.
Press Enter to advance to the next year.

The goal of the game is to get a lot of money, equivalent to 10x what you started with, with a 12% increase yearly.
I played a few times and once won in 24 years, since one company was annually getting 30% increases or more.

You will notice a line graph developing for each stock.
This shows the growth rate (profit / old value).

I won't try to explain the formula for stock profits / losses, but essentially, there are a few factors that affect the economy, and each stock is affected by those factors to varying levels.
The values of the company stock and the velocity of those values on one year are fairly predictable based on the values of the previous year, but the acceleration of the values is random (within a limited range).
Theoretically all stocks have potential to be the most valuable, although in my tests only a few of them ever became the most valuable.

Companies.txt:

Code: Select all

OS Inc

	embargo	= .1
	climate = 0
	resource = 0

	competition = .8
	market = tech
	random = .4
	start = 45

iMP3

	embargo	= .4
	climate = .1
	resource = .2

	competition = .7
	market = tech
	random = .7
	start = 12

We Own the Web

	embargo	= 0
	climate = 0
	resource = 0

	competition = .5
	market = tech
	random = .9
	start = 8

FB Coders Anonymous

	embargo	= 0
	climate = 0
	resource = 0

	competition = .4
	market = tech
	random = .2
	start = 10

Creative Labs, Huh?

	embargo	= .3
	climate = .3
	resource = .6

	competition = .6
	market = tech
	random = .3
	start = 32

Farmers Incorporated

	embargo	= .4
	climate = .9
	resource = .6

	competition = .3
	market = food
	random = .8
	start = 15

The Giants Who Sell Food

	embargo	= .2
	climate = .6
	resource = .4

	competition = 1
	market = food
	random = .4
	start = 5

Jewelry Ur Mom

	embargo	= .1
	climate = 0
	resource = 0

	competition = .7
	market = luxery
	random = .2
	start = 50

Expensive Cars and Then Some

	embargo	= .8
	climate = .2
	resource = .4

	competition = .3
	market = luxery
	random = .6
	start = 35

House Builders

	embargo	= .1
	climate = .4
	resource = .6

	competition = 0
	market = housing
	random = .8
	start = 10

Gasoline Corp

	embargo	= .9
	climate = .1
	resource = 1

	competition = .3
	market = resources
	random = .4
	start = 17

Lumber Plus Copper Megastore

	embargo	= .4
	climate = .1
	resource = 1

	competition = .2
	market = resources
	random = .5
	start = 12

Furniture for Executives

	embargo	= .2
	climate = .1
	resource = .2

	competition = .7
	market = junk
	random = .1
	start = 20

Buy It Online

	embargo	= .1
	climate = .1
	resource = .1

	competition = .7
	market = junk
	random = .7
	start = 42
Stock Market source:

Code: Select all

' Stock Market Simulation! v1.0
' (C) 2008 Innova and Kristopher Windsor

#include once "fbgfx.bi"

#define crash(t) print t: sleep: system

#macro update_success(x, dx)
  dx += (Rnd - Rnd) / 3
  If dx > 1 Then dx = 1
  If dx < 0 Then dx = 0
  x += (dx - .5) / 3
  If x > 1 Then x = 1
  If x < 0 Then x = 0
#endmacro

Const screenx = 800, screeny = 600, true = -1, winfactor = 1.12
Const company_max = 100, factor_max = 3, market_max = 20

Type market_type_alias As market_type

Type company_type
  Declare Sub update ()
  
  As String title
  As String market_title
  As market_type_alias Ptr market
  
  As Double factors(1 To factor_max)
  
  As Double competition
  As Double rand
  
  'for competition
  As Double success
  As Double success_d
  
  As Double start
  As Double value_true_p
  As Double value_true
  As Double value 'affected by speculation
  As Double value_p
  As Double change
  
  As Double sold
  
  As fb.image Ptr graphic
End Type

Type factor_type
  As Double value
  As Double value_d
End Type

Type market_type
  Const mcompany_max = 10
  
  Declare Sub update ()
  
  As String title
  
  As Double success
  As Double success_d
  
  As Double value
  As Double value_p
  As Double change
  
  As Integer mcompany_total
  As company_type Ptr mcompany(1 To mcompany_max)
  
  As Double sold
  
  As fb.image Ptr graphic
End Type

Dim Shared As Integer company_total, frame_total, market_total, quit
Dim Shared As Double cash
Dim Shared As company_type company(1 To company_max)
Dim Shared As factor_type factor(1 To factor_max)
Dim Shared As market_type market(1 To market_max)

Declare Sub control ()
Declare Sub finish ()
Declare Sub initialize ()
Declare Sub update ()

Screenres screenx, screeny, 32
initialize()

Do
  frame_total += 1
  
  update()
  control()
Loop Until quit Or cash > 50000 * winfactor ^ frame_total Or frame_total >= 100

finish

Sub company_type.update ()
  Dim As Double profit
  
  If value <= 0 Then Exit Sub
  
  update_success(success, success_d)
  
  profit += market -> success
  For i As Integer = 1 To factor_max
    profit += (factor(i).value - .5) * factors(i)
  Next i
  profit += (success - .5) * competition
  
  If rand / 5 > Rnd Then profit += Rnd * 2 * Sgn(Rnd - Rnd)
  
  value_true_p = value_true
  value_true = value_true_p * (profit + 5) / 5
  
  value_p = value
  value = value_true_p + (value_true - value_true_p) * 1.5
  
  Line graphic, (frame_total * 8 - 8, screeny * .25 * (1 - change / value_p)) - (frame_total * 8, screeny * .25 * (1 - (value - value_p) / value)), &HFFFFFFFF
  change = value - value_p
  
  If value <= 0 Then sold = 0
End Sub

Sub control ()
  Static As Integer s
  
  Dim As Integer smax
  Dim As String k
  
  If s = 0 Then s = 1
  Do
    Select Case k
    Case Chr(255, 72)
      If s > 1 Then s -= 1
    Case Chr(255, 80)
      If s < smax Then s += 1
    End Select
    
    smax = 0
    Screenlock
    Cls
    Color &HFFFFFFFF
    Print "Stockmarket! Year " & frame_total
    Print "[Space] to buy or sell, [Enter] for the next year"
    Print "Cash: " & Int(cash)
    Print "Goal: " & Int(50000 * winfactor ^ frame_total)
    Print
    Print "Stocks                          Value        Change       Purchased"
    Print
    For i As Integer = 1 To company_total
      With company(i)
        If .value <= 0 Then
          Print
        Else
          smax += 1
          If s = smax Then
            Put (0, screeny / 2), .graphic, trans
            Color &HFF8888FF
            If k = " " Then
              If .sold = 0 Then
                .sold = Int(cash / .value)
                cash -= .value * .sold
              Else
                cash += .value * .sold
                .sold = 0
              End If
            End If
          Else
            Color &HFFFFFFFF
          End If
          Print Left(.title & Space(32), 32) & "$" & Left(Int(.value) & Space(12), 12) & "$" & Left(Int(.change) & Space(12), 12) & "Shares: " & .sold
        End If
      End With
    Next i
    Color &HFFFFFFFF
    Print
    Print "Share Indexes:"
    Print
    For i As Integer = 1 To market_total
      With market(i)
        If .value <= 0 Then
          Print
        Else
          smax += 1
          If s = smax Then
            Put (0, screeny / 2), .graphic, trans
            Color &HFF8888FF
            If k = " " Then
              If .sold = 0 Then
                .sold = Int(cash / .value)
                cash -= .value * .sold
              Else
                cash += .value * .sold
                .sold = 0
              End If
            End If
          Else
            Color &HFFFFFFFF
          End If
          Print Left(.title & Space(32), 32) & "$" & Left(Int(.value) & Space(12), 12) & "$" & Left(Int(.value - .value_p) & Space(12), 12) & "Shares: " & .sold
        End If
      End With
    Next i
    Screenunlock
    
    Sleep 50, 1
    k = Inkey()
  Loop Until k = Chr(27) Or k = Chr(13) Or cash > 50000 * winfactor ^ frame_total
  
  If k = Chr(27) Then quit = true
End Sub

Sub finish ()
  Color &HFF8888FF
  Print
  Print "You have $" & Int(cash) & " cash!"
  
  If cash > 50000 * winfactor ^ frame_total Then
    Print "You won in " & frame_total & " years!!!"
  Elseif frame_total >= 100 Then
    Print "You lose and are $" & Int(50000 * winfactor ^ frame_total - cash) & " short!!!"
  Else
    Print "Goodbye!"
  End If
  
  For i As Integer = 1 To company_total
    imagedestroy(company(i).graphic)
  Next i
  For i As Integer = 1 To market_total
    imagedestroy(market(i).graphic)
  Next i
  
  While Len(Inkey) > 0: Sleep 200, 1: Wend
  Sleep 2000, 1
  While Len(Inkey) > 0: Sleep 200, 1: Wend
  Print
  Print "Press key to close..."
  Sleep
  
  System
End Sub

Sub initialize ()
  Dim As Integer x
  Dim As Double l1v
  Dim As String l, l0, l1
  
  Randomize Timer
  
  cash = 5000
  company_total = 0
  market_total = 0
  
  Open "companies.txt" For Input As #1
  While Not Eof(1)
    Line Input #1, l
    l = Trim(l, Any Chr(9, 32))
    
    If Len(l) > 0 Then
      If Instr(l, "=") > 0 Then
        'set properties
        If company_total = 0 Then crash("No company was specified before property assignment!")
        x = Instr(l, "=")
        l0 = Ucase(Trim(Left(l, x - 1), Any Chr(9, 32)))
        l1 = Ucase(Trim(Mid(l, x + 1), Any Chr(9, 32)))
        l1v = Val(l1)
        With company(company_total)
          Select Case l0
          Case "EMBARGO"
            .factors(1) = l1v
          Case "CLIMATE"
            .factors(2) = l1v
          Case "RESOURCE"
            .factors(3) = l1v
          Case "COMPETITION"
            .competition = l1v
          Case "RANDOM"
            .rand = l1v
          Case "MARKET"
            .market_title = l1
          Case "START"
            .start = l1v
            .value_true_p = l1v
            .value_true = l1v
            .value = l1v
          Case Else
            crash("Bad company property: " & l0)
          End Select
        End With
      Else
        'new company
        company_total += 1
        If company_total > company_max Then crash("Too many companies!")
        With company(company_total)
          .title = l
          .success = .5
          .success_d = .5
          .sold = 0
        End With
      End If
    End If
  Wend
  Close #1
  
  'setup markets now that companies are loaded
  For i As Integer = 1 To company_total
    x = 0
    For i2 As Integer = 1 To market_total
      If market(i2).title = company(i).market_title Then x = i2
    Next i2
    If x = 0 Then
      market_total += 1
      If market_total > market_max Then crash("Too many markets!")
      x = market_total
    End If
    
    company(i).market = @market(x)
    
    With market(x)
      If .mcompany_total = 0 Then
        .title = company(i).market_title
        .success = .5
        .success_d = .5
        .value = 1
      End If
      
      .mcompany_total += 1
      If .mcompany_total > .mcompany_max Then crash("Too many companies!")
      .mcompany(.mcompany_total) = @company(i)
    End With
  Next i
  
  'initialize factors
  For i As Integer = 1 To factor_max
    With factor(i)
      .value = Rnd
      .value_d = Rnd
    End With
  Next i
  
  'gfx
  For i As Integer = 1 To company_total
    company(i).graphic = imagecreate(screenx, screeny / 2)
    Line company(i).graphic, (0, screeny / 4) - Step(screenx - 1, 0), &HFF888888
  Next i
  For i As Integer = 1 To market_total
    market(i).graphic = imagecreate(screenx, screeny / 2)
    Line market(i).graphic, (0, screeny / 4) - Step(screenx - 1, 0), &HFF888888
  Next i
End Sub

Sub market_type.update ()
  Dim As Integer l
  
  If value <= 0 Then Exit Sub
  
  update_success(success, success_d)
  value_p = value
  value = 0
  
  l = 0
  While l < mcompany_total
    l += 1
    mcompany(l) -> update()
    If mcompany(l) -> value > 0 Then value += mcompany(l) -> value
  Wend
  
  Line graphic, (frame_total * 8 - 8, screeny * .25 * (1 - change / value_p)) - (frame_total * 8, screeny * .25 * (1 - (value - value_p) / value)), &HFFFFFFFF
  change = value - value_p
End Sub

Sub update ()
  Dim As Integer l
  
  'factors
  For i As Integer = 1 To factor_max
    With factor(i)
      update_success(.value, .value_d)
    End With
  Next i
  
  'markets (also updates companies)
  For i As Integer = 1 To market_total
    market(i).update()
  Next i
End Sub
nkk_kan
Posts: 209
Joined: May 18, 2007 13:01
Location: India
Contact:

Post by nkk_kan »

thats interesting program!

just one thing...why can't we control the number of shares we buy? =p
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

nkk_kan wrote:just one thing...why can't we control the number of shares we buy? =p
Go all in!!!
That's the best way to play, anyway.
If you want to avoid the occasionally stock crashes, you can invest in a share index, which is the total value of all stocks in a particular market. ;-)
williamgeorge
Posts: 1
Joined: Feb 13, 2009 23:42

Re:Small Stock Market Simulation

Post by williamgeorge »

(spam)
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Post by vdecampo »

What is this, a spam/ad bot? Go sell your wares on another forum. This is for people who want to learn and share programming in FreeBASIC.

-Vince
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

Spam. :o
stock-market
Posts: 1
Joined: Dec 07, 2009 13:18

hi

Post by stock-market »

really good experiment
BigBaddie
Posts: 40
Joined: Oct 10, 2009 10:08
Location: Space
Contact:

Post by BigBaddie »

Nice work!
integer
Posts: 410
Joined: Feb 01, 2007 16:54
Location: usa

Post by integer »

very nice.
This looks like a great tool for high school students.
Interesting & teaches at the same time.
Good work.
Dr_D
Posts: 2453
Joined: May 27, 2005 4:59
Contact:

Post by Dr_D »

Now all you need is some nicely done gfx of business guys bleeding from the eyes while frantically waving pieces of paper in the air and it'll be great! :p
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

Thanks. :)
Actually, I sort of forgot I wrote this, but I guess a person named "stock-market" would be expected to comment in this thread. :p
Post Reply