@anana's comment helped me click on how the neural network should work. As she said, I can just provide the average value of a stock in the last d (in my case, 5) days as the input to attempt to get a prediction.
This means that my training input is of the format:
[[rollingAverage, rollingMinimum, rollingMaximum], normalizedClosePrice]
for the past five days (so a total of 9 days are analyzed due to the rolling windows).
When I want to get a prediction after training, I provide input nodes of just the format:
[rollingAverage, rollingMinimum, rollingMaximum]
for the most recent 5 days.
Below is all the relevant logic, combined with the neural network I linked in the original question:
## ================================================================
def normalizePrice(price, minimum, maximum):
return ((2*price - (maximum + minimum)) / (maximum - minimum))
def denormalizePrice(price, minimum, maximum):
return (((price*(maximum-minimum))/2) + (maximum + minimum))/2
## ================================================================
def rollingWindow(seq, windowSize):
it = iter(seq)
win = [it.next() for cnt in xrange(windowSize)] # First window
yield win
for e in it: # Subsequent windows
win[:-1] = win[1:]
win[-1] = e
yield win
def getMovingAverage(values, windowSize):
movingAverages = []
for w in rollingWindow(values, windowSize):
movingAverages.append(sum(w)/len(w))
return movingAverages
def getMinimums(values, windowSize):
minimums = []
for w in rollingWindow(values, windowSize):
minimums.append(min(w))
return minimums
def getMaximums(values, windowSize):
maximums = []
for w in rollingWindow(values, windowSize):
maximums.append(max(w))
return maximums
## ================================================================
def getTimeSeriesValues(values, window):
movingAverages = getMovingAverage(values, window)
minimums = getMinimums(values, window)
maximums = getMaximums(values, window)
returnData = []
# build items of the form [[average, minimum, maximum], normalized price]
for i in range(0, len(movingAverages)):
inputNode = [movingAverages[i], minimums[i], maximums[i]]
price = normalizePrice(values[len(movingAverages) - (i + 1)], minimums[i], maximums[i])
outputNode = [price]
tempItem = [inputNode, outputNode]
returnData.append(tempItem)
return returnData
## ================================================================
def getHistoricalData(stockSymbol):
historicalPrices = []
# login to API
urllib2.urlopen("http://api.kibot.com/?action=login&user=guest&password=guest")
# get 14 days of data from API (business days only, could be < 10)
url = "http://api.kibot.com/?action=history&symbol=" + stockSymbol + "&interval=daily&period=14&unadjusted=1®ularsession=1"
apiData = urllib2.urlopen(url).read().split("\n")
for line in apiData:
if(len(line) > 0):
tempLine = line.split(',')
price = float(tempLine[1])
historicalPrices.append(price)
return historicalPrices
## ================================================================
def getTrainingData(stockSymbol):
historicalData = getHistoricalData(stockSymbol)
# reverse it so we're using the most recent data first, ensure we only have 9 data points
historicalData.reverse()
del historicalData[9:]
# get five 5-day moving averages, 5-day lows, and 5-day highs, associated with the closing price
trainingData = getTimeSeriesValues(historicalData, 5)
return trainingData