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:
- Lines 10–30: Initialisation — sets a system flag, defines the rounding function, then jumps to the setup block.
- Lines 40–80: Subroutines. Line 40 (
rt) right-justifies and printsR$. Lines 60–80 (FGS) format a floating-point value inGto two decimal places and store it inR$. - Lines 90–110: Game-start wait loop; reads the trend value and waits for the player to press S.
- Lines 120–570: Main display loop — shows stock prices, portfolio summary, cash, total assets, and brokerage fee.
- Lines 600–850: Transaction input and validation — reads share quantities, checks for overselling and overspending, applies trades.
- Lines 860–1070: Weekly report — prints the portfolio table, then handles dividends (R<0.15) and stock splits (R≥0.93).
- Lines 1080–1470: Price-update subroutine — advances both market “players” (buy/sell signals), calculates per-stock price changes, and periodically randomises the trend.
- Lines 1480–1510: Trend reset subroutine.
- Lines 1520–1600: End-game summary.
- 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 FGSandGO SUB rtuse 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 Qrounds to the nearest penny usingINT(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 byINT PI=3) for the price, then stepFby 6. - Market trend variable
A: A floating-point trend is computed each period asFN 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 usingINT PI - 6*RND + H5(≈ −3 to +3). - Buy/sell signal mechanism (lines 1080–1360): Two “player” slots (
S/PandS2/P2) store a target stock index and a countdown. When a player’s counter reaches their target stock, aBCbias 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 isP(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 andS(N)is set toH0(100 cents = $1.00), preventing bankruptcy of a stock. - SAVE with auto-run (line 1870):
SAVE "ST/EX" LINE PIsaves the program withLINE 3as the auto-start line — a slightly unusual choice since line 3 does not exist; the effective auto-start will be the next line, 10.
Content
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 P<A1 THEN GO TO 1320
1290 IF INT (S+H5)<>INT (N+H5) THEN GO TO 1360
1300 LET BC=-A1
1310 LET P=A0
1320 IF P2<A1 THEN GO TO 1360
1330 IF INT (S2+H5)<>INT (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<A1 THEN GO SUB 1480
1470 RETURN
1480 LET TR=VAL A$
1490 LET A=FN Q(RND/T0)
1500 IF RND<=H5 THEN RETURN
1510 LET A=-A: RETURN
1520 CLS
1530 PRINT ,,"AT THE END OF ";WK;" WEEKS TRADING"
1540 IF D<1E4 THEN LET N=A0
1550 IF NOT N THEN PRINT '"YOU HAVE LOST $";: LET G=1E4-D
1560 IF N THEN PRINT '"YOU HAVE EARNED $";: LET G=D-1E4
1570 GO SUB FGS
1580 PRINT R$
1590 PRINT '"ON THE "; FLASH A1;"""STOCK EXCHANGE"""; FLASH A0;".",'"HOPE IT'S BEEN FUN, ";N$;"."
1600 PRINT ,,"LET'S DO THIS AGAIN SOMETIME.": STOP
1610 DATA SGN PI,NOT PI,2,100,10,5,.5,40,A1,60,"AAA135BBB090CCC120DDD085EEE115",A0,F,F,F,F,F,F,F,F,1E4
1620 CLS : READ A1,A0,A2,H0,T0,A5
1630 PRINT AT T0,A5;"The "; FLASH A1;"""STOCK EXCHANGE"""; FLASH A0''" a simulation"
1640 DIM I$(A5,INT PI)
1650 DIM O$(A2): DIM S(A5)
1660 PRINT AT 15,A0;"A ""PEH SOFTWARE"" Special"
1670 READ H5,RT,F,FGS,A$
1680 FOR N=A1 TO A5
1690 LET I$(N)=A$(F TO F+INT PI)
1700 LET S(N)=ABS INT VAL A$(INT PI+F TO F+A5)
1710 LET F=F+6: NEXT N
1720 DIM P(A5): DIM T(A5)
1730 DIM C(A5)
1740 READ F,BF,D1,P,TT,D2,P2,WK,EA,C
1750 LET A=FN Q(RND/T0)
1760 INPUT "Please introduce yourself",N$
1770 LET A$="INT (RND*4.99)+1"
1780 PRINT #a1;"Do you need directions (Y OR N)": PAUSE a0
1790 IF INKEY$="N" THEN GO TO 90
1800 CLS
1810 PRINT '"Welcome to ""STOCK EXCHANGE""",TAB 16-(LEN N$/A2);N$;"."
1820 PRINT "Your current account balance is $10,000. You may buy or sell","stocks. A table of available","stock, their prices, and the no.of shares in your portfolio will be printed. With this are the"
1830 PRINT "initials used for each stock. Here you indicate a transaction.To buy a stock input XXX, XXX=the no. of shares you wish to"
1840 PRINT "buy. To sell Input -XXX, XXX= the no. of shares you wish to sell. A 1% brokerage fee will beautomatically charged to your","account"
1850 PRINT "GOOD LUCK ";N$;"."
1860 GO TO 90
1870 SAVE "ST/EX" LINE PI
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
