--- title: "Stock Exchange" id: 64741 type: "computer_media" slug: "stock-exchange" url: "http://localhost/computer_media/stock-exchange/" markdown_url: "http://localhost/computer_media/stock-exchange.md" published_at: "2026-03-07T14:41:04+00:00" modified_at: "2026-03-30T21:45:51+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/03/stock-exch-simul.png" excerpt: "Start with $10,000 and trade five stocks over weekly rounds, watching for dividends and splits in this BASIC market simulation." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Paul Holmgren" slug: "paul-holmgren" taxonomy: "indiv" url: "http://localhost/indiv/paul-holmgren/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 64715 title: "Miscellaneous Programs" type: "computer_media" url: "http://localhost/computer_media/miscellaneous-programs/" media_type: "Program" programmers: - name: "Paul Holmgren" slug: "paul-holmgren" taxonomy: "indiv" url: "http://localhost/indiv/paul-holmgren/" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/03/stock-exch-simul.png" media_type_tags: "Game" --- # Stock Exchange This program implements a five-stock market simulation called “STOCK EXCHANGE” where the player starts with $10,000 cash and buys or sells shares in five fictitious companies (AAA, BBB, CCC, DDD, EEE) over multiple trading weeks. Stock prices fluctuate each week based on a market trend variable, random factors, and occasional special events such as dividend declarations and stock splits. A 1% brokerage fee is levied on each transaction, and the game ends when the player chooses to stop, reporting net gain or loss. The program uses several compact numeric aliases (A0, A1, A2, A5, H0, H5, T0) loaded from a DATA statement to save memory and speed up execution, and employs a custom DEF FN for two-decimal-place rounding. *** ## Program Structure The program is divided into functional regions: 1. **Lines 10–30:** Initialisation — sets a system flag, defines the rounding function, then jumps to the setup block. 2. **Lines 40–80:** Subroutines. Line 40 (`rt`) right-justifies and prints `R$`. Lines 60–80 (`FGS`) format a floating-point value in `G` to two decimal places and store it in `R$`. 3. **Lines 90–110:** Game-start wait loop; reads the trend value and waits for the player to press S. 4. **Lines 120–570:** Main display loop — shows stock prices, portfolio summary, cash, total assets, and brokerage fee. 5. **Lines 600–850:** Transaction input and validation — reads share quantities, checks for overselling and overspending, applies trades. 6. **Lines 860–1070:** Weekly report — prints the portfolio table, then handles dividends (R<0.15) and stock splits (R≥0.93). 7. **Lines 1080–1470:** Price-update subroutine — advances both market “players” (buy/sell signals), calculates per-stock price changes, and periodically randomises the trend. 8. **Lines 1480–1510:** Trend reset subroutine. 9. **Lines 1520–1600:** End-game summary. 10. **Lines 1610–1870:** Data and initialisation — reads constants, stock names/prices, dimensions arrays, handles the optional instructions screen, and saves the program. ## Numeric Alias Constants All frequently used literals are loaded from `DATA` at lines 1620–1670 into short variable names. This is a classic Spectrum BASIC memory and speed optimisation because a stored numeric value is accessed faster than re-parsing a literal token each time. | Variable | Value | Meaning | | --- | --- | --- | | `A1` | SGN PI = 1 | Integer one | | `A0` | NOT PI = 0 | Integer zero | | `A2` | 2 | Integer two | | `H0` | 100 | Scaling factor (×100 for 2 d.p.) | | `T0` | 10 | Trend divisor / period | | `A5` | 5 | Number of stocks | | `H5` | 0.5 | Rounding offset / half | | `RT` | 40 | Line number alias used in `GO SUB rt` | | `FGS` | 60 | Line number alias used in `GO SUB FGS` and `PAUSE fgs` | `INT PI` (= 3) is used directly inline instead of a variable, serving as the number of ticker-symbol characters per stock. ## Notable Techniques - **Indirect subroutine calls via numeric variables:**`GO SUB FGS` and `GO SUB rt` use the values 60 and 40 stored in those variables. This is valid Spectrum BASIC and also makes the code self-documenting by naming the target. - **Two-decimal-place formatting (lines 60–80):** The `DEF FN Q` rounds to the nearest penny using `INT(H0*Z+H5)/H0`. The string formatter at lines 60–70 separately extracts integer and fractional parts, zero-pads the fractional part using `("0"+R$)(LEN R$ TO )`, and concatenates with a decimal point. - **Packed DATA string for stock initialisation (line 1610):** All five ticker symbols and their starting prices are packed into a single string `"AAA135BBB090CCC120DDD085EEE115"`. Lines 1690–1710 slice it with fixed 6-character strides: 3 chars for the symbol and 3 chars (offset by `INT PI`=3) for the price, then step `F` by 6. - **Market trend variable `A`:** A floating-point trend is computed each period as `FN Q(RND/T0)` (roughly 0–0.1) and randomly negated. Each stock’s weekly change at line 1360 blends this trend with a uniform random component and an integer-level noise term using `INT PI - 6*RND + H5` (≈ −3 to +3). - **Buy/sell signal mechanism (lines 1080–1360):** Two “player” slots (`S`/`P` and `S2`/`P2`) store a target stock index and a countdown. When a player’s counter reaches their target stock, a `BC` bias of ±1 is applied to that stock’s change, simulating market participants. - **Stock split (lines 1040–1060):** When `R≥0.93`, price is halved (`S(I)*H5`) and holdings doubled (`P(I)*A2`), correctly preserving portfolio value. - **Dividend payment (lines 1010–1020):** Dividend rate is `R*4+H5` (0.5–1.1 per share); total paid is `P(I)*(R*4+H5)` added to cash. - **`POKE 23658,8` (line 10):** Sets the FLAGS2 system variable bit to enable CAPS LOCK, ensuring uppercase input throughout without requiring the player to activate it manually. - **Random seed extraction (line 990):**`VAL ((STR$ RND)( TO 4))` takes the first four characters of the RND string representation to obtain a 0–1 value with only two significant digits, used to drive the dividend/split event check in a slightly flattened distribution. - **Zero-price floor (lines 1390–1420):** If a stock price reaches zero or below after applying the change, `C(N)` is zeroed and `S(N)` is set to `H0` (100 cents = $1.00), preventing bankruptcy of a stock. - **SAVE with auto-run (line 1870):**`SAVE "ST/EX" LINE PI` saves the program with `LINE 3` as the auto-start line — a slightly unusual choice since line 3 does not exist; the effective auto-start will be the next line, 10. ## Source Code ``` 10 POKE 23658,8 20 DEF FN Q(Z)=INT (H0*Z+H5)/H0 30 GO TO 1610 40 PRINT TAB 32-LEN R$;R$: RETURN 60 LET X=INT (ABS G+.005)*SGN G: LET B=INT ((ABS (G-X)*H0)+.5) 70 LET R$=STR$ B: LET R$=STR$ X+"."+("0"+R$)(LEN R$ TO ) 80 RETURN 90 LET TR=VAL A$ 100 PRINT #A1;" INPUT ""S"" to start.": PAUSE a0 110 IF INKEY$<>"S" THEN GO TO 110 120 IF RND>H5 THEN GO TO 140 130 LET A=-A 140 CLS : GO SUB 1080 150 PRINT '"Stock"," INT. $/Share--------------------------------" 160 LET G=S(A1) 170 PRINT "Alpha Assoc. AAA"; 180 GO SUB FGS: GO SUB rt 190 LET G=S(A2) 200 PRINT "B & B Bakery BBB"; 210 GO SUB FGS: GO SUB rt 220 LET G=S(INT PI) 230 PRINT "C/C Bros. Coal Co. CCC"; 240 GO SUB FGS: GO SUB rt 250 LET G=S(4) 260 PRINT "DD Auto Man. Inc. DDD"; 270 GO SUB FGS: GO SUB rt 280 LET G=S(A5) 290 PRINT "E & E Electric EEE"; 300 GO SUB FGS: GO SUB rt 310 LET TA=EA: LET EA=A0: LET SA=A0 320 FOR N=A1 TO A5 330 LET EA=EA+S(N) 340 LET SA=SA+S(N)*P(N): NEXT N 350 LET EA=FN Q(EA/A5) 360 LET NC=FN Q(EA-TA) 370 LET D=SA+C 380 PRINT ,,"Aver.:";EA;TAB 15; 390 IF F THEN PRINT "Net Change:";NC 400 PRINT ,,N$;":" 410 LET SA=FN Q(SA) 420 LET G=SA 430 PRINT "Stock Assets=$"; 440 GO SUB FGS: GO SUB rt 450 LET C=FN Q(C) 460 LET G=C 470 PRINT "Cash assets=$"; 480 GO SUB FGS: GO SUB rt 490 LET D=FN Q(D) 500 LET G=D 510 PRINT "Total assets=$"; 520 GO SUB FGS: GO SUB rt 530 LET BF=FN Q(BF) 540 LET G=BF 550 PRINT "Brokerage fee=$"; 560 GO SUB FGS: GO SUB rt 570 IF NOT F THEN PAUSE VAL "325": GO TO 600 580 PRINT #A1;"Hit -ENTER- OR ""N"" TO STOP ": PAUSE A0 590 IF INKEY$="N" THEN GO TO 1520 600 FOR N=A1 TO A5 610 INPUT INK 4;" INPUT No. of shares you wish to trade in ";(I$(N));"? "; LINE m$: REM T(N) 620 IF m$<>"" THEN LET t(n)=VAL m$ 630 IF m$="" THEN LET t(n)=0 640 NEXT N 650 PRINT #a1;"Processing transaction": PAUSE fgs 660 LET DP=A0: LET DS=A0 670 FOR N=A1 TO A5 680 LET T(N)=INT (T(N)+H5) 690 IF T(N)<=A0 THEN GO TO 720 700 LET DP=DP+T(N)*S(N) 710 GO TO 760 720 LET DS=DS-T(N)*S(N) 730 IF -T(N)<=P(N) THEN GO TO 760 740 PRINT #1;"You don't have that much to sell": PAUSE 300 750 GO TO 600 760 NEXT N 770 LET TT=DP+DS 780 LET BF=FN Q(.01*TT) 790 LET CT=C-DP-BF+DS 800 IF CT>=A0 THEN GO TO 830 810 PRINT #1;"You have tried to over spend by:";-CT 820 PAUSE 300: GO TO 600 830 LET C=CT 840 FOR N=A1 TO A5 850 LET P(N)=P(N)+T(N): NEXT N 860 CLS 870 GO SUB 1080 880 LET WK=WK+A1 890 PRINT " STOCK EXCHANGE WEEK ";WK,'"STK. $/SHR. HDS. $ VALUE CHANGE................................" 900 FOR N=A1 TO A5 910 LET G=S(N): GO SUB FGS 920 PRINT AT INT PI+N,A0;I$(N);TAB 11-LEN R$;R$;TAB 12;P(N); 930 LET G=S(N)*P(N) 940 GO SUB FGS 950 PRINT TAB 24-LEN R$;R$;TAB 26;C(N) 960 NEXT N 970 LET F=A1 980 PRINT 990 LET R=VAL ((STR$ RND)( TO 4)) 1000 LET I=INT (RND*A5)+A1 1010 IF R<.15 THEN PRINT I$(I);" Declares dividends of $";R*4+H5;"/share" 1020 IF R<.15 THEN LET C=C+P(I)*(R*4+H5) 1030 IF R<.93 THEN GO TO 310 1040 PRINT I$(I);" splits stock." 1050 LET S(I)=S(I)*H5 1060 LET P(I)=P(I)*A2 1070 GO TO 310 1080 IF D1 THEN GO TO 1120 1090 LET S=VAL A$ 1100 LET D1=VAL A$ 1110 LET P=A1 1120 IF D2 THEN GO TO 1160 1130 LET S2=VAL A$ 1140 LET D2=VAL A$ 1150 LET P2=A1 1160 LET D1=D1-A1 1170 LET D2=D2-A1 1180 FOR N=A1 TO A5 1190 LET R=RND 1200 IF R>.25 THEN GO TO 1220 1210 LET R=.25: GO TO 1270 1220 IF R>H5 THEN GO TO 1240 1230 LET R=H5: GO TO 1270 1240 IF R>.75 THEN GO TO 1260 1250 LET R=.75: GO TO 1270 1260 LET R=A0 1270 LET BC=A0 1280 IF PINT (N+H5) THEN GO TO 1360 1300 LET BC=-A1 1310 LET P=A0 1320 IF P2INT (N+H5) THEN GO TO 1360 1340 LET BC=A1 1350 LET P2=A0 1360 LET C(N)=INT (A*S(N))+R+INT (INT PI-6*RND+H5)+BC 1370 LET C(N)=FN Q(C(N)) 1380 LET S(N)=S(N)+C(N) 1390 IF S(N) THEN GO TO 1430 1400 LET C(N)=A0 1410 LET S(N)=H0 1420 GO TO 1440 1430 LET S(N)=FN Q(S(N)) 1440 NEXT N 1450 LET TR=TR-A1 1460 IF TR