Sunday, February 16, 2014

Some results on neural networks

Test on JAZ


std error train: 2.19 std error test: 2.32
max error train: 5.54 max error test: 5.54
std error train: 0.67 std error test: 0.71
max error train: 2.04 max error test: 2.01

This is the result after 100 training epochs
In [7]: testthresholds()
 0.00 <#:  395> <EUR:    4.57> <EUR/trade: 0.012> <%: 77.09> <%/trade:  0.20>
 0.05 <#:  346> <EUR:    4.69> <EUR/trade: 0.014> <%: 79.25> <%/trade:  0.23>
 0.10 <#:  301> <EUR:    5.11> <EUR/trade: 0.017> <%: 82.02> <%/trade:  0.27>
 0.15 <#:  258> <EUR:    5.34> <EUR/trade: 0.021> <%: 86.22> <%/trade:  0.33>
 0.20 <#:  208> <EUR:    4.97> <EUR/trade: 0.024> <%: 76.80> <%/trade:  0.37>
 0.25 <#:  152> <EUR:    4.72> <EUR/trade: 0.031> <%: 74.67> <%/trade:  0.49>
 0.30 <#:  129> <EUR:    4.27> <EUR/trade: 0.033> <%: 68.26> <%/trade:  0.53>
 0.35 <#:  101> <EUR:    3.61> <EUR/trade: 0.036> <%: 59.96> <%/trade:  0.59>
 0.40 <#:   83> <EUR:    3.22> <EUR/trade: 0.039> <%: 53.38> <%/trade:  0.64>
 0.45 <#:   62> <EUR:    2.43> <EUR/trade: 0.039> <%: 43.28> <%/trade:  0.70>
 0.50 <#:   55> <EUR:    2.39> <EUR/trade: 0.043> <%: 42.46> <%/trade:  0.77>
 0.55 <#:   51> <EUR:    2.28> <EUR/trade: 0.045> <%: 40.74> <%/trade:  0.80>
 0.60 <#:   45> <EUR:    1.78> <EUR/trade: 0.040> <%: 32.21> <%/trade:  0.72>
 0.65 <#:   38> <EUR:    1.34> <EUR/trade: 0.035> <%: 24.70> <%/trade:  0.65>
 0.70 <#:   34> <EUR:    1.39> <EUR/trade: 0.041> <%: 25.23> <%/trade:  0.74>
 0.75 <#:   25> <EUR:    0.83> <EUR/trade: 0.033> <%: 14.28> <%/trade:  0.57>
 0.80 <#:   20> <EUR:    0.58> <EUR/trade: 0.029> <%:  9.79> <%/trade:  0.49>
 0.85 <#:   10> <EUR:    0.65> <EUR/trade: 0.065> <%: 11.84> <%/trade:  1.18>
 0.90 <#:    8> <EUR:    0.51> <EUR/trade: 0.064> <%:  9.66> <%/trade:  1.21>
 0.95 <#:    4> <EUR:    0.37> <EUR/trade: 0.092> <%:  7.17> <%/trade:  1.79>
 1.00 <#:    3> <EUR:    0.33> <EUR/trade: 0.109> <%:  6.47> <%/trade:  2.16>


In [8]: able2generalize(buildsignals(0.6))
For NEW signals
   gain>0.sum()  --winning sum 0.292  # 3
   gain<0.sum()  --loosing sum -0.236  # 3
   gain/loss ratio :  1.23728813559  Hit ratio :  1.0
For OLD signals
   gain>0.sum()  --winning sum 2.538  # 27
   gain<0.sum()  --loosing sum -0.811  # 12
   gain/loss ratio :  3.12946979038  Hit ratio :  2.25

In [9]: able2generalize(buildsignals(0.7))
For NEW signals
   gain>0.sum()  --winning sum 0.292  # 3
   gain<0.sum()  --loosing sum -0.079  # 1
   gain/loss ratio :  3.69620253165  Hit ratio :  3.0
For OLD signals
   gain>0.sum()  --winning sum 1.825  # 21
   gain<0.sum()  --loosing sum -0.646  # 9
   gain/loss ratio :  2.82507739938  Hit ratio :  2.33333333333

In [10]: able2generalize(buildsignals(0.8))
For NEW signals
   gain>0.sum()  --winning sum 0.227  # 1
   gain<0.sum()  --loosing sum -0.079  # 1
   gain/loss ratio :  2.87341772152  Hit ratio :  1.0
