111 lines
6.2 KiB
Markdown
111 lines
6.2 KiB
Markdown
|
|
# Architekturkonzept: Hybrid Projectional Financial Editor
|
|
|
|
## 1. Motivation und Zielsetzung
|
|
Entwicklung einer Entwicklungsumgebung für Finanzanalysen (Backtesting, Indikatoren), die die Vorteile zweier Welten vereint:
|
|
1. **Visuelle Programmierung (Blöcke):** Für die grobe Architektur, den Datenfluss und die Übersichtlichkeit. Vermeidet Syntaxfehler bei komplexen Verschachtelungen.
|
|
2. **Textuelle Programmierung (S-Expressions):** Für mathematische Formeln und Detail-Logik. Ermöglicht schnelle Eingabe und präzises Editieren für Experten.
|
|
|
|
Das System verhält sich **reaktiv** (wie "Strudel" für Musik): Änderungen am Code oder an Parametern führen sofort zur Neuberechnung und Aktualisierung der Charts ("Live Coding").
|
|
|
|
---
|
|
|
|
## 2. Kern-Architektur (MVC)
|
|
|
|
Die Anwendung folgt strikt dem Model-View-Controller Muster, um Rendering von Logik zu trennen.
|
|
|
|
### Model (Der AST & Environment)
|
|
* **Immutable AST:** Der Abstract Syntax Tree besteht aus unveränderlichen Interfaces (`IAstNode`). Jede Änderung erzeugt einen neuen Teilbaum.
|
|
* **Environment (`TAstEnvironment`):** Hält den Laufzeit-Zustand (Variablen, definierte Makros) und führt den Code aus.
|
|
* **Domain:** Spezialisierte Datentypen für Finanzen (`ISeries` für Zeitreihen, `TDecimal` für Währung).
|
|
|
|
### View (`TWorkspace` & `TEditorFrame`)
|
|
* **Aufgabe:** Rein visuelle Darstellung. Kennt keine Logik, nur `TControl`-Hierarchien.
|
|
* **Rendering:** Zeichnet Blöcke, Verbindungen und visuelle Container.
|
|
* **Input:** Leitet Maus- und Tastatur-Events (Drag & Drop) an den Controller weiter.
|
|
|
|
### Controller (`TAstEditorController`)
|
|
* **Aufgabe:** Das "Gehirn". Synchronisiert AST und View.
|
|
* **Zustandsverwaltung:** Hält den aktuellen validen AST (`FCurrentAst`).
|
|
* **Undo/Redo:** Speichert Snapshots des ASTs auf einem Stack (Memento Pattern).
|
|
* **Reaktivität:** Feuert `OnChange` bei jeder Modifikation, um die Ausführungspipeline anzustoßen.
|
|
|
|
---
|
|
|
|
## 3. Der Hybride Editor-Ansatz
|
|
|
|
Das System entscheidet dynamisch, wie ein AST-Knoten dargestellt wird ("Smart Nodes").
|
|
|
|
### A. Die Makro-Ebene (Visuell)
|
|
Strukturelle Elemente werden als grafische Blöcke dargestellt:
|
|
* **Control Flow:** `If`, `Loop`, `Block` (do...end).
|
|
* **Definitionen:** `VarDecl`, `MacroDef`.
|
|
* **High-Level Funktionen:** `LoadCSV`, `Chart`, `Strategy`.
|
|
|
|
**Vorteil:** Der Benutzer erkennt die Topologie der Strategie auf einen Blick ("Code Folding" durch Visualisierung).
|
|
|
|
### B. Die Mikro-Ebene (Textuell / S-Expressions)
|
|
Mathematische Ausdrücke und Parameter werden als Text (Lisp-artige Syntax) dargestellt und editiert.
|
|
* Beispiel: Statt eines Baums aus 5 Boxen sieht der User ein Label: `(> Close (SMA Close 20))`.
|
|
|
|
### C. Drill-Down Editing (In-Place)
|
|
Der innovative Kern des Editors. Wenn ein User einen Knoten bearbeitet (Doppelklick), öffnet sich ein Texteditor über dem Knoten.
|
|
|
|
1. **Shallow Printing:** Der Editor zeigt nicht den gesamten tiefen Baum als Text, sondern nutzt **Platzhalter** (`#ID`) für komplexe Unter-Knoten.
|
|
* AST: `If(Condition, ThenBlock, ElseBlock)`
|
|
* Text: `(if #1 #2 #3)`
|
|
2. **Kontext:** Der Controller speichert in einem `TEditContext`, welcher AST-Knoten hinter `#1` steckt.
|
|
3. **Navigation:** Der User kann `#1` mit dem Cursor ansteuern und per Shortcut (z.B. `Ctrl+Space`) "in-place" expandieren.
|
|
* Text wird zu: `(if (> Close #4) #2 #3)`
|
|
4. **Commit:** Beim Bestätigen (Enter) wird der Text geparst (`TAstParser`). Die Platzhalter werden durch die originalen, unveränderten AST-Knoten aus dem Kontext ersetzt.
|
|
|
|
**Vorteil:** Maximale Effizienz. Man editiert nur das, was man ändern will. Der Rest des Baumes bleibt vor versehentlichen Syntaxfehlern geschützt.
|
|
|
|
---
|
|
|
|
## 4. Reaktivität & Live Coding
|
|
|
|
Das System kompiliert und führt den Code permanent aus, nicht erst auf Knopfdruck.
|
|
|
|
### Reactive Pipeline
|
|
1. **Änderung:** User zieht einen Block oder ändert eine Zahl.
|
|
2. **Controller:** Baut neuen AST -> `OnChange`.
|
|
3. **Runner:** Führt `FEnv.Run(NewAst)` aus.
|
|
4. **UI Update:** Charts und Indikatoren werden neu gezeichnet.
|
|
|
|
### Number Scrubbing
|
|
Benutzer können Zahlenwerte (Konstanten) mit der Maus "ziehen" (drücken + ziehen).
|
|
* Der Controller aktualisiert den AST "live" (hochfrequent).
|
|
* Der Chart verändert sich flüssig während der Mausbewegung.
|
|
* Ermöglicht intuitives Finden von Parametern (z.B. "Welche SMA-Länge passt visuell am besten?").
|
|
|
|
### Code as UI (Widgets)
|
|
Der Code kann UI-Elemente zurückgeben, die im REPL-Output gerendert werden.
|
|
* `var len := Slider("Period", 10, 200)` erzeugt einen Schieberegler.
|
|
* Bewegt man den Regler, wird das Skript mit dem neuen Wert für `len` erneut ausgeführt.
|
|
|
|
---
|
|
|
|
## 5. Technische Komponenten (Zusammenfassung)
|
|
|
|
| Komponente | Verantwortung |
|
|
| :--- | :--- |
|
|
| **`TAstPrettyPrinter`** | Wandelt AST-Knoten in S-Expressions (`(func arg1 arg2)`). Unterstützt "Shallow Printing" mit Platzhaltern. |
|
|
| **`TAstParser`** | Wandelt S-Expressions zurück in AST-Knoten. Löst Platzhalter (`#ID`) über den `TEditContext` auf. |
|
|
| **`TEditContext`** | Hält die Referenzen zwischen Text-Tokens (`#1`) und echten `IAstNode`-Instanzen während des Editierens. |
|
|
| **`TRtlRegistry`** | Registriert Finanzfunktionen (`SMA`, `RSI`) und UI-Widgets (`Slider`, `Chart`). |
|
|
| **`TAstEditorController`** | Orchestriert Edit-Vorgänge. Führt "Path Copying" durch, um den immutablen Baum nach einem Text-Edit zu aktualisieren. |
|
|
|
|
---
|
|
|
|
## 6. User Workflow Beispiel
|
|
|
|
1. **Struktur bauen:** User zieht `LoadCSV`, `VarDecl` (für SMA) und `Chart` als Blöcke in den Workspace.
|
|
2. **Logik verfeinern:** User doppelklickt auf den Parameter des SMA.
|
|
3. **Text Edit:** Ein kleines Popup erscheint. User tippt `(* 20 2)`.
|
|
4. **Commit:** Aus dem Text wird ein Multiplikations-Knoten. Der Block zeigt nun `40` (oder die Formel).
|
|
5. **Analyse:** Der Chart zeigt sofort den SMA(40).
|
|
6. **Tuning:** User klickt auf die `20` im Text/Label, zieht die Maus nach rechts. Die Zahl steigt auf `25`. Der Chart aktualisiert sich in Echtzeit.
|
|
7. **Refactoring:** User merkt, er braucht Logik. Er klickt auf den SMA-Block und drückt `Ctrl+Space` (Wrap in...). Wählt `If`.
|
|
* Der SMA ist nun das "Then"-Kind eines neuen If-Blocks.
|
|
* Die Struktur wurde geändert, ohne Text kopieren zu müssen. |