Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions Students/A.Kramer/Final_Project/Chart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
'''
Created on Dec 3, 2014

@author: Aleksey Kramer
'''
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import matplotlib.dates as mdates
from matplotlib.finance import candlestick
import pylab

# adjusted font size for the plots
matplotlib.rcParams.update({"font.size": 10})


# define RSI function
def rsiFunc(prices, n=14):
deltas = np.diff(prices)
seed = deltas[:n+1]
up = seed[seed >= 0].sum() / n
down = -seed[seed<0].sum() / n
rs = up/down
rsi = np.zeros_like(prices)
rsi[:n] = 100. - 100./(1. + rs)
for i in range(n, len(prices)):
delta = deltas[i-1]
if delta > 0:
upval = delta
downval = 0.
else:
upval = 0.
downval = -delta
up = (up * (n-1) +upval) / n
down = (down*(n-1) + downval) / n
rs = up/down
rsi[i] = 100. - 100. / (1. + rs)
return rsi

# define moving average function
def movingaverage(values, window):
weights = np.repeat(1.0, window) / window
smas = np.convolve(values, weights, 'valid')
return smas # numpy array

def graphData(stock, MA1=12, MA2=26):
try:
# define the data file
stockFile = "./data/" + stock + ".txt"

# Load data into numpy arrays
date, closep, highp, lowp, openp, volume = np.loadtxt(stockFile, delimiter=",",
unpack=True, converters = {0: mdates.strpdate2num("%Y%m%d")})

#-----------------------------------------------------------------------------------------------
# building data for drawing plotting candlestick chart. Basically, a an array of comma separated
# values. The order of elements is very specific, so check the documentation for candlestick
x = 0
y = len(date)
candleArray = []
while x < y:
# order of elements matters!!! - used for candlestick charting
appendLine = date[x], openp[x], closep[x], highp[x], lowp[x], volume[x]
candleArray.append(appendLine)
x += 1

# moving averages for 12 and 26 days
Av1 = movingaverage(closep, MA1)
Av2 = movingaverage(closep, MA2)
# Starting point for graphs
SP = len(date[MA2-1:])
# Creating Moving Average labels
label1=str(MA1) + " SMA"
label2=str(MA2) + " SMA"


# changing the face color of the graphics
fig = plt.figure(facecolor="#07000D")

# create room and plot candlestick chart
ax1 = plt.subplot2grid((5,4), (1,0), rowspan=4, colspan=4, axisbg="#07000D")
candlestick(ax1, candleArray[-SP:], width=0.75, colorup="#9EFF15", colordown="#FF1717")
# plot moving averages
ax1.plot(date[-SP:], Av1[-SP:], "#5998FF", label=label1, linewidth=1.5)
ax1.plot(date[-SP:], Av2[-SP:], "#E1EDF9", label=label2, linewidth=1.5)
# Set grid color to white
ax1.grid(True, color="white")
# Set number of tickers on x-axis
ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
# Format date for presentation
ax1.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
# Change label and border colors
ax1.yaxis.label.set_color("white")
ax1.spines["bottom"].set_color("#5998FF")
ax1.spines["top"].set_color("#5998FF")
ax1.spines["left"].set_color("#5998FF")
ax1.spines["right"].set_color("#5998FF")
# Change tick color to white
ax1.tick_params(axis="y", colors="white")
ax1.tick_params(axis="x", colors="white")
plt.ylabel("Stock Price and Volume")
# display legend and set size of font to 7
maLeg = plt.legend(loc=9, ncol=2, prop={"size":7}, fancybox=True)
# update label transparency
maLeg.get_frame().set_alpha(0.4)
textEd = pylab.gca().get_legend().get_texts()
# set label color
pylab.setp(textEd[0:5], color = "white")
# Tilt the labels to 45 degrees
for label in ax1.xaxis.get_ticklabels():
label.set_rotation(45)


# set up RSI area
ax0 = plt.subplot2grid((5,4), (0,0), sharex=ax1, rowspan=1, colspan=4, axisbg="#07000d")
#plot RSI
rsi = rsiFunc(closep)
rsiCol = "#00FFE8"
ax0.plot(date[-SP:],rsi[-SP:], rsiCol, linewidth=1.5)
ax0.axhline(70, color = rsiCol)
ax0.axhline(30, color = rsiCol)
# color the spaces between the horizontal lines and the RSI line
ax0.fill_between(date[-SP:],rsi[-SP:], 70, where=(rsi[-SP:] >= 70), facecolor=rsiCol, edgecolor=rsiCol)
ax0.fill_between(date[-SP:],rsi[-SP:], 30, where=(rsi[-SP:] <= 30), facecolor=rsiCol, edgecolor=rsiCol)
# Change label and border colors
ax0.spines["bottom"].set_color("#5998FF")
ax0.spines["top"].set_color("#5998FF")
ax0.spines["left"].set_color("#5998FF")
ax0.spines["right"].set_color("#5998FF")
# Change tick color to white
ax0.tick_params(axis="x", colors="white")
ax0.tick_params(axis="y", colors="white")
ax0.set_yticks([30,70])
ax0.yaxis.label.set_color("white")
plt.ylabel("RSI")


