ServerPortfolio  2.0
Python parsers and server
 All Classes Namespaces Files Functions Variables Properties Pages
YahooCSV.py
Go to the documentation of this file.
1 ## @package serverportfolio.Parsers.YahooCSV
2 # @brief Define the class YahooCSV to use the 'old' Yahoo API
3 #
4 # LastChanged $Id: YahooCSV.py 13 2015-04-12 19:45:14Z michael $
5 
6 # Note: CSV API, https://code.google.com/p/yahoo-finance-managed/wiki/csvHistQuotesDownload
7 # Adjusted Close includes both dividends and splits
8 # With HistoricalPrice, hp, You can download dividends by using &g=v in place of the three price variables
9 # yahoo.finance.dividend history use ichart/table.csv g=v to get dividend
10 
11 # adjusted close, present in yahoo CSV
12 # http://www.captaineconomics.fr/-dividende-fractionnement-effet-cours-action-bourse
13 
14 import copy, types, logging
15 import datetime, time
16 
17 # for dates_intro, maybe to move to an other HTML parser
18 from lxml import html, etree
19 
20 from serverportfolio import GlobalDicts
21 from serverportfolio.GlobalDicts import EAction
22 from serverportfolio.StockTemplates import StTmpl
23 from serverportfolio import Utils
24 # if missing run, but strange bug after...
25 from serverportfolio.PortfolioException import PortfolioError, ParserError
26 
27 from serverportfolio.Parsers.Abstract import AbstractParser
28 from serverportfolio.Parsers import UtilsParsers
29 
30 ## @class YahooCSV
31 # @brief Derived parser class for retrieving divers data from the 'old' Yahoo API
32 #
33 # Implement actions:
34 # - HistPrice : Historical Price
35 # - DivSplit : Dividend/Split history (not fully implemented)
36 # - DatesIntro : Get the first date available for the historical price
37 # - Fundamental : YQL is preferred for this action.
39 
40  # option g=v gives dividends (but no split)
41  __HISTORY_QUOTES_URL="http://ichart.yahoo.com/table.csv?"
42 
43  # other access http://ichart.finance.yahoo.com/x , contains data and dividends and split stock
44  # did not find documentation, would need to compare the data, make more test
45  # format is csv but different from table.csv, date format %y%m%d + keyword DIVIDEND/SPLIT
46  # http://ichart.finance.yahoo.com/x?s=GSZ.PA&d=1&e=16&f=2015&g=v&a=1&b=2&c=2000 (dates important)
47  # DIVIDEND, 20110506,0.750000
48  # 20110506,169.03,170.15,168.24,168.89,4839400,157.75
49  # 20110505,170.47,170.87,167.50,168.46,7332000,156.64
50  # SPLIT, 19970528,2:1
51  # 19970528,90.50,91.88,88.50,90.12,17898800,36.26
52  # 19970527,174.00,179.25,174.00,179.25,12950800,36.06
53  __HISTORY_QUOTES_X_URL="http://ichart.finance.yahoo.com/x?"
54 
55  # for currency discussion
56  # http://stackoverflow.com/questions/5108399/yahoo-finance-all-currencies-quote-api-documentation
57  #
58  # page for querying max date of quotations, particularly the first date of introduction
59  # related to pure HTML page
60  # us page is correct, but data are wrong when downloaded! 5 minutes after ok !
61  # http://finance.yahoo.com/q/hp?s=^FCHI&a=11&b=1&c=2014&d=01&e=9&f=2015&g=d
62  __HISTORY_DATES_URL="http://fr.finance.yahoo.com/q/hp?"
63 
64  # page to retrieve fundamental data, old CVS API
65  __QUOTES_CSV_URL="http://download.finance.yahoo.com/d/quotes.csv?" #s=AAPL,^
66 
67  ## @brief Constructor.
68  # @param action enumeration of the EAction to perform
69  def __init__(self, e_action ):
70  # init parent with action
71  super(YahooCSV, self).__init__(e_action)
72 
73  # only logger as internal data member
74  self.logger = logging.getLogger('SP.YahooCSV')
75  self.logger.debug("Init class YahooCSV")
76 
77  self.source = 'YCSV'
78 
79  ## @brief Create the url according to the action and the stock(s).
80  # Fundamental accepts multiple stocks.\n
81  # @todo Check day, with HistPrice before use day+1 but very dangerous, now C++ should deal with overlap
82  def create_url(self):
83  self.logger.debug("YahooCSV::create_url")
84  self.logger.debug("local stock: %s", self.local_stock)
85 
86  # extract symbol and stock from data member, correct output for one or multi stocks
87  code_yahoo = ','.join( stock.get_action('Static','code_yahoo') for stock in self.local_stock.values() )
88  self.logger.debug("code yahoo: %s" % code_yahoo)
89 
90  if self.e_action == EAction.HistPrice:
91  self.logger.debug("YahooCSV with EAction.HistPrice, only one stock")
92  assert ( len(self.local_stock) == 1 ), "YahooCSV with HistPrice deals only with one Stock at a time"
93 
94  symbol = self.local_stock.keys()[0]
95  self.logger.debug("full dictionary symbol %s: %s" % (symbol, self.local_stock[symbol].get_action()))
96 
97  # last date in file, first_date is wrong set to 0
98  lastdate = self.local_stock[symbol].get_action('HistPrice','last_date')
99  # first date in file, not important here
100  firstdate = self.local_stock[symbol].get_action('HistPrice','first_date')
101 
102  self.logger.debug("lastdate %s" % lastdate) # 1970-01-01
103  (year,month,day)=(lastdate.year,lastdate.month,lastdate.day)
104 
105  # use today as default for last day, if use datetime get all hour..secs
106  today = datetime.date.today()
107  self.logger.debug("max_date 0, today %s" % today)
108  (tyear,tmonth,tday)=(today.year,today.month,today.day)
109  self.logger.debug("today day %d" % tday)
110 
111  # wrong here a,b,c start, d,e,f end
112  # s=symbol &d=begin_month(-1) &e=begin_day &f= begin_year &g=d (for daily)
113  # &a= end_month(-1) &b=end_day &c=end_year
114 
115  # shift 1 for day to not copy again the same line ! Dangerous end of month ! Better checked in merging the data
116  # Seems ok, no more shift
117  self.url = self.__HISTORY_QUOTES_URL + "s=" + code_yahoo \
118  + "&d=" + str(tmonth-1) + "&e=" + str(tday) + "&f=" + str(tyear) \
119  + "&g=d" \
120  + "&a=" + str(month-1) + "&b=" + str(day) + "&c=" + str(year)
121  #+ "&a=" + str(month-1) + "&b=" + str(day+1) + "&c=" + str(year)
122 
123  # some common code with HistPrice, about dates
124  elif self.e_action == EAction.DivSplit :
125 
126  assert ( len(self.local_stock) == 1 ), "YahooCSV with DivSplit deals only with one Stock at a time"
127  symbol = self.local_stock.keys()[0]
128  self.logger.debug("full dictionary symbol %s: %s" % (symbol, self.local_stock[symbol].get_action()))
129 
130  # last date in file, first_date is wrong set to 0 at the moment
131  lastdate = self.local_stock[symbol].get_action('DivSplit','last_date')
132  # first date in file, not important here
133  firstdate = self.local_stock[symbol].get_action('DivSplit','first_date')
134 
135  self.logger.debug("lastdate %s" % lastdate) # 1970-01-01
136  (year,month,day)=(lastdate.year,lastdate.month,lastdate.day)
137  self.logger.debug("lastdate.day %d" % day)
138 
139  # update until now
140  today = datetime.date.today()
141  self.logger.debug("max_date today %s" % today)
142  (tyear,tmonth,tday)=(today.year,today.month,today.day)
143  self.logger.debug("today day %s" % tday)
144 
145  # g=v to print only Div and Split, dates optional restrict correctly
146  self.url = self.__HISTORY_QUOTES_X_URL + "s=" + code_yahoo + "&g=v" \
147  + "&a=" + str(month-1) + "&b=" + str(day) + "&c=" + str(year) \
148  + "&d=" + str(tmonth-1) + "&e=" + str(tday) + "&f=" + str(tyear)
149 
150  # set method for getting introduction date, first available date in CSV
151  elif self.e_action == EAction.DatesIntro :
152  assert ( len(self.local_stock) == 1 ), "YahooCSV with DatesIntro deals only with one Stock at a time"
153  self.url = self.__HISTORY_DATES_URL + "s=" + code_yahoo
154 
155  # this action can be performed with multiple stocks at a time
156  elif self.e_action == EAction.Fundamental :
157  # Ask not used but give correct value for EURUS
158  # symbol(s),name(n),Ask,MarketCapitalization(j1),SharesOwned(s1),DividendYield(d0),
159  # BVPS(b4),PriceBook(p6),PER(r0),PEG(r5), Error code e1
160  self.url = self.__QUOTES_CSV_URL + "s=" + code_yahoo + '&f=snaj1s1d0b4p6r0r5e1&e=.csv'
161 
162  else :
163  # not really an error, bug if not implemented, not exception here, assert better
164  self.logger.critical("ERROR method parser not valid %s" % self.e_action)
165  raise ParserError("YahooCSV not a valid e_action %s" % (self.e_action), \
166  self.local_stock.keys(), self.e_action.name, 'None' )
167 
168  self.logger.debug("url: %s",self.url)
169 
170  ## Parser implementation for YahooCSV, action dependent
171  # @param s page return by web_query
172  def parse( self, s):
173  self.logger.debug("parse()") #, s
174  self.logger.debug("self.e_action.name %s " % self.e_action.name )
175  # print the complete webpage
176  # print "s:\n", s
177  try:
178  if self.e_action == EAction.HistPrice:
179  self.parse_hp(s)
180  self.logger.debug("size of listCSV: %d" %
181  len(self.list_return_data['action_templ']['HistPrice']['list_csv']))
182 
183  elif self.e_action == EAction.DivSplit:
184  self.parse_div(s)
185 
186  elif self.e_action == EAction.Fundamental:
187  self.parse_fund(s)
188 
189  elif self.e_action == EAction.DatesIntro:
190  self.parse_dates_intro(s)
191 
192  else:
193  self.logger.error("Specific parse() function not defined for action: %s" % self.e_action)
194  raise ParserError("Specific parse() function not defined for action: %s" % (self.e_action),\
195  self.local_stock.keys()[0], self.e_action.name, self.url)
196 
197  except ParserError as ex:
198  self.logger.error("parse() caught ParserError ex: %s\n" % ex )
199  raise
200 
201  # ok, works well
202  except Exception as ex:
203  self.logger.error("parse() caught Exception ex: %s\n" % ex )
204  raise ParserError(ex, self.local_stock.keys()[0], self.e_action.name, self.url)
205 
206  ## @brief Specific parsing function to read a list of CSV, only daily values.
207  # To fit with design, must set a dict. Before never saved the listCSV only passed as argument
208  # keep a simple dictionary (first, last, error in data(to write), listCSV specific in self
209  # dictionary must be called dict_parser
210  # @param all_line the page returned by web_query
211  def parse_hp(self, all_line): #lastCSV, max_date = None ):
212  self.logger.debug("parse_hp()")
213 
214  # return all values in a list included in the template
215  listCSV=[]
216  # split line
217  line_split=all_line.split("\n")
218 
219  # pass the header, last line, not sure
220  for line_tmp in line_split[1:-1]:
221  #print "newline ",line_tmp
222  tmp_CSV=[]
223  data_split=line_tmp.split(",")
224 
225  compt=0
226  for data_tmp in data_split[:-1]:
227  # deal with date for first in the list, translate to timestamp for C++
228  # CSV on yahoo always date, no time
229  if compt == 0:
230  tmp_date=time.strptime(data_tmp,"%Y-%m-%d")
231  data_tmp=int( round(time.mktime(tmp_date)))
232  tmp_CSV.append(data_tmp)
233  #print "tmp_date ",tmp_date
234  #print "data_tmp ",data_tmp
235  #self.logger.debug("parse_hp date_tmp %s" % (Utils.timestamp_to_string(data_tmp)) )
236  #all other values convert to float (double for python,diff for C++)
237  else:
238  tmp_CSV.append(float(data_tmp))
239 
240  compt+=1
241  # add to the new list of data
242  listCSV.append(tmp_CSV)
243  #self.logger.debug("tmp_CSV %s" % tmp_CSV)
244  self.logger.debug("listCSV.size %d ", len(listCSV))
245 
246  # include the template and symbol, only one stock here, could be in parse ?
247  self.list_return_data = StTmpl.get_template_parser( self.e_action.name )
248  self.list_return_data['symbol'] = self.local_stock.keys()[0]
249  # assign data, must be specific, self.first not needed anymore
250  tmp_templ = self.list_return_data['action_templ'][ self.e_action.name ]
251  #tmp_templ['first_date'] = #listCSV[-1][0] #self.first_date
252  tmp_templ['last_date'] = datetime.datetime.fromtimestamp( listCSV[0][0] ) #self.last_date
253  tmp_templ['list_csv'] = listCSV
254 
255  self.logger.debug("list_data_return %s" % self.list_return_data)
256  # not used self.error
257  #tmp_templ['error'] = None
258 
259  ## @brief Specific parsing function for dividends/split.
260  # Save data in dictionary template DivSplit.list_div, list_split
261  # @param all_line the page returned by web_query
262  def parse_div(self, all_line):
263  self.logger.debug("parse_div()")
264  print "all_line ", all_line
265 
266  # return all values in lists, test after if empty, wrong
267  list_div=[]
268  list_split=[]
269 
270  # split by lines
271  line_split=all_line.split("\n")
272 
273  # pass the header, "Date,Dividends"
274  # format : DIVIDEND, 20141013,0.500000
275  # last line, not sure...
276  for line_tmp in line_split[1:]:
277  #print "newline ",line_tmp
278  data_split=line_tmp.split(",")
279 
280  if data_split[0] == 'DIVIDEND':
281  # datetime.strptime return a datetime
282  # date = datetime.datetime.strptime( data_split[1].strip(), "%Y%m%d" )
283  # time.strptime return a time_struct
284  date = time.strptime( data_split[1].strip(), "%Y%m%d" )
285  value = float(data_split[2])
286  self.logger.debug("dividend: %s %f" % (date, value))
287  self.logger.debug("mktime %d", int (time.mktime(date)))
288  date = int ( time.mktime( date ) )
289  list_div.append( [date, value])
290 
291  elif data_split[0] == 'SPLIT':
292  date = int ( time.mktime( time.strptime( data_split[1].strip(), "%Y%m%d" ) ) )
293  # format "1:4", always 1:X ??
294  value = data_split[2]
295  self.logger.debug("split: %s %s" % (date, value))
296  list_split.append( [date, value])
297  # check the STATUS
298  else:
299  #print "other "
300  print line_tmp
301  if data_split[0] == "STATUS":
302  assert( data_split[1].strip() == '0' )
303 
304 # new, first part could be done in parse()
305  self.list_return_data = StTmpl.get_template_parser( self.e_action.name )
306  # set the standard template with symbol
307  self.list_return_data['symbol'] = self.local_stock.keys()[0]
308 
309  tmp_template = self.list_return_data['action_templ'][ self.e_action.name ]
310  # must check for both not empty
311  if list_div :
312  # assign data, must be specific
313  #tmp_template['first_date'] = #listCSV[-1][0] #self.first_date
314  tmp_template['last_date'] = max( datetime.datetime.fromtimestamp( list_div[0][0] ), \
315  datetime.datetime.fromtimestamp( list_div[0][0] ) )
316  tmp_template['list_div'] = list_div
317  tmp_template['list_split'] = list_split
318 
319  self.logger.debug("list_return_data %s" % self.list_return_data)
320  self.logger.debug("list_div.size %d ", len(list_div))
321  self.logger.debug("list_split.size %d ", len(list_split))
322 
323  ## @brief Parse fundamental data with old API, CSV data.
324  # First implementation with fields specified in url, see Yahoo YQL for a better option.\n
325  #
326  # Support call with multiple stocks, one line by stock\n
327  # Name is also available for Info\n
328  # List of data:\n
329  # - symbol(s),name(n),Ask,MarketCapitalization(j1),SharesOwned(s1),DividendYield(d0),
330  # BVPS(b4),PriceBook(p6),PER(r0),PEG(r5), new added e1 for error in code
331  def parse_fund(self, all_line):
332  self.logger.debug("parse_fund()")
333  self.logger.debug("all_line %s" % all_line)
334 
335  # for debug with name containing ","
336  # line: "FSLR","First Solar, Inc.",... string format marked between double quotes...
337  # re.findall(r'"([^"]*)"', inputString), extract all string in double quotes, what happens if empty...
338 
339  # main dictionary to save in parser, list of template parsers
340  self.list_return_data = list()
341 
342  # parse line by line. One stock by line
343  line_split = all_line.split("\n")
344  for line in line_split :
345  # test empty line, seems last line is empty
346  if not line:
347  self.logger.warning("1 line is empty")
348  break
349  self.logger.debug("line: %s" % line)
350 
351  # split comma separated line, problem with name ex: "FSLR","First Solar, Inc.",...
352  elem_line = line.split(',')
353  #self.logger.debug("elem_line: %s" % elem_line )
354 
355  # module csv can do it also, maybe other option to use
356  yahoo_code = elem_line[0].replace('"', '').strip()
357  self.logger.debug("yahoo_code: %s" % yahoo_code )
358 
359  # need to retrieve the symbol from the yahoo_code
360  # raise a ParserError if cannot retrieve the symbol
361  symbol = self.get_symbol_from_code( yahoo_code, 'code_yahoo')
362 
363  # creates standard and specific template for each Stock
364  dict_data_stock = None
365  dict_data_stock = StTmpl.get_template_parser( self.e_action.name )
366  dict_data_stock['symbol'] = symbol
367 
368 # It is the part specific to this action
369 
370  # for both fundamental (YQL and CSV) can get an error about the code for devise
371  if UtilsParsers.check_nan(elem_line[10]) == False:
372  self.logger.error("error in parsing csv element[10] :%s" % line )
373  #return
374 
375  # make shortcut
376  tmp_dict = dict_data_stock['action_templ'][ self.e_action.name ]
377 
378  # test, can extract the name
379  # Not in template, but should work as. Tricky name contains "," First Solar, Inc.
380  # Should count number of field, or test is string...
381  # Could move name at the last position
382  #tmp_dict['Name'] = elem_line[1]
383 
384 
385  # B is deleted, maybe better function specific for Yahoo
386  tmp_dict['MarketCapitalization'] = UtilsParsers.extract_number(elem_line[3]) #'45.753B'
387  # did not pass because '-'
388  tmp_dict['SharesOwned'] = UtilsParsers.extract_number( elem_line[4] )
389  # return a float
390  tmp_dict['DividendYield'] = UtilsParsers.extract_number( elem_line[5] )
391  tmp_dict['BVPS'] = UtilsParsers.extract_number( elem_line[6] )
392  tmp_dict['PriceBook'] = UtilsParsers.extract_number( elem_line[7] )
393  tmp_dict['PER'] = UtilsParsers.extract_number (elem_line[8]) # 'N/A'
394  tmp_dict['PEG'] = UtilsParsers.extract_number (elem_line[9]) # 'N/A'
395 
396  # append data for all stocks
397  self.list_return_data.append( dict_data_stock )
398 
399  # end loop over line
400  self.logger.debug("self.list_return_data:%s" % self.list_return_data)
401  self.logger.debug("pretty test:\n%s" % Utils.pretty_dict( self.list_return_data ) )
402 
403  ## @brief To get introduction date of a stock, (first available on Yahoo) and last available.
404  # need to make more test
405  # @param html_page returned by web_query
406  def parse_dates_intro( self, html_page ):
407 
408  htmltree = html.document_fromstring ( html_page )
409  input_extracted = htmltree.xpath("//input[@id='startday']")
410  day_start = input_extracted[0].get("value")
411 
412  # get main_parent for other research
413  main_parent = input_extracted[0].getparent().getparent()
414  option_selected = main_parent.xpath("td/select/option[@selected]")
415  month_start = option_selected[0].get("value")
416  year_selected=main_parent.xpath("td/input[@id='startyear']")
417  year_start=year_selected[0].get("value")
418 
419  first_day = year_start+'-'+str(int(month_start)+1)+'-'+day_start
420  # transform to a struct_tm
421  date_start = time.strptime(first_day,"%Y-%m-%d")
422  datestamp_start=int( round(time.mktime(date_start)))
423  # return struct_tm
424  self.logger.debug("date_start: %s" % date_start)
425  # return integer
426  self.logger.debug("datestamp_start: %d" % datestamp_start)
427 
428 # again common, except for Fundamental, because multiple queries
429  # set the default template and symbol
430  self.list_return_data = StTmpl.get_template_parser( self.e_action.name )
431  # set the standard template with symbol
432  self.list_return_data['symbol'] = self.local_stock.keys()[0]
433 
434 # get specific template for this action
435  self.list_return_data['action_templ'][self.e_action.name]['intro'] = datestamp_start
436  self.list_return_data['action_templ'][self.e_action.name]['intro_str'] = \
437  datetime.datetime.fromtimestamp( datestamp_start ).strftime('%Y-%m-%d %H:%M:%S')
438 
439 # ###### Main for test
440 if __name__ == "__main__":
441 
442  from serverportfolio.DictionaryStocks import DictionaryStocks
443  import sys, traceback
444 
445  print "main module YahooCSV"
446 
447  logging.basicConfig(level=logging.DEBUG)
448  logging.getLogger('SP')
449  m_logger = logging.getLogger("SP.main")
450 
451  try:
452  m_stock = sys.argv[1]
453  m_action = sys.argv[2]
454  except IndexError:
455  print " Only for debugging, should call ./Run_Parsers for all options "
456  print " Usage:"
457  print " YahooCSV CAC40 HistPrice"
458  print " Action: HistPrice / Fundamental / DatesIntro / DivSplit"
459  print " For Fundamental it is possible to query multi-stocks CAC40,GSZ,FSLR"
460  sys.exit(1)
461 
462  # transform to a list, from format "Stock1,Stock2,.."
463  m_list_stock = m_stock.split(',')
464 
465  try :
466  if type(m_action) == types.StringType:
467  m_e_action = EAction[m_action]
468  #isisntance(EAction)
469  else:
470  m_e_action = m_action
471  except :
472  m_logger.error("Exception from EActione numeration, cannot assign an e_action from action: %s" % m_action)
473  raise
474 
475  m_logger.info("list_stock: %s" % m_list_stock)
476  m_logger.info("e_action: %s " % m_e_action)
477  m_parserCSV = YahooCSV( m_e_action )
478  #parserCSVsource = 'YCSV'
479 
480  m_logger.debug("\n== store copy of object in parser")
481  try :
482  m_parserCSV.store_stock_copy( m_list_stock )
483 
484  except ParserError as ex:
485  print "Caught ParserError ex", ex.get_format_string()
486  sys.exit(1)
487 
488  except Exception as ex:
489  print "Got error in store_stock_copy"
490  print "ex :", ex
491  sys.exit(1)
492 
493 # Preprocessing for HistPrice, DivSplit to set date range already available
494  if ( m_action == EAction.HistPrice.name ) | ( m_action == EAction.DivSplit.name ):
495  print "\n Preprocess for Action ", m_action
496  DictionaryStocks().get_stocks( m_list_stock[0] ).last_CSV( m_action )
497 
498  m_logger.debug("\n== create_url default 0 0")
499  try:
500  m_parserCSV.create_url()
501 
502  except PortfolioError as ex:
503  print "Catch PortfolioError from create_url: ", ex
504  print ex.get_format_string()
505  sys.exit(1)
506 
507  except Exception as ex:
508  print "Catch Exception from create_url: ", ex
509  # copy from parser stocks
510  exc_type, exc_value, exc_traceback = sys.exc_info()
511  print "*** print_tb:"
512  traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
513  # not working with print
514  #print "trace1 ", traceback.print_tb( sys.exc_info()[2] )
515  # return a tuple
516  print "exec_info ", sys.exc_info()
517  print "exec_info[2] ", sys.exc_info()[2]
518  print "trace: "
519  # ok
520  traceback.print_tb( sys.exc_info()[2] )
521  sys.exit(1)
522 
523  m_logger.debug("\n== web_query ")
524  try:
525  m_s = UtilsParsers.web_query( m_parserCSV.url )
526  # raise urllibERROR at the moment
527  except Exception as ex:
528  print "Got exception from web_query: ", ex
529  print "exit "
530  sys.exit(1)
531 
532  m_logger.debug("\n== parse the web page")
533  try:
534  m_parserCSV.parse(m_s)
535 
536  except ParserError as ex:
537  print "Catch PaserError ", ex
538  print "ex.get_format_string"
539  # here nice output with all information
540  print ex.get_format_string()
541  sys.exit(1)
542 
543  except Exception as ex:
544  print "Catch Exception from parse() ", ex
545  sys.exit(1)
546 
547  m_logger.debug("\n== update the stock(s)")
548 
549  # argument of run_parser, set by UpdateStocks
550  #m_parserCSV.option_post = {
551  # 'interactive': False,
552  # 'to_save' : True
553  #}
554 
555  m_parserCSV.update_stock()
556 
557  m_logger.debug("\n== print stock(s)")
558  # only print the dictionary as final processing
559  for stock in m_list_stock:
560  print Utils.pretty_dict( DictionaryStocks().get_stocks( stock ).get_action() )
561 
def parse_div
Specific parsing function for dividends/split.
Definition: YahooCSV.py:262
e_action
enumeration (EAction) of the type of query to perform
Definition: Abstract.py:40
def create_url
Create the url according to the action and the stock(s).
Definition: YahooCSV.py:82
def parse_dates_intro
To get introduction date of a stock, (first available on Yahoo) and last available.
Definition: YahooCSV.py:406
def parse
Parser implementation for YahooCSV, action dependent.
Definition: YahooCSV.py:172
Define the global variable StockTemplates.StTmpl and dictionary templates.
Define 2 abstract methods which need to be overridden by the Parsers and a generic algorithm (run_pa...
Definition: Abstract.py:29
Define custom and specific exceptions for the complete package.
Derived class specific to the parsers.
def parse_fund
Parse fundamental data with old API, CSV data.
Definition: YahooCSV.py:331
Define an abstract base class for specific Parsers.
Definition: Abstract.py:1
def parse_hp
Specific parsing function to read a list of CSV, only daily values.
Definition: YahooCSV.py:211
def get_symbol_from_code
Retrieve the symbol (or Stock) from the code_yahoo or code_bourso.
Definition: Abstract.py:211
Container of all Stocks objects, it also reads the static stocks configuration file "dictstocks...
Global variables for configuration: paths, TCP ports and generic definitions.
Definition: GlobalDicts.py:1
url
save url, useful for reporting errors and exceptions
Definition: Abstract.py:37
Define singleton class DictionaryStocks, act as the main container of Stocks objects.
Derived parser class for retrieving divers data from the 'old' Yahoo API.
Definition: YahooCSV.py:38