Download code: AEXKoers v1.0
Met behulp van deze in c# geschreven applicatie is het mogelijk om koersgegevens van de AEX op te vragen.
Een voorbeeld:
D:>aexkoers AEGON
AEX Koers application, Evert van Es 2004
Current system date: 17-3-2004 14:45:06
Date : 17 Mar 2004
Markt : AEX
Fonds : aegon
Current : 10.72
Change : 0.16
Time : 14:29
Bid : 10.72
Offer : 10.74
Volume : 6344245
High : 10.76
Low : 10.59
Open : 10.59
Finished.
D:>
En als alternatief kan een lijst met fonds namen opgevraagd worden:
D:>aexkoers -L
AEX Koers application, Evert van Es 2004
Current system date: 17-3-2004 14:46:46
AEX: abn amro
AEX: aegon
AEX: akzo nobel
<...KNIP...>
INDEX: AEX-index
INDEX: Euro Stoxx 50
INDEX: FTSE 100
INDEX: NY-Nasdaq Composite
Finished.
D:>
using System;
using System.Collections;
using System.Net;
using System.Data;
namespace AEXKoers
{
/// <summary>
/// Commandline tool om van internet pagina beurs gegevens te halen.
/// </summary>
class cMain
{
/// <summary>
/// Basis URL voor informatie. rubriek is een twee cijferige code. Bijv. 01
/// </summary>
const string MS_BASE_AEX = “http://www.aex.nl/scripts/marktinfo/koersrubriek.asp?tal=nl&rubriek=”;
/// <summary>
/// De uitvoer wordt uitgelijnd. De kolom met veld namen wordt dit aantal breed
/// </summary>
const int MI_HDR_WIDTH = 20;
#region Private structs voor opslag HTML tabel
/// <summary>
/// overeenkomst met HTML Table tag
/// </summary>
struct ETable
{
public string Name;
public ArrayList Rows;
public ETable( string psName )
{
Name = psName;
Rows = new ArrayList();
}
public void Add( ERow poRow )
{
Rows.Add( poRow );
}
public override string ToString()
{
string lsResult = “Table: ” + Name + “n”;
foreach ( ERow loRow in Rows )
{
lsResult += “{” + loRow.ToString() + “}n”;
}
return lsResult;
}
}
/// <summary>
/// Overeenkomt met HTML Tabel TR tag
/// </summary>
struct ERow
{
public string Name; // Dit veld wordt gebruikt om per fonds onderschied te maken in markt
public ArrayList Fields;
public bool IsKoersData; // De tabel heeft altijd twee regels voor: datum en kolom namen. Dit is dan geen koersdata
public ERow( string psName, bool pbIsKoersData )
{
Name = psName;
IsKoersData = pbIsKoersData;
Fields = new ArrayList();
}
public void Add( EField poField )
{
Fields.Add( poField );
}
public override string ToString()
{
string lsResult = “”;
foreach ( EField loField in Fields )
{
lsResult += (lsResult.Length > 0 ? “, ” : “”) + loField.Value;
}
return Name + “: ” + lsResult;
}
}
/// <summary>
/// Wellicht wat overkill maar dit is overeenkomstig een veld. Kan HTML tag TD of TH zijn
/// </summary>
struct EField
{
public string Value;
public EField( string psValue )
{
Value = psValue.Trim();
}
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Console.WriteLine( “AEX Koers application v1.0, Evert van Es 2004” );
Console.WriteLine( “” );
Console.WriteLine( “Current system date: ” + System.DateTime.Now.ToString() );
Console.WriteLine( “” );
// En zijn er commandline argumenten?
if ( args.Length == 0 )
{
ShowHelp();
}
else
{
// Laten we alvast de web pagina informatie in de cache laden!
ETable loTable = new ETable( “Data” );
string lsData = “”;
lsData = GetWebString( MS_BASE_AEX + “01” );
GetHTMLTable( lsData, “AEX”, ref loTable);
lsData = GetWebString( MS_BASE_AEX + “03” );
GetHTMLTable( lsData, “LOKAAL”, ref loTable);
lsData = GetWebString( MS_BASE_AEX + “24” );
GetHTMLTable( lsData, “AMX”, ref loTable);
lsData = GetWebString( MS_BASE_AEX + “18” );
GetHTMLTable( lsData, “NMAX”, ref loTable);
lsData = GetWebString( MS_BASE_AEX + “41” );
GetHTMLTable( lsData, “INDEX”, ref loTable);
lsData = GetWebString( MS_BASE_AEX + “50” );
GetHTMLTable( lsData, “INDEX”, ref loTable);
// Wat moeten we doen?
switch ( args[0].ToUpper() )
{
case “-L”:
GetLijst( loTable );
break;
default:
GetKoers( args[0], loTable );
break;
}
}
Console.WriteLine( “Finished.” );
}
/// <summary>
/// Tonen van een lijst van alle bekende koers namen per markt
/// </summary>
/// <param name=”poTable”>cache data met koersen</param>
static void GetLijst( ETable poTable)
{
foreach ( ERow loRow in poTable.Rows)
{
if (loRow.IsKoersData)
{
Console.WriteLine( loRow.Name + “: ” + ((EField) loRow.Fields[0]).Value);
}
}
}
/// <summary>
/// Help Helper!
/// </summary>
static void ShowHelp()
{
Console.WriteLine( “Please use one of the following options:” );
Console.WriteLine( ” -L List all known Stocks by name” );
Console.WriteLine( ” <stock> List stock details” );
Console.WriteLine( “” );
Console.WriteLine( “Example:” );
Console.WriteLine( ” AEGON Show details for AEGON” );
Console.WriteLine( “” );
}
/// <summary>
/// Zoek fonds en output naar console!
/// </summary>
/// <param name=”psFonds”>Welk fonds zoeken we</param>
/// <param name=”poTable”>cache data met koersen</param>
static void GetKoers( string psFonds, ETable poTable )
{
// Voor elke tij!
foreach ( ERow loRow in poTable.Rows)
{
if ( loRow.Fields.Count > 0 )
{
// Eerste kolom bevat fondsnaam!
EField loFirstCol = (EField) loRow.Fields[0];
if ( loFirstCol.Value.ToUpper() == psFonds.ToUpper() )
{
// De datum staat in de eerste rij, tijd is overigens een kolom…
ERow loDateRow = (ERow) poTable.Rows[0];
// De kolom namen staan in de tweede rij!
ERow loHeaderRow = (ERow) poTable.Rows[1];
// Even de datum uit de eerste rij plukken. Er staat iets in van:
// “AEX stocks at 17 Mar 2004<BR> ”
string lsDate = loDateRow.ToString();
int liDateStart = lsDate.IndexOf( “at “) + 3;
if (liDateStart != -1)
{
int liDateEnd = lsDate.IndexOf( “&”, liDateStart);
if ( liDateEnd != -1)
{
lsDate = lsDate.Substring( liDateStart, liDateEnd – liDateStart);
}
else
{
lsDate = lsDate.Substring( liDateStart);
}
}
// Padden met spaties tot juiste breedte
Console.WriteLine( “Date”.PadRight( MI_HDR_WIDTH) + “: ” + lsDate );
Console.WriteLine( “Markt”.PadRight( MI_HDR_WIDTH) + “: ” + loRow.Name );
for( int liField = 0; liField < loHeaderRow.Fields.Count; liField++)
{
// Er is altijd een lege kolom aanwezig. Deze is te herkennen aan het & teken!
if ( !((EField) loHeaderRow.Fields[liField]).Value.StartsWith( “&”) )
{
string lsHeader = ((EField) loHeaderRow.Fields[liField]).Value;
string lsColData = ((EField) loRow.Fields[liField]).Value;
Console.WriteLine( lsHeader.PadRight( MI_HDR_WIDTH) + “: ” + lsColData );
}
}
return;
}
}
}
}
/// <summary>
/// Convert HTML table naar structure
/// </summary>
/// <param name=”psData”>String data van een webpagina.</param>
/// <param name=”psRowName”>Naam voor een rij, dit kan dus afwijken per tabel</param>
/// <param name=”poTable”>Pointer naar tabel</param>
static void GetHTMLTable( string psData, string psRowName, ref ETable poTable )
{
// Eerste twee regels is geen data maar aanvullende info !
int liStartTable = psData.ToUpper().IndexOf(“<TABLE “);
int liLastTable = psData.ToUpper().IndexOf(“</TABLE>”) + 8;
string lsBuffer = psData.Substring( liStartTable, liLastTable – liStartTable);;
int liStrPointer = 0;
bool lbReady = false;
int liRowCount = 0;
while ( !lbReady )
{
if ( liStrPointer >= lsBuffer.Length )
{
lbReady = true;
}
else
{
// Voor elke Rij
int liRowStart = lsBuffer.ToUpper().IndexOf( “<TR”, liStrPointer);
if (liRowStart != -1 )
{
int liRowEnd = lsBuffer.ToUpper().IndexOf( “</TR”, liRowStart);
if ( liRowEnd != -1 )
{
liRowCount++;
// Voor elk Veld
string lsRow = lsBuffer.Substring( liRowStart, liRowEnd – liRowStart + 5);
bool lbRowReady = false;
int liRowPos = 0;
ERow loRow = new ERow(psRowName, (liRowCount<=2? false : true));
while ( !lbRowReady )
{
if ( liRowPos >= lsRow.Length )
{
lbRowReady = true;
}
else
{
// Voor elke Rij (TD tag of TH tag)
int liFieldStart = lsRow.ToUpper().IndexOf( “<T”, liRowPos);
if (liFieldStart != -1 )
{
int liFieldEnd = lsRow.ToUpper().IndexOf( “</T”, liFieldStart);
if ( liFieldEnd != -1 )
{
// Found Field
int liDataStart = lsRow.ToUpper().IndexOf( “>”, liFieldStart) + 1;
if ( liDataStart != -1 )
{
loRow.Add( new EField( StripHTML(lsRow.Substring( liDataStart, liFieldEnd – liDataStart ) ) ));
liRowPos = liFieldEnd;
}
else
{
lbRowReady = true;
}
}
else
{
lbRowReady = true;
}
}
else
{
lbRowReady = true;
}
}
}
poTable.Add( loRow );
//Console.WriteLine( loRow.ToString() );
liStrPointer = liRowEnd;
}
else
{
lbReady = true;
}
}
else
{
lbReady = true;
}
}
}
}
/// <summary>
/// Verwijder HTML tags
/// </summary>
/// <param name=”psData”>HTML data</param>
/// <returns>data zonder HTML tags</returns>
static string StripHTML( string psData )
{
bool lbFoundHTML = true;
string lsResult = psData;
while ( lbFoundHTML )
{
int liStart = lsResult.ToUpper().IndexOf( “<“);
if (liStart != -1 )
{
int liEnd = lsResult.ToUpper().IndexOf( “>”, liStart);
if (liEnd != -1)
{
lsResult = lsResult.Remove( liStart, liEnd – liStart + 1);
}
else
{
lbFoundHTML = false;
}
}
else
{
lbFoundHTML = false;
}
}
return lsResult;
}
/// <summary>
/// Haal web pagina als string
/// </summary>
/// <param name=”psUrl”>url</param>
/// <returns>webpagina</returns>
static string GetWebString(string psUrl)
{
HttpWebRequest myReq = (HttpWebRequest) WebRequest.Create(psUrl);
myReq.UserAgent = “Mozilla/4.0 (compatible; MSIE 4.01; Windows NT)”;
myReq.Accept = “text/html”;
myReq.Referer = “www.xyz.nl”;
myReq.ProtocolVersion = HttpVersion.Version11;
HttpWebResponse myResp = (HttpWebResponse) myReq.GetResponse();
System.IO.Stream loStream = myResp.GetResponseStream();
byte[] laBytes = new byte[1024];
int lnBytesToread;
string lsRegel = “”;
lnBytesToread = 1;
while (lnBytesToread > 0)
{
lnBytesToread = loStream.Read(laBytes, 0, 1024);
lsRegel = lsRegel + System.Text.Encoding.ASCII.GetString(laBytes, 0, lnBytesToread);
}
loStream.Close();
loStream = null;
myResp.Close();
myResp = null;
myReq = null;
return lsRegel;
}
}
}