Aktienkurse

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
Benutzeravatar
guinnes
Beiträge: 38
Registriert: 21. Apr 2020 19:46

Aktienkurse

Beitrag von guinnes »

Moin
Es ist sicherlich nicht das Ziel von Openhab, Aktienkurse zu verarbeiten, aber da Openhab wohl normalerweise 24/7 läuft, bietet sich die Erfassung von Kursen eigentlich ab. Hier mein Wertpapierprojekt :
Die Kurse werden von einer zeitgesteuerten Rule erfasst und direkt in die Items geschrieben. Dafür müßen die Namen der Items einem Schema folgen :
Die ISIN-Nummer gefolgt von _Name für den Wertpapiernamen, _Geld für Nachfrage, _Brief für Angebot und _Delta für die Veränderung zum Vortag. Es können nur Listen eingelesen werden : DAX, MDAX, TecDAX, SDAX usw. Weiterhin besteht die Möglichkeit, alle Aktien mit einem bestimmten Anfangsbuchstaben einzulesen. Es müßen nur Items erzeugt werden, von Aktien, die euch interessieren. Die Daten kommen von Tradegate und sind kostenlos. Es gibt keine API, die Daten werden aus den HTML-Seiten geparst. Hier Beispiele für die Items : ( Die GRuppe ist noch wichtig, darüber erreicht ich die Items )

Code: Alles auswählen

Group   g_Stock               "Aktien Items"
// Allianz
String   DE0008404005_Name       (g_Stock) 
Number   DE0008404005_Geld       (g_Stock)
Number   DE0008404005_Brief      (g_Stock)
Number   DE0008404005_Delta      (g_Stock)
// BASF
String   DE000BASF111_Name       (g_Stock) 
Number   DE000BASF111_Geld       (g_Stock)
Number   DE000BASF111_Brief      (g_Stock)
Number   DE000BASF111_Delta      (g_Stock)
// Daimler
String   DE0007100000_Name       (g_Stock) 
Number   DE0007100000_Geld       (g_Stock)
Number   DE0007100000_Brief      (g_Stock)
Number   DE0007100000_Delta      (g_Stock)
// Telekom
String   DE0005557508_Name       (g_Stock) 
Number   DE0005557508_Geld       (g_Stock)
Number   DE0005557508_Brief      (g_Stock)
Number   DE0005557508_Delta      (g_Stock)
// Linde
String   IE00BZ12WP82_Name       (g_Stock) 
Number   IE00BZ12WP82_Geld       (g_Stock)
Number   IE00BZ12WP82_Brief      (g_Stock)
Number   IE00BZ12WP82_Delta      (g_Stock)
// RWE
String   DE0007037129_Name       (g_Stock) 
Number   DE0007037129_Geld       (g_Stock)
Number   DE0007037129_Brief      (g_Stock)
Number   DE0007037129_Delta      (g_Stock)
// SAP
String   DE0007164600_Name       (g_Stock) 
Number   DE0007164600_Geld       (g_Stock)
Number   DE0007164600_Brief      (g_Stock)
Number   DE0007164600_Delta      (g_Stock)
// Siemens
String   DE0007236101_Name       (g_Stock) 
Number   DE0007236101_Geld       (g_Stock)
Number   DE0007236101_Brief      (g_Stock)
Number   DE0007236101_Delta      (g_Stock)
Hier die Rule :

Code: Alles auswählen

