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 16, 2014
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
Subscribe to:
Posts (Atom)