Symbol-Import aus txt-Datei

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
gboos
User
Beiträge: 3
Registriert: Freitag 30. September 2011, 18:27

Ein freundliches "hallo" an alle Forumsmitglieder,

ich moechte mit Hilfe von Python Kursdaten aus Yahoo importieren und das jeweils zu importierende Symbol aus einer Liste importieren, ohne fuer jedes einzelne Symbol eine Variable, Write- und Print-Anweisung im urspruenglichen Code implementieren zu muessen. Das mache ich naemlich jetzt und wird bei Verfollstaendigung der Liste dann aber > 4000 Zeilen Code enthalten. Sicher nicht Sinn und Zweck der Geschichte.

Nun kann ich mit folgendem Code die Yahoo-Kurse downloaden und im Verzeichnis wo das Programm "liegt" speichern :

Code: Alles auswählen

import urllib,time,datetime

class Quote(object):
  
  DATE_FMT = '%Y-%m-%d'
  TIME_FMT = '%H:%M:%S'
  
  def __init__(self):
    self.symbol = ''
    self.date,self.time,self.open_,self.high,self.low,self.close,self.volume = ([] for _ in range(7)) 

  def append(self,dt,open_,high,low,close,volume):
    self.date.append(dt.date())
    self.time.append(dt.time())
    self.open_.append(float(open_))
    self.high.append(float(high))
    self.low.append(float(low))
    self.close.append(float(close))
    self.volume.append(int(volume))
      
  def to_csv(self):
    return ''.join(["{0},{1},{2},{3:.2f},{4:.2f},{5:.2f},{6:.2f},{7}\n".format(self.symbol,
              self.date[bar].strftime('%Y-%m-%d'),self.time[bar].strftime('%H:%M:%S'),self.open_[bar],self.high[bar],self.low[bar],self.close[bar],self.volume[bar]) 
              for bar in xrange(len(self.close))])
    
  def write_csv(self,filename):
    with open(filename,'w') as f:
      f.write(self.to_csv())
        
  def read_csv(self,filename):
    self.symbol = ''
    self.date,self.time,self.open_,self.high,self.low,self.close,self.volume = ([] for _ in range(7)) 
    for line in open(filename,'r'):
      symbol,ds,ts,open_,high,low,close,volume = line.rstrip().split(',')
      self.symbol = symbol
      dt = datetime.datetime.strptime(ds+' '+ts,self.DATE_FMT+' '+self.TIME_FMT)
      self.append(dt,open_,high,low,close,volume)
    return True

  def __repr__(self):
    return self.to_csv()

   
class YahooQuote(Quote):
  ''' Daily quotes from Yahoo. Date format='yyyy-mm-dd' '''
  def __init__(self,symbol,start_date,end_date=datetime.date.today().isoformat()):
    super(YahooQuote,self).__init__()
    self.symbol = symbol.upper()
    start_year,start_month,start_day = start_date.split('-')
    start_month = str(int(start_month)-1)
    end_year,end_month,end_day = end_date.split('-')
    end_month = str(int(end_month)-1)
    url_string = "http://ichart.finance.yahoo.com/table.csv?s={0}".format(symbol)
    url_string += "&a={0}&b={1}&c={2}".format(start_month,start_day,start_year)
    url_string += "&d={0}&e={1}&f={2}".format(end_month,end_day,end_year)
    csv = urllib.urlopen(url_string).readlines()
    csv.reverse()
    for bar in xrange(0,len(csv)-1):
      ds,open_,high,low,close,volume,adjc = csv[bar].rstrip().split(',')
      open_,high,low,close,adjc = [float(x) for x in [open_,high,low,close,adjc]]
      if close != adjc:
        factor = adjc/close
        open_,high,low,close = [x*factor for x in [open_,high,low,close]]
      dt = datetime.datetime.strptime(ds,'%Y-%m-%d')
      self.append(dt,open_,high,low,close,volume)
 
