# Algorithmic Trading with MATLAB®: Evolutionary Learning

In AlgoTradingDemo2.m we saw how to add two signals together to get improved results. In this demo we'll use evolutionary learning (genetic algorithm) to select our signals and the logic used to build the trading strategy.

## Contents

Again, we'll import Bund data sampled minutely

```load bund1min
testPts = floor(0.8*length(data(:,4)));
step = 30; % 30 minute interval
BundClose = data(1:step:testPts,4);
BundCloseV = data(testPts+1:step:end,4);
annualScaling = sqrt(250*60*11/step);
cost = 0.01;
```

## Replicate the MA+RSI approach using evolutionary learning

First gather the indicator signals for the training set

```N = 2; M = 396; thresh = 55; P = 2; Q = 110;
srs = rsi(BundClose,[P,Q],thresh,annualScaling,cost);
marsi(BundClose,N,M,[P,Q],thresh,annualScaling,cost)

signals = [sma srs];
names = {'MA','RSI'};
```   Plot the "state" of the market represented by the signals

```figure
ax(1) = subplot(2,1,1); plot(BundClose);
ax(2) = subplot(2,1,2); imagesc(signals')
cmap = colormap([1 0 0; 0 0 1; 0 1 0]);
set(gca,'YTick',1:length(names),'YTickLabel',names);
``` ## Generate initial population

Generate initial population of signals we'll use to seed the search space.

```close all
I = size(signals,2);
pop = initializePopulation(I);
imagesc(pop)
xlabel('Bit Position'); ylabel('Individual in Population')
colormap([1 0 0; 0 1 0]); set(gca,'XTick',1:size(pop,2))
``` ## Fitness Function

Objective is to find a target bitstring (minimum value of -Sharpe Ratio)

```type fitness
```
```function f = fitness(pop,indicator,price,scaling,cost)
%%
% Copyright 2010, The MathWorks, Inc.
%% Generate Trading Signal from Population
s = (s*2-1); % scale to +/-1 range
col = size(s,2);

%% PNL Caclulation
r  = [zeros(1,col);
s(1:end-1,:).*repmat(diff(price),1,col)-abs(diff(s))*cost/2];
f = -scaling*sharpe(r,0);
```

Objective function definition as a function handle (the optimization sovlers need a function as an input, this is how to define them)

```obj = @(pop) fitness(pop,signals,BundClose,annualScaling,cost)
```
```obj =

@(pop)fitness(pop,signals,BundClose,annualScaling,cost)

```

Evaluate objective for initial population

```obj(pop)
```
```ans =

Columns 1 through 7

-2.3106   -1.9583    0.6715   -1.5312    0.6575    0.6715    0.6776

Columns 8 through 14

0.6776   -2.3106    0.6575    1.9040    0.6575    0.6654   -1.2089

Columns 15 through 21

-1.9583   -2.3106    0.6715   -1.9583    0.6715   -1.9583    1.9040

Columns 22 through 28

-1.9583   -1.5312   -1.9583    0.6654   -1.9583   -1.5312   -1.5312

Columns 29 through 35

0.6575   -1.2089    0.6575   -1.5312   -1.5312   -1.5312   -1.2089

Columns 36 through 42

0.6575    0.6715    0.6575   -1.5312    0.6776   -1.5312   -1.5312

Columns 43 through 49

-1.2089    1.9040   -1.9583    1.9040    0.6715    1.9040    0.6575

Columns 50 through 56

-1.2089    0.6575   -1.5312    0.6715   -1.5312   -1.5312    0.6575

Columns 57 through 63

-1.5312   -1.5312   -1.2089    0.6575   -1.9583   -1.2089    0.6575

Columns 64 through 70

0.6575    0.6575    0.6575    0.6654   -2.3106   -1.9583    0.6776

Columns 71 through 77

0.6654    1.9040   -1.9583   -1.5312   -1.5312    0.6715    0.6715

Columns 78 through 84

-1.9583    0.6575   -1.9583   -1.9583    0.6776   -1.5312   -2.3106

Columns 85 through 91

-1.9583    1.9040    0.6776    1.9040   -1.5312   -1.2089    0.6715

Columns 92 through 98

-1.5312    0.6776   -1.5312    0.6575   -1.9583    1.9040   -1.5312

Columns 99 through 105

0.6654    0.6654    1.9040    1.9040    0.6715   -1.9583    1.9040

Columns 106 through 112

0.6575   -1.5312    0.6654    0.6776   -1.5312    0.6575    0.6575

Columns 113 through 119

-2.3106   -1.5312   -1.9583    0.6654    1.9040    0.6575    1.9040

Columns 120 through 126

-2.3106    0.6575    0.6575    0.6575    0.6654    0.6654    0.6654

Columns 127 through 133

-2.3106   -1.9583    0.6715   -2.3106   -1.5312   -1.5312    0.6654

Columns 134 through 140

0.6575   -1.2089   -2.3106   -1.2089    0.6776    0.6575    0.6654

Columns 141 through 147

-1.2089   -1.9583   -1.5312    0.6776    0.6575   -1.2089    0.6654

Columns 148 through 150

0.6654    0.6654    0.6776

```