val Get_Stock_Data  =       
[ String HTTPAddr    // HTTP-Adresse, von der wir die Daten holen wollen
  |
  var String[] werte // Die HTML-Zeilen der einzelnen Päckchen der Aktienwerte
  var String wert    // Die eine Zeile eines Wertes
  var String hs      // Allgemeiner HilfsString
  var Integer count  // Anzahl der Aktienwerte
  var Integer i      // Die Schleifenvariable

  var response = sendHttpGetRequest(HTTPAddr)   
  var lBody    = response.substring(response.indexOf('<tbody') , response.indexOf('</tbody>'));

  werte = lBody.split('<tr') // Aufteilen in Päckchen mit den Werten Pro Aktie
  count = werte.size
  logInfo("Aktiendaten", "Anzahl {}",count)
  for (i=1; i<count; i++){
    var String isin   // String für die ISIN
    var String name   // String für den Wertpapiernamen
    var String bid    // String für Nachfrage
    var String ask    // String für Angebot
    var String delta  // String für Veränderung zum Vortag
    wert = werte.get(i)
    hs = wert.substring(wert.indexOf('id="name'), wert.indexOf('</td>')) // Den String mit ISIN und Namen rausschneiden
    isin = hs.substring(hs.indexOf('isin='), hs.indexOf('</a>'))
    name = isin.substring(isin.indexOf('">') + 2, isin.length)
    isin = isin.substring(5, isin.indexOf('">'))
    hs = wert.substring(wert.indexOf('<td id="bid'), wert.indexOf('<td id="ask'))
    bid = hs.substring(hs.indexOf('">') + 2, hs.indexOf('</td>'))
    bid = bid.replace(',','.')
    hs = wert.substring(wert.indexOf('<td id="ask'), wert.indexOf('<td id="sum'))
    ask = hs.substring(hs.indexOf('">') + 2, hs.indexOf('</td>'))
    ask = ask.replace(',','.')
    hs = wert.substring(wert.indexOf('<td id="delta'), wert.indexOf('%</td>'))
    delta = hs.substring(hs.indexOf('">') + 2, hs.length)
    delta = delta.replace(',','.')
    logInfo("Aktiendaten","ISIN {} Name {} Geld {} Brief {} Delta {}",isin,name,bid,ask,delta)

    val String visin = isin  // Nur, damit die Fehlermeldungen in VSCode verschwinden
    var wtemp = g_Stock.members.findFirst[j | j.name == visin + "_Name"]
  	if (wtemp !== null) {
      wtemp.postUpdate(name) 
    }  
    wtemp = g_Stock.members.findFirst[j | j.name == visin + "_Geld"]
  	if (wtemp !== null) {
      wtemp.postUpdate(bid) 
    }
    wtemp = g_Stock.members.findFirst[j | j.name == visin + "_Brief"]
  	if (wtemp !== null) {
      wtemp.postUpdate(ask) 
    }
    wtemp = g_Stock.members.findFirst[j | j.name == visin + "_Delta"]
  	if (wtemp !== null) {
      wtemp.postUpdate(delta) 
    }
  }
]

/*
Weitere Adressen, von denen man Kurse holen kann
"https://www.tradegate.de/indizes.php?index=DE000A1EXRV0"   // DAX
"https://www.tradegate.de/indizes.php?index=DE000A1EXRW8"   // MDAX
"https://www.tradegate.de/indizes.php?index=DE000A1EXRY4"   // TECDAX
"https://www.tradegate.de/indizes.php?index=DE000A1EXRX6"   // SDAX
"https://www.tradegate.de/indizes.php?index=EU0009658145"   // Eurostock 50
"https://www.tradegate.de/indizes.php?index=US0000000002"   // US-Top-Titel
"https://www.tradegate.de/indizes.php?buchstabe=A"          // Alle Aktien die Mit A anfangen
*/

rule "Aktienkurse Tradegate"
when 
   Time cron "0 * * * * ?"
then
    Get_Stock_Data.apply("https://www.tradegate.de/indizes.php?index=DE000A1EXRV0")  // DAX 
end
Natürlich können auch mehrere Listen hintereinander eingelesen werden, darum das Unterprogramm

Ich hoffe, es hilft

Glückauf
guinnes
Glückauf
guinnes

Benutzeravatar
PeterA
Beiträge: 610
Registriert: 8. Feb 2019 12:12
Answers: 10

Re: Aktienkurse

Beitrag von PeterA »

Moin guinnes,

witzig was man mit OH alles so treiben kann :D
Ich hatte es mal in OH eingebaut aber beim Aufruf über die
Gruppe in der Sitemap keine Werte usw angezeigt bekommen.
Obwohl die Rule brav alles in die Items geschrieben hat.

Gruß Peter
- OpenHab 2.4

Benutzeravatar
guinnes
Beiträge: 38
Registriert: 21. Apr 2020 19:46

Re: Aktienkurse

Beitrag von guinnes »

Moin
Ich zeige in der Sitemap auch nicht die Gruppe an sondern die Items

Glückauf
guinnes
Glückauf
guinnes

Benutzeravatar
PeterA
Beiträge: 610
Registriert: 8. Feb 2019 12:12
Answers: 10

Re: Aktienkurse

Beitrag von PeterA »

Ok,

noch ein Kurzes Code Snippet Deiner Sitemap vielleicht?

Merci
- OpenHab 2.4

Benutzeravatar
guinnes
Beiträge: 38
Registriert: 21. Apr 2020 19:46

Re: Aktienkurse

Beitrag von guinnes »

Kein Problem, ich hab allerding das Zeug mittlerweile erweitert :
Sitemap :

