DMelt:Finance/Market Prediction
Market prediction
In Section Neural Network we discussed how to build a neural net based on backpropogation algorithm. Now we will show how to use this neural network approach to make predictions of financial market market.
Using Joone
Let us consider Joone Neural net for forecasting market predictions using a generated time series in the form cos(x)*sin(x)+Gaussian noise.
from org.joone.engine import NeuralNetListener,TanhLayer,DelayLayer
from org.joone.engine import SigmoidLayer,FullSynapse,Monitor
from org.joone.io import FileInputSynapse,FileOutputSynapse
from org.joone.engine.learning import TeachingSynapse
from org.joone.net import NeuralNet
from java.lang import System
from java.io import *
from jhplot import *
from java.awt import *
import math
from java.util import Random
class joone(NeuralNetListener):
mills=0
epochs=1000
fileName=""
nnet = NeuralNet()
input = DelayLayer()
hidden = SigmoidLayer()
output = TanhLayer()
# a function to help connect layers
def connect(self,layer1, syn, layer2):
layer1.addOutputSynapse(syn)
layer2.addInputSynapse(syn)
def createDataSet(self,fileName,firstRow, lastRow, advColSel):
fInput = FileInputSynapse()
fInput.setInputFile(File(fileName))
fInput.setFirstRow(firstRow)
fInput.setLastRow(lastRow)
fInput.setAdvancedColumnSelector(advColSel)
return fInput
def createNet(self,fileName,epochs,trainingPatterns,temporalWindow):
self.epochs=epochs
print "Running NN for ", epochs, " epochs"
self.fileName=fileName
self.input.setTaps(temporalWindow-1)
self.input.setRows(1)
self.hidden.setRows(15)
self.output.setRows(1)
self.connect(self.input,FullSynapse(), self.hidden)
self.connect(self.hidden,FullSynapse(), self.output)
self.input.addInputSynapse(self.createDataSet(self.fileName, 1, trainingPatterns, "1"))
trainer = TeachingSynapse()
trainer.setDesired(self.createDataSet(self.fileName, 2, trainingPatterns+1, "1"))
self.output.addOutputSynapse(trainer)
self.nnet.addLayer(self.input, NeuralNet.INPUT_LAYER)
self.nnet.addLayer(self.hidden, NeuralNet.HIDDEN_LAYER)
self.nnet.addLayer(self.output, NeuralNet.OUTPUT_LAYER)
self.mills = System.currentTimeMillis()
self.nnet.randomize(0.5)
def train(self):
mon = self.nnet.getMonitor()
mon.setLearningRate(0.2)
mon.setMomentum(0.7)
mon.setTrainingPatterns(trainingPatterns)
mon.setTotCicles(epochs)
mon.setPreLearning(temporalWindow)
mon.setLearning(True)
mon.addNeuralNetListener(self)
self.nnet.start()
mon.Go()
self.nnet.join()
def interrogate(self,outputFile):
mon = self.nnet.getMonitor()
self.input.removeAllInputs()
startRow = trainingPatterns - temporalWindow
self.input.addInputSynapse(self.createDataSet(self.fileName, startRow+1, startRow+40, "1"))
self.output.removeAllOutputs()
fOutput = FileOutputSynapse()
fOutput.setFileName(outputFile)
self.output.addOutputSynapse(fOutput)
mon.setTrainingPatterns(40)
mon.setTotCicles(1)
mon.setLearning(False)
self.nnet.start()
mon.Go()
self.nnet.join()
def netStopped(self,e):
mon =e.getSource()
if (mon.isLearning()):
epoch = mon.getTotCicles() - mon.getCurrentCicle()
print "Epoch:",epoch," last RMSE=",mon.getGlobalError()
else:
delay = System.currentTimeMillis() - self.mills
print "Training finished after ",delay," ms"
def cicleTerminated(self,e):
mon = e.getSource()
epoch = mon.getTotCicles() - mon.getCurrentCicle()
if ((epoch > 0) and ((epoch % 100) == 0)):
print "Epoch:",epoch," RMSE=",mon.getGlobalError()
def netStarted(self,e):
pass
def errorChanged(self,e):
pass
def netStoppedError(self,e):
pass
r=Random()
print "Create a file joone_timeseries.txt with time series cos(x)*sin(x)+noise"
f = open("joone_timeseries.txt", "w")
for x in range(0,1000):
yEst = 0.9*math.cos(x*0.4)*math.sin(0.7*x)+0.02*r.nextGaussian() # cos(x*0.3)*sim(x)+noise
f.write( str(yEst) + "\n" )
f.close()
# get input file with TimeSeries
fileName = "joone_timeseries.txt"
print "Downloading .. "+fileName
# Web.get("http://datamelt.org/examples/data/"+fileName)
trainingPatterns = 200
epochs = 10000
temporalWindow = 20
c1 = HPlot("show data")
c1.visible()
c1.setRangeX(0,1100)
c1.setNameX("time")
c1.setNameY("price")
c1.setMarginLeft(90)
# show data
dataIN = [line.strip() for line in open(fileName, 'r')]
print "Total data size=",len(dataIN), " For learning=",trainingPatterns
p1=P1D("Time series")
p1.setDrawLine(True)
p1.setPenWidth(1)
for i in range(len(dataIN)):
p1.add(i,float(dataIN[i]))
c1.draw(p1)
# run NN for predictions
ts=joone()
ts.createNet(fileName,epochs,trainingPatterns,temporalWindow)
print "Training..."
ts.train()
ts.interrogate("results1.txt")
ts.interrogate("results2.txt")
# show predictions
data = [line.strip() for line in open("results2.txt", 'r')]
p2=P1D("Prediction")
p2.setColor(Color.red)
p2.setDrawLine(True)
for i in range(len(data)):
p2.add(len(dataIN)+i,float(data[i]))
c1.draw(p2)
print "Done."
Here is the output image that shows the original time series and the predicted trends (n red).
As you can see, the neural net correctly predicts the expected behavior.
Market prediction
Now we consider another practical example. First, we will fetch data from Yahoo and store this data in a file: YahooFinance.egb. We will gather training data for the last 2 years, stopping 60 days short of today.
from java.io import File
from java.util import *
from org.encog.ml.data.market import MarketMLDataSet,MarketDataDescription,TickerSymbol,MarketDataType
from org.encog.ml.data.market.loader import YahooFinanceLoader
from org.encog.util.simple import EncogUtility
INPUT_WINDOW=10; PREDICT_WINDOW=1
TICKER =TickerSymbol("AAPL")
loader =YahooFinanceLoader()
market =MarketMLDataSet(loader,INPUT_WINDOW, PREDICT_WINDOW)
desc=MarketDataDescription(TICKER, MarketDataType.ADJUSTED_CLOSE, True, True)
market.addDescription(desc)
end = GregorianCalendar(); begin =end.clone()
begin.add(Calendar.DATE, -60) # Gather training data for the last 2 years, stopping 60 days short of today.
end.add(Calendar.DATE, -60) # The 60 days will be used to evaluate prediction.
begin.add(Calendar.YEAR, -2)
market.load(begin.getTime(), end.getTime())
market.generate()
print "Fetched records=",market.getRecordCount()
# print input and ideal output
for p in market.getData():
print p.getInputArray().tolist(), ' ideal=', p.getIdealArray().tolist()
print "--> save data in a current directory"
EncogUtility.saveEGB(File("./","YahooFinance.egb"), market)
This script also prints input (10 values) and output (one value): A single entry out of 491 will look as this:
[0.00384, 0.00178, 0.006807,
-0.00833, 0.00795, 0.014900,
-0.00409, 0.00220, -0.00312,
-0.00934]
ideal= [-0.01494]
Now let us build a neural net with 10 inputs, one output and 20 hidden layers.
We will train this network for 1 minute and then save the trained network in a file.
The script code is given below.
<ifauthr>
from java.io import File
from org.encog.util.simple import EncogUtility
MINUTES = 1 # how many minutes to train
HID1 = 20 # number of hidden layers
HID2 = 0
# get training data
data=EncogUtility.loadEGB2Memory( File("./","YahooFinance.egb") )
# train network
network = EncogUtility.simpleFeedForward(data.getInputSize(),HID1, HID2,data.getIdealSize(),True)
EncogUtility.trainConsole(network, data, MINUTES)
print "Final Error: ", network.calculateError(data)
print "Training complete, saving network"
EncogDirectoryPersistence.saveObject(File("marketNetwork.eg"), network)
</ifauth>
Now we read data from YahooFinance again, this time using last 30 days. Then we read trained neural network and perform the prediction based on the last 2 year trend. We compare the actual and predicted value, and print likelihood of our correct prediction:
from java.io import File
from java.util import *
from org.encog.ml.data.market import MarketMLDataSet,MarketDataDescription,TickerSymbol,MarketDataType
from org.encog.ml.data.market.loader import YahooFinanceLoader
from org.encog.util.simple import EncogUtility
from math import *
from java.text import DecimalFormat
from org.encog.persist import EncogDirectoryPersistence
INPUT_WINDOW=10;
PREDICT_WINDOW=1
TICKER =TickerSymbol("AAPL")
# +1 is UP
# -1 is down
def determineDirection(d):
if (d < 0): return -1;
else: return 1;
print "Fetching data from Yahoo .. "
loader =YahooFinanceLoader()
data=MarketMLDataSet(loader,INPUT_WINDOW, PREDICT_WINDOW)
desc=MarketDataDescription(TICKER, MarketDataType.ADJUSTED_CLOSE, True, True)
data.addDescription(desc)
end=GregorianCalendar() # today
begin =end.clone() # begin 30 days ago
begin.add(Calendar.DATE, -60)
data.load(begin.getTime(), end.getTime())
data.generate()
# get neural net
network = EncogDirectoryPersistence.loadObject(File("marketNetwork.eg"));
format=DecimalFormat("#0.0000")
correct=0.0; count=0.0
print "Print prediction.."
for pair in data:
input=pair.getInput()
actualData = pair.getIdeal()
predictData = network.compute(input)
actual = actualData.getData(0)
predict = predictData.getData(0)
diff = abs(predict - actual)
actualDirection = determineDirection(actual)
predictDirection = determineDirection(predict)
count= count+1
if actualDirection == predictDirection: correct=correct+1
print "Day ",count, ":actual=",format.format(actual) ,"(", actualDirection ,") predict=" + format.format(predict),"(",predictDirection,"),diff=",diff
percent =correct /count;
print "Direction correct:", correct, "/",count
print "Directional Accuracy:",format.format(percent * 100) ,"%";
The output of the execution of this script will look something like:
Fetching data from Yahoo .. Print prediction.. Day 1.0 :actual= -0.0113 ( -1 ) predict=-0.0041 ( -1 ),diff= 0.00723281045594 Day 2.0 :actual= -0.0108 ( -1 ) predict=0.0056 ( 1 ),diff= 0.016323498302 Day 3.0 :actual= 0.0070 ( 1 ) predict=0.0068 ( 1 ),diff= 0.000142392841989 Day 4.0 :actual= 0.0320 ( 1 ) predict=0.0026 ( 1 ),diff= 0.0294366145542 Day 5.0 :actual= 0.0226 ( 1 ) predict=-0.0030 ( -1 ),diff= 0.0256697221103 Day 6.0 :actual= 0.0055 ( 1 ) predict=0.0132 ( 1 ),diff= 0.00767318237177 Day 7.0 :actual= -0.0080 ( -1 ) predict=0.0118 ( 1 ),diff= 0.0198059904802 Day 8.0 :actual= -0.0057 ( -1 ) predict=0.0092 ( 1 ),diff= 0.0148906339578 Day 9.0 :actual= 0.0176 ( 1 ) predict=0.0020 ( 1 ),diff= 0.0156139264763 Day 10.0 :actual= -0.0038 ( -1 ) predict=0.0031 ( 1 ),diff= 0.00693045712649 Day 11.0 :actual= 0.0156 ( 1 ) predict=-0.0033 ( -1 ),diff= 0.0188739030904 Day 12.0 :actual= -0.0018 ( -1 ) predict=0.0065 ( 1 ),diff= 0.00835930166595 Day 13.0 :actual= 0.0022 ( 1 ) predict=0.0024 ( 1 ),diff= 0.000244326149596 Day 14.0 :actual= 0.0065 ( 1 ) predict=-0.0063 ( -1 ),diff= 0.0127469148732 Day 15.0 :actual= 0.0003 ( 1 ) predict=0.0071 ( 1 ),diff= 0.00687984465776 Day 16.0 :actual= 0.0034 ( 1 ) predict=-0.0029 ( -1 ),diff= 0.00624265349531 Day 17.0 :actual= -0.0158 ( -1 ) predict=0.0020 ( 1 ),diff= 0.0177893230083 Day 18.0 :actual= 0.0032 ( 1 ) predict=-0.0046 ( -1 ),diff= 0.00781173668604 Day 19.0 :actual= -0.0172 ( -1 ) predict=0.0009 ( 1 ),diff= 0.0180277119123 Day 20.0 :actual= 0.0514 ( 1 ) predict=-0.0004 ( -1 ),diff= 0.0518078026793 Day 21.0 :actual= -0.0046 ( -1 ) predict=0.0060 ( 1 ),diff= 0.010602114572 Day 22.0 :actual= 0.0057 ( 1 ) predict=0.0051 ( 1 ),diff= 0.000595736696516 Day 23.0 :actual= 0.0154 ( 1 ) predict=0.0064 ( 1 ),diff= 0.00904954951323 Day 24.0 :actual= 0.0124 ( 1 ) predict=0.0152 ( 1 ),diff= 0.00284543760372 Day 25.0 :actual= -0.0018 ( -1 ) predict=-0.0040 ( -1 ),diff= 0.00223833948343 Day 26.0 :actual= 0.0092 ( 1 ) predict=0.0017 ( 1 ),diff= 0.0074896027783 Day 27.0 :actual= 0.0129 ( 1 ) predict=0.0012 ( 1 ),diff= 0.0116513741193 Day 28.0 :actual= 0.0149 ( 1 ) predict=0.0018 ( 1 ),diff= 0.0131001498602 Day 29.0 :actual= -0.0089 ( -1 ) predict=0.0062 ( 1 ),diff= 0.0151645127572 Day 30.0 :actual= -0.0006 ( -1 ) predict=-0.0028 ( -1 ),diff= 0.00226212010508 Day 31.0 :actual= -0.0020 ( -1 ) predict=-0.0015 ( -1 ),diff= 0.000477980160665 Day 32.0 :actual= -0.0142 ( -1 ) predict=-0.0026 ( -1 ),diff= 0.0116349624231 Direction correct: 25.0 / 32.0 Directional Accuracy: 63.1250 %