if __name__ == '__main__':
  q = YahooQuote('VXX','1950-01-01') 					
  print q                                          		
  # ETF's
  var1 = YahooQuote('GLD','1950-01-01') 	
  var1.write_csv('GLD.csv')                          	
  var1 = Quote()                                      	
  var1.read_csv('GLD.csv')                           	
  print var1                                          	
  var2 = YahooQuote('XLF','1950-01-01') 	
  var2.write_csv('XLF.csv')                          	
  var2 = Quote()                                      	
  var2.read_csv('XLF.csv')                           	
  print var2
  var3 = YahooQuote('SPY','1950-01-01') 		
  var3.write_csv('SPY.csv')                          	
  var3 = Quote()                                      	
  var3.read_csv('SPY.csv')   
  print var3
  var4 = YahooQuote('VXX','1950-01-01') 		
  var4.write_csv('VXX.csv')                          	
  var4 = Quote()                                      	
  var4.read_csv('VXX.csv')   
  print var4
  var5 = YahooQuote('EEM','1950-01-01') 		
  var5.write_csv('EEM.csv')                          	
  var5 = Quote()                                      	
  var5.read_csv('EEM.csv')   
  print var5
  var6 = YahooQuote('EWJ','1950-01-01') 		
  var6.write_csv('EWJ.csv')                          	
  var6 = Quote()                                      	
  var6.read_csv('EWJ.csv')   
  print var6
  var7 = YahooQuote('IWM','1950-01-01') 		
  var7.write_csv('IWM.csv')                          	
  var7 = Quote()                                      	
  var7.read_csv('IWM.csv')   
  print var7
  var8 = YahooQuote('QQQ','1950-01-01') 		
  var8.write_csv('QQQ.csv')                          	
  var8 = Quote()                                      	
  var8.read_csv('QQQ.csv')   
  print var8
  var9 = YahooQuote('XIV','1950-01-01') 		
  var9.write_csv('XIV.csv')                          	
  var9 = Quote()                                      	
  var9.read_csv('XIV.csv')   
  print var9
  var10 = YahooQuote('SLV','1950-01-01') 		
  var10.write_csv('SLV.csv')                          	
  var10 = Quote()                                      	
  var10.read_csv('SLV.csv')   
  print var10
  var11 = YahooQuote('XLU','1950-01-01') 		
  var11.write_csv('XLU.csv')                          	
  var11 = Quote()                                      	
  var11.read_csv('XLU.csv')   
  print var11
  var12 = YahooQuote('XLE','1950-01-01') 		
  var12.write_csv('XLE.csv')                          	
  var12 = Quote()                                      	
  var12.read_csv('XLE.csv')   
  print var12
  var13 = YahooQuote('EWH','1950-01-01') 		
  var13.write_csv('EWH.csv')                          	
  var13 = Quote()                                      	
  var13.read_csv('EWH.csv')   
  print var13
  var14 = YahooQuote('USO','1950-01-01') 		
  var14.write_csv('USO.csv')                          	
  var14 = Quote()                                      	
  var14.read_csv('USO.csv')   
  print var14
  var15 = YahooQuote('XLP','1950-01-01') 		
  var15.write_csv('XLP.csv')                          	
  var15 = Quote()                                      	
  var15.read_csv('XLP.csv')   
  print var15
  var16 = YahooQuote('FXI','1950-01-01') 		
  var16.write_csv('FXI.csv')                          	
  var16 = Quote()                                      	
  var16.read_csv('FXI.csv')   
  print var16
  var17 = YahooQuote('VWO','1950-01-01') 		
  var17.write_csv('VWO.csv')                          	
  var17 = Quote()                                      	
  var17.read_csv('VWO.csv')   
  print var17

Wie man aber zum Schluss sehr gut sehen kann, muss ich fuer jedes gewuenscht Symbol extra Code hinzufuegen. Ich wuerde aber gerne eine Textdatei, im Ordner wo das Programm liegt, mit allen benoetigten Symbolen hinterlegen. Somit soll das Programm dann jedes Symbol nach und nach abarbeiten, eine csv-Datei mit dem Namen des Symbols schreiben. Die txt-Datei mit den Symbolen soll wie folgt aussehen :

Code: Alles auswählen

SPY
QQQ
DIA
GLD
SLV
XLF
XLU
:
usw.
Frage :

1. Wie mache ich das das ich das Programm dazu bringe jede Zeile der txt-Datei nach dem Symbol zu checken und das dann jeweils hier (siehe Code : SYMBOL) :

Code: Alles auswählen

var4 = YahooQuote('SYMBOL','1950-01-01') 		
var4.write_csv('SYMBOL.csv')                          	
var4 = Quote()                                      	
var4.read_csv('SYMBOL.csv')
einzusetzen, die csv-Datei zu schreiben und dann das naechste Symbol aus der txt-Datei zu nehmen, bis alle Symbole abgearbeitet sind. Schoen waere natuerlich wenn man die txt-Datei beliebig in der Anzahl der Symbole erweitern koennte. Fuer Anregungen bin ich sehr dankbar.

Viele Gruesse

Mike
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Wann immer man beginnt Variablen zu nummerieren, sollte man eine Liste verwenden. Um die Liste zu befüllen, verwendet man eine Schleife. Lies also das Tutorial deiner Wahl zu dem Thema.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@gboos: ich gehe mal davon aus, dass die Klassen nicht von Dir geschrieben sind, da Du ansonsten Listen und for-Schleifen kennen müßtest. Da es sich dabei um so etwas Grundlegendes handelt, würde ich Dir empfehlen, ein Python-Tutorial durchzuarbeiten.

noch ein paar Anmerkungen:
- Einrücktiefe sind 4 Leerzeichen, nicht 2
- zum Lesen und Schreiben von csv-Dateien gibt es das csv-Modul
- warum liest Du die gerade eben geschriebene Datei wieder ein?
- statt sieben Einzellisten solltest Du nur eine Liste mit den Daten verwenden, die aus Tupeln mit jeweils 7 Elementen besteht.
- bei read_csv wird die Datei nicht wieder geschlossen, weil sie im Gegensatz zu write_csv ohne with geöffnet wird.
gboos
User
Beiträge: 3
Registriert: Freitag 30. September 2011, 18:27

