TS Stock

Date: 198x
Type: Program
Platform(s): TS 2068

This program performs covered call option analysis, calculating return on investment figures for both exercised and unexercised scenarios on a stock option position. The user enters the stock symbol, strike price, option expiration date, today’s date, share count, share price, periodic dividend, commissions, number of call contracts, and option premium. Two date-to-serial-number conversion routines (subroutines at lines 2000 and 3000) handle the calendar arithmetic, including a leap-year adjustment, to compute days remaining until expiration and to reverse-convert a serial day number back into a human-readable date for the last trading day display. Results shown include ROI, annualized ROI (scaled to 365 days), net return, break-even price per share, net capital invested, and a commission summary, all formatted with AT-positioned PRINT statements filling the screen.


Program Analysis

Program Structure

The program is organized into a main flow (lines 50–999) and five subroutines:

Line RangePurpose
50–66Initialization: call splash screen, build days-per-month array Q(12)
70–344Input gathering: symbol, strike price, dates, shares, dividends, commissions, option details
350–720Financial calculations and full-screen results display
780–999Continue/quit prompt loop
2000–2036Subroutine: date string → serial day number (NZ)
3000–3050Subroutine: serial day number → date string (Z$), used for last trading day
4000–4015Subroutine: populate cumulative day-of-year offsets array W(12)
4500–4540Subroutine: convert fractional leap-year indicator Q7 to 0 or 1
5000–5099Splash screen subroutine

Date Arithmetic

The date-to-serial routine at line 2000 converts a MM/DD/YY string stored in Z$ into a linear day count NZ. It extracts month, day, and two-digit year into array T(3). Years below 48 are treated as 2000s by adding 100, then 48 is subtracted to obtain an offset from a base epoch (1948). A simple leap-year correction JJ is computed as INT(1 + T(3)/4); if the current month is January or February of a leap year, JJ is decremented by one. The cumulative month offset is looked up from W(12) (populated by the subroutine at 4000), and the final serial is W(month) + day + year*365 + JJ.

The inverse routine at line 3000 walks forward year by year, subtracting 365 or 366 days, using subroutine 4500 to resolve the leap-year flag Q7 from a fractional value. Once the target year is found, it iterates through months using Q(A) to find the month and remaining day, then formats the result back into Z$.

Financial Calculations

The core option analysis is computed at lines 350–414. Key intermediate values:

  • L1 = NS * PS — gross cost of shares
  • L2 = L1 + UC — total capital invested (stock cost + underlying commission)
  • L3 = NC * PR — gross premium received (premium is multiplied by 100 at line 350)
  • L4 = L3 - OC — net option premium after option commission
  • D3 = PD * NS — total period dividend
  • P1 = NS * P — proceeds at strike price
  • L5 = P1 - (L2 + UC) — capital gain/loss if exercised (note: UC is double-counted here, which is a bug)
  • L6 = L5 + D3 + L4 — total net return if exercised
  • L7 = D3 + L4 — net return if unexercised (premium + dividend only)
  • R1, R2 — exercised ROI and annualized ROI (×100 for percentage)
  • R3, R4 — unexercised ROI and annualized ROI
  • L8 = (L2 - L7) / NS — break-even price per share

Day-of-Week Calculation for Expiration

Lines 230–250 compute the last Saturday of the expiration month as the option expiry date. The serial number of the first of the expiration month (NZ) is used: C1 = 9 - (NZ MOD 7), further reduced modulo 7, then D1 = NZ + 15 + C1. This places the result on the third Saturday of the month, consistent with standard U.S. equity options expiration conventions of the era. The last trading day is then D1 - 1 (the Friday before), computed at line 680 and decoded by subroutine 3000.

Notable Techniques and Idioms

  • The flag variable Q1 at line 2003 prevents re-dimensioning T(3) and W(12) and re-running the W initialization on subsequent calls to the date subroutine — a guard idiom common in BASIC programs that share subroutines across multiple input loops.
  • Input validation uses length checks (LEN Z$<>4 at line 127, LEN Z$<>6 at line 263) and re-prompts with GO TO on failure.
  • Date strings entered as compact MMYY or MMDDYY are reformatted by string slicing and concatenation into MM/DD/YY before use (lines 128, 264), avoiding the need to parse separators during input.
  • The INKEY$ polling loop at lines 785–787 first waits for any keypress, then checks for “Y” to restart — but because INKEY$ is re-read at line 787 independently, a fast typist may miss the “Y” check (a subtle timing bug).
  • The splash subroutine at 5000 uses a short FOR/NEXT loop (lines 5020–5030, only 25 iterations) as a minimal delay before clearing the screen — effectively negligible on this hardware.