Code: Alles auswählen

      Group item=g_Stock label="Aktienkurse" {
        Frame label="Allianz" {  
          Chart item=g_Allianz  label="" refresh=60000 period=D service="rrd4j"
          Text  item=DE0008404005_Name
          Text  item=DE0008404005_Geld
          Text  item=DE0008404005_Brief
          Text  item=DE0008404005_Delta
          Text  item=DE0008404005_Anzahl
          Text  item=DE0008404005_Kauf
          Text  item=DE0008404005_Wert
          Text  item=DE0008404005_Gewinn
          Group item=g_Allianz label="Kaufpreis/Anzahl ändern" {
            Frame label="Kaufpreis/Anzahl ändern" {
      	      Webview icon="zertifikat" url="http://192.168.178.27:8080/static/textInput.html?item=DE0008404005_Anzahl&label=Anzahl" height=1
	            Webview icon="euro" url="http://192.168.178.27:8080/static/textInput.html?item=DE0008404005_Kauf&label=Kaufpreis" height=1
            }
          }
        }
        Frame label="BASF" {
          Chart item=g_BASF  label="" refresh=60000 period=D service="rrd4j"
          Text  item=DE000BASF111_Name
          Text  item=DE000BASF111_Geld
          Text  item=DE000BASF111_Brief
          Text  item=DE000BASF111_Delta
          Text  item=DE000BASF111_Anzahl
          Text  item=DE000BASF111_Kauf
          Text  item=DE000BASF111_Wert
          Text  item=DE000BASF111_Gewinn
          Group item=g_BASF label="Kaufpreis/Anzahl ändern" {
            Frame label="Kaufpreis/Anzahl ändern" {
      	      Webview icon="zertifikat" url="http://192.168.178.27:8080/static/textInput.html?item=DE000BASF111_Anzahl&label=Anzahl" height=1
	            Webview icon="euro" url="http://192.168.178.27:8080/static/textInput.html?item=DE000BASF111_Kauf&label=Kaufpreis" height=1
            }
          }
        }
 ......
Items :

Code: Alles auswählen

Group   g_Stock     "Aktien Items" <zertifikat>
Group   g_Allianz                  <allianz>
Group   g_BASF                     <basf>
Group   g_Daimler                  <daimler>
Group   g_Telekom                  <telekom>
Group   g_Linde                    <linde>
Group   g_RWE                      <rwe>
Group   g_SAP                      <sap>
Group   g_Siemens                  <siemens>

// Allianz
String   DE0008404005_Name   "Name [%s]"            <allianz>     (g_Stock) 
Number   DE0008404005_Geld   "Geld [%.2f €]"        <euro>        (g_Stock,P_1Min,g_Allianz)
Number   DE0008404005_Brief  "Brief [%.2f €]"       <zertifikat>  (g_Stock,P_1Min,g_Allianz)
Number   DE0008404005_Delta  "Veränderung zum Vortag [%.2f %%]"   (g_Stock,P_1Min)
Number   DE0008404005_Anzahl "Anzahl der Aktien [%.0f Stück]"     (g_Stock)  
Number   DE0008404005_Kauf   "Gesammt Kaufpreis [%.3f €]"         (g_Stock)
Number   DE0008404005_Wert   "Wert Jetzt [%.2f €]"                (g_Stock)
Number   DE0008404005_Gewinn "Veränderung [%.2f %%]"              (g_Stock)
// BASF
String   DE000BASF111_Name   "Name [%s]"            <basf>        (g_Stock)
Number   DE000BASF111_Geld   "Geld [%.2f €]"        <euro>        (g_Stock,P_1Min,g_BASF)
Number   DE000BASF111_Brief  "Brief [%.2f €]"       <zertifikat>  (g_Stock,P_1Min,g_BASF)
Number   DE000BASF111_Delta  "Veränderung zum Vortag [%.2f %%]"   (g_Stock,P_1Min)
Number   DE000BASF111_Anzahl "Anzahl der Aktien [%.0f Stück]"     (g_Stock)
Number   DE000BASF111_Kauf   "Gesammt Kaufpreis [%.3f €]"         (g_Stock)
Number   DE000BASF111_Wert   "Wert Jetzt [%.2f €]"                (g_Stock)
Number   DE000BASF111_Gewinn "Veränderung [%.2f %%]"              (g_Stock)
......
zusätliches Unterprogramm in den Rules :

Code: Alles auswählen

val Set_Stock_Value  =       
[ String Isin    // Isin der Aktie
  |
  var NumberItem brief
  var NumberItem anzahl
  var NumberItem aktienwert
  var NumberItem kauf
  var NumberItem gewinn
  var float wert

  brief = g_Stock.members.findFirst[j | j.name == Isin + "_Brief"] as NumberItem
  if (brief !== null) {
    anzahl = g_Stock.members.findFirst[j | j.name == Isin + "_Anzahl"] as NumberItem
    if (brief !== null) {
      aktienwert = g_Stock.members.findFirst[j | j.name == Isin + "_Wert"] as NumberItem
      if (aktienwert !== null) {
        kauf = g_Stock.members.findFirst[j | j.name == Isin + "_Kauf"] as NumberItem
        if (kauf !== null) {
          gewinn = g_Stock.members.findFirst[j | j.name == Isin + "_Gewinn"] as NumberItem
          if (gewinn !== null) {
            wert = (brief.state as Number).floatValue * (anzahl.state as Number).floatValue
            aktienwert.postUpdate(wert)
            if ((kauf.state as Number).floatValue > 0) {
              wert = (wert / (kauf.state as Number).floatValue) - 1
              gewinn.postUpdate(wert * 100)
            }
          }
        }
      }
    }
  }  
]
Rules :

Code: Alles auswählen

rule "Allianz"
when
  Item DE0008404005_Brief changed
then
  Set_Stock_Value.apply("DE0008404005")
end

rule "BASF"
when
  Item DE000BASF111_Brief changed
then
  Set_Stock_Value.apply("DE000BASF111")
end

rule "Daimler"
when
  Item DE0007100000_Brief changed
then
  Set_Stock_Value.apply("DE0007100000")
end
....
Und noch der HTML-Quelltext für die Eingaben :( sieht schlimm aus, ist es auch, aber ich nichts besseres gefunden )
textInput.html

Code: Alles auswählen

<html class="ui-icons-enabled">
<script>
    var openHabianPI = "192.168.178.27"
    function getParam(param)
    {
        var qs = (function(a) {
            if (a == "") return {};
            var b = {};
            for (var i = 0; i < a.length; ++i) {
                var p=a[i].split('=', 2);
                if (p.length == 1)
                    b[p[0]] = "";
                else
                    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
            }
            return b;
        })(window.location.search.substr(1).split('&'));       
        return qs[param]
    }
    function httpGet(theUrl)
    {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function() {
    		if (this.readyState == 4 && this.status == 200) {
		    	document.getElementById('textInput').value = xmlHttp.responseText;
		    }
		};
        xmlHttp.open("GET", theUrl, true);
        xmlHttp.setRequestHeader("Accept", "text/plain");
        xmlHttp.send();
        return 
    }
    function httpPut(theUrl, theValue)
    {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("PUT", theUrl, true);
        xmlHttp.setRequestHeader("Content-type", "text/plain");
        xmlHttp.setRequestHeader("Accept", "application/json");
        xmlHttp.send(theValue)
    }
	function sendValue()
	{
        url = "http://" + openHabianPI + ":8080/rest/items/" + getParam('item') + "/state";
        httpPut(url, document.getElementById('textInput').value)
    }
	function getValue()
	{
        url = "http://" + openHabianPI + ":8080/rest/items/" + getParam('item') + "/state";
        httpGet(url)
    }
</script>
<head>

	<link rel="stylesheet" type="text/css" href="../basicui/mdl/material.min.css" />
	<link rel="stylesheet" type="text/css" href="../basicui/material-icons.css" />
	<link rel="stylesheet" type="text/css" href="../basicui/roboto.css" />
	<link rel="stylesheet" type="text/css" href="../basicui/smarthome.css" />
	<script src="../basicui/mdl/material.min.js"></script>
	
	<style>
		form {
			margin-bottom: 0;
		}
		.mdl-form__row {
			border-bottom-style: none;
			height: auto;
			padding-top: 0;
			padding-right: 0;
			padding-bottom: 0;
			padding-left: 0;
		}
	</style>
</head>
<body class="mdl-color-text--grey-700" data-icon-type="svg">
	<form action="JavaScript:sendValue()">
		<div class="mdl-form__row mdl-cell mdl-cell--6-col mdl-cell--8-col-tablet">
			<span class="mdl-form__icon">
				<img data-icon="text" src="../icon/text?format=svg" />
			</span>
			<div class="mdl-form__label" id=label>
			</div>
			<div>
				<input type="text" name="textInput" id="textInput">
			</div>
			<div>
				<input type="submit" value="Submit">
			</div>
		</div>
		<script>
			document.getElementById('label').innerHTML = getParam('label');
			document.getElementById('textInput').value = getValue()
		</script>
	</form>
</body>
</html>
Glückauf
guinnes

Antworten