John Hurley, CS 461
Drools Expert + ECJ SystemCombined my rules-based system for testing
strategies with GA from ECJDid not use GUI due to resource issues. Just used the
GA functionalityThis still added up to a very bulky system for my four-
year old laptop (1 gig RAM). Performance was difficult, but I still got good results
Developed rules for an individual investor with a single buy rule and a single short rule, not a metainvestor. My testing system can run a metainvestor, but this was too slow to run with the GA.
How This Could Be UsefulTransaction rules, including the learned ones, are
expressed in Drools Rules languageRules are separate from functionalityEasy for humans, including subject matter experts
who are nonprogrammers, to understand Learned rules can be easily studied by humans,
applied to other testing logic, tweaked, compared to programmed rules
Additional functionality could be built for nonprogrammers to track the application of each easily-understood rule
Drools Expert + ECJ SystemWhat happens at runtime:My setup code calls ECJ’s Evolve object, which loads stock
data from file
for each genome:
Evolve generates genome, calls fitness functionFitness function calls my InvestorTester InvestorTester converts genome from array of bools to
if/then rules, writes the rules to a Drools rule file, saves file InvestorTester adds Investor, the new rules file, a standard
rule file, and necessary stock info to Drools runtimeDrools applies rules, which are implemented by Investor
methods InvestorTester returns the ending wealth to fitness function,
which returns it to Evolve
Drools Expert + ECJ SystemAt end of GA run:Evolve reports best genome based on end-of-
period wealthUser tests this genome again on training data
(matches outcome of GA test but also generates a chart with comparison to buy and hold), then tests on test data
Drools Expert + ECJ SystemData Split75% train, 25% testAllocation is stored in the data file, so I can run repeated trials on
the same data and preserve the data split from a particular training run to use in testing
Each day, a standard rule orders all investors to close all positions at the closing price
If the day is not in the current set (ie, if we are training and it is a test day or if we are testing and it is a train day) nothing else happens
If the day is in the current set, buy or short rules are executed If day is in the set, we capture *tomorrow’s* price change, not
today’s. In other words, the allocation is offset by one day. This is OK because we are interested in the *ending* value, not the particular days. Much simpler to implement than any other approach I could think of …
Drools Expert + ECJ SystemLimitation on investors
file system sync issues
Drools Expert + ECJ System
From Gen 0
Drools Expert + ECJ System
From Gen 10,Same Run
Drools Expert + ECJ System
From Gen 16,Same Run
Genome 1001111111111111001000101010111001Training Data
Genome 1001111111111111001000101010111001Test Data
Drools Expert + ECJ Systempackage stockInvestmentrule “clearout"
salience 10when
inv: Investor()tick : TimeTick(tickNum:tickNum)
stock: Stock(price:price) then
inv.sellAll(price);inv.closeShort(price);
end
package stockInvestmentrule "GA Test Buy [Z@16caf43"
salience 1 when
Inv:InvGA()tick : TimeTick()stock: Stock(price:price && trainTest:trainTest&&
lastTick:lastTick && maTen:maTen && maFifty:maFifty
&& maTwoHundred:maTwoHundred)eval(trainTest == "train")eval(lastTick == "up")(moving average tests all evaluated true for all values,
ie ignore them)then
inv.buyAll(price);end
Drools Expert + ECJ System
rule "GA Test Sell [Z@16caf43"salience 1 wheninv:InvGA()tick : TimeTick()stock: Stock(price:price && trainTest:trainTest&& lastTick:lastTick && maTen:maTen && maFifty:maFifty && maTwoHundred:maTwoHundred)eval(trainTest == "train")eval((price < maTen) == true)eval((price < maFifty) == true)eval((price < maTwoHundred) == true)eval((maTen < maTwoHundred) == true)eval((maFifty < maTwoHundred) == false)theninv.shortMax(price);
end
Drools Expert + ECJ System
Drools Expert + ECJ System