10 CLEAR
20 REM *** PROGRAM BY CHRISTOPHER D. VAN DER KAAY, PH.D. 2025 ***
30 REM *** SIMPLE EXPONENTIAL SMOOTHING FORECASTING TOOL (MBASIC-80) ***
40 REM *** REM - UP TO 100 DATA POINTS; FORECAST HORIZON N+H b	$ 100 ***
50 REM *** OPTIMIZES SMOOTHING PARAMETER ALPHA BY BRUTE-FORCE SEARCH ***
60 REM *** COMPUTES AND DISPLAYS STATISTICAL ACCURACY MEASURES ***
70 PRINT STRING$(79, "=")
80 PRINT TAB(20); "WELCOME TO THE TIME-SERIES FORECASTING TOOL"
90 PRINT STRING$(79, "=")
100 PRINT
110 PRINT TAB(10); "SIMPLE EXPONENTIAL SMOOTHING METHOD FOR TIME-SERIES FORECASTING"
120 PRINT TAB(10); STRING$(60, "-")
130 PRINT
140 PRINT TAB(5); "THIS PROGRAM USES THE SIMPLE EXPONENTIAL SMOOTHING METHOD"
150 PRINT TAB(5); "TO FORECAST FUTURE VALUES IN A TIME SERIES BASED ON HISTORICAL"
160 PRINT TAB(5); "DATA POINTS. IT CALCULATES FORECASTED VALUES BY AUTOMATICALLY"
170 PRINT TAB(5); "DETERMINING THE OPTIMAL ALPHA VALUE THAT MINIMIZES THE FORECAST ERROR"
180 PRINT TAB(5); "AND PROVIDES VARIOUS STATISTICAL MEASURES OF FORECAST ACCURACY."
190 PRINT TAB(5); "THIS METHOD IS USEFUL FOR SERIES WITH NO TREND OR SEASONAL PATTERN."
200 PRINT
210 PRINT STRING$(79, "-")
220 PROMPT$ = "LEARN ABOUT THE FORECAST ACCURACY METRICS BEFORE PROCEEDING? (Y/N): "
230 GOSUB 3650
240 IF RESP$ = "Y" THEN GOSUB 1830
250 PRINT STRING$(79, "-")
260 PRINT
270 PRINT "ENTER THE HISTORICAL DATA POINTS AND FORECAST HORIZON."
280 PRINT "THE PROGRAM WILL AUTOMATICALLY CALCULATE THE OPTIMAL ALPHA VALUE"
290 PRINT "THAT MINIMIZES THE FORECAST ERROR."
300 PRINT
310 PRINT STRING$(79, "=")
320 PRINT
330 DIM Y(100), F(100), S(100)   ' Y() = INPUT DATA; F() = FORECASTS; S() = SMOOTHED VALUES
340 DIM U(100), L(100)  ' U() AND L() FOR UPPER/LOWER CONFIDENCE INTERVALS; ALL ARRAYS INDEX 1..N+H
350 INPUT "ENTER NUMBER OF HISTORICAL DATA POINTS: "; N
360 IF N < 2 OR N > 100 THEN PRINT "INVALID INPUT. ENTER AN INTEGER BETWEEN 2 AND 100.": GOTO 350
370 AVE = 0
380 FOR I = 1 TO N
390 INPUT "ENTER DATA POINT "; A$   ' ACCEPT INPUT AS STRING TO VALIDATE NUMERICS
400 Y(I) = VAL(A$)   ' CONVERT TO NUMERIC VALUE
410 IF Y(I) = 0 AND A$ <> "0" THEN PRINT "INVALID INPUT. ENTER A NUMERICAL VALUE.": GOTO 390   ' ALLOW "0" ONLY IF INPUT IS STRING "0"
420 AVE = AVE + Y(I)
430 NEXT I
440 PRINT
450 GOSUB 3750 ' *** EXPLANATORY MESSAGE ABOUT STATIONARITY TEST ***
460 PROMPT$ = "VIEW THE FIRST-DIFFERENCED SERIES FOR STATIONARITY CHECK? (Y/N): "
470 GOSUB 3650
480 IF RESP$ = "Y" THEN GOSUB 2710
490 PROMPT$ = "COMPARE MEANS AND VARIANCES OF THE FIRST AND SECOND HALVES? (Y/N): "
500 GOSUB 3650
510 IF RESP$ = "Y" THEN GOSUB 2900
520 AVE = AVE / N
530 INPUT "ENTER FORECAST HORIZON: "; H
540 IF H <= 0 THEN PRINT "INVALID INPUT. ENTER A POSITIVE INTEGER.": GOTO 530
550 IF N + H > 100 THEN PRINT "N + H EXCEEDS 100. REDUCE FORECAST HORIZON.": GOTO 530
560 PRINT
570 INPUT "ENTER STEP SIZE (BETWEEN 0.001 AND 0.1): "; ALPHASTEP
580 IF ALPHASTEP <= 0 OR ALPHASTEP > .1 THEN PRINT "INVALID INPUT. ENTER A VALUE BETWEEN 0.001 AND 0.1.": GOTO 570
590 PRINT "CALCULATING OPTIMAL ALPHA VALUE..."
600 PRINT "USING STEP SIZE OF "; ALPHASTEP; " FOR ALPHA SEARCH..."
610 TSS = 0
620 FOR I = 1 TO N
630 TSS = TSS + (Y(I) - AVE) ^ 2
640 NEXT I
650 DIM TEMPS(100), TEMPF(100)
660 BALPHA = 0
670 MINMSE = 1E+30
680 FOR ALPHA = ALPHASTEP TO .99 STEP ALPHASTEP  ' BRUTE-FORCE GRID SEARCH FOR ALPHA IN [ALPHASTEP, 0.99]
690 TEMPS(1) = Y(1)
700 TEMPF(1) = Y(1)
710 SSE = 0
720 FOR I = 2 TO N   ' LOOP OVER DATA TO COMPUTE MSE FOR CURRENT ALPHA
730 TEMPS(I) = ALPHA * Y(I) + (1 - ALPHA) * TEMPS(I-1)
740 TEMPF(I) = TEMPS(I-1)
750 SSE = SSE + (Y(I) - TEMPF(I)) ^ 2
760 NEXT I
770 MSE = SSE / N
780 PRINT "ALPHA = "; ALPHA; " MSE = "; MSE  'PRINT ALPHA AND MSE
790 IF MSE < MINMSE THEN GOTO 810    ' KEEP MINIMUM MSE AND CORRESPONDING ALPHA
800 GOTO 830
810 MINMSE = MSE
820 BALPHA = ALPHA
830 NEXT ALPHA
840 ALPHA = BALPHA
850 PRINT CHR$(26):PRINT "OPTIMAL ALPHA VALUE IS: "; ALPHA
860 PRINT
870 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
880 PRINT
890 S(1) = Y(1)
900 F(1) = Y(1)
910 SSE = 0
920 MAPE = 0
930 MAPECOUNT = 0
940 FOR I = 2 TO N
950 S(I) = ALPHA * Y(I) + (1 - ALPHA) * S(I-1)   ' COMPUTE SMOOTHED VALUE FOR PERIOD I
960 F(I) = S(I-1)   ' FORECAST FOR I IS PREVIOUS SMOOTHED VALUE
970 SSE = SSE + (Y(I) - F(I)) ^ 2
980 IF Y(I) <> 0 THEN GOTO 1000   ' ONLY CALCULATE MAPE IF ACTUAL DOES NOT EQUAL 0 TO AVOID DIVISION BY ZERO
990 GOTO 1020
1000 MAPE = MAPE + ABS((Y(I) - F(I)) / Y(I))
1010 MAPECOUNT = MAPECOUNT + 1
1020 NEXT I
1030 S(N+1) = ALPHA * Y(N) + (1 - ALPHA) * S(N)
1040 F(N+1) = S(N)
1050 FOR I = N+2 TO N+H
1060 S(I) = ALPHA * F(I-1) + (1 - ALPHA) * S(I-1)
1070 F(I) = S(I-1)
1080 NEXT I
1090 REM *** COMPUTE FORECAST INTERVALS ***
1100 GOSUB 3500
1110 SSE = SSE + (Y(N+1) - F(N+1)) ^ 2
1120 MSE = SSE / N
1130 MAE = 0
1140 COUNT = 0
1150 FOR I = 2 TO N
1160 MAE = MAE + ABS(Y(I) - F(I))
1170 COUNT = COUNT + 1
1180 NEXT I
1190 MAE = MAE / COUNT
1200 IF MAPECOUNT > 0 THEN MAPE = MAPE / MAPECOUNT * 100 ELSE MAPE = -1
1210 SMAPE = 0
1220 SMAPECOUNT = 0
1230 FOR I = 2 TO N
1240 NUM = ABS(Y(I) - F(I))
1250 DEN = ABS(Y(I)) + ABS(F(I))
1260 IF DEN = 0 THEN GOTO 1290   ' PREVENT DIVISION BY ZERO IF BOTH ACTUAL AND FORECAST ARE ZERO
1270 SMAPE = SMAPE + (NUM / (DEN / 2))
1280 SMAPECOUNT = SMAPECOUNT + 1
1290 NEXT I
1300 IF SMAPECOUNT > 0 THEN SMAPE = 100 * SMAPE / SMAPECOUNT ELSE SMAPE = -1
1310 PRINT CHR$(7):PRINT "FORECASTING RESULTS:"
1320 PRINT "============================================================"
1330 LINES = 0
1340 FOR I = 1 TO H
1350 PRINT "PERIOD " I;
1360 PRINT " : FORECAST = " F(N+I)
1370 PRINT "   LOWER 95% = " L(N+I)
1380 PRINT "   UPPER 95% = " U(N+I)
1390 PRINT
1400 LINES = LINES + 4
1410 IF LINES >= 15 THEN INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$: PRINT CHR$(26): LINES = 0   ' PAUSE AFTER 15 LINES
1420 NEXT I
1430 PRINT "============================================================"
1440 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
1450 PRINT
1460 PRINT "OPTIMAL ALPHA VALUE: "; ALPHA
1470 PRINT "MEAN ABSOLUTE ERROR (MAE): "; MAE
1480 PRINT "MEAN SQUARED ERROR (MSE): "; MSE
1490 PRINT "ROOT MEAN SQUARED ERROR (RMSE): "; (MSE ^ .5)
1500 PRINT "MEAN ABSOLUTE PERCENTAGE ERROR (MAPE): "; MAPE; "%"
1510 PRINT "SYMMETRIC MEAN ABSOLUTE PERCENTAGE ERROR (SMAPE): "; SMAPE; "%"
1520 PRINT
1530 REM *** DISPLAY MAPE THRESHOLDS AND INTERPRETATION ***
1540 PRINT "MAPE INTERPRETATION THRESHOLDS:"
1550 PRINT "-----------------------------------------"
1560 PRINT "MAPE < 10%           : HIGHLY ACCURATE FORECASTING"
1570 PRINT "10% <= MAPE < 20%    : GOOD FORECASTING"
1580 PRINT "20% <= MAPE < 50%    : REASONABLE FORECASTING"
1590 PRINT "MAPE >= 50%          : INACCURATE FORECASTING"
1600 PRINT "-----------------------------------------"
1610 PRINT
1620 REM *** INTERPRETATION OF MAPE ***
1630 IF MAPE <= 10 THEN GOTO 1700
1640 IF MAPE >= 10 AND MAPE <= 20 THEN GOTO 1690
1650 IF MAPE >= 20 AND MAPE < 50 THEN GOTO 1680
1660 IF MAPE >= 50 THEN GOTO 1670
1670 PRINT "INTERPRETATION: INACCURATE FORECASTING" : GOTO 1710
1680 PRINT "INTERPRETATION: REASONABLE FORECASTING" : GOTO 1710
1690 PRINT "INTERPRETATION: GOOD FORECASTING" : GOTO 1710
1700 PRINT "INTERPRETATION: HIGHLY ACCURATE FORECASTING"
1710 PRINT
1720 PRINT "(R)ESTART, (S)HOW RESULTS, (P)RINT REPORT, OR (E)ND"
1730 INPUT "(R/S/P/E): "; R$
1740 IF R$ = "R" THEN GOTO 10
1750 IF R$ = "S" THEN GOTO 1310
1760 IF R$ = "P" THEN PROMPT$ = "===> IS THE PRINTER POWERED ON AND READY? (Y/N): " : GOSUB 3650
1770 IF RESP$ = "Y" THEN GOSUB 3960 : GOTO 1720
1780 IF RESP$ = "N" THEN PRINT "SKIPPING PRINTING.": GOTO 1720
1790 IF R$ = "E" THEN GOTO 1810
1800 PRINT "INVALID INPUT. ENTER R, S, P, OR E.": GOTO 1730
1810 PRINT CHR$(7):PRINT "THANK YOU FOR USING THE TIME-SERIES FORECASTING TOOL!"
1820 END
1830 REM *** EXPLANATION SUBROUTINE ***
1840 PRINT CHR$(26)
1850 PRINT STRING$(79, "=")
1860 PRINT TAB(22); "***** FORECAST ACCURACY METRICS *****"
1870 PRINT STRING$(79, "=")
1880 GOSUB 1960 ' MAE
1890 GOSUB 2120 ' MSE
1900 GOSUB 2270 ' RMSE
1910 GOSUB 2420 ' MAPE
1920 PRINT
1930 RETURN
1940 PRINT
1950 RETURN
1960 REM *** MAE (MEAN ABSOLUTE ERROR) EXPLANATION ***
1970 PRINT 
1980 PRINT " MAE (MEAN ABSOLUTE ERROR)"
1990 PRINT STRING$(79, "-")
2000 PRINT " THE MAE MEASURES THE AVERAGE MAGNITUDE OF THE"
2010 PRINT " ERRORS IN A SET OF FORECASTS, WITHOUT CONSIDERING"
2020 PRINT " THEIR DIRECTION." 
2030 PRINT
2040 PRINT " USAGE: MAE IS USED TO UNDERSTAND THE AVERAGE"
2050 PRINT " ERROR MAGNITUDE. LOWER MAE VALUES INDICATE BETTER"
2060 PRINT " ACCURACY."
2070 PRINT STRING$(79, "-")
2080 PRINT STRING$(79, "=")
2090 PRINT
2100 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
2110 RETURN
2120 REM *** MSE (MEAN SQUARED ERROR) EXPLANATION ***
2130 PRINT 
2140 PRINT " MSE (MEAN SQUARED ERROR)"
2150 PRINT STRING$(79, "-")
2160 PRINT " THE MSE MEASURES THE AVERAGE OF THE SQUARES OF"
2170 PRINT " THE ERRORS."
2180 PRINT
2190 PRINT " USAGE: MSE PENALIZES LARGER ERRORS MORE THAN"
2200 PRINT " SMALLER ONES, MAKING IT USEFUL FOR IDENTIFYING"
2210 PRINT " MODELS THAT NEED TO MINIMIZE LARGE ERRORS."
2220 PRINT STRING$(79, "-")
2230 PRINT STRING$(79, "=")
2240 PRINT
2250 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
2260 RETURN
2270 REM *** RMSE (ROOT MEAN SQUARED ERROR) EXPLANATION ***
2280 PRINT 
2290 PRINT " RMSE (ROOT MEAN SQUARED ERROR)"
2300 PRINT STRING$(79, "-")
2310 PRINT " THE RMSE IS THE SQUARE ROOT OF THE AVERAGE OF"
2320 PRINT " THE SQUARED ERRORS."
2330 PRINT
2340 PRINT " USAGE: RMSE PROVIDES A MEASURE OF THE SPREAD OF"
2350 PRINT " THE ERRORS IN THE SAME UNITS AS THE DATA, MAKING"
2360 PRINT " IT EASIER TO INTERPRET."
2370 PRINT STRING$(79, "-")
2380 PRINT STRING$(79, "=")
2390 PRINT
2400 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
2410 RETURN
2420 REM *** MAPE (MEAN ABSOLUTE PERCENTAGE ERROR) EXPLANATION ***
2430 PRINT 
2440 PRINT " MAPE (MEAN ABSOLUTE PERCENTAGE ERROR)"
2450 PRINT STRING$(79, "-")
2460 PRINT " THE MAPE MEASURES THE AVERAGE MAGNITUDE OF THE"
2470 PRINT " ERRORS AS A PERCENTAGE OF THE ACTUAL VALUES."
2480 PRINT
2490 PRINT " USAGE: MAPE NORMALIZES THE ERRORS AS PERCENTAGES,"
2500 PRINT " FACILITATING COMPARISONS ACROSS DIFFERENT SCALES."
2510 PRINT STRING$(79, "-")
2520 PRINT STRING$(79, "=")
2530 PRINT
2540 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
2550 REM *** SMAPE (SYMMETRIC MEAN ABSOLUTE PERCENTAGE ERROR) EXPLANATION ***
2560 PRINT 
2570 PRINT " SMAPE (SYMMETRIC MEAN ABSOLUTE PERCENTAGE ERROR)"
2580 PRINT STRING$(79, "-")
2590 PRINT " THE SMAPE IS A MODIFICATION OF MAPE THAT IS SYMMETRIC,"
2600 PRINT " MEANING IT TREATS OVER- AND UNDER-FORECASTS EQUALLY AND"
2610 PRINT " HANDLES ZERO OR NEAR-ZERO ACTUAL VALUES BETTER."
2620 PRINT
2630 RETURN
2640 PRINT " USAGE: SMAPE IS USEFUL FOR TIME SERIES WHERE ACTUALS"
2650 PRINT " CAN BE ZERO OR CLOSE TO ZERO. IT PROVIDES A PERCENTAGE"
2660 PRINT " ERROR THAT IS BOUNDED BETWEEN 0% AND 200%."
2670 PRINT STRING$(79, "-")
2680 PRINT STRING$(79, "=")
2690 PRINT
2700 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
2710 REM *** FIRST-DIFFERENCING SUBROUTINE WITH PAGING ***
2720 REM *** DISPLAYS THE FIRST-DIFFERENCED TIME SERIES (Y(I) - Y(I-1)), PAUSING EVERY 16 LINES ***
2730 PRINT CHR$(26)
2740 PRINT "FIRST-DIFFERENCED SERIES"
2750 PRINT STRING$(60, "-")
2760 LINES = 0
2770 FOR I = 2 TO N
2780 D = Y(I) - Y(I - 1)
2790 PRINT "DIFF("; I; ") = "; D
2800 LINES = LINES + 1
2810 IF LINES = 16 THEN GOSUB 2860: LINES = 0
2820 NEXT I
2830 PRINT STRING$(60, "-")
2840 IF LINES > 0 THEN GOSUB 2860
2850 RETURN
2860 REM *** PAUSE FOR PAGINATION ***
2870 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
2880 PRINT CHR$(26)
2890 RETURN
2900 REM *** MEAN AND VARIANCE STABILITY CHECK ***
2910 REM *** COMPUTE MIDPOINT OF SERIES ***
2920 MID = INT(N / 2)
2930 SUM1 = 0: SUM2 = 0
2940 FOR I = 1 TO MID
2950 SUM1 = SUM1 + Y(I)
2960 NEXT I
2970 FOR I = MID + 1 TO N
2980 SUM2 = SUM2 + Y(I)
2990 NEXT I
3000 MEAN1 = SUM1 / MID
3010 MEAN2 = SUM2 / (N - MID)
3020 REM *** NOW COMPUTE VARIANCES ***
3030 VAR1 = 0: VAR2 = 0
3040 FOR I = 1 TO MID
3050 VAR1 = VAR1 + (Y(I) - MEAN1) ^ 2
3060 NEXT I
3070 VAR1 = VAR1 / MID
3080 FOR I = MID + 1 TO N
3090 VAR2 = VAR2 + (Y(I) - MEAN2) ^ 2
3100 NEXT I
3110 VAR2 = VAR2 / (N - MID)
3120 REM *** PRINT RESULTS ***
3130 PRINT CHR$(26)
3140 PRINT "STATIONARITY CHECK: MEAN AND VARIANCE COMPARISON"
3150 PRINT STRING$(60, "-")
3160 PRINT "FIRST HALF MEAN     = "; MEAN1
3170 PRINT "SECOND HALF MEAN    = "; MEAN2
3180 PRINT "FIRST HALF VARIANCE = "; VAR1
3190 PRINT "SECOND HALF VARIANCE= "; VAR2
3200 PRINT STRING$(60, "-")
3210 IF ABS(MEAN2 - MEAN1) > .1 * ABS(MEAN1) THEN GOTO 3240   ' WARN IF MEAN SHIFT >10%
3220 IF VAR1 <> 0 THEN IF ABS(VAR2 - VAR1) > .2 * VAR1 THEN GOTO 3240   ' WARN IF VARIANCE SHIFT >20%
3230 GOTO 3250
3240 PRINT "WARNING: MEAN/VARIANCE SHIFT DETECTED! POSSIBLE NON-STATIONARITY!"
3250 PRINT
3260 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
3270 RETURN
3280 REM *** MAPE (MEAN ABSOLUTE PERCENTAGE ERROR) ***
3290 PRINT STRING$(79, "=")
3300 PRINT " MAPE (MEAN ABSOLUTE PERCENTAGE ERROR)"
3310 PRINT STRING$(79, "-")
3320 PRINT " THE MAPE MEASURES THE AVERAGE MAGNITUDE OF THE"
3330 PRINT " ERRORS AS A PERCENTAGE OF THE ACTUAL VALUES. IT"
3340 PRINT " IS CALCULATED AS:"
3350 PRINT
3360 PRINT "   MAPE = (100/N) * SUM(|(FORECASTI - ACTUALI) / ACTUALI|)"
3370 PRINT
3380 PRINT " WHERE:"
3390 PRINT "   N IS THE NUMBER OF FORECASTS"
3400 PRINT "   FORECASTI IS THE FORECASTED VALUE"
3410 PRINT "   ACTUALI IS THE ACTUAL VALUE"
3420 PRINT
3430 PRINT " USAGE: MAPE NORMALIZES THE ERRORS AS PERCENTAGES,"
3440 PRINT " FACILITATING COMPARISONS ACROSS DIFFERENT SCALES."
3450 PRINT STRING$(79, "-")
3460 PRINT STRING$(79, "=")
3470 PRINT
3480 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
3490 RETURN
3500 REM *** SUBROUTINE FOR COMPUTING FORECAST INTERVALS ***
3510 REM *** COMPUTE FORECAST INTERVALS ***
3520 RESVAR = SSE / N
3530 PHI = 1 - ALPHA
3540 FOR I = 1 TO H
3550 VARFACTOR = 0
3560 FOR J = 0 TO I - 1
3570 VARFACTOR = VARFACTOR + (PHI ^ (2 * J))
3580 NEXT J
3590 STDERR = SQR(RESVAR * VARFACTOR)
3600 ZVAL = 1.96  ' 95% CONFIDENCE
3610 U(N+I) = F(N+I) + ZVAL * STDERR
3620 L(N+I) = F(N+I) - ZVAL * STDERR
3630 NEXT I
3640 RETURN
3650 REM *** Y/N VALIDATION SUBROUTINE ***
3660 REM *** PROMPTS USER WITH PROMPT$, ACCEPTS ONLY Y/N (CASE-INSENSITIVE), REPEATS UNTIL VALID ***
3670 PRINT
3680 PRINT PROMPT$;
3690 INPUT ""; RESP$
3700 IF RESP$ = "" THEN PRINT "ENTER Y OR N.": GOTO 3680
3710 RESP$ = LEFT$(RESP$,1)
3720 IF RESP$ = "Y" OR RESP$ = "Y" THEN RESP$ = "Y": RETURN
3730 IF RESP$ = "N" OR RESP$ = "N" THEN RESP$ = "N": RETURN
3740 PRINT "INVALID INPUT. ENTER Y OR N.": GOTO 3680
3750 REM *** STATIONARITY CHECK EXPLANATION SUBROUTINE ***
3760 PRINT CHR$(26)
3770 PRINT STRING$(79, "=")
3780 PRINT "STATIONARITY CHECK EXPLANATION"
3790 PRINT STRING$(79, "-")
3800 PRINT "THE PROGRAM OPTIONALLY CHECKS FOR STATIONARITY BY COMPARING"
3810 PRINT "THE MEAN AND VARIANCE OF THE FIRST HALF AND SECOND HALF OF"
3820 PRINT "THE INPUT TIME SERIES."
3830 PRINT
3840 PRINT "A WARNING WILL BE ISSUED IF EITHER OF THE FOLLOWING IS TRUE:"
3850 PRINT " - THE ABSOLUTE DIFFERENCE IN MEANS EXCEEDS 10% OF THE"
3860 PRINT "   FIRST HALF'S MEAN."
3870 PRINT " - OR THE ABSOLUTE DIFFERENCE IN VARIANCES EXCEEDS 20% OF"
3880 PRINT "   THE FIRST HALF'S VARIANCE."
3890 PRINT
3900 PRINT "THIS INDICATES A SHIFT IN LEVEL OR SPREAD, SUGGESTING"
3910 PRINT "THE DATA MAY BE NON-STATIONARY, WHICH CAN REDUCE THE"
3920 PRINT "ACCURACY OF SIMPLE EXPONENTIAL SMOOTHING FORECASTS."
3930 PRINT STRING$(79, "-")
3940 INPUT "PRESS RETURN TO CONTINUE..."; DUMMY$
3950 RETURN
3960 REM *** STATISTICAL REPORT ***
3970 LPRINT STRING$(79, "=")
3980 LPRINT TAB(22); "STATISTICAL SUMMARY REPORT"
3990 LPRINT STRING$(79, "=")
4000 LPRINT "INPUT DATA POINTS: "; N; TAB(36); "FORECAST HORIZON: "; H
4010 LPRINT
4020 LPRINT "OPTIMAL ALPHA: "; ALPHA
4030 LPRINT "MEAN ABSOLUTE ERROR (MAE): "; MAE
4040 LPRINT "MEAN SQUARED ERROR (MSE): "; MSE
4050 LPRINT "ROOT MEAN SQUARED ERROR (RMSE): "; (MSE ^ .5)
4060 IF MAPE >= 0 THEN LPRINT "MEAN ABSOLUTE PERCENTAGE ERROR (MAPE): "; MAPE; "%" : GOTO 4080
4070 LPRINT "MEAN ABSOLUTE PERCENTAGE ERROR (MAPE): N/A"
4080 IF SMAPE >= 0 THEN LPRINT "SYMMETRIC MAPE (SMAPE): "; SMAPE; "%" : GOTO 4100
4090 LPRINT "SYMMETRIC MAPE (SMAPE): N/A"
4100 LPRINT
4110 LPRINT "MAPE INTERPRETATION:"
4120 IF MAPE < 0 THEN LPRINT "   N/A" : GOTO 4170
4130 IF MAPE < 10 THEN LPRINT "   HIGHLY ACCURATE FORECASTING" : GOTO 4170
4140 IF MAPE < 20 THEN LPRINT "   GOOD FORECASTING" : GOTO 4170
4150 IF MAPE < 50 THEN LPRINT "   REASONABLE FORECASTING" : GOTO 4170
4160 LPRINT "   INACCURATE FORECASTING"
4170 LPRINT
4180 LPRINT STRING$(79, "=")
4190 LPRINT TAB(10); "*** END OF REPORT ***"
4200 LPRINT STRING$(79, "=")
4210 PRINT "PRINT COMPLETE!"
4220 RETURN
