Here is an example of rules created through genetic programming to simulate trades in one asset with data from other assets.
This example uses daily close values to simulate trades entering long at the next trading day's close value of NASDAQ 100 with and exiting at the close the next trading day.
The inputs are close values for the current trading day (suffix raw000), and close values for the previous 21 trading days (suffixes raw001 through raw021) downloaded from Yahoo finance for the following:
The software supports the interest rates, equities, and volatility as separate types as in this post, and operations between different types result in undef values which evaluate false in the if statements.
In the following generated pseudocode rules, "return 1" means the trade would be entered on the close of the next trading day. Each block ending with a "return 1" is an individual rule from a separate run of the rule generating software.
The training data had 5310 simulated trades starting 1993-06-04 through 2014-07-03.
The out-of-sample evaluation data had 2275 simulated trades starting 2014-07-07 through 2023-07-28 with
total return 260.67% (not including dividends or trading costs); compound annual return 15.20%; mean return 0.0564%; median return 0.1121%; winning percent 55.47
The evaluation period with the generated rules applied had 1676 simulated, one-trading-day trades (73.67% of the total evaluation trading days) with
total return 643.1014% (not including dividends or trading costs); compound annual return 24.76%; mean return 0.1197%; median return 0.1554%; winning percent 57.88
If trades on consecutive trading days were combined (total return unchanged), there would have been 227 trades with
mean return 0.8874%; median return 0.7334%; winning percent 69.16
The combined trades would have lasted from 1 to 89 trading days with a mean 7.38 trading days and a median 3 trading days.
Each individual rule had better performance per trade on the out-of-sample data than the equivalent buy-and-hold trades. I think there is a reasonable chance the rules would have better performance than buy-and-hold trades in the future.
Comments?
This example uses daily close values to simulate trades entering long at the next trading day's close value of NASDAQ 100 with and exiting at the close the next trading day.
The inputs are close values for the current trading day (suffix raw000), and close values for the previous 21 trading days (suffixes raw001 through raw021) downloaded from Yahoo finance for the following:
- irxrawNNN -- 13 Week Treasury Bill (^IRX)
- fvxrawNNN -- Treasury Yield 5 Years (^FVX)
- tnxrawNNN -- Treasury Yield 10 Years (^TNX)
- tyxrawNNN -- Treasury Yield 30 Years (^TYX)
- aordrawNNN -- ALL ORDINARIES (^AORD)
- asx200rawNNN -- S&P/ASX 200 (^AXJO)
- jkserawNNN -- IDX COMPOSITE (^JKSE)
- hsirawNNN -- HANG SENG INDEX (^HSI)
- vixrawNNN -- CBOE Volatility Index (^VIX)
The software supports the interest rates, equities, and volatility as separate types as in this post, and operations between different types result in undef values which evaluate false in the if statements.
In the following generated pseudocode rules, "return 1" means the trade would be entered on the close of the next trading day. Each block ending with a "return 1" is an individual rule from a separate run of the rule generating software.
Code:
# types_for_runtime_checking ^(?:vix)raw\d ^(?:fvx|irx|tnx|tyx)raw\d ^(?:aord|asx200|bfx|bvsp|cac40|dji|djt|dju|gdaxi|gspc|gsptse|hsi|ixic|jkse|mid|mxx|n225|nd100|ndbank|ndfin|ndind|ndinsr|ndtran|nya|rua|rui|rut|sp100|sp600|spcd|spcst|spenrg|spfin|sphe|spind|spmat|sptech|sptel|sput|ta125|uty|w5000|xau|xoi)raw\d
R0 = R1 = undef
R1 = 0.967139 * aordraw013
if aordraw004 >= R1 R1 = 0.873757 * tyxraw013
R0 = 0.967687 * tnxraw005
if R1 > irxraw002 if R1 < R0 if R0 <= tnxraw000 if tyxraw019 >= R0 R0 = 0.925426 * tyxraw002
if fvxraw010 > R0 if tnxraw018 >= R0 if irxraw017 <= R1 return 1
R1 = R0 = undef
R0 = 0.874442 * vixraw018
if R0 > vixraw007 R0 = 0.872526 * vixraw021
if R0 <= vixraw005 if vixraw000 >= R0 R0 = 0.924405 * vixraw015
R1 = 0.930402 * vixraw018
if R0 <= vixraw018 R1 = 0.936894 * vixraw011
if R1 < vixraw016 if vixraw010 <= R0 if vixraw008 < R0 return 1
R0 = R1 = undef
R0 = 0.836893 * irxraw016
if R0 < irxraw013 R1 = 0.105203 * fvxraw019
R0 = 0.978807 * irxraw021
if irxraw010 < R0 R0 = 0.724784 * irxraw015
if irxraw017 <= R0 R0 = 0.851472 * irxraw020
if R1 > irxraw002 R1 = 0.946637 * asx200raw015
if asx200raw000 > R1 if R0 < irxraw013 if asx200raw008 >= R1 if asx200raw017 >= R1 return 1
R0 = R1 = undef
R1 = 0.133722 * fvxraw011
R0 = 0.123306 * fvxraw017
if R1 >= R0 R1 = 0.983625 * asx200raw003
if R1 < asx200raw008 R1 = 0.0825821 * fvxraw000
R0 = 0.703178 * irxraw018
if R1 >= irxraw021 if irxraw010 > R0 R0 = 0.123306 * fvxraw017
if R0 >= R1 if irxraw010 > R0 R0 = 0.123306 * fvxraw017
if irxraw010 > R0 if irxraw009 < R0 R0 = 0.123306 * fvxraw017
if R0 > irxraw012 if irxraw015 < R0 return 1
R0 = R1 = undef
R1 = 0.934906 * asx200raw018
R0 = 0.979026 * jkseraw000
if jkseraw019 >= R0 R0 = 0.518442 * asx200raw003
if jkseraw015 >= R0 if R1 < asx200raw001 if R1 < asx200raw009 R0 = 0.953588 * jkseraw001
if jkseraw010 <= R0 if R1 > asx200raw004 R1 = 0.975936 * jkseraw010
if R1 > jkseraw008 if R1 <= asx200raw009 if jkseraw021 >= R0 if R1 <= asx200raw007 return 1
R0 = R1 = undef
R1 = 0.993643 * asx200raw002
if aordraw013 >= R1 if asx200raw010 <= R1 R1 = 0.968812 * asx200raw003
if aordraw014 < R1 R1 = 0.965842 * aordraw009
if asx200raw020 <= R1 if aordraw004 > R1 R0 = 0.999385 * asx200raw021
if aordraw018 >= R0 R0 = 0.983193 * asx200raw018
R1 = 0.968812 * asx200raw003
if R1 > asx200raw021 if R1 >= R0 R1 = 0.967574 * aordraw001
if R0 <= asx200raw019 if asx200raw002 > R1 if R0 < asx200raw005 if aordraw000 > R1 return 1
R1 = R0 = undef
R0 = 0.970766 * aordraw007
if aordraw015 > R0 R0 = 0.996531 * asx200raw011
if R0 > asx200raw012 R1 = 0.995876 * asx200raw011
R0 = 0.993601 * asx200raw014
if R1 < aordraw004 if R1 > R0 if aordraw016 >= R0 if R1 <= aordraw003 return 1
The training data had 5310 simulated trades starting 1993-06-04 through 2014-07-03.
The out-of-sample evaluation data had 2275 simulated trades starting 2014-07-07 through 2023-07-28 with
total return 260.67% (not including dividends or trading costs); compound annual return 15.20%; mean return 0.0564%; median return 0.1121%; winning percent 55.47
The evaluation period with the generated rules applied had 1676 simulated, one-trading-day trades (73.67% of the total evaluation trading days) with
total return 643.1014% (not including dividends or trading costs); compound annual return 24.76%; mean return 0.1197%; median return 0.1554%; winning percent 57.88
If trades on consecutive trading days were combined (total return unchanged), there would have been 227 trades with
mean return 0.8874%; median return 0.7334%; winning percent 69.16
The combined trades would have lasted from 1 to 89 trading days with a mean 7.38 trading days and a median 3 trading days.
Each individual rule had better performance per trade on the out-of-sample data than the equivalent buy-and-hold trades. I think there is a reasonable chance the rules would have better performance than buy-and-hold trades in the future.
Comments?


