Skip to content

Commit 9acf6f5

Browse files
committed
Merge pull request UWPCE-PythonCert#91 from voite1/master
Submitting Adding Final Assignment
2 parents cd68b7f + 6ee3091 commit 9acf6f5

File tree

6 files changed

+302
-3
lines changed

6 files changed

+302
-3
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
'''
2+
Created on Dec 3, 2014
3+
4+
@author: Aleksey Kramer
5+
'''
6+
import numpy as np
7+
import matplotlib
8+
import matplotlib.pyplot as plt
9+
import matplotlib.ticker as mticker
10+
import matplotlib.dates as mdates
11+
from matplotlib.finance import candlestick
12+
import pylab
13+
14+
# adjusted font size for the plots
15+
matplotlib.rcParams.update({"font.size": 10})
16+
17+
18+
# define RSI function
19+
def rsiFunc(prices, n=14):
20+
deltas = np.diff(prices)
21+
seed = deltas[:n+1]
22+
up = seed[seed >= 0].sum() / n
23+
down = -seed[seed<0].sum() / n
24+
rs = up/down
25+
rsi = np.zeros_like(prices)
26+
rsi[:n] = 100. - 100./(1. + rs)
27+
for i in range(n, len(prices)):
28+
delta = deltas[i-1]
29+
if delta > 0:
30+
upval = delta
31+
downval = 0.
32+
else:
33+
upval = 0.
34+
downval = -delta
35+
up = (up * (n-1) +upval) / n
36+
down = (down*(n-1) + downval) / n
37+
rs = up/down
38+
rsi[i] = 100. - 100. / (1. + rs)
39+
return rsi
40+
41+
# define moving average function
42+
def movingaverage(values, window):
43+
weights = np.repeat(1.0, window) / window
44+
smas = np.convolve(values, weights, 'valid')
45+
return smas # numpy array
46+
47+
def graphData(stock, MA1=12, MA2=26):
48+
try:
49+
# define the data file
50+
stockFile = "./data/" + stock + ".txt"
51+
52+
# Load data into numpy arrays
53+
date, closep, highp, lowp, openp, volume = np.loadtxt(stockFile, delimiter=",",
54+
unpack=True, converters = {0: mdates.strpdate2num("%Y%m%d")})
55+
56+
#-----------------------------------------------------------------------------------------------
57+
# building data for drawing plotting candlestick chart. Basically, a an array of comma separated
58+
# values. The order of elements is very specific, so check the documentation for candlestick
59+
x = 0
60+
y = len(date)
61+
candleArray = []
62+
while x < y:
63+
# order of elements matters!!! - used for candlestick charting
64+
appendLine = date[x], openp[x], closep[x], highp[x], lowp[x], volume[x]
65+
candleArray.append(appendLine)
66+
x += 1
67+
68+
# moving averages for 12 and 26 days
69+
Av1 = movingaverage(closep, MA1)
70+
Av2 = movingaverage(closep, MA2)
71+
# Starting point for graphs
72+
SP = len(date[MA2-1:])
73+
# Creating Moving Average labels
74+
label1=str(MA1) + " SMA"
75+
label2=str(MA2) + " SMA"
76+
77+
78+
# changing the face color of the graphics
79+
fig = plt.figure(facecolor="#07000D")
80+
81+
# create room and plot candlestick chart
82+
ax1 = plt.subplot2grid((5,4), (1,0), rowspan=4, colspan=4, axisbg="#07000D")
83+
candlestick(ax1, candleArray[-SP:], width=0.75, colorup="#9EFF15", colordown="#FF1717")
84+
# plot moving averages
85+
ax1.plot(date[-SP:], Av1[-SP:], "#5998FF", label=label1, linewidth=1.5)
86+
ax1.plot(date[-SP:], Av2[-SP:], "#E1EDF9", label=label2, linewidth=1.5)
87+
# Set grid color to white
88+
ax1.grid(True, color="white")
89+
# Set number of tickers on x-axis
90+
ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
91+
# Format date for presentation
92+
ax1.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
93+
# Change label and border colors
94+
ax1.yaxis.label.set_color("white")
95+
ax1.spines["bottom"].set_color("#5998FF")
96+
ax1.spines["top"].set_color("#5998FF")
97+
ax1.spines["left"].set_color("#5998FF")
98+
ax1.spines["right"].set_color("#5998FF")
99+
# Change tick color to white
100+
ax1.tick_params(axis="y", colors="white")
101+
ax1.tick_params(axis="x", colors="white")
102+
plt.ylabel("Stock Price and Volume")
103+
# display legend and set size of font to 7
104+
maLeg = plt.legend(loc=9, ncol=2, prop={"size":7}, fancybox=True)
105+
# update label transparency
106+
maLeg.get_frame().set_alpha(0.4)
107+
textEd = pylab.gca().get_legend().get_texts()
108+
# set label color
109+
pylab.setp(textEd[0:5], color = "white")
110+
# Tilt the labels to 45 degrees
111+
for label in ax1.xaxis.get_ticklabels():
112+
label.set_rotation(45)
113+
114+
115+
# set up RSI area
116+
ax0 = plt.subplot2grid((5,4), (0,0), sharex=ax1, rowspan=1, colspan=4, axisbg="#07000d")
117+
#plot RSI
118+
rsi = rsiFunc(closep)
119+
rsiCol = "#00FFE8"
120+
ax0.plot(date[-SP:],rsi[-SP:], rsiCol, linewidth=1.5)
121+
ax0.axhline(70, color = rsiCol)
122+
ax0.axhline(30, color = rsiCol)
123+
# color the spaces between the horizontal lines and the RSI line
124+
ax0.fill_between(date[-SP:],rsi[-SP:], 70, where=(rsi[-SP:] >= 70), facecolor=rsiCol, edgecolor=rsiCol)
125+
ax0.fill_between(date[-SP:],rsi[-SP:], 30, where=(rsi[-SP:] <= 30), facecolor=rsiCol, edgecolor=rsiCol)
126+
# Change label and border colors
127+
ax0.spines["bottom"].set_color("#5998FF")
128+
ax0.spines["top"].set_color("#5998FF")
129+
ax0.spines["left"].set_color("#5998FF")
130+
ax0.spines["right"].set_color("#5998FF")
131+
# Change tick color to white
132+
ax0.tick_params(axis="x", colors="white")
133+
ax0.tick_params(axis="y", colors="white")
134+
ax0.set_yticks([30,70])
135+
ax0.yaxis.label.set_color("white")
136+
plt.ylabel("RSI")
137+
138+
139+
# Plot volume on the same range as ax1
140+
volumeMin = 0
141+
ax1v = ax1.twinx()
142+
# subtract moving average calculations
143+
ax1v.fill_between(date[-SP:], volumeMin, volume[-SP:], facecolor="#00FFE8", alpha=.5)
144+
ax1v.axes.yaxis.set_ticklabels([])
145+
# hide grid
146+
ax1v.grid(False)
147+
# Change label and border colors
148+
ax1v.spines["bottom"].set_color("#5998FF")
149+
ax1v.spines["top"].set_color("#5998FF")
150+
ax1v.spines["left"].set_color("#5998FF")
151+
ax1v.spines["right"].set_color("#5998FF")
152+
# update the height of the volume part
153+
ax1v.set_ylim(0,3*volume.max())
154+
# Change axis color
155+
ax1v.tick_params(axis="x", colors="white")
156+
ax1v.tick_params(axis="y", colors="white")
157+
158+
159+
# Setting up the overall appearance of the plot
160+
plt.subplots_adjust(left=.08, bottom=.14, right=.95, top=.95, wspace=.20, hspace=0)
161+
plt.suptitle(stock, color="white")
162+
plt.setp(ax0.get_xticklabels(), visible=False)
163+
plt.show()
164+
fig.savefig("./data/" + stock + ".png", facecolor=fig.get_facecolor())
165+
166+
except Exception, e:
167+
print "main loop", str(e)
168+
169+
if __name__ == "__main__":
170+
# testing the calls
171+
# a list of stocks to process (for testing)
172+
stocksToPull = 'AAPL', 'GOOG', 'AMZN', 'EBAY', 'CMG', 'MSFT', 'C', 'BA', 'TSLA'
173+
174+
graphData(stocksToPull[3])
175+
176+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'''
2+
Created on Nov 28, 2014
3+
4+
@author: Aleksey Kramer
5+
'''
6+
import os
7+
import time
8+
import urllib2
9+
import datetime
10+
11+
def pullStockData(stock):
12+
# check if data directory exists, if not, create
13+
if not os.path.exists("./data"):
14+
os.makedirs("./data")
15+
16+
# print out the pull time
17+
print "Pulling stock", stock, "\t",
18+
print str(datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S"))
19+
20+
# define url and file
21+
urlToVisit="http://chartapi.finance.yahoo.com/instrument/1.0/" + stock + "/chartdata;type=quote;range=1y/csv"
22+
saveFileLine = stock + ".txt"
23+
24+
# Determine the time of the last entry in the file, if file exists
25+
# set the last Unix time to 0, if file dies not exist
26+
try:
27+
existingData = open("./data/" + saveFileLine, "r")
28+
allLines = existingData.read();
29+
splitExisting = allLines.split("\n")
30+
lastLine = splitExisting[-2]
31+
lastUnix = int(lastLine.split(",")[0])
32+
existingData.close()
33+
except Exception, e:
34+
print "Pulling data: Determining last date", e
35+
lastUnix = 0
36+
37+
# Obtain data for the ticket from Yahoo finance and split the file by new line
38+
sourceCode = urllib2.urlopen(urlToVisit).read()
39+
splitSource = sourceCode.split("\n")
40+
41+
# Open file for writing and filter out the data to ensure that
42+
# each line contains 6 entries separated by comma
43+
# no 'visited' in the line
44+
# and the timing in the entries for each record is greater than the last one already
45+
# stored in existing file
46+
saveFile = open("./data/" + saveFileLine, "a")
47+
for eachLine in splitSource:
48+
if "values" not in eachLine:
49+
splitLine = eachLine.split(",")
50+
if len(splitLine) == 6:
51+
# assure we are only getting new data in the file
52+
if int(splitLine[0]) > lastUnix:
53+
lineToWrite = eachLine + "\n"
54+
saveFile.write(lineToWrite)
55+
saveFile.close()
56+
57+
# Print out logging info and make program sleep for 1 second
58+
print "Pulled Stock", stock
59+
print "Sleeping....."
60+
print str(datetime.datetime.fromtimestamp(time.time()).strftime("%Y-%m-%d %H:%M:%S"))
61+
time.sleep(3)
62+
63+
64+
# Pull the data for selected stocks
65+
if __name__ == "__main__":
66+
# Testing data pull
67+
stocksToPull = 'AAPL', 'GOOG', 'AMZN', 'EBAY', 'CMG', 'MSFT', 'C', 'BA', 'TSLA'
68+
pullStockData(stocksToPull[3])
69+
70+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
1. Libraries used in the code:
2+
os
3+
time
4+
datetime
5+
urllib2
6+
matplotlib
7+
numpy
8+
pylab
9+
10+
2. To run the code, run RunFinal.py from command line.
11+
Once prompted for an input, input the valid stock on the
12+
prompt and hit ENTER key. Wait for several seconds. The
13+
code is getting data from Yahoo Finance web services,
14+
creates a 'data' directory in the directory from which
15+
the script is run, saves the data file with the name of the
16+
stock in the 'data' directory.
17+
18+
After the data is saved, the code is plotting the data
19+
to the screen.
20+
21+
After the code is done with plotting, it saves the image
22+
of the plot in the data directory with the name of the
23+
stock in .png format.
24+
25+
The logs and warnings displayed are just for logging and
26+
verification of the output.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'''
2+
Created on Dec 3, 2014
3+
4+
The code pulls one year worth of data for the stock of your choice
5+
and graphs the data using matplotlib, displaying candlestick chart,
6+
simple moving averages for 12 and 26 days (default), and a Relative
7+
Strength Index (RSI) for selected stock.
8+
9+
I found an excellent video tutorial on financial graphing with python
10+
that shows how to use matplotlib, change parameters of the plots
11+
and to do math calculation to derive moving averages and RSI indexes.
12+
The tutorial can be found on this web site: http://sentdex.com/
13+
This is excellent source to learn charting with matplotlib
14+
15+
@author: Aleksey Kramer
16+
'''
17+
from Chart import graphData
18+
from DataFactory import pullStockData
19+
20+
def runCode():
21+
''' Execute code for final project '''
22+
answer = raw_input("Enter The stock to graph: ")
23+
pullStockData(answer.upper().strip())
24+
graphData(answer.upper().strip())
25+
26+
# run main program
27+
if __name__ == "__main__":
28+
runCode()
29+

Students/A.Kramer/session08/generator_solution.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ def prime():
3838
def __is_prime(n):
3939
if n < 2:
4040
return False
41-
if n == 2:
42-
return True
4341
# checking only odd numbers
44-
for x in range(3, int(n**0.5)+1, 2):
42+
for x in range(2, int(n**0.5)+1, 2):
4543
if n % x == 0:
4644
return False
4745
return True
Binary file not shown.

0 commit comments

Comments
 (0)