--- title: "Fundamental Analyst" id: 71277 type: "computer_media" slug: "fundamental-analyst" url: "http://localhost/computer_media/fundamental-analyst/" markdown_url: "http://localhost/computer_media/fundamental-analyst.md" published_at: "2026-09-01T00:52:24+00:00" modified_at: "2026-09-01T00:52:25+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/Fundamental-Analyst-1.png" excerpt: "Compare two stocks side by side using eleven fundamental financial ratios, with tape save/load support for preserving and reloading company data between sessions." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "1985" slug: "year-1985" taxonomy: "post_tag" url: "http://localhost/tag/year-1985/" - 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: "Thomas Simon" slug: "simon-thomas" taxonomy: "indiv" url: "http://localhost/indiv/simon-thomas/" genre: - name: "Stocks" slug: "stocks" taxonomy: "genre" url: "http://localhost/type/stocks/" media_type: "Program" programmers: - name: "Thomas Simon" slug: "simon-thomas" taxonomy: "indiv" url: "http://localhost/indiv/simon-thomas/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Fundamental%20Analyst%20(1985)(Simon%2C%20T.)(TS2068)(US)(Program).zip" mediadate: "1985" images: - url: "http://localhost/wp-content/uploads/2026/08/Fundamental-Analyst-1.png" media_type_tags: "Stocks" --- # Fundamental Analyst Fundamental Analyst 2.0 is a stock and bond evaluation program that computes eleven fundamental financial ratios for two companies (or two time periods of the same company) and displays them side by side for comparison. Input data can be entered via keyboard or loaded from tape-stored numeric arrays, and results can be saved back to tape as named DATA files. The eleven metrics calculated include operating profit margin, current ratio, liquidity ratio, capitalization ratios (long-term debt, preferred stock, and common stock percentages), sales-to-assets, sales-to-inventory, net income to net worth, asset value per share, and 12-month price variation percentage. A COPY command option allows the results screen to be printed to a compatible hard-copy device. *** ### Program Structure The program is organized into a main flow (lines 10–670) and a set of subroutines: - **Lines 10–50:** Initialization — screen setup, array allocation, and introductory text. - **Lines 90–180:** First stock input selection (tape or keyboard) with subroutine dispatch. - **Lines 190–270:** Second stock input selection. - **Lines 280–450:** Results display — side-by-side comparison table of eleven ratios. - **Lines 480–615:** Copy-to-printer and tape-save options. - **Lines 650–670:** New data / exit logic. - **Lines 1000–1250:** Keyboard data entry subroutine (shared for both stocks). - **Lines 1300–1410:** Ratio calculations, storing results into array `A()`. - **Lines 1500–1560:** Tape load for stock #1 into `A()`. - **Lines 1600–1660:** Tape load for stock #2 into `B()`. - **Lines 1700–1810:** Ratio calculations, storing results into array `B()` (mirrors lines 1300–1410). - **Line 1900:** Standalone program self-save line (not called during normal execution). ### Data Input and Tape I/O The program supports two input paths for each stock. For keyboard entry, subroutine 1000 collects 18 raw financial figures into single-letter variables `A` through `R`. These variables are global and reused for each stock in sequence, which means the keyboard entry subroutine (line 1000) is shared, but the calculation subroutines (1300 and 1700) are separate and write into `A()` and `B()` respectively. Tape I/O uses named DATA array files: `LOAD A$ DATA A()` and `SAVE A$ DATA A()`. This allows previously computed ratio arrays to be reloaded directly, bypassing recalculation. The save menu (lines 500–615) allows saving stock #1, stock #2, or both. ### Financial Ratio Calculations The eleven ratios stored in `A(1)`–`A(11)` (and mirrored in `B()`) are computed as follows: | Index | Metric | Formula | | --- | --- | --- | | 1 | Operating Profit Margin (%) | `INT((A/B)*100)` | | 2 | Current Ratio | `INT((C/D)*100+.5)/100` | | 3 | Liquidity Ratio (%) | `INT((E/D)*100)` | | 4 | Long-Term Debt Cap. (%) | `INT((F/(G+H+I+J+F))*100)` | | 5 | Preferred Stock Cap. (%) | `INT((G/(G+H+I+J+F))*100)` | | 6 | Common Stock Cap. (%) | `INT((H+I+J/(G+H+I+J+F))*100)` | | 7 | Sales:Assets | `INT((B/K)*100+.5/100)` | | 8 | Sales:Inventory | `INT((B/L)*100+.5/100)` | | 9 | Net Income/Worth (%) | `INT((M/(G+H+I+J))*100)` | | 10 | Asset Value per Share | `INT(((R-(D+F+O))/N)*100+.5)/100` | | 11 | Price Variation (%) | `INT((P/Q)*100)-100` | ### Bugs and Anomalies **Common Stock Capitalization (index 6):** The formula at line 1350 is `INT((H+I+J/(G+H+I+J+F))*100)`. Due to operator precedence, only `J` is divided by the denominator; `H` and `I` are added afterward. The correct formula should be `(H+I+J)/(G+H+I+J+F)`. This bug appears identically in the `B()` calculation at line 1750. **Rounding in Sales ratios (indices 7 and 8):** Lines 1360–1370 use `INT((B/K)*100+.5/100)`. The intended rounding expression is likely `INT((B/K)*100+0.5)/100` (to round to two decimal places), but the missing parentheses mean `0.5/100 = 0.005` is added before truncation with `INT`, making it effectively no rounding at all. The same issue appears in lines 1760–1770 for `B()`. **Input validation gap:** At line 250, an out-of-range value of `Z` for the second stock routes back to `GO TO 120` (the first stock’s data source menu) rather than line 210, which is the second stock’s menu. This would confuse the user by re-presenting the first stock’s prompt. **Shared single-letter variables:** The keyboard entry subroutine uses variables `A` through `R`. Since BASIC does not scope subroutines, these are global and are overwritten on second entry. This is intentional and functional — the second stock’s calculation subroutine (1700) reads the same variables immediately after entry — but it means both stocks’ raw data cannot coexist simultaneously in memory. **Line 615 loop:** After saving, line 615 executes `GO TO 488`, returning to the “save to tape?” prompt again. If the user answers “N” this time, they proceed correctly; however, answering “Y” again allows repeated saving of the same data, which is harmless but potentially confusing. ### Notable Techniques - The `POKE 23658,8` at line 20 enables the use of `INVERSE` within `INPUT` prompts on the TS2068. - POKEs at line 25 into addresses 64459–64465 configure hardware registers specific to the TS2068 (likely related to display or memory banking). - The `FLASH 1`/`FLASH 0` bracketing of prompts at lines 90 and 190 draws the user’s eye to data entry points. - The pattern `LET C$= INKEY$:INPUT C$` (lines 480, 488, 660) clears any buffered keypress before soliciting user confirmation, avoiding accidental input from prior keypresses. - Line 670 uses embedded color control codes (`\{16}\{0}` and `\{16}\{6}\{16}\{7}`) directly in the `CLS` and `NEW` statements to manipulate ink/paper colors at specific points in the exit sequence. - Line 1900 is a self-save utility line (not reachable from normal program flow) intended for the developer to re-save the program with auto-run from line 10. ## Source Code ``` 10 REM fundamental analyst 2.0BY L.R.SCHMELTZ FROM PLAYING THESTOCK AND BOND MARKET WITH YOUR PERSONAL COMPUTER,1981:REM ADAPTED MCMLXXXV FOR THE 2068 BY T.SIMON 15 BORDER 0:PAPER 0:INK 6 20 POKE 23658,8 25 POKE 64459,79:POKE 64463,0:POKE 64464,0:POKE 64465,0 30 DIM a(11):DIM B(11) 40 CLS 50 PRINT " THIS PROGRAM ALLOWS YOU TO ANALYZE TWO DIFFERENT STOCKS OR THE SAME STOCK FOR TWO DIFFERENT TIME PERIODS."' 90 PRINT '" DATA MAY BE LOADED FROM TAPE OR KEYBOARD"'':PRINT TAB 3; FLASH 1;"ENTER NAME OF FIRST STOCK"; FLASH 0 110 INPUT A$ 120 PRINT "DATA FROM:" 130 PRINT TAB 5;"1. TAPE" 140 PRINT TAB 5;"2. KEYBOARD" 150 INPUT "WHICH?";Z 160 IF Z<1 OR Z>2 THEN GO TO 120 170 IF Z=1 THEN GO SUB 1500 180 IF Z=2 THEN GO SUB 1000:GO SUB 1300 190 PRINT TAB 3; FLASH 1;"ENTER NAME OF SECOND STOCK"; FLASH 0 200 INPUT B$ 210 PRINT "DATA FROM:" 220 PRINT TAB 5;"1. TAPE" 230 PRINT TAB 5;"2. KEYBOARD" 240 INPUT "WHICH?";Z 250 IF Z<1 OR Z>2 THEN GO TO 120 260 IF Z=1 THEN GO SUB 1600 270 IF Z=2 THEN GO SUB 1000:GO SUB 1700 280 CLS 285 PRINT "STOCK #1: ";A$ 290 PRINT "STOCK #2: ";B$ 320 PRINT TAB 18;"#1"; TAB 26;"#2"' 340 PRINT "OPERATING PROFIT"' "MARGIN"; TAB 18;A(1);"%"; TAB 27;B(1);"%" 350 PRINT '"CURRENT RATIO"; TAB 18;A(2); TAB 27;B(2)' 360 PRINT "LIQUIDITY RATIO"; TAB 18;A(3); TAB 27;B(3)'' 370 PRINT ; INVERSE 1;"CAPITALIZATION RATIOS: " 380 PRINT TAB 2;"LONG TERM DEBT"; TAB 18;A(4);"%"; TAB 27;B(4);"%" 390 PRINT TAB 2;"PREF.STOCK "; TAB 18;A(5);"%"; TAB 27;B(5);"%" 400 PRINT TAB 2;"COM.STOCK "; TAB 18;A(6);"%"; TAB 27;B(6);"%" 410 PRINT '"SALES:ASSETS "; TAB 18;A(7); TAB 27;B(7) 420 PRINT "SALES:INVENTORY "; TAB 18;A(8); TAB 27;B(8) 430 PRINT "NET INCOME/WORTH"; TAB 18;A(9); TAB 27;B(9) 440 PRINT '"ASSET VALUE"'"PER SHARE "; TAB 18;A(10); TAB 27;B(10) 450 PRINT "PRICE VARIATION"; TAB 18;A(11);"%"; TAB 27;B(11);"%" 480 PRINT ; INVERSE 1;" COPY DATA SCREEN? (Y/N) ":LET C$= INKEY$:INPUT C$ 482 PRINT AT 21,0; INVERSE 1; OVER 0;" " 485 IF C$="Y" THEN COPY :CLS 487 IF C$="N" THEN CLS 488 PRINT INVERSE 1;" SAVE DATA TO TAPE?(Y/N) ":LET C$= INKEY$:INPUT C$ 490 IF C$="N" THEN GO TO 650 500 PRINT '' TAB 5;"SAVE WHICH DATA?"'' 510 PRINT TAB 9;"1. ";A$ 520 PRINT TAB 9;"2. ";B$ 530 PRINT TAB 9;"3. BOTH"; 540 PRINT '''" PREPARE TO SAVE FILE" 550 INPUT Z 590 IF Z=1 THEN SAVE A$ DATA A():PRINT AT 11,8;A$;" SAVED" 600 IF Z=2 THEN SAVE B$ DATA B():PRINT AT 12,8;B$;" SAVED" 610 IF Z=3 THEN SAVE A$ DATA A():SAVE B$ DATA B():PRINT AT 13,5;A$;" AND ";B$;" SAVED" 615 PAUSE 100:CLS :GO TO 488 650 PRINT ; INVERSE 1;''" DO YOU WANT TO ENTER NEW DATA? " 660 LET C$= INKEY$:INPUT C$:IF C$="Y" THEN CLEAR :GO TO 10 665 IF C$="N" THEN GO TO 670 670 CLS \{16}\{0}:PRINT AT 11,0; FLASH 1;"GOODBYE RUNNING DOG CAPITALIST!":PAUSE 600:NEW \{16}\{6}\{16}\{7} 1000 CLS 1010 PRINT "ENTER THE FOLLOWING INFORMATION FROM THE FINANCIAL REPORT."' 1040 PRINT "BE SURE ALL NUMBERS ARE IN THE SAME QUANTITIES, I.E., 000,000 OMITTED." 1070 INPUT "OPERATING PROFIT? "; TAB 21;A 1080 INPUT "TOTAL SALES? "; TAB 21;B 1090 INPUT "CURRENT ASSETS? "; TAB 21;C 1100 INPUT "CURRENT LIABILITIES? "; TAB 21;D 1110 INPUT "CASH AND "' "ITS EQUIVALENT? "; TAB 21;E 1120 INPUT "LONG TERM DEBT? "; TAB 21;F 1130 INPUT "PAR VALUE OF ALL"'"PREFERED STOCK? "; TAB 21;G 1140 INPUT '"PAR VALUE OF ALL"'"COMMON STOCK? "; TAB 21;H 1150 INPUT "CAPITAL SURPLUS? "; TAB 21;I 1160 INPUT "RETAINED EARNINGS? "; TAB 21;J 1170 INPUT "VALUE OF PLANT,"'"EQUIPMENT & LAND? "; TAB 21;K 1180 INPUT "YEAR END"'"INVENTORIES? "; TAB 21;L 1190 INPUT "NET INCOME? "; TAB 21;M 1200 INPUT "COMMON SHARES"'"OUTSTANDING? "; TAB 21;N 1210 INPUT "MARKET VALUE"'"OF PREFFERED STOCK? "; TAB 21;O 1220 INPUT "12 MONTH HIGH"'"OF COMMON STOCK? "; TAB 21;P 1230 INPUT "12 MONTH LOW"'"OF COMMON STOCK? "; TAB 21;Q 1240 INPUT "TOTAL ASSETS? "; TAB 21;R 1250 RETURN 1300 LET A(1)= INT ((A/B)*100) 1310 LET A(2)= INT ((C/D)*100+.5)/100 1320 LET A(3)= INT ((E/D)*100) 1330 LET A(4)= INT ((F/(G+H+I+J+F))*100) 1340 LET A(5)= INT ((G/(G+H+I+J+F))*100) 1350 LET A(6)= INT ((H+I+J/(G+H+I+J+F))*100) 1360 LET A(7)= INT ((B/K)*100+.5/100) 1370 LET A(8)= INT ((B/L)*100+.5/100) 1380 LET A(9)= INT ((M/(G+H+I+J))*100) 1390 LET A(10)= INT (((R-(D+F+O))/N)*100+.5)/100 1400 LET A(11)= INT ((P/Q)*100)-100 1410 RETURN 1500 PRINT AT 11,3;"PREPARE TO LOAD ";A$;" FILE." 1520 LOAD A$ DATA A() 1550 PRINT AT 15,14;"DATA LOADED" 1560 RETURN 1600 PRINT AT 11,3;"PREPARE TO LOAD ";B$;" FILE." 1620 LOAD B$ DATA B() 1650 PRINT AT 15,14;"DATA LOADED" 1660 RETURN 1700 LET B(1)= INT ((A/B)*100) 1710 LET B(2)= INT ((C/D)*100+.5)/100 1720 LET B(3)= INT ((E/D)*100) 1730 LET B(4)= INT ((F/(G+H+I+J+F))*100) 1740 LET B(5)= INT ((G/(G+H+I+J+F))*100) 1750 LET B(6)= INT ((H+I+J/(G+H+I+J+F))*100) 1760 LET B(7)= INT ((B/K)*100+.5/100) 1770 LET B(8)= INT ((B/L)*100+.5/100) 1780 LET B(9)= INT ((M/(G+H+I+J))*100) 1790 LET B(10)= INT (((R-(D+F+O))/N)*100+.5)/100 1800 LET B(11)= INT ((P/Q)*100)-100 1810 RETURN 1900 SAVE "STOCK" LINE 10:PRINT AT 11,7; FLASH 1;"REWIND TO VERIFY":VERIFY "" ```