import alogos as al
import unified_map as um
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA, GOOG
import alogos as al
ebnf_text = """
PROGRAM = L00 NL L01 NL L02 NL L03 NL L04 NL L05 NL L06 NL L07 NL L08 NL L09 NL L10 NL L11 NL L12 NL L13 NL L14 NL L15 NL L16 NL L17 NL L18 NL L19 NL L20 NL L21
L00 = "class EvoStrat(Strategy):"
L01 = " n1 = " NUMBER
L02 = " n2 = " NUMBER
L03 = " n3 = " NUMBER
L04 = " n4 = " NUMBER
L05 = ""
L06 = " def init(self):"
L07 = " close = self.data.Close"
L08 = " self.sma1 = self.I(SMA, close, self.n1)"
L09 = " self.sma2 = self.I(SMA, close, self.n2)"
L10 = " self.sma3 = self.I(SMA, close, self.n3)"
L11 = " self.sma4 = self.I(SMA, close, self.n4)"
L12 = ""
L13 = " def next(self):"
L14 = " if " CONDITION ":"
L15 = " " ACTION
L16 = " if " CONDITION ":"
L17 = " " ACTION
L18 = " if " CONDITION ":"
L19 = " " ACTION
L20 = " if " CONDITION ":"
L21 = " " ACTION
NL = "\n"
CONDITION = "crossover(" VAR ", " VAR ")"
VAR = "self.sma1" | "self.sma2" | "self.sma3" | "self.sma4"
ACTION = "self.buy()" | "self.sell()"
NUMBER = NONZERO_DIGIT DIGIT | DIGIT
NONZERO_DIGIT = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
DIGIT = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
"""
grammar = al.Grammar(ebnf_text=ebnf_text)
The objective function gets a candidate solution (=a string of the grammar's language) and returns a fitness value for it. This is done by 1) executing the string as Python program, which creates a class that implements a trading strategy, and 2) backtest that strategy on chosen data.
def string_to_strategy(string):
var = dict()
exec(string, None, var)
return var['EvoStrat']
def strategy_to_performance(strat):
bt = Backtest(GOOG, strat, cash=10000, commission=.002, exclusive_orders=True)
output = bt.run()
# return output['Return [%]']
# return output['SQN']
# return output['Calmar Ratio']
# return output['Sharpe Ratio']
return output['Sortino Ratio']
def objective_function(string):
strat = string_to_strategy(string)
ret = strategy_to_performance(strat)
return ret
objective_function(grammar.generate_string())
Check if grammar and objective function work as intended.
random_string = grammar.generate_string()
print(random_string)
objective_function(random_string)
ea = al.EvolutionaryAlgorithm(
grammar, objective_function, 'max', max_generations=100,
population_size=100, offspring_size=100, evaluator=um.univariate.parallel.futures, verbose=True)
best_ind = ea.run()
string = best_ind.phenotype
print(string)
objective_function(string)
strat = string_to_strategy(string)
bt = Backtest(GOOG, strat, cash=10000, commission=.002, exclusive_orders=True)
output = bt.run()
bt.plot()
output
output['Return [%]'] / output['Buy & Hold Return [%]']