Bugs and Anomalies

  • Double commission deduction: At line 380, L5 = P1 - (L2 + UC) subtracts UC twice (once already included in L2 = L1 + UC), overstating the commission cost and understating the exercised net return.
  • Leap-year subroutine 4500: This routine converts a fractional Q7 (0.25 for a leap year, 0 otherwise) to a boolean 0 or 1. However, the logic sets Q7=1 when it equals 0, then immediately returns — meaning non-leap years are counted as leap years. Only when Q7 was already 1 does it return 1, which never happens since Q7 is computed as a fraction. The effective result is that every year is treated as having 366 days in subroutine 3000, causing incorrect last-trading-day output.
  • Line 347 and 750: These are empty statement lines with no code, likely remnants of deleted lines.
  • STOP at lines 3006 and 3017: These act as error traps if the date arithmetic overflows its loop bounds, providing no user-facing error message.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   50 GO SUB 5000
   51 DIM Q(12)
   52 LET Q(1)=31
   53 LET Q(2)=28
   54 LET Q(3)=31
   55 LET Q(4)=30
   56 LET Q(5)=31
   57 LET Q(6)=30
   58 LET Q(7)=31
   59 LET Q(8)=31
   60 LET Q(9)=30
   62 LET Q(10)=31
   64 LET Q(11)=30
   66 LET Q(12)=31
   70 LET Q1=0
   80 CLS 
   90 PRINT "ENTER\::STOCK\::SYMBOL"
   92 INPUT S$
   94 PRINT S$
  110 PRINT "ENTER\::STRIKE\::PRICE"
  115 INPUT P
  117 PRINT P
  120 PRINT "ENTER\::OPTION\::DATE MMYY"
  125 INPUT Z$
  127 IF LEN Z$<>4 THEN GO TO 120
  128 LET Z$=Z$(1 TO 2)+"/01/"+Z$(3 TO 4)
  129 PRINT Z$
  140 GO SUB 2000
  210 IF NZ=0 THEN GO TO 120
  230 LET C1=NZ-7*INT (NZ/7)
  240 LET C1=9-C1
  242 LET C1=C1-7*INT (C1/7)
  250 LET D1=NZ+15+C1
  251 REM PRINT D1
  260 PRINT "ENTER\::TODAYS\::DATE MMDDYY"
  262 INPUT Z$
  263 IF LEN Z$<>6 THEN GO TO 260
  264 LET Z$=Z$(1 TO 2)+"/"+Z$(3 TO 4)+"/"+Z$(5 TO 6)
  266 PRINT Z$
  270 GO SUB 2000
  272 IF NZ=0 THEN GO TO 260
  280 LET D2=D1-NZ
  282 REM PRINT D2
  300 PRINT "ENTER\::NO.\::OF\::SHARES"
  305 INPUT NS
  307 PRINT NS
  309 PRINT "ENTER\::PRICE/SHARE"
  311 INPUT PS
  313 PRINT PS
  315 PRINT "ENTER\::PERIOD\::DIVIDEND"
  317 INPUT PD
  319 PRINT PD
  320 PRINT "ENTER\::UNDERLYING\::COMMISSION"
  322 INPUT UC
  324 PRINT UC
  325 CLS 
  326 PRINT "ENTER\::NO.\::OF\::CALLS"
  327 INPUT NC
  329 PRINT NC
  332 PRINT "ENTER\::PREMIUM"
  334 INPUT PR
  336 PRINT PR
  340 PRINT "ENTER\::OPTION\::COMMISSION"
  342 INPUT OC
  344 PRINT OC
  347 
  350 LET PR=PR*100
  360 LET L1=NS*PS
  362 LET L2=L1+UC
  364 LET L3=NC*PR
  366 LET L4=L3-OC
  370 LET D3=PD*NS
  372 LET P1=NS*P
  380 LET L5=P1-(L2+UC)
  382 LET L6=L5+D3+L4
  390 LET R1=L6/L2
  392 LET R2=R1*(365/D2)
  400 LET R1=R1*100
  402 LET R2=R2*100
  410 LET L7=D3+L4
  412 LET R3=100*(L7/L2)
  414 LET R4=R3*(365/D2)
  420 LET L8=(L2-L7)/NS
  430 CLS 
  432 PRINT AT 0,2;"COVERED\::OPTION\::ANALYSIS--";S$
  434 PRINT AT 1,1;"\::\::\::\::\::\::EXERCISED\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
  436 PRINT AT 2,1;"ROI= ";R1
  438 PRINT AT 3,1;"ANN.\::ROI= ";R2
  440 PRINT AT 4,1;"NET\::RETURN= ";L6
  442 PRINT AT 5,1;"\::\::\::\::\::\::UNEXERCISED\::\::\::\::\::\::\::\::\::\::\::\::\::"
  444 PRINT AT 6,1;"ROI= ";R3
  446 PRINT AT 7,1;"ANN.\::ROI= ";R4
  448 PRINT AT 8,1;"NET\::RETURN= ";L7
  450 PRINT AT 9,1;"\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::\::"
  460 PRINT AT 10,1;"NET PROCEEDS: $";L4
  590 PRINT AT 11,1;"BRK.EVEN $";L8;" /SHARE"
  595 PRINT AT 12,1;"NET CAPITAL INVESTED $";L2-L4
  650 PRINT AT 13,1;"BUY ";NS;" SHARES AT ";PS
  660 PRINT AT 14,1;"SELL ";NC;" OPTIONS AT ";PR/100
  670 PRINT AT 15,1;"DAYS TO EXPIRATION ";D2
  680 LET N=D1-1
  682 GO SUB 3000
  684 PRINT AT 16,1;"LAST TRADING DAY ";Z$
  700 PRINT AT 17,1;"COMMISSIONS: "
  702 PRINT AT 18,4;"STOCK= ";UC;" OPTION= ";OC
  710 PRINT AT 19,1;"PERIOD DIVIDEND= ";PD
  720 PRINT AT 20,1;"STRIKE PRICE= $";P
  750 
  780 PRINT AT 21,1;"CONTINUE\::? Y/N "
  785 IF INKEY$="" THEN GO TO 780
  787 IF INKEY$="Y" THEN GO TO 51
  999 STOP 
 1100 STOP 
 2000 REM 
 2003 IF Q1=1 THEN GO TO 2009
 2004 DIM T(3)
 2005 DIM W(12)
 2006 GO SUB 4000
 2009 LET Q1=1
 2011 LET T(1)=0
 2012 LET T(2)=0
 2013 LET T(3)=0
 2015 LET T(1)=VAL Z$(1 TO 2)
 2017 LET T(2)=VAL Z$(4 TO 5)
 2019 LET T(3)=VAL Z$(7 TO 8)
 2021 IF T(3)<48 THEN LET T(3)=T(3)+100
 2023 LET T(3)=T(3)-48
 2024 LET JJ=INT (1+T(3)/4)
 2026 IF JJ<0 THEN LET JJ=0
 2028 IF T(1)<3 AND (INT (T(3)/4)=(T(3)/4)) THEN LET JJ=JJ-1
 2030 LET T(1)=W(T(1))
 2032 LET NZ=T(1)+T(2)+(T(3)*365)+JJ
 2036 RETURN 
 3000 FOR B=0 TO 99
 3001 LET Q7=(B/4)-INT (B/4)
 3002 GO SUB 4500
 3003 IF 0>=N-(365+Q7) THEN GO TO 3007
 3004 LET N=(N-(365+Q7))
 3005 NEXT B
 3006 STOP 
 3007 LET Q8=48+B
 3008 LET Q(2)=28+Q7
 3009 FOR A=1 TO 12
 3010 IF 0>=N-Q(A) THEN GO TO 3020
 3012 LET N=N-Q(A)
 3014 NEXT A
 3017 STOP 
 3020 LET Q9=A
 3025 LET P7=N
 3030 LET Z$=STR$ (Q9)+"/"+STR$ (P7)+"/"+STR$ (Q8)
 3050 RETURN 
 4000 LET W(1)=0
 4001 LET W(2)=31
 4002 LET W(3)=59
 4003 LET W(4)=90
 4004 LET W(5)=120
 4006 LET W(6)=151
 4008 LET W(7)=181
 4009 LET W(8)=212
 4010 LET W(9)=243
 4011 LET W(10)=273
 4012 LET W(11)=304
 4013 LET W(12)=334
 4015 RETURN 
 4500 REM 
 4510 IF Q7=0 THEN LET Q7=1
 4520 IF Q7=1 THEN RETURN 
 4530 LET Q7=0
 4540 RETURN 
 5000 REM 
 5010 PRINT AT 10,10;"TS-STOCK"
 5012 PRINT AT 11,3;"COVERED OPTION ANALYSIS"
 5020 FOR N=1 TO 25
 5030 NEXT N
 5040 CLS 
 5099 RETURN 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top