ApplyTheme() setzt beim Indikator-Start die Chart-Eigenschaften auf die Dashboard-Palette: Bull #3B82F6 (blau) - Bear #EF4444 (rot) - BG #0D1117 Gitter #10151C (dezent) - Text #8B949E - Kerzen gefuellt (CHART_CANDLES) Liquiditaets-Pfeile Gold #F59E0B (= "Liquiditaetszone" der Legende) Periodentrenner aus, Bid/Ask in Bull/Bear-Farbe. Abschaltbar via InpApplyTheme, alle Farben einzeln als Inputs ueberschreibbar. WARNUNG dokumentiert: aendert das Chart dauerhaft (bleibt nach Entfernen des Indikators bestehen). Kompiliert. CLAUDE.md aktualisiert (Indikator-Stand v1.12 -> v1.15, inkl. der v1.14-Umstellung auf "nur Pfeile rechtsbuendig"). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
430 lines
21 KiB
Plaintext
430 lines
21 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| SR_Levels.mq5 |
|
|
//| Zeichnet Support-/Resistance-Linien + Zonen (Ranges), die der |
|
|
//| Python-Bot (Oil Trading Server) nach MQL5\Files\sr_levels.csv |
|
|
//| schreibt. Das Python-MetaTrader5-Paket kann selbst KEINE Chart- |
|
|
//| Objekte erzeugen — daher diese Datei-Bridge. |
|
|
//| |
|
|
//| Installation: |
|
|
//| 1) Diese Datei nach <Terminal>\MQL5\Indicators\ kopieren. |
|
|
//| 2) In MetaEditor öffnen und mit F7 kompilieren. |
|
|
//| 3) Im Navigator auf den WTI-Chart (SpotCrude) ziehen. |
|
|
//| 4) Der Bot muss laufen (schreibt die CSV alle ~5 s). |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Oil Trading Bot"
|
|
#property version "1.15"
|
|
// v1.15 (2026-07-30): CHART-THEME (User: „Farben im MT5 wie im Bild") — setzt beim
|
|
// Start Hintergrund/Gitter/Kerzenfarben auf die Dashboard-Palette
|
|
// (Bull #3B82F6, Bear #EF4444, BG #0D1117, Gitter #10151C dezent).
|
|
// Liquiditäts-Pfeile jetzt GOLD #F59E0B (= „Liquiditätszone" der Legende).
|
|
// Abschaltbar via InpApplyTheme. ⚠ ändert das Chart dauerhaft.
|
|
// v1.14 (2026-07-30): Liquiditäts-LINIEN + Text-Labels ENTFERNT (User: „blende die
|
|
// liquiditätslinien aus, nur die Pfeile sollen rechtsbündig angezeigt werden").
|
|
// Es bleibt NUR der Pfeil auf dem Wand-Preis, RECHTSBÜNDIG am aktuellen Rand
|
|
// (wird in RepositionLabels() nachgeführt, bleibt beim Scrollen rechts).
|
|
// Details (Seite/Größe/Dominanz/Preis) jetzt im TOOLTIP statt im Chart.
|
|
// Die pinke Liquiditäts-Trendlinie bleibt unverändert.
|
|
// v1.13 (2026-07-30): Liquiditäts-Wände bekommen einen PFEIL in ihrer Wirkrichtung
|
|
// (Lesart „die Wand hält" — Nachfrage stützt hoch, Angebot deckelt runter;
|
|
// die GRÖSSERE Wand wird dicker gezeichnet + "<<"). NEU: pinke
|
|
// LIQUIDITÄTS-TRENDLINIE (LT;…) = Regression über den volumengewichteten
|
|
// Wand-Schwerpunkt der letzten ~60 min — zeigt, wohin das Gewicht der
|
|
// RUHENDEN Orders wandert (nicht der gehandelte Kurs).
|
|
// ⚠ Pfeilrichtung ist INTERPRETATION, nicht gemessen (s. analyze_bookflow.py).
|
|
// v1.12 (2026-07-30): Chartmuster-Linien (PT;…) ENTFERNT (User-Wunsch, Chart war zu
|
|
// voll — Kachel/PWA-Anzeige bleibt). NEU: ECHTE Liquiditäts-Wände (LQ;…) aus
|
|
// dem Hyperliquid-L2-Orderbuch, basis-korrigiert auf CFD-Niveau — die einzigen
|
|
// Linien im Chart, die nicht aus Pivots geschätzt sind, sondern tatsächlich
|
|
// ruhende Orders zeigen (dick gestrichelt + Größen-Label). Reine Anzeige.
|
|
// v1.11: Chartmuster-Linien (jetzt entfernt).
|
|
// ⚠ nach dem Update den Indikator NEU mit F7 kompilieren.
|
|
#property indicator_chart_window
|
|
#property indicator_plots 0
|
|
|
|
input string InpFile = "sr_levels.csv"; // Datei in MQL5\Files
|
|
input int InpRefreshS = 2; // Aktualisierung (Sekunden)
|
|
input color InpResColor = clrDodgerBlue; // Widerstand (blau kräftig)
|
|
input color InpSupColor = clrDeepSkyBlue; // Support (blau hell)
|
|
input bool InpShowRange = false; // dynamische Handels-Range zeichnen (aus per User-Wunsch)
|
|
input int InpRangeBars = 50; // Range = Hoch/Tief der letzten N Kerzen
|
|
input color InpRangeColor = clrGoldenrod; // Range-Farbe
|
|
input bool InpRangeFill = false; // Range füllen (aus = nur Umriss)
|
|
input bool InpShowChannel = true; // Regressionskanal (M30) zeichnen
|
|
input color InpChanColor = clrYellow; // Kanal-Farbe
|
|
input bool InpShowWalls = true; // echte Liquiditäts-Wände (Hyperliquid-Orderbuch)
|
|
input color InpWallBidColor = C'245,158,11'; // Liquidität Nachfrage (Bid) — Gold
|
|
input color InpWallAskColor = C'245,158,11'; // Liquidität Angebot (Ask) — Gold
|
|
input bool InpShowLiqTrend = true; // Liquiditäts-Trendlinie zeichnen
|
|
input color InpLiqTrendColor = clrMagenta; // Liquiditäts-Trend (pink)
|
|
// ── Chart-THEME (User-Vorgabe 2026-07-30 „Farben im MT5 wie im Bild") ────────
|
|
// Setzt beim Start die Chart-Eigenschaften auf die Dashboard-Palette, damit MT5
|
|
// und die PWA gleich aussehen. Farben in MQL5-Notation C'R,G,B'.
|
|
// Bullish #3B82F6 · Bearish #EF4444 · Liquidität #F59E0B · Entry/Target #22C55E
|
|
// Hintergrund #0D1117 · Gitter #10151C (sehr dezent) · Text #8B949E
|
|
// ⚠ Ändert das Chart dauerhaft (bleibt auch nach Entfernen des Indikators) —
|
|
// deshalb per Schalter abschaltbar.
|
|
input bool InpApplyTheme = true; // Chart-Farben setzen (Dashboard-Look)
|
|
input color InpThemeBull = C'59,130,246'; // Bullish Candle (blau)
|
|
input color InpThemeBear = C'239,68,68'; // Bearish Candle (rot)
|
|
input color InpThemeBg = C'13,17,23'; // Hintergrund
|
|
input color InpThemeGrid = C'16,21,28'; // Gitternetz (dezent)
|
|
input color InpThemeText = C'139,148,158'; // Achsen/Text
|
|
|
|
const string PFX = "SRB_"; // Präfix S/R-Linien (aus Datei)
|
|
const string RPFX = "SRR_"; // Präfix dynamische Range (aus Chart)
|
|
string g_last = "\x01"; // letzter Datei-Inhalt (gegen Flackern)
|
|
bool g_range_drawn = false; // hat DIESE Instanz die Range gezeichnet?
|
|
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
if(InpApplyTheme) ApplyTheme();
|
|
EventSetTimer(MathMax(1, InpRefreshS));
|
|
Redraw();
|
|
DrawRange();
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Chart-Farben auf die Dashboard-Palette setzen (User-Vorgabe). |
|
|
//| Kerzen werden GEFÜLLT gezeichnet (Body in Bull-/Bear-Farbe), damit|
|
|
//| es aussieht wie im Referenzbild. |
|
|
//+------------------------------------------------------------------+
|
|
void ApplyTheme()
|
|
{
|
|
ChartSetInteger(0, CHART_MODE, CHART_CANDLES);
|
|
ChartSetInteger(0, CHART_COLOR_BACKGROUND, InpThemeBg);
|
|
ChartSetInteger(0, CHART_COLOR_FOREGROUND, InpThemeText);
|
|
ChartSetInteger(0, CHART_SHOW_GRID, true);
|
|
ChartSetInteger(0, CHART_COLOR_GRID, InpThemeGrid);
|
|
// Body-Füllung
|
|
ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, InpThemeBull);
|
|
ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, InpThemeBear);
|
|
// Umriss + Docht in derselben Farbe → klare, flächige Kerzen wie im Bild
|
|
ChartSetInteger(0, CHART_COLOR_CHART_UP, InpThemeBull);
|
|
ChartSetInteger(0, CHART_COLOR_CHART_DOWN, InpThemeBear);
|
|
ChartSetInteger(0, CHART_COLOR_CHART_LINE, InpThemeText);
|
|
ChartSetInteger(0, CHART_COLOR_BID, InpThemeBull);
|
|
ChartSetInteger(0, CHART_COLOR_ASK, InpThemeBear);
|
|
ChartSetInteger(0, CHART_COLOR_STOP_LEVEL, C'239,68,68');
|
|
ChartSetInteger(0, CHART_SHOW_PERIOD_SEP, false);
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
EventKillTimer();
|
|
ObjectsDeleteAll(0, PFX);
|
|
ObjectsDeleteAll(0, RPFX);
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
void OnTimer() { Redraw(); DrawRange(); RepositionLabels(); }
|
|
//+------------------------------------------------------------------+
|
|
//| Zeitpunkt der horizontalen Chart-Mitte (sichtbarer Bereich) |
|
|
//+------------------------------------------------------------------+
|
|
datetime CenterTime()
|
|
{
|
|
long first = ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR);
|
|
long width = ChartGetInteger(0, CHART_WIDTH_IN_BARS);
|
|
int mid = (int)MathMax(0, first - width / 2);
|
|
return iTime(_Symbol, PERIOD_CURRENT, mid);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Hält die S/R-Beschriftungen beim Scrollen/Zoomen mittig |
|
|
//+------------------------------------------------------------------+
|
|
void RepositionLabels()
|
|
{
|
|
datetime ct = CenterTime();
|
|
int total = ObjectsTotal(0, 0, OBJ_TEXT);
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
string nm = ObjectName(0, i, 0, OBJ_TEXT);
|
|
if(StringFind(nm, PFX + "T") == 0)
|
|
{
|
|
double pr = ObjectGetDouble(0, nm, OBJPROP_PRICE);
|
|
ObjectMove(0, nm, 0, ct, pr);
|
|
}
|
|
}
|
|
// Liquiditäts-PFEILE rechtsbündig halten: die CSV ändert sich nicht bei jedem
|
|
// Tick, ohne Nachführung würden die Pfeile mit jeder neuen Kerze nach links
|
|
// wandern. Preis bleibt, nur die Zeit wird an den rechten Rand gezogen.
|
|
datetime rt = iTime(_Symbol, PERIOD_CURRENT, 0) + (datetime)(PeriodSeconds() * 2);
|
|
int na = ObjectsTotal(0, 0, OBJ_ARROW);
|
|
for(int i = 0; i < na; i++)
|
|
{
|
|
string nm = ObjectName(0, i, 0, OBJ_ARROW);
|
|
if(StringFind(nm, PFX + "ALQ_") == 0)
|
|
ObjectMove(0, nm, 0, rt, ObjectGetDouble(0, nm, OBJPROP_PRICE));
|
|
}
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Dynamische Handels-Range = Hoch/Tief der letzten N Kerzen des |
|
|
//| AKTUELLEN Charts (TF-genau). In-place via ObjectMove → kein |
|
|
//| Flackern, passt sich an M1/M5/…/H1 automatisch an. |
|
|
//+------------------------------------------------------------------+
|
|
void DrawRange()
|
|
{
|
|
string nm = RPFX + "BOX";
|
|
if(!InpShowRange)
|
|
{
|
|
// Nur löschen, was DIESE Instanz gezeichnet hat — sonst kämpfen zwei
|
|
// Instanzen (eine an/eine aus) um die Box → Blinken im 2-s-Takt.
|
|
if(g_range_drawn) { ObjectDelete(0, nm); g_range_drawn = false; ChartRedraw(); }
|
|
return;
|
|
}
|
|
int total = Bars(_Symbol, PERIOD_CURRENT);
|
|
if(total < 5) return;
|
|
int n = InpRangeBars;
|
|
if(n > total - 1) n = total - 1;
|
|
int hi_i = iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, n, 0);
|
|
int lo_i = iLowest (_Symbol, PERIOD_CURRENT, MODE_LOW, n, 0);
|
|
if(hi_i < 0 || lo_i < 0) return;
|
|
double hi = iHigh(_Symbol, PERIOD_CURRENT, hi_i);
|
|
double lo = iLow (_Symbol, PERIOD_CURRENT, lo_i);
|
|
datetime t0 = iTime(_Symbol, PERIOD_CURRENT, n - 1);
|
|
datetime t1 = iTime(_Symbol, PERIOD_CURRENT, 0) + PeriodSeconds();
|
|
if(ObjectFind(0, nm) < 0)
|
|
{
|
|
ObjectCreate(0, nm, OBJ_RECTANGLE, 0, t0, lo, t1, hi);
|
|
ObjectSetInteger(0, nm, OBJPROP_COLOR, InpRangeColor);
|
|
ObjectSetInteger(0, nm, OBJPROP_STYLE, STYLE_SOLID);
|
|
ObjectSetInteger(0, nm, OBJPROP_WIDTH, 1);
|
|
ObjectSetInteger(0, nm, OBJPROP_FILL, InpRangeFill);
|
|
ObjectSetInteger(0, nm, OBJPROP_BACK, true);
|
|
ObjectSetInteger(0, nm, OBJPROP_SELECTABLE, false);
|
|
ObjectSetString (0, nm, OBJPROP_TEXT, "Range " + IntegerToString(n));
|
|
}
|
|
else
|
|
{
|
|
ObjectMove(0, nm, 0, t0, lo); // linke untere Ecke
|
|
ObjectMove(0, nm, 1, t1, hi); // rechte obere Ecke
|
|
}
|
|
g_range_drawn = true;
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Pflicht-Funktion jedes Indikators — hier No-op (wir zeichnen |
|
|
//| über OnTimer aus der Datei, nicht aus den Kursreihen). |
|
|
//+------------------------------------------------------------------+
|
|
int OnCalculate(const int rates_total,
|
|
const int prev_calculated,
|
|
const datetime &time[],
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &low[],
|
|
const double &close[],
|
|
const long &tick_volume[],
|
|
const long &volume[],
|
|
const int &spread[])
|
|
{
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
void Redraw()
|
|
{
|
|
int h = FileOpen(InpFile, FILE_READ|FILE_TXT|FILE_ANSI|FILE_SHARE_READ|FILE_SHARE_WRITE);
|
|
if(h == INVALID_HANDLE)
|
|
return; // Datei (noch) nicht da → nächster Tick
|
|
|
|
// Ganze Datei in einen String lesen und mit dem letzten Stand vergleichen —
|
|
// nur bei ÄNDERUNG neu zeichnen (sonst flackert der delete/recreate alle 2 s).
|
|
string content = "";
|
|
while(!FileIsEnding(h))
|
|
content += FileReadString(h) + "\n";
|
|
FileClose(h);
|
|
if(content == g_last)
|
|
return; // nichts geändert → nicht anfassen
|
|
g_last = content;
|
|
|
|
ObjectsDeleteAll(0, PFX);
|
|
string rows[];
|
|
int nr = StringSplit(content, '\n', rows);
|
|
int idx = 0;
|
|
|
|
for(int r = 0; r < nr; r++)
|
|
{
|
|
string line = rows[r];
|
|
if(StringLen(line) < 2) continue;
|
|
string p[];
|
|
int k = StringSplit(line, ';', p);
|
|
if(k < 2) continue;
|
|
string typ = p[0];
|
|
|
|
// 1. Zeile: SYM;<symbol> — nur auf dem passenden Chart zeichnen
|
|
if(typ == "SYM")
|
|
{
|
|
if(p[1] != _Symbol)
|
|
{
|
|
ObjectsDeleteAll(0, PFX);
|
|
ChartRedraw();
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
// Horizontale S/R-Linien + sichtbares Text-Label an der Linie
|
|
if(typ == "R" || typ == "S")
|
|
{
|
|
double price = StringToDouble(p[1]);
|
|
if(price <= 0) continue;
|
|
string lbl = (typ=="R" ? "Widerstand " : "Unterstützung ")
|
|
+ DoubleToString(price, (int)_Digits);
|
|
color col = (typ=="R" ? InpResColor : InpSupColor);
|
|
string nm = PFX + typ + "_" + IntegerToString(idx);
|
|
if(ObjectCreate(0, nm, OBJ_HLINE, 0, 0, price))
|
|
{
|
|
ObjectSetInteger(0, nm, OBJPROP_COLOR, col);
|
|
ObjectSetInteger(0, nm, OBJPROP_STYLE, STYLE_DASH);
|
|
ObjectSetInteger(0, nm, OBJPROP_WIDTH, 1);
|
|
ObjectSetInteger(0, nm, OBJPROP_BACK, true);
|
|
ObjectSetInteger(0, nm, OBJPROP_SELECTABLE, false);
|
|
ObjectSetString (0, nm, OBJPROP_TEXT, lbl); // Tooltip
|
|
}
|
|
// Beschriftung als eigenes Text-Objekt: horizontal ZENTRIERT im sicht-
|
|
// baren Chart, direkt über der Linie (bleibt via RepositionLabels()
|
|
// auch beim Scrollen/Zoomen zentriert)
|
|
string tn = PFX + "T" + typ + "_" + IntegerToString(idx);
|
|
if(ObjectCreate(0, tn, OBJ_TEXT, 0, CenterTime(), price))
|
|
{
|
|
ObjectSetString (0, tn, OBJPROP_TEXT, lbl);
|
|
ObjectSetInteger(0, tn, OBJPROP_COLOR, col);
|
|
ObjectSetInteger(0, tn, OBJPROP_FONTSIZE, 8);
|
|
ObjectSetInteger(0, tn, OBJPROP_ANCHOR, ANCHOR_LOWER); // zentriert über dem Punkt
|
|
ObjectSetInteger(0, tn, OBJPROP_BACK, false);
|
|
ObjectSetInteger(0, tn, OBJPROP_SELECTABLE, false);
|
|
}
|
|
idx++;
|
|
}
|
|
// Regressionskanal: CH;<U|M|L>;t1;p1;t2;p2 → diagonale Trendlinie (OBJ_TREND),
|
|
// nach rechts verlängert. Anker in Broker-Zeit (= Server-Zeit im Terminal).
|
|
if(typ == "CH")
|
|
{
|
|
if(!InpShowChannel) continue;
|
|
if(k < 6) continue;
|
|
string kind = p[1];
|
|
datetime t1 = (datetime)StringToInteger(p[2]);
|
|
double pr1 = StringToDouble(p[3]);
|
|
datetime t2 = (datetime)StringToInteger(p[4]);
|
|
double pr2 = StringToDouble(p[5]);
|
|
if(pr1 <= 0 || pr2 <= 0 || t1 <= 0 || t2 <= 0) continue;
|
|
string nm = PFX + "CH_" + kind;
|
|
if(ObjectCreate(0, nm, OBJ_TREND, 0, t1, pr1, t2, pr2))
|
|
{
|
|
ObjectSetInteger(0, nm, OBJPROP_COLOR, InpChanColor);
|
|
ObjectSetInteger(0, nm, OBJPROP_STYLE, (kind == "M" ? STYLE_DOT : STYLE_DASH));
|
|
ObjectSetInteger(0, nm, OBJPROP_WIDTH, 1);
|
|
ObjectSetInteger(0, nm, OBJPROP_RAY_RIGHT, true); // nach rechts verlängern
|
|
ObjectSetInteger(0, nm, OBJPROP_RAY_LEFT, false);
|
|
ObjectSetInteger(0, nm, OBJPROP_BACK, true);
|
|
ObjectSetInteger(0, nm, OBJPROP_SELECTABLE, false);
|
|
ObjectSetString (0, nm, OBJPROP_TEXT, "Kanal " + kind);
|
|
}
|
|
continue;
|
|
}
|
|
// ECHTE Liquiditäts-Wände: LQ;<B|A>;preis;size (B = Nachfrage/Bid-Wand,
|
|
// A = Angebot/Ask-Wand). Quelle = Hyperliquid-L2-Orderbuch, größtes Level je
|
|
// Seite, im Bot BASIS-KORRIGIERT auf CFD-Niveau (HL notiert ~0,45 $ tiefer).
|
|
// ⚠ Das ist die EINZIGE Linie im Chart, die nicht aus Pivots geschätzt ist,
|
|
// sondern tatsächlich ruhende Orders zeigt. Dick + gestrichelt, damit sie sich
|
|
// klar von den dünnen S/R-Linien abhebt. REINE ANZEIGE (kein Signal).
|
|
// (Chartmuster-Linien „PT;…" wurden 2026-07-30 auf User-Wunsch entfernt.)
|
|
if(typ == "LQ")
|
|
{
|
|
if(k < 3) continue;
|
|
if(!InpShowWalls) continue;
|
|
string side = p[1];
|
|
double lpx = StringToDouble(p[2]);
|
|
double lsz = (k > 3) ? StringToDouble(p[3]) : 0.0;
|
|
if(lpx <= 0) continue;
|
|
bool isBid = (side == "B");
|
|
color lcol = isBid ? InpWallBidColor : InpWallAskColor;
|
|
// ⚠ 2026-07-30 (User): KEINE waagerechte Linie und KEIN Text-Label mehr —
|
|
// der Chart war zu voll. Es bleibt NUR der Pfeil, RECHTSBÜNDIG am aktuellen
|
|
// Rand, auf dem Preisniveau der Wand. Die Details (Seite/Größe/Dominanz)
|
|
// stehen im TOOLTIP (Maus drüber) statt fest im Chart.
|
|
string dirc = (k > 4) ? p[4] : (isBid ? "U" : "D");
|
|
bool isDom = (k > 5 && p[5] == "1");
|
|
string an = PFX + "ALQ_" + side;
|
|
// Rechter Rand = aktuelle (rechteste) Kerze + kleiner Versatz, damit der
|
|
// Pfeil frei neben dem Kursverlauf steht und beim Scrollen rechts bleibt.
|
|
datetime atime = iTime(_Symbol, PERIOD_CURRENT, 0)
|
|
+ (datetime)(PeriodSeconds() * 2);
|
|
if(ObjectCreate(0, an, OBJ_ARROW, 0, atime, lpx))
|
|
{
|
|
ObjectSetInteger(0, an, OBJPROP_ARROWCODE, (dirc == "U" ? 233 : 234));
|
|
ObjectSetInteger(0, an, OBJPROP_COLOR, lcol);
|
|
ObjectSetInteger(0, an, OBJPROP_WIDTH, (isDom ? 4 : 2));
|
|
ObjectSetInteger(0, an, OBJPROP_ANCHOR, ANCHOR_LEFT);
|
|
ObjectSetInteger(0, an, OBJPROP_SELECTABLE, false);
|
|
}
|
|
else
|
|
{
|
|
ObjectMove(0, an, 0, atime, lpx);
|
|
ObjectSetInteger(0, an, OBJPROP_WIDTH, (isDom ? 4 : 2));
|
|
ObjectSetInteger(0, an, OBJPROP_COLOR, lcol);
|
|
ObjectSetInteger(0, an, OBJPROP_ARROWCODE, (dirc == "U" ? 233 : 234));
|
|
}
|
|
ObjectSetString(0, an, OBJPROP_TOOLTIP,
|
|
(isBid ? "Liquiditaet NACHFRAGE " : "Liquiditaet ANGEBOT ")
|
|
+ DoubleToString(lsz, 0) + (isDom ? " (dominant)" : "")
|
|
+ " @ " + DoubleToString(lpx, (int)_Digits));
|
|
// evtl. noch vorhandene Alt-Objekte (Linie/Label aus v1.13) entfernen
|
|
ObjectDelete(0, PFX + "LQ_" + side);
|
|
ObjectDelete(0, PFX + "TLQ_" + side);
|
|
continue;
|
|
}
|
|
// Liquiditäts-TRENDLINIE: LT;t1;p1;t2;p2;<U|D> (pink, nach rechts verlängert).
|
|
// Regression über den VOLUMENGEWICHTETEN Schwerpunkt der beiden Wände über die
|
|
// letzten ~60 min: zeigt, wohin das Gewicht der RUHENDEN Orders wandert —
|
|
// NICHT wohin der gehandelte Kurs läuft. Steigt sie, ziehen die Käufer ihre
|
|
// großen Gebote hoch. Zeiten kommen bereits in Broker-Zeit aus dem Bot.
|
|
if(typ == "LT")
|
|
{
|
|
if(k < 5) continue;
|
|
if(!InpShowLiqTrend) continue;
|
|
datetime t1 = (datetime)StringToInteger(p[1]);
|
|
double q1 = StringToDouble(p[2]);
|
|
datetime t2 = (datetime)StringToInteger(p[3]);
|
|
double q2 = StringToDouble(p[4]);
|
|
string td = (k > 5) ? p[5] : "";
|
|
if(t1 <= 0 || t2 <= 0 || q1 <= 0 || q2 <= 0) continue;
|
|
string nm = PFX + "LIQTREND";
|
|
if(ObjectCreate(0, nm, OBJ_TREND, 0, t1, q1, t2, q2))
|
|
{
|
|
ObjectSetInteger(0, nm, OBJPROP_COLOR, InpLiqTrendColor);
|
|
ObjectSetInteger(0, nm, OBJPROP_STYLE, STYLE_SOLID);
|
|
ObjectSetInteger(0, nm, OBJPROP_WIDTH, 2);
|
|
ObjectSetInteger(0, nm, OBJPROP_RAY_RIGHT, true);
|
|
ObjectSetInteger(0, nm, OBJPROP_RAY_LEFT, false);
|
|
ObjectSetInteger(0, nm, OBJPROP_BACK, true);
|
|
ObjectSetInteger(0, nm, OBJPROP_SELECTABLE, false);
|
|
}
|
|
else
|
|
{
|
|
ObjectMove(0, nm, 0, t1, q1);
|
|
ObjectMove(0, nm, 1, t2, q2);
|
|
}
|
|
string tl = PFX + "TLIQTREND";
|
|
string tt = "Liquiditäts-Trend " + (td == "U" ? CharToString(94) : CharToString(118));
|
|
if(ObjectCreate(0, tl, OBJ_TEXT, 0, t2, q2))
|
|
{
|
|
ObjectSetString (0, tl, OBJPROP_TEXT, tt);
|
|
ObjectSetInteger(0, tl, OBJPROP_COLOR, InpLiqTrendColor);
|
|
ObjectSetInteger(0, tl, OBJPROP_FONTSIZE, 9);
|
|
ObjectSetInteger(0, tl, OBJPROP_ANCHOR, ANCHOR_LOWER);
|
|
ObjectSetInteger(0, tl, OBJPROP_SELECTABLE, false);
|
|
}
|
|
else
|
|
{
|
|
ObjectMove(0, tl, 0, t2, q2);
|
|
ObjectSetString(0, tl, OBJPROP_TEXT, tt);
|
|
}
|
|
continue;
|
|
}
|
|
// ("Z;"-Zonen-Zeilen schreibt der Bot nicht mehr — die dynamische Handels-
|
|
// Range zeichnet DrawRange() selbst aus den Chart-Kerzen.)
|
|
}
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|