Personal Portfolio Manager is a comprehensive stock investment tracking program that maintains data for up to 50 stocks (configurable via the variable `r` at line 9090), storing up to 12 buy/sell transactions per stock in a three-dimensional array `a(r,13,4)`. The program uses a cassette tape save/load system, storing stock names in a string array `a$()` and numeric data in `a()`, with the stock count and last-update date encoded in the final array elements. Financial calculations include unrealized gain/loss, percentage gain/loss, average cost per share using a running weighted average, and portfolio totals; results are formatted to a specified number of decimal places via a dedicated subroutine at line 200. A bar-graph display at lines 2320–2373 renders individual stock and overall portfolio percentage gain/loss as pixel-drawn horizontal bars with audio feedback, using BEEP pitch to sonify the drawing process. Error handling uses ON ERR to trap tape load/save failures and system errors, with a RESET fallback at line 9900.
Program Analysis
Program Structure
The program is organized into clearly separated functional blocks, each accessed via the main menu at line 610. Initialization is split between two subroutines: line 9000 sets up all variables and dimensions arrays, while line 8000 displays a title screen with an animated line-art graphic. The main dispatch loop sits at line 610–790, branching to numbered modules for each menu option.
| Line Range | Function |
|---|---|
| 1–10 | Bootstrap: calls init subroutines, jumps to main menu |
| 100–190 | Utility subroutines: find last transaction, format date string |
| 200–330 | Number formatting to d decimal places |
| 350–420 | Input validation: check for numeric characters |
| 500–570 | Date string cleanup (strip slashes) |
| 610–790 | Main menu display and dispatch |
| 1000–1430 | Stock entry: new stock, additional purchases, sales |
| 2000–2650 | Individual stock performance report with bar graph |
| 3000–3220 | Portfolio-wide performance summary with bar graph |
| 4010–4090 | Current price update for all active holdings |
| 5005–5125 | Save file to tape (two DATA blocks) |
| 6005–6060 | Load file from tape |
| 8010–8180 | Title screen with animated stock-chart graphic |
| 9000–9140 | Variable and array initialization |
| 9900–9930 | Error handler chain |
Data Model
The core data structure is the three-dimensional numeric array a(r,13,4), where the first dimension indexes the stock (up to r=50), the second indexes the transaction slot (1–12) plus a running-totals slot at index 13, and the third holds: (1) dollar amount, (2) number of shares, (3) transaction date as a packed integer, (4) price per share. Stock names are held in a$(r+3, l) where l=12 characters, with a$(r+1) storing the stock count and a$(r+2) storing the last-update date string.
The running-totals slot a(i,13,…) is updated on every transaction: element 1 accumulates total cost, element 3 accumulates total shares, element 2 is recalculated as the weighted average cost per share, and element 4 is a flag (0=active, 1=inactive/fully sold). This design avoids rescanning all transactions to compute current position.
Key BASIC Idioms
- INKEY$ polling loops: The pattern
IF INKEY$="" THEN GO TO nfollowed immediately byLET q$=INKEY$is used throughout for single-keypress menu input without requiring ENTER. - Decimal formatting subroutine (line 200): Sets
dbefore calling; rounds viaINT(x*10^d+.5)/10^d, converts to string, then appends trailing zeros to reach exactlyddecimal places. The variableoreturns the length of the integer part for right-justification withTAB(n-o). - Date storage as packed integer: Dates are stored as 6-digit integers (YYMMDD), then unpacked by the formatting code at lines 160–190 into MM/DD/YY display form by slicing pairs of characters with
STEP -2. - VAL a$(r+1) for stock count persistence: The integer
i(next free stock slot) is serialized into the string array before saving and restored withLET i=VAL a$(r+1)after loading. - Numeric input character-by-character: Lines 1085–1170 build input string
s$one keypress at a time, calling the validation subroutine at line 350 on each character, allowing backspace correction (DELETE key, code 12) and auto-inserting slash separators for date fields.
Financial Logic
Sales are recorded as negative dollar amounts and negative share counts. The sale entry path (lines 1400–1430) checks that the requested number of shares does not exceed the current holding in a(i,13,3), with a tolerance comparison that rounds both values to three decimal places to avoid floating-point false mismatches. When the entire position is sold, element 4 of the totals slot is set to 1, marking the stock inactive. The inactive flag suppresses the stock from current price updates (line 4030) and portfolio value totals (line 3053), while still allowing viewing of historical data.
Bar Graph Display
Individual stock (lines 2320–2342) and portfolio (lines 2362–2373) percentage gain/loss are rendered as pixel-wide vertical bars drawn with PLOT/DRAW from a center axis at pixel x=128. Gains extend right in the default ink color; losses extend left drawn in INK 2 (red). The scale is ±100%, mapped to ±111 pixels. Both gain bars can appear simultaneously on screen when reporting an individual inactive stock alongside the portfolio total. Each pixel column is accompanied by a BEEP whose pitch is derived from the column position, creating an ascending tone for gains and a mapped tone for losses.
Error Handling
Line 9000 installs an ON ERR GO TO 9900 handler before any file or array operations. The handler at 9900 chains: first attempts RESET (line 9900), then pauses, reinstalls itself, and finally falls through to ON ERR CONTINUE at line 9930. This multi-level chain is intended to recover gracefully from tape errors without crashing the program entirely.
Save/Load Architecture
The file is saved as two separate named DATA blocks: "names" for the string array a$() and "data" for the numeric array a(). Lines 5064 unconditionally jumps over the VERIFY block at lines 5065–5100 with a GO TO/REM construct, meaning the verify feature is present in the code but disabled at runtime. On a fresh portfolio start after saving, line 5115 uses RESTORE before GO TO 1 to re-read the DATA statements for b$() prompt strings.
Anomalies and Notes
- Line 1025 references
GO TO 10(notGO TO 600) to return to the main menu, which is consistent with line 10 containingGO TO 600. - Line 730 uses a double colon (
::) as a statement separator afterLET uf1=0, which is valid syntax. - The title screen at line 8050 displays “T/S 2000” as the platform identifier and line 8060 shows an author name — both are part of the splash screen strings in the program listing.
- The variable
lis set to 12 at line 9100 and is reused as both the string array column width and the maximum number of transactions per stock, which are coincidentally equal but logically distinct roles. - Line 2085 re-uses the label for the
uf2=1input prompt (GO TO 2075) when an out-of-range number is entered, which correctly loops back to the add-to-stock prompt regardless of which transaction mode is active.
Content
Image Gallery
Source Code
1 GO SUB 9000
5 GO SUB 8000
7 LET df=0: LET puf=0
9 DIM c(r)
10 GO TO 600
110 FOR y=1 TO 12
120 IF a(q,y,1)=0 THEN RETURN
130 NEXT y: RETURN
160 LET e$=STR$ d
165 IF LEN e$=5 THEN LET e$="0"+e$
170 LET d$=""
175 FOR m=6 TO 2 STEP -2
180 LET d$=e$(m-1 TO m)+d$
185 IF m>2 THEN LET d$="/"+d$
190 NEXT m: RETURN
210 LET x=(INT (x*10^d+.5))/10^d: LET x$=STR$ x: LET z$=x$
240 FOR o=1 TO LEN x$
250 IF CODE z$=46 THEN GO TO 290
260 LET z$=z$(2 TO )
270 NEXT o
280 LET x$=x$+"."
300 FOR p=1 TO d
310 IF LEN x$(o+1 TO )=d THEN RETURN
320 LET x$=x$+"0"
330 NEXT p: RETURN
360 LET fg=0: LET x$=z$
380 FOR n=1 TO LEN x$
390 IF CODE x$>=45 AND CODE x$<=47 THEN GO TO 420
400 IF CODE x$<48 OR CODE x$>57 THEN LET fg=1: RETURN
410 LET x$=x$(2 TO )
420 NEXT n: RETURN
510 LET x$=z$: LET z$=""
530 FOR n=1 TO 8
540 IF CODE x$=47 THEN GO TO 560
550 LET z$=z$+CHR$ CODE x$
560 LET x$=x$(2 TO )
570 NEXT n: RETURN
610 BORDER 1: PAPER 5: INK 0: CLS
620 IF df=0 THEN INPUT "Please enter todays date:";g$: LET df=1
625 IF LEN g$>16 THEN LET g$=g$( TO 16)
630 BEEP .3,12: BEEP .5,9: PRINT : PRINT TAB 10; INVERSE 1;" MAIN MENU "
635 PLOT 64,158: DRAW 0,11: DRAW 118,0: DRAW 0,-11: DRAW -118,0
640 PLOT 0,150: DRAW INK 1;255,0: PLOT 0,145: DRAW INK 1;255,0
645 PRINT : PRINT : PRINT "1..Load the Stock File from Tape"
647 PLOT 0,132: DRAW INK 1;255,0
650 PRINT : PRINT "2..Enter Current Stock Prices"
660 PRINT "3..Enter Additional Purchases"
670 PRINT "4..Enter Sale of Current Stock"
680 PRINT "5..Enter a New Stock"
685 PLOT 0,92: DRAW INK 1;255,0
690 PRINT : PRINT "6..Report a Stock's Performance"
700 PRINT "7..Report Portfolio Performance"
703 PLOT 0,68: DRAW INK 1;255,0
705 PRINT : PRINT "8..Save the Stock File to Tape"
707 PLOT 0,52: DRAW INK 1;255,0: PLOT 0,44: DRAW INK 1;255,0: PLOT 0,36: DRAW INK 1;255,0: PLOT 0,31: DRAW INK 1;255,0: PLOT 0,26: DRAW INK 1;255,0
710 PRINT AT 19,0;"Today's Date:", g$: PRINT "Last Updated:",a$(r+2)
715 BEEP .1,12: PRINT AT 21,0; PAPER 1; INK 5;TAB 4;"Which do you wish to do?";TAB 32
716 IF INKEY$="" THEN GO TO 716
720 LET q$=INKEY$
725 IF i=1 AND (q$<>"1" AND q$<>"5") THEN PRINT AT 21,0; PAPER 7; INK 1; BRIGHT 1;"No file in memory<>select 1 or 5": BEEP .1,-12: GO TO 716
730 IF q$="5" THEN LET uf1=0:: LET uf2=0: LET pn=1: GO TO 1000
740 IF q$="3" THEN LET uf1=1: GO TO 1000
745 IF q$="4" THEN LET uf2=1: GO TO 1000
750 IF q$="6" THEN GO TO 2000
760 IF q$="7" THEN GO TO 3000
770 IF q$="2" THEN LET rf=0: GO TO 4000
780 IF q$="8" THEN GO TO 5000
785 IF q$="1" THEN GO TO 6000
790 BEEP .1,-12: BEEP .1,-12: PRINT AT 21,0; PAPER 2; FLASH 1;" PLEASE RE-ENTER MENU SELECTION ": GO TO 716
1012 LET ti=i
1013 IF uf1=0 AND uf2=0 THEN GO TO 1031
1022 LET ti=i: LET pg=0: GO SUB 2011: GO SUB 100: LET pn=y
1025 IF y>12 THEN BEEP .1,-12: BEEP .1,-12: PRINT INVERSE 1;"No room for more transactions w/"; FLASH 1; INVERSE 0;a$(q); INVERSE 0; FLASH 0;"Press ENTER for MAINMENU": INPUT q$: GO TO 10
1028 LET i=q
1031 BORDER 1: PAPER 1: INK 7: CLS
1034 BEEP .05,0: BEEP .05,5: BEEP .05,12
1037 IF ef=1 THEN GO TO 1060
1040 LET ef=1
1050 FOR i=1 TO r
1060 IF i>r THEN GO TO 1280
1061 IF (uf1=0 AND uf2=0) THEN PRINT AT 0,8; INK 5;"STOCK NUMBER "; BRIGHT 1; INK 3;i: GO TO 1065
1062 IF uf1=1 THEN PRINT " ADDITIONAL STOCK PURCHASES": GO TO 1064
1063 PRINT " SALE OF CURRENT EQUITY HOLDING"
1064 PRINT AT 4,15; BRIGHT 1; PAPER 7; INK 0;a$(q)
1065 PRINT AT 20,0;"Press ""r"" to return to MAIN MENUPress ""p"" to proceed "
1066 IF INKEY$="" THEN GO TO 1066
1067 IF INKEY$="r" THEN LET uf1=0: LET uf2=0: LET i=ti: GO TO 10
1068 IF INKEY$<>"p" THEN BEEP .1,12: GO TO 1065
1069 PRINT AT 20,0;TAB 31;" ": PRINT AT 21,0;TAB 31;" "
1070 IF uf1=0 AND uf2=0 THEN LET puf=0: LET pg=0
1071 FOR j=1 TO 4
1075 BEEP .1,-6: PRINT AT (j+1)*2,0;b$(j)
1077 IF (uf1=1 OR uf2=1) AND j=1 THEN PRINT AT 4,15; BRIGHT 1; PAPER 7; INK 0;a$(q): GO TO 1230
1085 LET s$=""
1090 FOR k=1 TO l
1095 IF uf2=1 AND j=2 AND k=1 THEN LET s$="-": GO TO 1160
1096 IF uf2=1 AND j=3 AND k=1 THEN LET s$="-": GO TO 1160
1100 IF INKEY$<>"" THEN GO TO 1100
1110 IF INKEY$="" THEN GO TO 1110
1115 PRINT AT 18,0;TAB 31;" "
1120 LET c$=INKEY$
1130 IF CODE c$=13 THEN GO TO 1180
1135 IF CODE c$=12 AND k>1 THEN LET k=k-2: PRINT AT (j+1)*2,17;" ": LET s$=s$( TO LEN s$-1): GO TO 1150
1139 IF j=3 AND k=1 AND a(i,pn,1)<0 THEN LET s$="-": NEXT k
1140 LET s$=s$+c$
1143 IF j=4 AND (k=2 OR k=5) THEN LET s$=s$+"/": LET k=k+1
1145 IF j<>1 THEN LET z$=c$: GO SUB 350
1147 IF fg=1 THEN PRINT AT (j+1)*2+1,13; PAPER 7; INK 2; FLASH 1;"MUST BE A NUMBER": BEEP 1,20: PAUSE 200: PRINT AT (j+1)*2+1,13;" ": LET s$=s$( TO k-1): GO TO 1100
1150 BEEP .05,0
1160 PRINT AT (j+1)*2,17; PAPER 5; INK 0;s$
1165 IF j=4 AND LEN s$=8 THEN GO TO 1185
1170 NEXT k
1180 IF j>1 AND LEN s$=0 THEN LET fg=1: GO TO 1147
1185 BEEP .1,12: PRINT AT 21,4;"Is this correct? (y/n)?"
1187 IF INKEY$="" THEN GO TO 1187
1188 PRINT AT 21,0;TAB 32
1190 IF INKEY$="n" THEN PRINT AT 21,0;TAB 31;" ": GO TO 1200
1192 IF INKEY$="y" THEN PRINT AT 21,0;TAB 31;" ": GO TO 1215
1194 GO TO 1185
1200 PRINT AT (j+1)*2,17;j$
1210 GO TO 1085
1215 IF j=4 AND k<8 THEN LET fg=1: GO TO 1147
1220 IF j=1 THEN LET a$(i)=s$
1221 IF j=4 THEN LET z$=s$: GO SUB 500: LET s$=z$
1222 IF j>1 THEN LET a(i,pn,j-1)=VAL s$: IF a(i,pn,j-1)=0 THEN LET fg=1: GO TO 1147
1230 NEXT j
1235 BEEP .2,0
1236 IF a(i,pn,1)<0 THEN GO TO 1400
1237 LET a(i,pn,4)=a(i,pn,1)/a(i,pn,2): LET a(i,13,1)=a(i,13,1)+a(i,pn,1): LET a(i,13,3)=a(i,13,3)+a(i,pn,2): LET a(i,13,2)=a(i,13,1)/a(i,13,3): LET a(i,13,4)=0
1240 IF (uf1=0 AND uf2=0) THEN PRINT AT 21,6; BRIGHT 1;"Another stock? (y/n)"
1247 IF uf1=1 THEN PRINT AT 21,2;"Add to another stock? (y/n)"
1248 IF uf2=1 THEN PRINT AT 21,1;"Sell from another stock? (y/n)"
1249 IF INKEY$="" THEN GO TO 1249
1250 LET q$=INKEY$
1251 IF (uf1=1 OR uf2=1) AND q$="y" THEN LET i=ti: LET q$="3": GO TO 1008
1255 IF (uf1=1 OR uf2=1) AND q$="n" THEN LET i=ti: LET uf1=0: LET uf2=0: GO TO 10
1256 IF (uf1=1 OR uf2=1) THEN GO TO 1249
1260 IF q$="n" THEN GO TO 1300
1265 IF q$="y" THEN LET i=ti+1: GO TO 1008
1268 GO TO 1240
1270 CLS
1275 NEXT i
1280 PAPER 3: INK 1: CLS
1282 PRINT AT 10,1;"NO ROOM FOR ADDITIONAL ENTRIES"
1284 FOR m=1 TO 3
1285 FOR n=1 TO 16 STEP 3
1290 BEEP .01,n
1291 NEXT n
1292 PAUSE 20
1293 NEXT m
1296 INPUT "Press ""ENTER"" for Main Menu";q$: GO TO 10
1300 LET i=i+1: GO TO 10
1405 IF (INT (ABS (a(i,pn,2)*1000)+.5))/1000=(INT (a(i,13,3)*1000+.5))/1000 THEN LET a(i,pn,2)=-1*a(i,13,3): LET a(i,13,4)=1: GO TO 1420
1410 IF ABS a(i,pn,2)>a(i,13,3) THEN BEEP .5,-12: BEEP .25,-14: PRINT AT 18,1; INVERSE 1; BRIGHT 1; FLASH 1;"INSUFFICIENT SHARES AVAILABLE.": PRINT AT 19,0; INVERSE 1; BRIGHT 1;"Please enter ";a(i,13,3);TAB 21;"shares max.": PRINT AT 8,17;j$: PRINT AT 10,17;j$: LET j=3: GO TO 1075
1420 PRINT AT 20,0;TAB 31;" "
1430 LET a(i,13,1)=a(i,13,1)+a(i,pn,2)*a(i,13,2): LET a(i,13,3)=a(i,13,3)+a(i,pn,2): LET a(i,pn,4)=a(i,pn,1)/a(i,pn,2): GO TO 1240
2003 CLS
2004 IF q$="3" OR q$="4" THEN GO TO 2011
2005 IF puf=1 THEN GO TO 2011
2006 BEEP .2,-6: PRINT "Stocks have not been updated with current prices. Press:"'' """u"" to enter current prices"' """r"" to return to the MAIN MENU."
2007 IF INKEY$="" THEN GO TO 2007
2008 IF INKEY$="u" THEN LET rf=1: GO SUB 4000: GO TO 2011
2009 IF INKEY$="r" THEN GO TO 10
2010 BEEP .1,12: GO TO 2007
2011 BORDER 1: PAPER 6: INK 0: CLS
2020 BEEP .05,0: BEEP .05,5: BEEP .05,12
2030 PRINT AT 1,7;"CURRENT HOLDINGS"
2040 PLOT 54,158: DRAW 0,11: DRAW 130,0: DRAW 0,-11: DRAW -130,0
2045 PRINT
2050 FOR n=1 TO i-1
2055 IF n=18 OR (n-18)/22=INT ((n-18)/22) THEN INPUT "Press ENTER to Continue List ";q$: CLS : PRINT : PRINT : PRINT
2060 PRINT n;"...";a$(n);
2065 IF a(n,13,4)=0 THEN PRINT ""
2066 IF a(n,13,4)=1 THEN PRINT "(Inactive)"
2070 NEXT n
2075 IF uf1=1 THEN INPUT "Which stock to add to? (Enter ""r"" for MAIN MENU)";q$: GO TO 2083
2077 IF uf2=1 THEN INPUT "Which stock to sell from? (Enter ""r"" for MAIN MENU)";q$: GO TO 2083
2080 INPUT "Which stock to report? (Enter number preceeding choice. Enter""r"" to return to MAIN MENU)";q$
2083 IF q$="r" THEN LET uf1=0: LET uf2=0: LET i=ti: GO TO 10
2085 IF CODE q$<48 OR CODE q$>57 THEN GO TO 2075
2086 IF VAL q$>=i THEN GO TO 2075
2090 LET q=VAL q$
2095 IF uf1=1 OR uf2=1 THEN RETURN
2100 CLS
2105 BEEP .1,24
2110 PRINT INVERSE 1;" ";a$(q);TAB (31-LEN g$);g$;TAB 32
2115 IF a(q,13,4)=1 THEN PRINT TAB 11; INVERSE 1;" INACTIVE "
2130 PRINT "Shares held:";
2135 LET x=a(q,13,3): LET d=3: GO SUB 200: PRINT TAB (24-o);x$
2140 PRINT "Avg. cost/share";
2145 LET x=a(q,13,2): LET d=2: GO SUB 200: PRINT TAB (23-o);"$";x$
2150 PRINT "Total cost";
2155 LET x=a(q,13,1): LET d=2: GO SUB 200: PRINT TAB (23-o);"$";x$
2158 IF a(q,13,4)=1 THEN GO TO 2200
2159 PLOT 0,140: DRAW 255,0
2160 PRINT : PRINT "Current price";
2165 LET x=c(q): LET d=3: GO SUB 200: PRINT TAB (23-o);"$";x$
2170 PRINT "Current value";
2175 LET x=a(q,13,3)*c(q): LET d=2: GO SUB 200: PRINT TAB (23-o);"$";x$
2180 PRINT "Unrealized"'"Gain/(Loss)";
2185 LET x=a(q,13,3)*c(q)-a(q,13,1): LET d=2: GO SUB 200: PRINT TAB (23-o); BRIGHT 1;"$";x$
2190 PRINT "Per Cent unreal."'"Gain/(Loss)";
2193 IF INT a(q,13,1)=0 THEN PRINT TAB 22;"0.0%": GO TO 2200
2195 LET x=(a(q,13,3)*c(q)-a(q,13,1))/a(q,13,1)*100: LET d=2: GO SUB 200: PRINT TAB (24-o); BRIGHT 1;x$;" %"
2200 PRINT "Last transaction";
2205 GO SUB 100
2215 LET e$=STR$ a(q,y-1,3)
2220 IF LEN e$=5 THEN LET e$="0"+e$
2223 LET d$=""
2225 FOR n=6 TO 2 STEP -2
2230 LET d$=e$(n-1 TO n)+d$
2235 IF n>2 THEN LET d$="/"+d$
2238 NEXT n
2240 PRINT TAB 20;d$
2245 LET rf=0
2250 IF a(q,13,4)=0 THEN GO TO 2320
2270 PLOT 0,124: DRAW 255,0: PLOT 0,121: DRAW 255,0
2275 LET in=0: LET out=0
2280 FOR n=1 TO y-1
2285 IF a(q,n,1)>0 THEN LET in=in+a(q,n,1)
2290 IF a(q,n,1)<0 THEN LET out=out+ABS a(q,n,1)
2295 NEXT n
2300 PRINT : PRINT "Total purchases:";: LET x=in: LET d=2: GO SUB 200: PRINT TAB (23-o);"$";x$
2305 PRINT "Total sales:";: LET x=out: LET d=2: GO SUB 200: PRINT TAB (23-o);"$";x$
2310 PRINT "Capital Gain/Loss:";: LET x=out-in: LET d=2: GO SUB 200: PRINT TAB (23-o);"$";x$
2315 PRINT "Per Cent Gain/Loss:";: LET x=(out-in)/in*100: LET d=1: GO SUB 200: PRINT TAB (24-o);x$;" %"
2316 IF pg=1 THEN LET pg=0: LET pgi=1
2317 GO TO 2322
2320 PLOT 0,77: DRAW 255,0: PLOT 0,79: DRAW 255,0
2321 IF pgi=1 THEN LET pg=1
2322 PRINT AT 13,1; PAPER 1;TAB 31: PRINT AT 14,1; PAPER 1;TAB 2; PAPER 7;TAB 30; PAPER 1;TAB 31: PRINT AT 15,1; PAPER 1;TAB 31
2323 PRINT AT 13,2;a$(q)
2324 PLOT 8,48: DRAW 0,24: DRAW 239,0: DRAW 0,-24: DRAW -239,0
2325 PLOT 16,56: DRAW 0,8: DRAW 223,0: DRAW 0,-8: DRAW -223,0
2326 PRINT AT 17,0;"-100%";TAB 16;"0";TAB 27;"+100%"
2327 PLOT 16,40: DRAW 0,12: PLOT 128,40: DRAW 0,36: PLOT 239,40: DRAW 0,12
2328 IF VAL x$>100 THEN LET x$="100"
2329 IF VAL x$<0 THEN GO TO 2340
2330 FOR n=128 TO 128+INT (VAL x$/100*111)
2331 BEEP .01,(n-110)/2: PLOT n,56: DRAW 0,8
2332 NEXT n: GO TO 2360
2340 FOR n=128 TO 128-INT ABS (VAL x$/100*111) STEP -1
2341 BEEP .01,n/2-48: PLOT n,56: DRAW INK 2;0,8
2342 NEXT n
2360 IF pg=0 THEN GO TO 2375
2361 PRINT AT 18,1; PAPER 1;TAB 31: PRINT AT 19,1; PAPER 1;TAB 2; PAPER 7;TAB 30; PAPER 1;TAB 31: PRINT AT 20,1; PAPER 1;TAB 31
2362 PRINT AT 18,2; INK 1; PAPER 7; INVERSE 1;"PORTFOLIO"
2363 PLOT 8,8: DRAW 0,24: DRAW 239,0: DRAW 0,-24: DRAW -239,0
2364 PLOT 16,16: DRAW 0,8: DRAW 223,0: DRAW 0,-8: DRAW -223,0
2365 PLOT 128,8: DRAW 0,24
2366 IF pp<0 THEN GO TO 2371
2367 IF pp>100 THEN LET pp=100
2368 FOR n=128 TO 128+INT (pp/100*111)
2369 BEEP .01,(n-110)/2: PLOT n,16: DRAW 0,8
2370 NEXT n: GO TO 2375
2371 FOR n=128 TO 128-INT ABS (pp/100*111) STEP -1
2372 BEEP .01,n/2-48: PLOT n,16: DRAW INK 2;0,7
2373 NEXT n
2374 IF pgi=1 THEN LET pg=1
2375 BEEP .1,12: PRINT AT 21,0; INVERSE 1;TAB 2;"Print the information? (y/n)";TAB 31;" "
2376 IF INKEY$="" THEN GO TO 2376
2377 IF INKEY$="y" THEN PRINT AT 21,0;TAB 31;" ": LPRINT "STOCK PERFORMANCE REPORT": COPY : LPRINT : GO TO 2380
2378 IF INKEY$="n" THEN GO TO 2380
2379 GO TO 2375
2380 BEEP .1,12: PRINT AT 21,0; INVERSE 1;TAB 4;"Purchase history? (y/n)";TAB 31;" "
2381 IF INKEY$="" THEN GO TO 2381
2382 IF INKEY$="y" THEN GO TO 2410
2383 IF INKEY$="n" THEN GO TO 2385
2384 GO TO 2380
2385 BEEP .1,12: PRINT AT 21,0; INVERSE 1;TAB 6;"Another stock? (y/n)";TAB 31;" "
2386 IF INKEY$="" THEN GO TO 2386
2387 IF INKEY$="y" THEN GO TO 2000
2388 IF INKEY$="n" THEN GO TO 2399
2389 GO TO 2385
2399 BEEP .1,-6: PRINT AT 21,0;TAB 31;" ": INPUT " Press ENTER for MAIN MENU";q$: GO TO 10
2410 CLS
2420 BEEP .1,24
2430 PRINT INVERSE 1;" ";a$(q),"Purchase History"
2440 PRINT AT 2,0;" Date Amount $/Share # Shares"
2450 PRINT AT 2,0; OVER 1;" ____ ______ _______ ________": PRINT
2460 GO SUB 100
2470 FOR n=1 TO y-1
2480 LET d$=STR$ a(q,n,3): IF LEN d$=5 THEN PRINT 0;
2490 PRINT d$;
2500 LET x=a(q,n,1): LET d=2: GO SUB 200: PRINT TAB (14-o);x$;
2510 LET x=a(q,n,4): LET d=3: GO SUB 200: PRINT TAB (21-o);x$;
2520 LET x=a(q,n,2): LET d=3: GO SUB 200: PRINT TAB (29-o);x$
2530 NEXT n
2540 PRINT "______ ________ _______ _______"
2550 PRINT "TOTALS";
2560 LET x=a(q,13,1): LET d=2: GO SUB 200: PRINT TAB (14-o);x$;
2570 LET x=a(q,13,2): LET d=3: GO SUB 200: PRINT TAB (21-o);x$;
2580 LET x=a(q,13,3): LET d=3: GO SUB 200: PRINT TAB (29-o);x$
2600 PRINT TAB 16;"(Average)"
2610 BEEP .1,12: PRINT AT 21,0; INVERSE 1;TAB 2;"Print the information? (y/n)";TAB 31;" "
2613 IF INKEY$="" THEN GO TO 2613
2615 IF INKEY$="n" THEN GO TO 2630
2620 IF INKEY$="y" THEN PRINT AT 21,0;TAB 31;" ": COPY : LPRINT "Today's Date: ";g$: LPRINT : LPRINT : GO TO 2630
2625 GO TO 2610
2630 BEEP .1,12: PRINT AT 21,0; INVERSE 1;TAB 1;"Return to stock report? (y/n)";TAB 31;" "
2633 IF INKEY$="" THEN GO TO 2633
2635 IF INKEY$="n" THEN GO TO 2650
2640 IF INKEY$="y" THEN GO TO 2000
2645 GO TO 2630
2650 BEEP .1,-6: PRINT AT 21,0;TAB 31;" ": INPUT " Press ENTER for MAIN MENU";q$: GO TO 10
3003 BORDER 6: PAPER 6: INK 0: CLS
3004 CLS
3005 IF puf=1 THEN GO TO 3011
3006 BEEP .2,-6: PRINT "Stocks have not been updated with current prices. Press:"'' """u"" to enter current prices"' """r"" to return to the MAIN MENU."
3007 IF INKEY$="" THEN GO TO 3007
3008 IF INKEY$="u" THEN LET rf=1: GO SUB 4000: GO TO 3011
3009 IF INKEY$="r" THEN GO TO 10
3010 BEEP .1,12: GO TO 3007
3011 BEEP .05,0: BEEP .05,5: BEEP .05,12
3012 LET pg=1
3015 CLS : PRINT INVERSE 1;TAB 6;"PORTFOLIO PERFORMANCE";TAB 32
3016 PRINT AT 20,0;"Press ""r"" to return to MAIN MENUPress ""p"" to proceed "
3017 IF INKEY$="" THEN GO TO 3017
3018 IF INKEY$="r" THEN LET uf1=0: LET uf2=0: LET i=ti: GO TO 10
3019 IF INKEY$<>"p" THEN BEEP .1,12: GO TO 3016
3020 PRINT AT 20,0;TAB 31;" ": PRINT AT 21,0;TAB 31;" "
3025 BEEP .1,24: PRINT AT 2,0;"Stock Cost Value %G/L"
3030 PRINT AT 2,0; OVER 1;"______ ________ ________ ______"
3040 PRINT
3045 LET tot1=0: LET tot2=0
3050 FOR n=1 TO i-1
3053 IF a(n,13,4)=1 THEN GO TO 3075
3055 PRINT a$(n, TO 8);
3060 LET x=a(n,13,1): LET tot1=tot1+x: LET d=2: GO SUB 200: PRINT TAB (14-o);x$;
3065 LET x=a(n,13,3)*c(n): LET tot2=tot2+x: LET d=2: GO SUB 200: PRINT TAB (23-o);x$;
3067 IF INT a(n,13,1)=0 THEN PRINT TAB 28;"0.0": GO TO 3074
3070 LET x=(a(n,13,3)*c(n)-a(n,13,1))/a(n,13,1)*100: LET d=1: GO SUB 200
3072 IF VAL x$>=0 THEN PRINT TAB (30-o);x$;"%"
3073 IF VAL x$<0 THEN PRINT TAB (30-o); FLASH 1;x$;"%"
3074 IF n=17 OR (n-17)/22=INT ((n-17)/22) THEN GO SUB 3200
3083 NEXT n
3084 PRINT "______ ________ ________ ______"
3085 PRINT INVERSE 1;"TOTALS";
3090 LET x=tot1: LET d=2: GO SUB 200: PRINT TAB (14-o);x$;
3095 LET x=tot2: LET d=2: GO SUB 200: PRINT TAB (23-o);x$;
3097 IF INT tot1=0 THEN PRINT TAB 28;"0.0": GO TO 3105
3100 LET x=(tot2-tot1)/tot1*100: LET d=1: GO SUB 200
3101 LET pp=VAL x$
3102 IF VAL x$>0 THEN PRINT TAB (30-o);x$;"%"
3103 IF VAL x$<0 THEN PRINT TAB (30-o); FLASH 1;x$;"%"
3110 PRINT : PRINT : PRINT TAB 6; PAPER 4;"NET DOLLAR GAIN/LOSS"
3115 LET x=tot2-tot1: LET d=2: GO SUB 200: PRINT : PRINT TAB (32-LEN x$)/2-1; PAPER 4; BRIGHT 1;"$";x$
3116 LET rf=0
3117 BEEP .1,12: PRINT AT 21,0; INVERSE 1;TAB 2;"Print the information? (y/n)";TAB 31;" "
3118 IF INKEY$="" THEN GO TO 3118
3119 IF INKEY$="y" THEN PRINT AT 21,0;TAB 31;" ": COPY : LPRINT "Today's Date: ";g$: LPRINT : LPRINT : GO TO 3125
3120 IF INKEY$="n" THEN GO TO 3125
3124 GO TO 3117
3125 BEEP .1,12: PRINT AT 20,0; INVERSE 1;" Report a Stock's Performance?";TAB 31;" ";" (y/n)";TAB 31;" "
3126 IF INKEY$="" THEN GO TO 3126
3127 IF INKEY$="y" THEN GO TO 2000
3129 IF INKEY$="n" THEN GO TO 3135
3131 GO TO 3125
3135 BEEP .1,-6: PRINT AT 20,0;TAB 31;" ";TAB 31;" ": INPUT " Press ENTER for MAIN MENU.";q$: GO TO 10
3200 PRINT AT 21,0; INVERSE 1;TAB 2;"Print the information?";TAB 31;" "
3205 IF INKEY$="" THEN GO TO 3205
3210 IF INKEY$="y" THEN PRINT AT 21,0;TAB 31;" ": COPY : CLS : RETURN
3215 IF INKEY$="n" THEN CLS : RETURN
3220 GO TO 3200
4010 CLS : PRINT " Current Price Update": PRINT
4015 PRINT "Stock:","Price:": PRINT
4017 PLOT 0,150: DRAW 48,0: PLOT 128,150: DRAW 48,0
4020 FOR n=1 TO i-1
4030 IF a(n,13,4)=1 THEN GO TO 4060
4040 BEEP .1,12: INPUT "Current Price for "; INVERSE 1;(a$(n)); INVERSE 0;" ?";"(Enter ""r"" for MAIN MENU)";q$
4042 IF q$="r" THEN GO TO 10
4044 IF CODE q$<46 OR CODE q$>57 THEN GO TO 4040
4046 LET c(n)=VAL q$
4050 PRINT a$(n),q$
4060 NEXT n
4065 LET puf=1
4070 IF rf=1 THEN RETURN
4073 LET pg=0: LET pgi=0
4080 BEEP .1,-6: INPUT " Press ENTER for MAIN MENU";q$
4090 GO TO 10
5005 BEEP .05,0: BEEP .05,5: BEEP .05,12
5010 BORDER 2: PAPER 2: INK 7: CLS
5015 PRINT TAB 7;"SAVE FILE TO TAPE"
5020 PLOT 0,168: DRAW INK 0;255,0
5025 BEEP .1,24: PRINT AT 20,0;"Press ""r"" to return to MAIN MENUPress ""p"" to proceed "
5027 IF INKEY$="" THEN GO TO 5027
5030 IF INKEY$="r" THEN GO TO 10
5035 IF INKEY$<>"p" THEN GO TO 5025
5040 BEEP .1,24: CLS : PRINT TAB 7;"SAVE FILE TO TAPE": PLOT INK 0;0,168: DRAW INK 0;255,0
5041 PRINT "Place file tape in the cassetterecorder. Connect the ""MIC"" leadand disconnect the ""EAR"" lead.Set recorder to ""RECORD"". Press""ENTER"", then any key when readyto SAVE the Stock File.": INPUT q$
5045 LET a$(r+2)=g$
5046 LET a$(r+1)=STR$ i
5050 PRINT TAB 11; FLASH 1;" SAVEing "
5055 BEEP .2,-12: SAVE "names" DATA a$()
5056 BEEP .1,12: BEEP .1,12: PRINT AT 7,9; INVERSE 1;" FILE SAVED ": PRINT "First section of the file hasbeen SAVEd. Keep the tape movingand press ""ENTER"", then any keyto SAVE the second section ofthe Stock File.": INPUT q$: PRINT AT 7,9; FLASH 1;" SAVEing "
5060 BEEP .2,-12: SAVE "data" DATA a()
5063 PRINT AT 7,9; INVERSE 1;" FILE SAVED "
5064 GO TO 5110: REM skip VERIFY
5065 BEEP .1,12: BEEP .1,12: PRINT AT 14,7;"VERIFY FILE SAVE"
5066 PLOT 0,56: DRAW INK 0;255,0
5070 PRINT : PRINT "Rewind file tape, reconnect the ""EAR"" lead, and set recorder to ""PLAY"". Press ENTER when ready to VERIFY.": INPUT q$
5075 PRINT TAB 10; FLASH 1;" VERIFYing "
5080 BEEP .2,-12: VERIFY "names" DATA a$()
5090 BEEP .1,-12: VERIFY "data" DATA a()
5100 PRINT AT 20,8; INVERSE 1;" FILE VERIFIED "
5110 BEEP .1,12: PRINT AT 21,0; INVERSE 1;TAB 2;"Enter a New Portfolio? (y/n)";TAB 31;" "
5113 IF INKEY$="" THEN GO TO 5113
5115 IF INKEY$="y" THEN RESTORE : GO TO 1
5120 IF INKEY$="n" THEN GO TO 10
5125 GO TO 5110
6005 BEEP .05,0: BEEP .05,5: BEEP .05,12
6010 BORDER 4: PAPER 4: INK 0: CLS
6014 PRINT TAB 6;"LOAD FILE FROM TAPE"
6015 PLOT 0,168: DRAW INK 7;255,0
6016 BEEP .1,24: PRINT AT 20,0;"Press ""r"" to return to MAIN MENUPress ""p"" to proceed "
6017 IF INKEY$="" THEN GO TO 6017
6018 IF INKEY$="r" THEN GO TO 10
6019 IF INKEY$<>"p" THEN GO TO 6016
6020 CLS : PRINT TAB 6;"LOAD FILE FROM TAPE": PLOT 0,168: DRAW INK 7;255,0: PRINT : PRINT "Place file tape in the cassetterecorder. Make sure ""EAR"" leadis connected. Set recorder on""PLAY""."''"Press ""ENTER"" when ready."
6025 BEEP .1,12: INPUT q$
6026 PRINT AT 9,11; FLASH 1;" LOADing "
6030 BEEP .2,-12: LOAD "names" DATA a$()
6040 BEEP .1,12: LOAD "data" DATA a()
6043 DIM c(r): LET pg=0: LET puf=0
6044 LET ef=1
6045 LET i=VAL a$(r+1)
6047 PRINT AT 9,9; INVERSE 1;" FILE LOADED "
6050 BEEP .1,24: BEEP .1,24: PRINT AT 15,8; FLASH 1;" STOP THE TAPE "
6055 PRINT AT 21,0;"Rewind the file tape, then"
6060 BEEP .1,12: INPUT "press ENTER for MAIN MENU";q$: GO TO 10
8010 BEEP .1,24: BORDER 1: PAPER 7: INK 0: CLS
8020 FOR n=0 TO 255 STEP 16: PLOT n,0: DRAW 0,175: NEXT n
8030 BEEP .1,24: FOR n=0 TO 175 STEP 16: PLOT 0,n: DRAW 255,0: NEXT n
8040 BEEP .1,24: PRINT BRIGHT 1;"PORTFOLIO MANAGER"
8050 PRINT AT 18,23; BRIGHT 1;"T/S 2000"
8060 PRINT AT 19,23; BRIGHT 1;"R.B. CRAM"
8070 PRINT AT 20,23; BRIGHT 1;" \*1983 "
8080 BEEP .1,-24: PLOT 0,0: DRAW INK 2;23,60
8090 BEEP .1,-12: DRAW INK 2;20,-10
8100 BEEP .1,-18: DRAW INK 2;45,55
8110 BEEP .1,-6: DRAW INK 2;35,-15
8120 BEEP .1,-12: DRAW INK 2;60,40
8130 BEEP .1,0: DRAW INK 2;32,-5
8140 BEEP .1,12: DRAW INK 2;40,50
8150 BEEP .2,0: PRINT AT 21,0; INK 7; PAPER 1; INVERSE 1; FLASH 1;" PRESS ANY KEY TO BEGIN.";TAB 32
8160 IF INKEY$="" THEN GO TO 8160
8180 RETURN
9000 ON ERR GO TO 9900
9010 DIM b$(4,16)
9020 FOR n=1 TO 4
9030 READ b$(n)
9040 NEXT n
9050 DATA "Company","Dollar Amount","Number of Shares","Transaction Date"
9055 LET i=1
9056 LET ti=1
9060 LET j$=" "
9070 LET fg=0
9075 LET uf1=0: LET uf2=0
9076 LET pg=0
9077 LET pgi=0
9078 LET rf=0
9080 LET ef=0
9090 LET r=50
9100 LET l=12
9110 DIM a$(r+3,l)
9120 DIM a(r,13,4)
9125 LET a$(r+2)="New File"
9130 POKE 23609,50
9140 RETURN
9900 ON ERR RESET
9910 PAUSE 100
9920 ON ERR GO TO 9900
9930 ON ERR CONTINUE
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.