Natuerlich ist das Programm nicht von mir geschrieben worden. Ich habe es lediglich fuer mich ergaenzt. Gut dann muss ich den anderen langwierigen Weg gehen und mit dem Download noch warten .... Danke.
- warum liest Du die gerade eben geschriebene Datei wieder ein?
Weil ich die Daten waehrend des Downloads in der Shell sehen moechte, um zu sehen zu welchem Symbol der Download gerade laeuft
- statt sieben Einzellisten solltest Du nur eine Liste mit den Daten verwenden, die aus Tupeln mit jeweils 7 Elementen besteht.
Hmmm, das muss ich mir dann nochmal anschauen ... Wie wuerde denn ein Vorschlag Deinerseits aussehen ?

Viele Gruesse.

Mike
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Code: Alles auswählen

import urllib,datetime
from collections import namedtuple

class Quote(namedtuple('Quote','date,open,high,low,close,volume')):
    STRFORMAT="{:%Y-%m-%d,%H:%M:%S},{},{:.2f},{:.2f},{:.2f},{}"
    DATE_FMT = '%Y-%m-%d,%H:%M:%S'
    DATE_FMT2 = '%Y-%m-%d'
    
    @classmethod
    def parse(cls, line):
        date,open,high,low,close,volume = line.rsplit(',',5)
        return cls(
            datetime.datetime.strptime(date, cls.DATE_FMT),
            float(open),float(high),float(low),float(close),int(volume)
        )

    @classmethod
    def parse_yahoo(cls, line):
        date,open,high,low,close,volume, adjc = line.rsplit(',',6)
        factor = float(adjc)/float(close)
        return cls(
            datetime.datetime.strptime(date, cls.DATE_FMT2),
            factor*float(open), factor*float(high),
            factor*float(low), factor*float(close), int(volume)
        )
      
    def __str__(self):
        return self.STRFORMAT.format(*self)
    
class Quotes(list):
    def __init__(self, symbol=''):
        self.symbol = symbol
        
    def __str__(self):
        return ''.join("{},{}\n".format(self.symbol,q) for q in self)

    def write_csv(self,filename):
        with open(filename,'w') as f:
            f.writelines("{},{}\n".format(self.symbol,q) for q in self)
        
    def read_csv(self,filename):
        with open(filename,'r') as f:
            for line in f:
                symbol, other = line.split(',', 1)
                self.append(Quote.parse(other))
        self.symbol = symbol
   
class YahooQuotes(Quotes):
    ''' Daily quotes from Yahoo. Date format='yyyy-mm-dd' '''
    URL = "http://ichart.finance.yahoo.com/table.csv?s={0}&a={1:%m}&b={1:%d}&c={1:%Y}&d={2:%m}&e={2:%d}&f={2:%Y}"
    DATE_FMT = '%Y-%m-%d'

    def __init__(self,symbol,start_date,end_date=datetime.date.today().isoformat()):
        super(YahooQuotes,self).__init__()
        self.symbol = symbol.upper()
        start_date = datetime.datetime.strptime(start_date,self.DATE_FMT)
        end_date = datetime.datetime.strptime(end_date,self.DATE_FMT)
        url_string = self.URL.format(self.symbol, start_date, end_date)
        csv = urllib.urlopen(url_string)
        _header = next(csv)
        for line in csv:
            self.append(Quote.parse_yahoo(line))
        self.reverse()

if __name__ == '__main__':
    # ETF's
    for symbol in ('GLD','XLF','SPY','VXX','EEM','EWJ',
                   'IWM','QQQ','XIV','SLV','XLU','XLE',
                   'EWH','USO','XLP','FXI','VWO'):
        quotes = YahooQuotes(symbol,'1950-01-01')
        quotes.write_csv('%s.csv'%symbol)
        print quotes
gboos
User
Beiträge: 3
Registriert: Freitag 30. September 2011, 18:27

@Sirius3

Klasse. Habe daraus auch gleich wieder 3 Sachen neu gelernt. Mit meiner Version des WRITE & READ der csv-Datei ist die letzt aufgerufene Datei in der Tat immer wieder geschrieben und gelesen worden - solange das Programm offen ist. Das habe ich bisher, ehrlich gesagt, gar nicht gemerkt.

Schaue mir gerade das Einlesen von Daten aus csv-Dateien an und bin eventuell auf einen Weg gestossen mit dem ich mein Problem, nach Deinem Denkanstoss, wahrscheinlich selbst loesen kann. Muss nur fuer mich selber rausfinden wie ich die Symbole aus der csv-Datei in Deine Var "symbol" bekomme und statt der momentanen Aufzaehlung eben immer die Symbole uebernehme. Muss das aber fuer mich erstmal selbst versuchen. Sollte ich Probleme haben wuerde ich gerne nochmal fragen und sonst demnaechst hoffentlich meinen Loesungsvorschlag praesentieren wollen. Dann koennt Ihr Euch sicher darueber totlachen.

Dritte Erkenntnis ist die das Deine Version 100mal schneller laeuft als mein Write & Read und ich versuche das vom Code her zu verinnerlichen.

Hey Klasse .... Tausend Dank. Habe also fue rmich was zu tun und zu lernen. Super !!!

Viele Gruesse Mike
Antworten