SQL Tabellenspalten gem. einer Formel befüllen

Rossibaer

Lieutenant
Registriert
Apr. 2007
Beiträge
754
Hallo zusammen,

zur Zeit realisiere ich in einem Hobbyprojekt ein Programm zur Analyse von Aktienkursen. Ich verwende MS SqlServer zur Speicherung der Kursdaten. In diesem Programm werden verschiedene Indikatoren verwendet um Kauf bzw. Verkaufssignale für eine Aktie zu generieren. Diese Indikatoren möchte ich aus Performancegründen während des Imports der Kursdaten berechnen lassen. Bisher soweit alles noch möglich, jedoch brauche ich jetzt einen Indikator dessen Wert sich aus dem Wert vom Vortag und dem aktuellen Kurs berechnet. Die notwendigen Tabellen habe ich in einer 1:n Beziehung mit folgender Stuktur vorliegen:

-- Kursdaten der Aktien
CREATE TABLE dbo.STOCK_QUOTE(
STOCK_QUOTE_ID INT, -- PK der Tabelle (Identity Spalte)
STOCK_ID INT, -- Id. der Aktie
QUOTE_DATE DATE, -- Tag des Kurses
QUOTE_CLOSE DECIMAL(28,2) -- Schlusskurs der Aktie für den jeweiligen Tag
)