For OLD signals
   gain>0.sum()  --winning sum 0.961  # 12
   gain<0.sum()  --loosing sum -0.526  # 6
   gain/loss ratio :  1.82699619772  Hit ratio :  2.0


After some more training (100+)

In [13]: testthresholds()
 0.00 <#:  395> <EUR:    7.54> <EUR/trade: 0.019> <%:118.29> <%/trade:  0.30>
 0.05 <#:  325> <EUR:    7.25> <EUR/trade: 0.022> <%:118.08> <%/trade:  0.36>
 0.10 <#:  281> <EUR:    7.12> <EUR/trade: 0.025> <%:117.50> <%/trade:  0.42>
 0.15 <#:  250> <EUR:    7.06> <EUR/trade: 0.028> <%:117.26> <%/trade:  0.47>
 0.20 <#:  218> <EUR:    5.50> <EUR/trade: 0.025> <%: 93.98> <%/trade:  0.43>
 0.25 <#:  192> <EUR:    5.63> <EUR/trade: 0.029> <%: 95.48> <%/trade:  0.50>
 0.30 <#:  165> <EUR:    5.35> <EUR/trade: 0.032> <%: 90.27> <%/trade:  0.55>
 0.35 <#:  140> <EUR:    5.05> <EUR/trade: 0.036> <%: 86.64> <%/trade:  0.62>
 0.40 <#:  120> <EUR:    4.60> <EUR/trade: 0.038> <%: 78.43> <%/trade:  0.65>
 0.45 <#:  101> <EUR:    4.65> <EUR/trade: 0.046> <%: 78.80> <%/trade:  0.78>
 0.50 <#:   83> <EUR:    4.08> <EUR/trade: 0.049> <%: 69.27> <%/trade:  0.83>
 0.55 <#:   71> <EUR:    4.02> <EUR/trade: 0.057> <%: 69.81> <%/trade:  0.98>
 0.60 <#:   63> <EUR:    3.22> <EUR/trade: 0.051> <%: 59.43> <%/trade:  0.94>
 0.65 <#:   58> <EUR:    2.98> <EUR/trade: 0.051> <%: 55.46> <%/trade:  0.96>
 0.70 <#:   52> <EUR:    2.76> <EUR/trade: 0.053> <%: 51.10> <%/trade:  0.98>
 0.75 <#:   47> <EUR:    2.53> <EUR/trade: 0.054> <%: 47.97> <%/trade:  1.02>
 0.80 <#:   42> <EUR:    2.14> <EUR/trade: 0.051> <%: 39.21> <%/trade:  0.93>
 0.85 <#:   35> <EUR:    1.50> <EUR/trade: 0.043> <%: 28.33> <%/trade:  0.81>
 0.90 <#:   26> <EUR:    0.60> <EUR/trade: 0.023> <%: 11.54> <%/trade:  0.44>
 0.95 <#:   22> <EUR:    0.68> <EUR/trade: 0.031> <%: 11.80> <%/trade:  0.54>
 1.00 <#:   18> <EUR:    0.65> <EUR/trade: 0.036> <%: 11.09> <%/trade:  0.62>

In [14]: able2generalize(buildsignals(0.6))
For NEW signals
   gain>0.sum()  --winning sum 0.58  # 8
   gain<0.sum()  --loosing sum -0.329  # 4
   gain/loss ratio :  1.76291793313  Hit ratio :  2.0
For OLD signals
   gain>0.sum()  --winning sum 4.025  # 37
   gain<0.sum()  --loosing sum -1.052  # 14
   gain/loss ratio :  3.82604562738  Hit ratio :  2.64285714286

In [15]: able2generalize(buildsignals(0.7))
For NEW signals
   gain>0.sum()  --winning sum 0.462  # 6
   gain<0.sum()  --loosing sum -0.329  # 4
   gain/loss ratio :  1.40425531915  Hit ratio :  1.5
For OLD signals
   gain>0.sum()  --winning sum 3.424  # 31
   gain<0.sum()  --loosing sum -0.797  # 11
   gain/loss ratio :  4.29611041405  Hit ratio :  2.81818181818

