1
+ + # Name: stockAnalysis7.py
2
+ + # Version: 7
3
+ + # Author: Ty Lim
4
+ + # Date: August 30, 2014
5
+ + # Description: This program gather all COGS, SGA, Revenue information for a NASDAQ traded stock and
6
+ + # displays and makes all pertinent CVP calcualtions for that stock based on released financial data.
7
+ + # Notes:
8
+ + # 1. This application utilizes Google Finance to read in stock information.
9
+ + # 2. This application reads in financial data from a fixed position within the Google Finance generated html file.
10
+ + # Changes:
11
+ + # 1. Added ability to write to an html file.
12
+ + # a. Added file object to export data to html file.
13
+ + # b. File being written to /tmp/stock.html
14
+ +
15
+ + import csv
16
+ + import sys
17
+ + from os import path
18
+ + import urllib2
19
+ + from bs4 import BeautifulSoup
20
+ + from urllib2 import urlopen
21
+ + import json
22
+ +
23
+ + class buildCSVFinancials :
24
+ + def __init__ (self ,url ,csvFile ):
25
+ + self .url = url
26
+ +
27
+ + def writeCSV (self ):
28
+ + soup = BeautifulSoup (urlopen (self .url ))
29
+ + table = soup .find ('table' , attrs = { "class" : "gf-table rgt" })
30
+ + headers = [header .text for header in table .find_all ('td' )]
31
+ + rows = []
32
+ +
33
+ + for row in table .find_all ('td' ):
34
+ + rows .append ([val .text .encode ('utf8' ) for val in row .find_all ('td' )])
35
+ +
36
+ + with open (csvFile , 'wb' ) as f :
37
+ + writer = csv .writer (f )
38
+ + writer .writerow (headers )
39
+ + writer .writerows (row for row in rows if row )
40
+ +
41
+ +
42
+ + class readCSV :
43
+ + def __init__ (self ,csvFile ):
44
+ + self .csvFile = csvFile
45
+ +
46
+ + def readCSVFile (self ):
47
+ + cr = csv .reader (open (self .csvFile ,"rb" ))
48
+ +
49
+ + for row in cr :
50
+ + # Name value pair. This goes in the specific row position in the read html file.
51
+ + # These positions are fixed within the finance site.
52
+ + # Note: These will be different for other finance sites.
53
+ +
54
+ + revenue_header = row [0 ]
55
+ + rev_current_qtr = row [1 ]
56
+ + rev_previous_qtr = row [2 ]
57
+ + cogs_current_qtr = row [20 ]
58
+ + cogs_previous_qtr = row [21 ]
59
+ + sga_current_qtr = row [32 ]
60
+ + sga_previous_qtr = row [33 ]
61
+ +
62
+ + #replace comma with null
63
+ + # Convert from string to integer. Remove all ','
64
+ + rev_current_qtr = rev_current_qtr .replace (',' ,'' )
65
+ + rev_current_qtr = rev_current_qtr .replace ('.00' ,'' )
66
+ + rev_current_qtr = float (rev_current_qtr )
67
+ +
68
+ + rev_previous_qtr = rev_previous_qtr .replace (',' ,'' )
69
+ + rev_previous_qtr = rev_previous_qtr .replace ('.00' ,'' )
70
+ + rev_previous_qtr = float (rev_previous_qtr )
71
+ +
72
+ + cogs_current_qtr = cogs_current_qtr .replace (',' ,'' )
73
+ + cogs_current_qtr = cogs_current_qtr .replace ('.00' ,'' )
74
+ + cogs_current_qtr = float (cogs_current_qtr )
75
+ +
76
+ + cogs_previous_qtr = cogs_previous_qtr .replace (',' ,'' )
77
+ + cogs_previous_qtr = cogs_previous_qtr .replace ('.00' ,'' )
78
+ + cogs_previous_qtr = float (cogs_previous_qtr )
79
+ +
80
+ + sga_current_qtr = sga_current_qtr .replace (',' ,'' )
81
+ + sga_current_qtr = sga_current_qtr .replace ('.00' ,'' )
82
+ + sga_current_qtr = float (sga_current_qtr )
83
+ +
84
+ + sga_previous_qtr = sga_previous_qtr .replace (',' ,'' )
85
+ + sga_previous_qtr = sga_previous_qtr .replace ('.00' ,'' )
86
+ + sga_previous_qtr = float (sga_previous_qtr )
87
+ +
88
+ +
89
+ + #print revenue_header
90
+ + #print current_qtr
91
+ + #print previous_qtr
92
+ + return rev_current_qtr , rev_previous_qtr ,cogs_current_qtr ,cogs_previous_qtr ,sga_current_qtr ,sga_previous_qtr
93
+ +
94
+ + class incomeAnaylsis :
95
+ + def __init__ (self , sales , cogs , sga ):
96
+ + self .sales = sales
97
+ + self .cogs = cogs
98
+ + self .sga = sga
99
+ +
100
+ + def contributionMargin (self ):
101
+ +
102
+ + #print self.sales
103
+ + #type(self.sales)
104
+ + CM = float (self .sales )- float (self .cogs )
105
+ + return CM
106
+ +
107
+ + def contrinbutionMarginRatio (self ):
108
+ + CM = float (self .sales )- float (self .cogs )
109
+ + CMR = float (CM / self .sales )
110
+ + return CMR
111
+ +
112
+ + def unitCM (self ):
113
+ + unitCM = self .sales / (float (self .sales )- float (self .cogs ))
114
+ + return unitCM
115
+ +
116
+ + def profit (self ):
117
+ + CM = float (self .sales )- float (self .cogs )
118
+ + CMR = float (CM / self .sales )
119
+ + profit = CMR * self .sales - self .sga
120
+ + return profit
121
+ +
122
+ + def fixedCosts (self ):
123
+ + CM = float (self .sales )- float (self .cogs )
124
+ + CMR = float (CM / self .sales )
125
+ + profit = CMR * self .sales - self .sga
126
+ + fixedCosts = CMR * self .sales - profit
127
+ + return fixedCosts
128
+ +
129
+ +
130
+ + ##### MAIN ######
131
+ + #stockSymbol = input("Enter a stock symbol: ")
132
+ + #Sublime BUG. Need to fix. For now, hardcode the stock symbol.
133
+ + stock = 'swks'
134
+ + URL = 'http://www.google.com/finance?q=NASDAQ%3A' + stock + '&fstype=ii&ei=LvYAVKCBCsSyiAKN7IGoCA'
135
+ + csvFile = '/tmp/output_file5.csv'
136
+ + buildCSVFinancialsObject = buildCSVFinancials (URL ,csvFile )
137
+ + buildCSVFinancialsObject .writeCSV ()
138
+ + readCSVObject = readCSV (csvFile )
139
+ + rev_current_qtr ,rev_previous_qtr ,cogs_current_qtr ,cogs_previous_qtr ,sga_current_qtr ,sga_previous_qtr = readCSVObject .readCSVFile ()
140
+ + incomeAnaylsisObjectCurrentQuarter = incomeAnaylsis (rev_current_qtr ,cogs_current_qtr ,sga_current_qtr )
141
+ + contributionMargin = incomeAnaylsisObjectCurrentQuarter .contributionMargin ()
142
+ + contributionMarginRatio = incomeAnaylsisObjectCurrentQuarter .contrinbutionMarginRatio ()
143
+ + unitCM = incomeAnaylsisObjectCurrentQuarter .unitCM ()
144
+ + profit = incomeAnaylsisObjectCurrentQuarter .profit ()
145
+ + fixedCosts = incomeAnaylsisObjectCurrentQuarter .fixedCosts ()
146
+ + #print 'CM = '+ CM
147
+ +
148
+ + print 'STOCK SYMBOL: ' + stock
149
+ + print ''
150
+ + print 'Revenue Current Quarter: ' + str (rev_current_qtr )+ ' ' + 'COGS Current Quarter: ' + str (cogs_current_qtr )
151
+ + print 'Revenue Previous Quarter: ' + str (rev_previous_qtr )+ ' ' + 'COGS Previous Quarter: ' + str (cogs_previous_qtr )
152
+ + print ''
153
+ + print 'SGA Current Quarter: ' + str (sga_current_qtr )+ ' ' + 'Contribution Margin: ' + str (contributionMargin )
154
+ + print 'SGA Previous Quarter: ' + str (sga_previous_qtr )+ ' ' + 'Unit CM: ' + str (unitCM )
155
+ + print ''
156
+ + print 'Contribution Margin Ratio: ' + str (contributionMarginRatio )
157
+ + print ''
158
+ + print 'Fixed Costs: ' + str (fixedCosts )
159
+ + print ''
160
+ + print 'Profit: ' + str (profit )
161
+ +
162
+ +
163
+ + # Write to output output file
164
+ +
165
+ + f = open ('/tmp/stock.html' , 'w' )
166
+ + # This is a test of whether or not the file has been opened.
167
+ + #print f
168
+ + # Build this as an object. Seperate this out as a stand-alone, callable file.
169
+ + f .write ('<HTML>\n ' )
170
+ + f .write ('<H1>Cost-Volume-Profit Analysis</H1>' )
171
+ + f .write ('<BOLD><H1>STOCK SYMBOL: ' + stock + '</H1><BOLD><BR>' )
172
+ +
173
+ + f .write ('\n <BOLD>Revenue Current Quarter:</BOLD> ' + str (rev_current_qtr ) + '\n <BR>' )
174
+ + f .write ('\n <BOLD>Revenue Previous Quarter:</BOLD>' + str (rev_previous_qtr ) + '\n <BR>' )
175
+ + f .write ('\n <BOLD>COGS Current Quarter: </BOLD>' + str (cogs_current_qtr ) + '\n <BR>' )
176
+ + f .write ('\n <BOLD>COGS Previous Quarter:</BOLD> ' + str (cogs_previous_qtr ) + '\n <BR>' )
177
+ +
178
+ + f .write ('\n <BR><BOLD>SGA Current Quarter: </BOLD> ' + str (sga_current_qtr ) + '\n <BR>' )
179
+ + f .write ('\n <BOLD>SGA Previous Quarter: </BOLD> ' + str (sga_previous_qtr ) + '\n <BR>' )
180
+ +
181
+ +
182
+ + f .write ('\n <BOLD>Contribution Margin:</BOLD> ' + str (contributionMargin ) + '\n <BR>' )
183
+ + f .write ('\n <BR><BOLD>Unit CM:</BOLD> ' + str (unitCM ) + '\n <BR>' )
184
+ + f .write ('\n <BOLD>Contribution Margin Ratio:</BOLD> ' + str (contributionMarginRatio ) + '\n <BR>' )
185
+ + f .write ('\n <BOLD>Fixed Costs:</BOLD> ' + str (fixedCosts ) + '\n <BR>' )
186
+ + f .write ('\n <BOLD>Profit:</BOLD> ' + str (profit ) + '\n <BR>' )
187
+ +
188
+ +
189
+ + f .write ('\n </HTML>' )
190
+ + # Write HTML to stock.html
191
+ + # Close the file from writing.
192
+ + f .close ()
193
+ +
194
+ + # Dump data inot JSON file for access in JAVASCRIPT.
195
+ + # This can be utilized for the mobile application as the reader for the 'viewer' mobile app.
196
+ + data = {'stock' : stock , 'Revenue Current Quarter' :rev_current_qtr , 'Revenue Previous Quarter' :rev_previous_qtr ,'COGS Current Quarter' :cogs_current_qtr ,'COGS Previous Quarter' :cogs_previous_qtr }
197
+ +
198
+ + jSonDumpFile = open ('/tmp/json_stock.json' , 'w' )
199
+ + json .dump (data , jSonDumpFile , ensure_ascii = False )
200
+ +
0 commit comments