## Solve With Genetic Algorithm

Find best trading rule and maximum Sharpe ratio (min -Sharpe ratio)

```options = gaoptimset('Display','iter','PopulationType','bitstring',...
'PopulationSize',size(pop,1),...
'InitialPopulation',pop,...
'CrossoverFcn', @crossover,...
'MutationFcn', @mutation,...
'PlotFcns', @plotRules,...
'Vectorized','on');

[best,minSh] = ga(obj,size(pop,2),[],[],[],[],[],[],[],options)
```
```                               Best           Mean      Stall
Generation      f-count        f(x)           f(x)    Generations
1           300          -2.311         -0.7954        0
2           450          -2.311          -1.049        1
3           600          -2.311          -1.342        2
4           750          -2.311          -1.736        3
5           900          -2.311          -1.898        4
6          1050          -2.311          -1.988        5
7          1200          -2.311          -2.068        6
8          1350          -2.311          -2.157        7
9          1500          -2.311          -2.124        8
10          1650          -2.311          -2.155        9
11          1800          -2.311          -2.167       10
12          1950          -2.311          -2.155       11
13          2100          -2.311          -2.223       12
14          2250          -2.311          -2.231       13
15          2400          -2.311          -2.277       14
16          2550          -2.311          -2.222       15
17          2700          -2.311          -2.211       16
18          2850          -2.311           -2.25       17
19          3000          -2.311          -2.268       18
20          3150          -2.311           -2.16       19
21          3300          -2.311          -2.215       20
22          3450          -2.311          -2.243       21
23          3600          -2.311          -2.228       22
24          3750          -2.311          -2.241       23
25          3900          -2.311          -2.241       24
26          4050          -2.311          -2.233       25
27          4200          -2.311          -2.214       26
28          4350          -2.311          -2.227       27
29          4500          -2.311          -2.227       28
30          4650          -2.311          -2.264       29

Best           Mean      Stall
Generation      f-count        f(x)           f(x)    Generations
31          4800          -2.311          -2.224       30
32          4950          -2.311          -2.251       31
33          5100          -2.311          -2.228       32
34          5250          -2.311          -2.244       33
35          5400          -2.311          -2.203       34
36          5550          -2.311          -2.223       35
37          5700          -2.311          -2.197       36
38          5850          -2.311          -2.093       37
39          6000          -2.311          -2.105       38
40          6150          -2.311          -2.137       39
41          6300          -2.311          -2.214       40
42          6450          -2.311          -2.172       41
43          6600          -2.311          -2.203       42
44          6750          -2.311          -2.251       43
45          6900          -2.311          -2.251       44
46          7050          -2.311          -2.111       45
47          7200          -2.311          -2.091       46
48          7350          -2.311          -2.072       47
49          7500          -2.311          -2.188       48
50          7650          -2.311          -2.216       49
51          7800          -2.311          -2.215       50
Optimization terminated: average change in the fitness value less than options.TolFun.

best =

1     0     0     1     1     1

minSh =

-2.3106

``` ## Evaluate Best Performer

```s = tradeSignal(best,signals);
s = (s*2-1); % scale to +/-1
r  = [0; s(1:end-1).*diff(BundClose)-abs(diff(s))*cost/2];
sh = annualScaling*sharpe(r,0);

% Plot results
figure
ax(1) = subplot(2,1,1);
plot(BundClose)
title(['Evolutionary Learning Resutls, Sharpe Ratio = ',num2str(sh,3)])
ax(2) = subplot(2,1,2);
plot([s,cumsum(r)])
legend('Position','Cumulative Return')
title(['Final Return = ',num2str(sum(r),3), ...
' (',num2str(sum(r)/BundClose(1)*100,3),'%)'])
``` Note that this results is the same as found in (AlgoTradingDemo2.m). This validates the evolutionary approach can be used to select a trading strategy. We'll now add another signal to the mix and see if this appraoch will find a better solution. But first, we'll rerun the validation set to make sure we're consistent with the earlier result.

## Check validation set

```sma = leadlag(BundCloseV,N,M,annualScaling,cost);
srs = rsi(BundCloseV,[P Q],thresh,annualScaling,cost);
marsi(BundCloseV,N,M,[P Q],thresh,annualScaling,cost)

signals = [sma srs];
s = (s*2-1); % scale to +/-1
r  = [0; s(1:end-1).*diff(BundCloseV)-abs(diff(s))*cost/2];
sh = annualScaling*sharpe(r,0);

% Plot results
figure
ax(1) = subplot(2,1,1);
plot(BundCloseV)
title(['Evolutionary Learning Resutls, Sharpe Ratio = ',num2str(sh,3)])
ax(2) = subplot(2,1,2);
plot([s,cumsum(r)])
legend('Position','Cumulative Return')
title(['Final Return = ',num2str(sum(r),3), ...
' (',num2str(sum(r)/BundCloseV(1)*100,3),'%)'])    