In [16]: able2generalize(buildsignals(0.8))
For NEW signals
   gain>0.sum()  --winning sum 0.462  # 6
   gain<0.sum()  --loosing sum -0.293  # 3
   gain/loss ratio :  1.57679180887  Hit ratio :  2.0
For OLD signals
   gain>0.sum()  --winning sum 2.516  # 25
   gain<0.sum()  --loosing sum -0.54  # 8
   gain/loss ratio :  4.65925925926  Hit ratio :  3.125



If targets are set to +/-0.8 instead of +/-1, many less signals are generated, although with more profit per trade:
In [33]: testthresholds()
 0.00 <#:  395> <EUR:    3.57> <EUR/trade: 0.009> <%: 68.60> <%/trade:  0.17>
 0.05 <#:  337> <EUR:    2.63> <EUR/trade: 0.008> <%: 52.00> <%/trade:  0.15>
 0.10 <#:  209> <EUR:    3.55> <EUR/trade: 0.017> <%: 61.01> <%/trade:  0.29>
 0.15 <#:  125> <EUR:    4.09> <EUR/trade: 0.033> <%: 71.54> <%/trade:  0.57>
 0.20 <#:   73> <EUR:    3.98> <EUR/trade: 0.055> <%: 68.25> <%/trade:  0.93>
 0.25 <#:   36> <EUR:    2.85> <EUR/trade: 0.079> <%: 48.34> <%/trade:  1.34>
 0.30 <#:   24> <EUR:    2.32> <EUR/trade: 0.097> <%: 37.38> <%/trade:  1.56>
 0.35 <#:   19> <EUR:    1.79> <EUR/trade: 0.094> <%: 29.80> <%/trade:  1.57>
 0.40 <#:   13> <EUR:    1.27> <EUR/trade: 0.097> <%: 20.72> <%/trade:  1.59>
 0.45 <#:   10> <EUR:    1.16> <EUR/trade: 0.116> <%: 19.55> <%/trade:  1.96>
 0.50 <#:   10> <EUR:    1.16> <EUR/trade: 0.116> <%: 19.55> <%/trade:  1.96>
 0.55 <#:    9> <EUR:    1.17> <EUR/trade: 0.130> <%: 19.81> <%/trade:  2.20>
 0.60 <#:    8> <EUR:    0.97> <EUR/trade: 0.122> <%: 15.51> <%/trade:  1.94>
 0.65 <#:    7> <EUR:    0.88> <EUR/trade: 0.126> <%: 13.86> <%/trade:  1.98>
 0.70 <#:    6> <EUR:    0.84> <EUR/trade: 0.140> <%: 13.33> <%/trade:  2.22>
 0.75 <#:    5> <EUR:    0.71> <EUR/trade: 0.142> <%: 11.16> <%/trade:  2.23>
 0.80 <#:    4> <EUR:    0.27> <EUR/trade: 0.068> <%:  6.09> <%/trade:  1.52>
 0.85 <#:    4> <EUR:    0.27> <EUR/trade: 0.068> <%:  6.09> <%/trade:  1.52>
 0.90 <#:    3> <EUR:    0.11> <EUR/trade: 0.038> <%:  3.05> <%/trade:  1.02>
 0.95 <#:    3> <EUR:    0.11> <EUR/trade: 0.038> <%:  3.05> <%/trade:  1.02>
 1.00 <#:    3> <EUR:    0.11> <EUR/trade: 0.038> <%:  3.05> <%/trade:  1.02>




Sunday, February 2, 2014

A neural network to predict the next value of a sine wave

Reportedly, neural networks are able to learn complex rules. Let's see if they can learn to predict the next value of a sine wave...

Predicting from two past values


Start generating pairs of values of a sine wave described by cos(6t) and a sampling period of 0.1s

t=t=np.linspace(0,10,101)
ds = SupervisedDataSet(2, 1)
s1=np.cos(6*t)

for ix in range(2,101):
   ds.addSample(s1[ix-2:ix],s1[ix])


Then, build the neural network

net = buildNetwork(2, 3, 1, hiddenclass=TanhLayer) 
trainer = BackpropTrainer(net, ds)




Make a different dataset for testing. Note it has the same frequency

# Test dataset with different values
dst = SupervisedDataSet(2, 1)
st=np.cos(6*(t-0.11))
for ix in range (2,101):
   dst.addSample(st[ix-2:ix],st[ix])


Define a function to test quality of the resulting network

