Entwickler-Ecke
ASP.NET und Web - Aktienkurse abrufen aus dem Web
SSC streezer - Fr 20.03.09 11:11
Titel: Aktienkurse abrufen aus dem Web
Hallo,
ich schreibe gerade ein tool mit dem man mittels gridview seine Aktien verwalten kann und bei auswahl noch weitere Details anzeigt.
nun weiss ich nicht wie ich an die daten ran komme die auf yahoo finance sind (dafür gibt es ja in excel schöne add-ins welche auch super funzen).
gibt es so was auch für WPF - irgend eine connection klasse welche die verbindung zu irgend einer page aufbaut auf welcher Aktienkurse sich befinden?
wäre forh um jeden tipp / hinweis da es doch relativ komplex wäre das zu implementieren...
gruss,
streezer
Moderiert von
Kha: Topic aus WPF / Silverlight verschoben am Fr 20.03.2009 um 11:49
Kha - Fr 20.03.09 12:48
SSC streezer hat folgendes geschrieben : |
nun weiss ich nicht wie ich an die daten ran komme die auf yahoo finance sind (dafür gibt es ja in excel schöne add-ins welche auch super funzen). |
Google soll da manchmal ganz nützlich sein :) -
http://www.gummy-stuff.org/Yahoo-data.htm
Damit bekommst du eine schöne CSV-Datei (wahrscheinlich die gleiche, die diese Excel-Addins benutzen), die du dann zerlegen kannst. Entweder per Hand oder du suchst zB auf CodeProject.com nach einem CSV-Reader.
PS: Ich verschiebe mal das Topic, da es ja (noch) nichts mit WPF zu tun hat. Erstelle für das Anzeigen in WPF dann bitte ein neues Topic.
SSC streezer - Fr 20.03.09 13:44
ok gut - ich versuche das mal so via CSV - ne das excel addin ist eine xla datei
SSC streezer - Fr 20.03.09 16:12
hab bis jetzt folgendes entwickelt:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| class Aktie { private string URL { get; set; }
public DataTable MakeURL(string aktienName, object Höchstwert, object Tiefstwert) { string URL = "http://finance.yahoo.com/d/quotes.csv?s="; URL = URL + aktienName + "&f=" + "s" + Höchstwert + Tiefstwert;
List<string[]> result = parseCSV(URL); DataTable daten = new DataTable(); foreach (string column in result[0]) { daten.Columns.Add(); }
foreach (string[] row in result) { daten.Rows.Add(row); }
return daten; }
public List<string[]> parseCSV(string url) { List<string[]> parsedData = new List<string[]>();
using (StreamReader readFile = new StreamReader(url)) { string line; string[] row;
while ((line = readFile.ReadLine()) != null) { row = line.Split(','); parsedData.Add(row); } }
return parsedData; } } |
bei der Instanzierung des neuen Streamreader objects readFile, stürzt das teil ab und sagt mir URI Format wird nicht unterstützt. Mein CSV wird ja abgeholt aus dem Web (siehe oben - da wird die URL geneiriert). Die URL funzt soweit (getestet - kopiert in Browser). Doch das CSV file kann nicht abgeholt werden.
wie mache ich das? muss ich das file irgendwie zuerst lokal speichern und dann von dort aus öffnen? geht das während der laufzeit?
Kha - Fr 20.03.09 16:57
FileStream (den benutzt StreamReader(string)) kann nur Dateien im Intranet öffnen. Für einen HTTP-Download brauchst du die WebRequest-Klasse.
SSC streezer - Fr 20.03.09 17:08
problem ist ja, die daten verändern sich ja ständig. ich frage mich nun ob es sinn macht die files immer runterzuladen... theoretisch sind sie auch online einsehbar...
dann würde das klappen mit filestream oder? dass z.b. via button immer gerefresht wird und so das file neu nei "eingelesen" wird was dann auf der yahoo seite ist und nicht lokal.
löse ich das mit dem filestream? das hab ich ja eigentlich jetzt so (siehe oben) aber das klappt ja nicht...
SSC streezer - Mo 23.03.09 10:15
kleiner nachtrag
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| public static string GetUrlResponse(string url,string username,string password) { string content = null; WebRequest webRequest = WebRequest.Create(url); if(username == null || password == null) { NetworkCredential networkCredential = new NetworkCredential(username, password); webRequest.PreAuthenticate = true; webRequest.Credentials = networkCredential; } WebResponse webResponse = webRequest.GetResponse(); StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.ASCII); content = sr.ReadToEnd(); return content.ToString(); } |
SSC streezer - Mo 23.03.09 16:14
sooo...
ich habe nun folgende klasse erstellt:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| public class Aktie { public string Name { get; set; } public string Symbol { get; set; } public int Aktuell { get; set; } public int Veraenderung { get; set; } public int Vortag { get; set; } public int Eroeffnung { get; set; } public int Volumen { get; set; } } |
um auf dem xaml dann via bdinging auf die eigenschaften zugrieffen kann. nun hab ich aber folgende frage: wie kann ich von der liste mit den daten (string[]) die eitnräge den eigenschaften zuweisen?
habs so versucht:
neueAktie.Name = parsedData[0].ToString(); klappt aber nicht wirklich (index out of range heisst es immer)
was muss ich anders machen?
Kha - Mo 23.03.09 16:50
Lies dir deinen Beitrag bitte noch einmal durch und frage dich, was man darauf antworten soll :| . Wir haben keine Ahnung, woher "parsedData" kommt, aber es scheint wohl keinen einzigen String zu enthalten :nixweiss: .
SSC streezer - Mo 23.03.09 17:02
sorry wenn ichs nicht genau erklärt habe :(
ich möchte einfach nur die Items in der Liste "gezeichneteAktienListe" auf das Listview bringen und anzeigen lassen.
mit folgendem klappts schon mal nicht (zeile 5) - obwohl das eigentlich sollte (binding auf xaml seite gemacht / konfiguriert):
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| private void ButtonAdd_Click(object sender, RoutedEventArgs e) { AktieListe neueAktienListe = new AktieListe(); Window1 main = new Window1(); main.ListviewAktien.DataContext = neueAktienListe.GetUrlResponse(txtAktienName.Text); this.Close(); } |
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| public class AktieListe { private string URL { get; set; }
public List<Aktie> GetUrlResponse(string aktie) { List<Aktie> gezeichneteAktienListe = new List<Aktie>(); URL = "http://finance.yahoo.com/d/quotes.csv?s=" + aktie + "&f=" + "n" + "s" + "l";
WebRequest webRequest = WebRequest.Create(URL); WebResponse webResponse = webRequest.GetResponse(); StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.ASCII);
string line; string[] row; List<string[]> parsedData = new List<string[]>(); Aktie neueAktie = new Aktie();
while ((line = sr.ReadLine()) != null) { row = line.Split(','); parsedData.Add(row);
neueAktie.Name = row[0].ToString(); neueAktie.Symbol = row[1].ToString(); } gezeichneteAktienListe.Add(neueAktie); return gezeichneteAktienListe; } } |
Kha - Mo 23.03.09 17:42
Schonmal ein Schritt in die richtige Richtung, aber wirklich weiter hilft mir das auch nicht ;) . Du verrätst nicht einmal, ob die Methode im Debugger richtige Ergebnisse liefert - wenn ja, muss es wohl am Xaml liegen, ansonsten wären Input des Web-Services und Output der Methode nützlich.
Eines fällt mir aber schonmal auf: Überlege dir einmal, wie viele Aktie-Instanzen du erstellst und wie viele du der Liste hinzufügst. parsedData solltest du jetzt eigentlich weglassen können.
SSC streezer - Di 24.03.09 09:26
ah ja stimmt parsedData brauchts nicht mehr. Im Debugger werden die Daten richtig in das Aktienobjekt abegefüllt (in Attribut Name, Symbol etc.). Doch angezeigt werden die Objekte in der Listview nicht.
hier der xaml code - wo ich mir auch nicht sicher bin bezüglich des Bindings....
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| <StackPanel Margin="5" x:Name="Main"> <StackPanel x:Name="ManageAktien" Orientation="Horizontal"> <ListView Height="170" Name="ListviewAktien" TabIndex="1" Width="700" HorizontalAlignment="Left" SelectionMode="Single" ItemsSource="{Binding}"> <ListView.View> <GridView> <GridViewColumn Width="100" Header="Name" DisplayMemberBinding="{Binding Name}" /> <GridViewColumn Width="50" Header="Symbol" DisplayMemberBinding="{Binding Symbol}"/> <GridViewColumn Width="80" DisplayMemberBinding="{Binding Aktuell}">Aktuell</GridViewColumn> <GridViewColumn Width="80" DisplayMemberBinding="{Binding Veraenderung}">Veränderung</GridViewColumn> <GridViewColumn Width="80" DisplayMemberBinding="{Binding Vortag}">Vortag</GridViewColumn> <GridViewColumn Width="80" DisplayMemberBinding="{Binding Eroeffnung}">Eröffnung</GridViewColumn> <GridViewColumn Width="80" DisplayMemberBinding="{Binding Volumen}">Volumen</GridViewColumn> </GridView> </ListView.View> </ListView> <Button Height="23" Name="btnAddNeueAktie" Margin="10" Width="117" VerticalContentAlignment="Top" VerticalAlignment="Top" Click="btnAddNeueAktie_Click">Neue Aktie hinzufügen</Button> </StackPanel> </StackPanel> |
UGrohne - Di 24.03.09 09:54
Sieht eigentlich gut aus. Schau aber mal in die Ausgabe in VS, evtl. findest Du dort den Fehler. Ansonsten kannst Du aber auch den Namespace Systems.Diagnostics importieren (xmlns:diag-Deklaration im Root-Element) und dann Dein Binding genauer Debuggen lassen mittels
{Binding,diag:PresentationTraceSources.TraceLevel=High}, dann bekommst Du in der Ausgabe genauen Angaben, was das Binding macht.
SSC streezer - Di 24.03.09 10:17
ist das assembyl system? mscorlib? System.Core? oder Windowsbase?
xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=System"
und wo muss ich genau dieses spezielle binding reintun? beim control selbst, oder bei den spalten?
vielen dank für die infos..
//output
Quelltext
1: 2: 3:
| F:\2_Privat\StockManager\StockManager\Window1.xaml(8,134): error MC1000: Unknown build error, 'Key cannot be null. F:\2_Privat\StockManager\StockManager\Window1.xaml(8,134): error MC1000: Parameter name: key Line 8 Position 134.' Done building project "StockManager.csproj" -- FAILED. |
UGrohne - Di 24.03.09 10:27
Ah, das hab ich vergessen, das ist WindowsBase, da es zu WPF gehört. Das Attribut verwendest Du am Besten erstmal beim ItemsSource-Binding der ListView.
SSC streezer - Di 24.03.09 10:38
ok danke dir...
erhalte aber folgenden fehler beim kompilieren des projekts...
UGrohne - Di 24.03.09 11:09
SSC streezer hat folgendes geschrieben : |
ok danke dir...
erhalte aber folgenden fehler beim kompilieren des projekts... |
Und was steht dort?
SSC streezer - Di 24.03.09 11:12
siehe printscreen weiter oben xD
UGrohne - Di 24.03.09 11:15
SSC streezer hat folgendes geschrieben : |
siehe printscreen weiter oben xD |
Nein, was steht in Zeile 8, Spalte 134?
SSC streezer - Di 24.03.09 11:49
ach so sorry xD
das steht auf linie 8:
Quelltext
1:
| <ListView Height="170" Name="ListviewAktien" TabIndex="1" Width="700" HorizontalAlignment="Left" SelectionMode="Single" ItemsSource="{Binding,diag:PresentationTraceSources.TraceLevel=High}"> |
es betrifft das ItemSource Element...
UGrohne - Di 24.03.09 12:10
Laut Deinem früheren Zitat hast Du Diagnostics aber unter dem Kürzel diagnostics, nicht diag eingefügt, check das mal bitte.
SSC streezer - Di 24.03.09 12:30
ja stimmt - habs geändert fehler erscheint aber trotzdem :(
Kha - Di 24.03.09 15:02
Merkwürdig. Kannst du es noch einmal ohne Diagnostics probieren? Wenn die Quelle nicht leer ist, aber nichts angezeigt wird, dann sollte eigentlich irgendwas im "Ausgabe"-Fenster angezeigt werden.
SSC streezer - Di 24.03.09 16:10
sooo habs rausgefunden...
das problem war dass ich eine normale
List<> verwendet habe. Bei WPF ist es so dass man, um die Liste autom. aktualisieren zu lassen, eine
ObservableCollection<> verwenden muss.
dazu dieser link:
http://geekswithblogs.net/shahed/archive/2007/10/10/115983.aspx
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!