-- Details zu den Kursdaten mit Indikatoren
CREATE TABLE dbo.STOCK_GDS(
STOCK_QUOTE_ID INT, Id. des Kurses der Aktie pro Tag (FK zu dbo.STOCK_QUOTE
GDS_DAYS INT, Anzahl der Tage für den gleitenden Durchschnitt
EGDS DECIMAL(28,2), -- der Indikator den ich berechnen möchte
-- ... weitere Indikatoren-Spalten
)

Die Tabelle STOCK_QUOTE befülle ich mit den Kursdaten per INSERT mit Informationen aus dem Internet. Im Nachgang würde ich nun die STOCK_GDS Tabelle mit INSERT ... SELECT befüllen, dabei werden die Kursdaten aus der STOCK_QUOTE Tabelle gezogen und für jeden GDS_DAYS Wert von 10 bis 100 berechnet. Bei der Berechnung des EGDS Wertes hänge ich nun, da er sich aus dem EGDS Wert des Vortages + dem Schlusskurs der Aktie für den aktuellen Tag berechnet. Spezialität dabei ist, dass für den ersten Tag der EGDS = der Schlusskurs ist. Ich bräuchte eure Hilfe wie ich das am Besten realisieren kann.

Noch eine Anmerkung: Es sind die Kursdaten von 30 Aktien über einen Zeitraum vom 01.01.2003 bis heute. Bei der STOCK_GDS Tabelle bin ich in einer Größenordnung von ca. 10.000.000 Datensätzen. D.h. ich brauche eine relativ performante Lösung, wo die Daten in nicht mehr als 30 Minuten initial gefüllt werden. Wenn nun ein neuer Tag ist, werden nicht mehr alle Daten sondern nur die Daten vom Vortag + vom aktuellen Tag eingefügt. Die Lösung müsste also auch damit klar kommen...

Vielen Dank schon mal für das Lesen und noch mehr Dank wenn ihr eine Idee für eine Lösung meines Problems habt.

Tschüß
Rossibaer
 
Mit welcher Sprache sprichst Du denn den Webservice im Internet an, um Dir die Kurse zu ziehen? Dort kannst Du doch auch die Daten entsprechend transformieren und dann in die DB reinblasen, oder?
 
Die Daten kommen per CSV. Das CSV parse ich und lade sie per INSERT in meine STOCK_QUOTE Tabelle. Je nach Service sind sie nach Datum aufsteigend oder absteigend sortiert.
 
Genau, mit WAS parst Du die Daten?
 
ich kann dir nur dringend empfehlen, import und indikator-berechnung voneinander zu trennen. zudem würde ich für die auswertung ms sql server analysis services in betracht ziehen. dann kannst du mit data mining bestimmt viele interessante dinge machen. ich finde das thema sehr reizvoll und habe selbst schon mehrfach darüber nachgedacht.
 
Hallo,
falls SQL Server verwendet wird, dann die Daten mittel SQL Server Integration Services (SSIS) integrieren. Einfacher geht es nicht! Das ist reines "klicki bunti"!

greetz
hroessler
 
Zuletzt bearbeitet von einem Moderator:
Genau, mit WAS parst Du die Daten?

Ich nutze kein extra Tool dafür. Das Parsen übernimmt eine Routine in meinem Programm. Kann also beliebig Code einbauen und bin flexibel.

ich kann dir nur dringend empfehlen, import und indikator-berechnung voneinander zu trennen.
Gibts da auch Gründe dafür? Der Import ist für sich gesehen, getrennt von der Indikatorberechnung. Nach dem Import wird in einem nachgelagerten Schritt die Indikatorberechnung angestossen, wo ich nun Hilfe beim entsprechenden INSERT brauche, damit ich die Daten in die Datenbank prügeln kann. Zur Auswahl habe ich nur SQL (auch in Form von T-SQL) und C#. Das Programm soll die Indikatorberechnung erledigen. Externe Tools sind nicht erwünscht. Sorry für meine unzureichende Beschreibung des Problems. Ich hätte erwähnen sollen, dass ich in meinem Hobbyprojekt MS SQLServer Express verwende.

Laut Microsoft werden in der Express Version folgende Features nicht unterstützt:

- Integration Services (ehemals Data Transformation Services)
- Analysis Services
- OLAP-Dienste (Analysis Services)/Data Mining

Kurzum, es ist ein Hobbyprojekt mit Hobbybudget. Ich kann keine Enterprise Features nutzen... Danke trotzdem an alle für die bisherigen Hinweise. Um mein Problem weiter eingrenzen zu können: Ich brauche einen SQL Befehl, siehe Pseudocode
Code:
INSERT INTO dbo.STOCK_GDS(...) SELECT STOCK_QUOTE_ID, 10 GDS_DAYS, {Kurs} + {EGDS vom Vortag bzw. QUOTE_CLOSE wenn es der erste Tag ist} *  {EGDS vom Vortag bzw. QUOTE_CLOSE wenn es der erste Tag ist} FROM dbo.STOCK_QUOTE

Die Formel sieht natürlich anders aus und ist hier nur stellvertretend geschrieben.

Probleme bei der Berechnung/Befüllung der dbo.STOCK_GDS Tabelle:
1. EGDS vom Vortag wird in der Formel mehrfach benötigt
2. Je nachdem, wie das SELECT die Daten für das INSERT "aufbereitet", komme ich auf keinen grünen Zweig (Stichwort Sortierung die bei der Berechnung des EGDS wichtig ist)
3. Die Tabelle wird große Datenmengen enthalten
4. über T-SQL liese sich die Berechnung relativ leicht umsetzen, jedoch habe ich Bedenken bei der Geschwindigkeit (Wechsel der DB Engine von T-SQL zu SQL und wieder zurück)
5. Ich muss ein SQL Statement um diesen Indikator EGDS erweitern.

Das was ich bisher habe, läuft ca. 40 Minuten auf der DB trotz entsprechender Indizes...
 
Rossibaer schrieb:
Laut Microsoft werden in der Express Version folgende Features nicht unterstützt:



Kurzum, es ist ein Hobbyprojekt mit Hobbybudget. Ich kann keine Enterprise Features nutzen... Danke trotzdem an alle für die bisherigen Hinweise.
.

Hinweis, es gibt die SQL Server Developer Edition kostenlos bei den DevEssentials:

https://blogs.technet.microsoft.com...oft-sql-server-developer-edition-is-now-free/

Laut https://www.microsoft.com/en/server-cloud/products/sql-server-editions/overview.aspx hat diese alle Features.....
 
@kelox: SQL Server Developer Edition klingt interessant, aber woran ich scheitere ist folgendes:

SQL Server Developer Edition is for development and testing only, and not for production environments or for use with production data.

Dies Sache ist die: fürs Entwickeln könnte ich es ja nutzen, aber jeder der die Software dann einsetzen will, fällt nunmal nicht mehr in diese Kategorie, sondern braucht dann eine entsprechende teuer zu erkaufende Lizenz. Um es nochmal zu verdeutlichen, alles außer SQLServer Express ist für mich in meinem Hobbyprojekt nicht nutzbar! Desweiteren haben schon Freunde und Bekannte die Software unentgeltlich im Einsatz und ich kann nicht von denen Verlangen sich bei einem MS Programm anzumelden um dann die Developer Version herunterzuladen, Lizenzrechtlich schlecht dazustehen, nur um dann mit einem besonderen Feature die Daten einzuladen/auszuwerten.

Die DB soll möglichst dumm nur als Datenspeicher von Kursdaten mit entsprechend berechneten Indikatorwerten fungieren. Mir bleibt der Weg nur über SQL (T-SQL). C# habe ich mittlerweile ausgeschlossen, da hier zu viele Roundtrips zur DB notwendig sind und somit die Performance massiv einbüßt.

Gibt es keinen der ein paar hilfreiche Tipps in der Gestaltung eines SQL Befehls hat? Um es mit ein paar blumigen Worten zu umschreiben: Ich suche Hilfe von jemanden, der sich nicht scheut nur mit einem Filzstift bewaffnet eine Mona Lisa zu malen, ohne gleich tausende Euro für eine vollständige Pinsel und Ölfarben Kollektion auszugeben. Klar wird die Filzstiftvariante nie an das Original heranreichen, aber mir geht es hier um die Technik, das Know-How, den Weg, nicht um Black Magic Feature X von Editon Y. Ich will es machen, weil ich es können will.

Nur mal ein Beispiel: Wie bilde ich eine komma getrennte Liste von Namen aus einer fiktiven Adressentabelle für die Stadt Hamburg?

Sehr oft schon gesehen und doch nie verwendet:

Code:
DECLARE cData CURSOR LOCAL FAST_FORWARD FOR SELECT NAME FROM dbo.ADDRESS WHERE CITY = 'Hamburg'
DECLARE @NameList VARCHAR(MAX) = ''
DECLARE @Name VARCHAR(100)
OPEN cData
WHILE 1=1 BEGIN
  FETCH NEXT FROM cData INTO @Name
  IF NOT @@FETCH_STATUS = 0 BREAK
  SET @NameList = @NameList + ',' + @Name
END
CLOSE cData
DEALLOCATE cData
-- letzter Schritt, Liste ausgeben:
SELECT @NameList

Was ich bevorzugen würde, wäre:

Code:
DECLARE @NameList VARCHAR(MAX) = ''
SELECT @NameList = @NameList + ',' + NAME FROM dbo.ADDRESS WHERE CITY = 'Hamburg'
-- letzter Schritt, Liste ausgeben:
SELECT @NameList

SQL (T-SQL) ist meine Komfortzone, wo ich nicht in einem Hobbyprojekt ausbrechen will...
 
Zuletzt bearbeitet: (kleiner Bug in T-SQL Code gefixt)
Nachtrag:
Nach längerem rumprobieren und frickeln bin ich nun bei einer Möglichkeit gelandet, die mir alle notwendigen Indikatoren + den neuen Indikator in Form von 10 Millionen Datensätze in die Datenbank wirft. Am Ende ist eine Stored Procedure daraus geworden, musste einen Index der STOCK_GDS Tabelle optimieren und statt dem Monster INSERT einen T-SQL Block mit Cursor und Gedöns verwenden. Die Transaktionsblöcke sind somit wieder relativ klein. Der Kontextwechsel von T-SQL zu SQL und zurück schien doch nicht so gravierend zu sein, wie ich anfangs vermutete. Schlussendlich konnte ich die Ausführungszeit von >40 Minuten auf ca. 16 Minuten reduzieren. Da diese lange Zeitdauer nur beim Reset der Kursdaten und beim erstmaligen Befüllen der Kurstabelle, z.B. während der Installation ist, kann ich damit leben. Problem gelöst...

Danke nochmal an die, die sich beteiligt haben ...
 
Zurück
Oben