def evalnet():
  
   out=net.activateOnDataset(dst)
   stderr=np.std(out.T-st[2:101])
   print 'std error :'+str(stderr)


Then train the network and display result repeatedly:

trainer.trainEpochs(200)
evalnet()


Here are the results

Run #1
In [81]: execfile( 'example_sine.py')
std error :0.475135957881
std error :0.00528582169261
std error :0.00420217821467
std error :0.00388770773851


Run #2
In [82]: execfile( 'example_sine.py')
std error :0.825420526812
std error :0.0231771366421
std error :0.0206355959287
std error :0.0188795980662


Run #2
In [83]: execfile( 'example_sine.py')
std error :0.790629966353
std error :0.0095095475289
std error :0.0078286464515
std error :0.00764017583539


Is the network able to predict cos(5t) if trained for cos(6t)?

In [88]: execfile( 'example_sine.py')
std error :0.981991629948
std error :0.0691771695798
std error :0.0695395180253
std error :0.0691409803733

In [89]: execfile( 'example_sine.py')
std error :1.20686164247
std error :0.0741454399328
std error :0.0724747717285
std error :0.0700249455395


So, it doesn't perform very well, but it is fair enough!
If we set up a dataset with 50% of data corresponding to cos(5t) and 50% corresponding to cos(6t) and test with a similar data set:

In [123]: execfile( 'example_sine.py')
std error :0.513686241649
std error :0.0340440621768
std error :0.0339060173516
std error :0.0338778895194

In [125]: execfile( 'example_sine.py')
std error :0.669916052193
std error :0.0395873020069
std error :0.0374792495802
std error :0.0359768805783


In [126]: execfile( 'example_sine.py')
std error :0.696332858547
std error :0.037025395267
std error :0.0363592341024
std error :0.03641336896


How well does it predict a sine wave of a different amplitude?

tt=np.linspace(0,0.2,3)
In [153]: v=0.5*np.cos(5*tt-4); print v;net.activate([v[0],v[1]])
[-0.32682181 -0.46822834 -0.49499625]
Out[153]: array([-0.58104487])


Not quite well but, again, fair enough!

What happens with a network with more hidden neurons? 2,3,1 -> 2,5,1

In [156]: execfile( 'example_sine.py')
std error :1.04554148959
std error :0.0385415333149
std error :0.0388701113238
std error :0.0386260279819  <- similar to before

In [157]: v=0.5*np.cos(5*tt-4); print v;net.activate([v[0],v[1]])
[-0.32682181 -0.46822834 -0.49499625]
Out[157]: array([-0.48321326])


And with another hidden layer? 2,3,1 -> 2,3,3,1

In [161]: execfile( 'example_sine.py')
std error :0.788084537967
std error :0.0435729774591
std error :0.041549014995
std error :0.0398895692455

In [162]: v=0.2*np.cos(5*tt-2); print v;net.activate([v[0],v[1]])
[-0.08322937  0.01414744  0.10806046]
Out[162]: array([ 0.00811018])

With 2,3,1 -> 2,4,4,1 it performs more or less the same

Predicting from three past values

In [203]: execfile( 'example_sine3.py')
std error :0.849241666555
max error :2.67855045373
std error :0.0536682726789
max error :0.120103597074
std error :0.0475902319921
max error :0.108592376129
std error :0.0422407920624
max error :0.0944045487712

In [204]: v=0.7*np.cos(5.5*tt-0.2); print v;net.activate([v[0],v[1],v[2]])
[ 0.6860466   0.6575609   0.43512698  0.08435194]
Out[204]: array([ 0.07766859])

In [205]: v=0.5*np.cos(4*tt-0.2); print v;net.activate([v[0],v[1],v[2]])
[ 0.49003329  0.49003329  0.41266781  0.27015115]
Out[205]: array([ 0.21284467])

In [206]: v=0.6*np.cos(4.2*tt-0.6); print v;net.activate([v[0],v[1],v[2]])
[ 0.49520137  0.59030622  0.58280278  0.47399534]
Out[206]: array([ 0.41496148])

Works very good!


Saturday, February 1, 2014

Neural networks for stock market prediction


Tools which I have chosen: pyBrain

There is also neuroph, which seems an instructive tool written in java. This link has also an interesting tutorial on predicting a sine wave.

To install pyBrain:
sudo apt-get install python-setuptools
sudo easy_install pybrain