# Plot volume on the same range as ax1
volumeMin = 0
ax1v = ax1.twinx()
# subtract moving average calculations
ax1v.fill_between(date[-SP:], volumeMin, volume[-SP:], facecolor="#00FFE8", alpha=.5)
ax1v.axes.yaxis.set_ticklabels([])
# hide grid
ax1v.grid(False)
# Change label and border colors
ax1v.spines["bottom"].set_color("#5998FF")
ax1v.spines["top"].set_color("#5998FF")
ax1v.spines["left"].set_color("#5998FF")
ax1v.spines["right"].set_color("#5998FF")
# update the height of the volume part
ax1v.set_ylim(0,3*volume.max())
# Change axis color
ax1v.tick_params(axis="x", colors="white")
ax1v.tick_params(axis="y", colors="white")


# Setting up the overall appearance of the plot
plt.subplots_adjust(left=.08, bottom=.14, right=.95, top=.95, wspace=.20, hspace=0)
plt.suptitle(stock, color="white")
plt.setp(ax0.get_xticklabels(), visible=False)
plt.show()
fig.savefig("./data/" + stock + ".png", facecolor=fig.get_facecolor())

except Exception, e:
print "main loop", str(e)

if __name__ == "__main__":
# testing the calls
# a list of stocks to process (for testing)
stocksToPull = 'AAPL', 'GOOG', 'AMZN', 'EBAY', 'CMG', 'MSFT', 'C', 'BA', 'TSLA'

graphData(stocksToPull[3])


70 changes: 70 additions & 0 deletions Students/A.Kramer/Final_Project/DataFactory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'''
Created on Nov 28, 2014

@author: Aleksey Kramer
'''
import os
import time
import urllib2
import datetime

def pullStockData(stock):
# check if data directory exists, if not, create
if not os.path.exists("./data"):
os.makedirs("./data")

# print out the pull time
print "Pulling stock", stock, "\t",
print str(datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S"))

# define url and file
urlToVisit="http://chartapi.finance.yahoo.com/instrument/1.0/" + stock + "/chartdata;type=quote;range=1y/csv"
saveFileLine = stock + ".txt"

# Determine the time of the last entry in the file, if file exists
# set the last Unix time to 0, if file dies not exist
try:
existingData = open("./data/" + saveFileLine, "r")
allLines = existingData.read();
splitExisting = allLines.split("\n")
lastLine = splitExisting[-2]
lastUnix = int(lastLine.split(",")[0])
existingData.close()
except Exception, e:
print "Pulling data: Determining last date", e
lastUnix = 0

# Obtain data for the ticket from Yahoo finance and split the file by new line
sourceCode = urllib2.urlopen(urlToVisit).read()
splitSource = sourceCode.split("\n")

# Open file for writing and filter out the data to ensure that
# each line contains 6 entries separated by comma
# no 'visited' in the line
# and the timing in the entries for each record is greater than the last one already
# stored in existing file
saveFile = open("./data/" + saveFileLine, "a")
for eachLine in splitSource:
if "values" not in eachLine:
splitLine = eachLine.split(",")
if len(splitLine) == 6:
# assure we are only getting new data in the file
if int(splitLine[0]) > lastUnix:
lineToWrite = eachLine + "\n"
saveFile.write(lineToWrite)
saveFile.close()

# Print out logging info and make program sleep for 1 second
print "Pulled Stock", stock
print "Sleeping....."
print str(datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S"))
time.sleep(3)


# Pull the data for selected stocks
if __name__ == "__main__":
# Testing data pull
stocksToPull = 'AAPL', 'GOOG', 'AMZN', 'EBAY', 'CMG', 'MSFT', 'C', 'BA', 'TSLA'
pullStockData(stocksToPull[3])


26 changes: 26 additions & 0 deletions Students/A.Kramer/Final_Project/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
1. Libraries used in the code:
os
time
datetime
urllib2
matplotlib
numpy
pylab

2. To run the code, run RunFinal.py from command line.
Once prompted for an input, input the valid stock on the
prompt and hit ENTER key. Wait for several seconds. The
code is getting data from Yahoo Finance web services,
creates a 'data' directory in the directory from which
the script is run, saves the data file with the name of the
stock in the 'data' directory.

After the data is saved, the code is plotting the data
to the screen.

After the code is done with plotting, it saves the image
of the plot in the data directory with the name of the
stock in .png format.

The logs and warnings displayed are just for logging and
verification of the output.
29 changes: 29 additions & 0 deletions Students/A.Kramer/Final_Project/RunFinal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'''
Created on Dec 3, 2014

The code pulls one year worth of data for the stock of your choice
and graphs the data using matplotlib, displaying candlestick chart,
simple moving averages for 12 and 26 days (default), and a Relative
Strength Index (RSI) for selected stock.

I found an excellent video tutorial on financial graphing with python
that shows how to use matplotlib, change parameters of the plots
and to do math calculation to derive moving averages and RSI indexes.
The tutorial can be found on this web site: http://sentdex.com/
This is excellent source to learn charting with matplotlib

@author: Aleksey Kramer
'''
from Chart import graphData
from DataFactory import pullStockData

def runCode():
''' Execute code for final project '''
answer = raw_input("Enter The stock to graph: ")
pullStockData(answer.upper().strip())
graphData(answer.upper().strip())

# run main program
if __name__ == "__main__":
runCode()

4 changes: 1 addition & 3 deletions Students/A.Kramer/session08/generator_solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,8 @@ def prime():
def __is_prime(n):
if n < 2:
return False
if n == 2:
return True
# checking only odd numbers
for x in range(3, int(n**0.5)+1, 2):
for x in range(2, int(n**0.5)+1, 2):
if n % x == 0:
return False
return True
Expand Down
Binary file not shown.