// --- GLOBALE VARIABLEN ---

JSONArray Kerzen;

float[] öffnungen, hochs, tiefs, schließungen, volumen;

float aktuellerPreis, ATH , LOW= 0;

String ech = "1m";

ArrayList liquidationClusters = new ArrayList();

ArrayList clusterCounts = new ArrayList();

//ArrayList supports = new ArrayList();

ArrayList supportBroken = new ArrayList();

int random= 0;

ArrayList supports = new ArrayList();

ArrayList supportBreaks = new ArrayList();

String symbol = "BTCUSDT";

int countSymbol=1;

String[] symbole = {

"BTCUSDT", "PAXGUSDT","BTCUSDC","TRUMPUSDC","ANIMEUSDC", "CAKEUSDC", "VIRTUALUSDC", "SAHARAUSDC","CUSDC","FUSDC", "PEPEUSDT","ETHUSDT", "BNBUSDT", "SOLUSDT", "XRPUSDT", "DOGEUSDT", "ADAUSDT", "AVAXUSDT", "AUCTIONUSD", "DOTUSDT",

„TRXUSDT“, „LTCUSDT“, „LINKUSDT“, „BCHUSDT“, „ATOMUSDT“, „XLMUSDT“, „HMSTRUSD“, „UNIUSDT“, „ETCUSDT“, „FILUSDT“, „ICPUSDT“,

„HBARUSDT“, „APTUSDT“, „IMXUSDT“, „ARBUSDT“, „NEARUSDT“, „OPUSDT“, „GRTUSDT“, „VETUSDT“, „EGLDUSDT“, „SANDUSDT“,

"AXSUSDT", "MANAUSDT", "STXUSDT", "XTZUSDT", "THETAUSDT", "RNDRUSDT", "AAVEUSDT", "KAVAUSDT", "ALGOUSDT", "DYDXUSDT",

„TUSDT“, „CROUSDT“, „FTMUSDT“, „GALAUSDT“, „CHZUSDT“, „ENJUSDT“, „ONEUSDT“, „RUNEUSDT“, „ZILUSDT“, „LRCUSDT“,

„FLOWUSDT“, „ROSEUSDT“, „CRVUSDT“, „ENSUSDT“, „ZRXUSDT“, „BATUSDT“, „KSMUSDT“, „COMPUSDT“, „WAVESUSDT“, „1INCHUSDT“,

„BALUSDT“, „SUSHIUSDT“, „XEMUSDT“, „YFIUSDT“, „BNTUSDT“, „SKLUSDT“, „OCEANUSDT“, „ANKRUSDT“, „CELOUSDT“, „GLMRUSDT“,

"SRMUSDT", "MOVRUSDT", "CTSIUSDT", "REEFUSDT", "CVCUSDT", "BANDUSDT", "LITUSDT", "API3USDT", "ALICEUSDT", "RLCUSDT",

„KNCUSDT“, „STORJUSDT“, „NKNUSDT“, „DENTUSDT“, „POWRUSDT“, „RENUSDT“, „ARPAUSDT“, „VTHOUSDT“, „TRBUSDT“, „IDEXUSDT“,

„FORTHUSDT“, „MTLUSDT“, „PERLUSDT“, „SYSUSDT“, „TLMUSDT“, „UFTUSDT“, „XNOUSDT“, „XVGUSDT“, „ELAUSDT“, „BICOUSDT“

};

ArrayList resistances = new ArrayList();

float fundingRates[] ;//= fetchFundingRates(symbol, 1000); // Finanzierungsraten der letzten 1000

float[] fetchFundingRates(String symbol, int limit) {

float[] rates = new float[limit];

String url = "https://fapi.binance.com/fapi/v1/fundingRate?symbol=" + symbol + "&limit=" + limit;

versuchen {

String raw = join(loadStrings(url), "");

JSONArray arr = parseJSONArray(raw);

println( " Finanzierungsname: "+ arr.size());

for (int i = 0; i < arr.size(); i++) {

JSONObject obj = arr.getJSONObject(i);

rates[i] = float(obj.getString("fundingRate"));

if ( rates[i] < 0) println( " detecteeeee");

}

} catch(Exception e) {

println("Fehler beim Abrufen der Fördermittel: " + e);

}

Renditen;

}

// --- PARAMETER (wie Ihre Pine-Eingänge) ---

int lookbackVol = 50;

float volMult = 2.5;

float wickRatio = 0.6f;

float minBodyRatio = 0.1f;

float proximityPts = 20f; // Toleranz für die Gruppierung von Clustern

int pivotLeft = 5;

int pivotRight = 5;

int interval = 1000; // 1000 ms = 1 Sekunde

int lastUpdate = 0;

Ganzzahlen Breiten;

// --- EMA-Berechnung ---

float[] ema(float[] data, int period) {

float[] ema = new float[data.length];

float alpha = 2.0 / (period + 1.0);

// Initialisierung: Wir beginnen mit dem ersten Rohwert

ema[0] = data[0];

for (int i = 1; i < data.length; i++) {

ema[i] = alpha * data[i] + (1 - alpha) * ema[i-1];

}

return ema;

}

// --- AUFSTELLEN ---

void setup() {

//size(1200, 800);

Vollbild();

//size(int(displayWidth*2),int( displayHeight));

Symbol = Symbole[AnzahlSymbole];

fetchData( symbol );

Breiten = int(Breite * 8,7); // 8,1

fundingRates = fetchFundingRates(symbol, 1000); // Letzte 1000 Finanzierungsraten

//frameRate(1);

// Ändern Sie das Symbol, wenn Sie möchten

}

float startDist;

float zoom = 1.0;

float offsetX = 0;

float offsetY = 0;

void touchStarted() {

if (touches.length == 2) {

startDist = dist(touches[0].x, touches[0].y, touches[1].x, touches[1].y);

}

}

void touchMoved() {

if (touches.length == 2) {

float newDist = dist(touches[0].x, touches[0].y, touches[1].x, touches[1].y);

float d = newDist / startDist;

zoom *= d;

zoom = constrain(zoom, 0.1, 10); // begrenzt den Zoom

startDist = newDist;

} else if (touches.length == 1) {

offsetX += (touches[0].x - pmouseX) / zoom;

offsetY += (touches[0].y - pmouseY) / zoom;

}

}

// Mit der Maus ziehen (nützlich zum Testen auf dem PC)

void mouseDragged() {

offsetX += (mouseX - pmouseX) / zoom;

offsetY += (mouseY - pmouseY) / zoom;

if ( mouseX < width && mouseX > width-100 && mouseY > height-200 && mouseY < height-100){

++gapMin;

}

if ( mouseX < width && mouseX > width-100 && mouseY > height-100 && mouseY < height){

--gapMin;

}

}

void mousePressed()

{

//++countSymbol;

//fill(255);

//rect(width-200, 100,200,200);

if ( mouseX > width-200 && mouseY < 300 && mouseY >100 )

++countSymbol;

if ( mouseX > width-200 && mouseY < 500 && mouseY >300 )

--countSymbol;

if (countSymbol<0)

countSymbol =0;

if (countSymbol>101)

countSymbol =0;

//text(symbols[countSymbol],width-150,150);

Symbol = Symbole[AnzahlSymbole];

}

void mouseReleased()

{

if ( mouseX < width && mouseX > width-100 && mouseY > height-200 && mouseY < height-100){

++gapMin;

}

if ( mouseX < width && mouseX > width-100 && mouseY > height-100 && mouseY < height){

--gapMin;

}

}

float rsi(int i, float[] closes, int period) {

if (i < period) return 50; // Standardwert, falls nicht genügend Daten vorhanden sind

Gleitkomma-Gewinn = 0, Verlust = 0;

for (int j = 1; j <= period; j++) {

float change = closes[i - j + 1] - closes[i - j];

if (change > 0) gain += change;

sonst Verlust -= Veränderung;

}

float avgGain = Verstärkung / Periode;

float durchschnittlicher Verlust = Verlust / Periode;

if (avgLoss == 0) return 100; // Maximaler RSI bei keinem Verlust

float rs = avgGain / avgLoss;

return 100 - (100 / (1 + rs));

}

int n = 30; // Fenstergröße

float tolerance = 100.5; // Abstand, der anzeigt, dass der Wert an die Decke stößt

void detectResistance(int i, float[] highs, float[] closes) {

if (i < n) return; // Noch nicht genügend Daten

// Wir nehmen den Maximalwert der letzten n Kerzen.

float maxRecent = highs[i];

for (int j = 1; j < n; j++) {

if (highs[i - j] > maxRecent) {

maxRecent = highs[i - j];

}

}

Wir zählen, wie oft der Preis nahe am Maximalwert angelangt ist.

int touchess = 0;

for (int j = 0; j < n; j++) {

if (abs(highs[i - j] - maxRecent) < tolerance) {

berührungslos++;

}

}

// RSI-Berechnung nicht anzeigen

// Verkauf am Tiefststand

float rsiValue = rsi(i, closes, 27);

// Wenn es häufig auftritt, aber nicht über 100 °C steigt, Signal

if (touchess > 2 && closes[i] < highs[i] - tolerance && rsiValue > 60) {

float xp = map(i, 0, closes.length - 1, 50, widths - 50);

float y = map(highs[i], min(closes), max(closes), height - 50, 50);

fill(255, 255, 0, 150);

noStroke();

rect(xp, y, 30, 15);

//fill(255);

textAlign(CENTER);

text("SHORT ×100", xp, y - 10);

}

}

// --- Zeichenschleife ---

void draw() {

Zufall = 0;

if (millis() - lastUpdate >= interval) {

//fetchData(symbol); // Wir aktualisieren die Daten

/*closes = new float[666]; // setzt das Closures-Array zurück

supports.clear(); // Wir leeren die Liste der Stützstellen.

supportBreaks.clear(); // Liste der Pausen löschen

liquidationClusters.clear(); // on vide les clusters de liquidation

clusterCounts.clear();

supportBroken.clear();*/

Symbol = Symbole[AnzahlSymbole];

fetchData( symbol );

lastUpdate = millis(); // Wir setzen den Zähler auf Null zurück.

}

pushMatrix();

translate(width/2 + offsetX*zoom, height/2 + offsetY*zoom-400);

//translate(width/2 + offsetX, height/2 + offsetY-400);

Skalierung(Zoom);

//fetchData("BTCUSDT");

Hintergrund(20);

stroke(255);

fill(200);

// Vertikale Skalierungsgrenzen

float maxP = max(closes);

float minP = min(closes);

/*

for (int i = 0; i < closes.length; i+=10) {

float xpr = map(i, 0, closes.length - 1, 50, widths-50);

float y = map(lows[i], minP, maxP, height - 50, 50);

fill(255, 25, 255,150);

noStroke();

rect(xpr-20, y - 40,40,40);

}

for (int i = 5; i < closes.length; i+=10) {

float xpr = map(i, 0, closes.length - 1, 50, widths-50);

float y = map(lows[i], minP, maxP, height - 50, 50);

fill(25, 255, 255, 150);

noStroke();

rect(xpr-20, y - 40,40,40);

}

*/

// --- NÄCHSTE ---

stroke(255, 255, 0);

float yATH = map(ATH, minP, maxP, height-50, 50);

line(50, yATH, widths-50, yATH);

fill(255, 255, 0);

text("ATH " + ATH, 55, yATH-5);

fill(255,0,0,55);rect(50,yATH,widths,100);

// --- NÄCHSTE ---

stroke(25, 255, 255);

yATH = map(LOW, minP, maxP, height-50, 50);

line(50, yATH, widths-50, yATH);

fill(255, 255, 0);

text("LOW " + LOW, 55, yATH-5);

fill(0,255,0,55);rect(50,yATH,widths,-100);

// Kursdiagramm (Schlusskursdiagramm)

/*

for (int i=1; i

float x1 = map(i-1, 0, closes.length, 50, width-50);

float y1 = map(closes[i-1], minP, maxP, height-50, 50);

float x2 = map(i, 0, closes.length, 50, width-50);

float y2 = map(closes[i], minP, maxP, height-50, 50);

stroke(180);

strokeWeight(2);

Linie(x1, y1, x2, y2);

öffnet = neues float[n];

highs = new float[n];

lows = new float[n];

schließt = neues float[n];

}*/

strokeWeight(1.3);

fill(223,12);

beginShape();

for (int i = 0; i < closes.length; i++) {

float x = map(i, 0, closes.length - 1, 50, widths-50);

float y = map(closes[i], minP, maxP, height - 50, 50);

vertex(x, y);

// Limit-Orders

}

endShape();

noStroke();

float[] ema3 = ema(closes, 666);//18

strokeWeight(3);

noFill();

for (int i = 1; i < ema3.length; i++) {

float x1 = map(i-1, 0, closes.length-1, 50, widths-50);

float y1 = map(ema3[i-1], minP, maxP, height-50, 50);

float x2 = map(i, 0, closes.length-1, 50, widths-50);

float y2 = map(ema3[i], minP, maxP, height-50, 50);

if (ema3[i] > ema3[i-1]) {

stroke(0, 255, 0); // vert if up

} anders {

stroke(255, 0, 0); // rouge si descend

}

Linie(x1 , y1, x2 , y2);

}

ema3 = ema(closes, 18);//18

strokeWeight(3);

noFill();

for (int i = 1; i < ema3.length; i++) {

float x1 = map(i-1, 0, closes.length-1, 50, widths-50);

float y1 = map(ema3[i-1], minP, maxP, height-50, 50);

float x2 = map(i, 0, closes.length-1, 50, widths-50);

float y2 = map(ema3[i], minP, maxP, height-50, 50);

if (ema3[i] > ema3[i-1]) {

stroke(0, 255, 0); // vert if up

} anders {

stroke(255, 0, 0); // rouge si descend

}

Linie(x1 , y1, x2 , y2);

}

/*

// Breite jeder Kerze + Abstand

float candleW = 5;

float spacing = 2; // Abstand zwischen den Kerzen

float chartWidth = (candleW + spacing) * closes.length;

for (int i = 0; i < closes.length; i++) {

// X mit regelmäßigem Abstand

float x = 50 + i * (candleW + spacing);

// Zuordnung Y

float yo = map(opens[i], minP, maxP, height - 50, 50);

float yc = map(closes[i], minP, maxP, height - 50, 50);

float yh = map(highs[i], minP, maxP, height - 50, 50);

float yl = map(lows[i], minP, maxP, height - 50, 50);

// --- Wick ---

stroke(200);

Linie(x, yh, x, yl);

// --- Korps ---

if (closes[i] >= opens[i]) {

fill(0, 200, 0);

stroke(0, 200, 0);

rect(x - candleW/2, yc, candleW, yo - yc);

} anders {

fill(200, 0, 0);

stroke(200, 0, 0);

rect(x - candleW/2, yo, candleW, yc - yo);

}

}

*/

for (int i = 0; i < closes.length; i++) {

float x = map(i, 0, closes.length - 1, 50, widths-50);

// Zuordnung Y

float yo = map(opens[i], minP, maxP, height - 50, 50);

float yc = map(closes[i], minP, maxP, height - 50, 50);

float yh = map(highs[i], minP, maxP, height - 50, 50);

float yl = map(lows[i], minP, maxP, height - 50, 50);

// Breite einer Kerze

float candleW = 4.5;

// --- Wick ---

if (closes[i] >= opens[i])

// Grüne Kerze

stroke(0,200,0);

anders

stroke(200,0,0);

strokeWeight(1.3);

Linie(x, yh, x, yl);

noStroke();

// --- Korps ---

if (closes[i] >= opens[i]) {

// Grüne Kerze

fill(0, 200, 0);

stroke(0, 200, 0);

rect(x - candleW/2, yc, candleW, yo - yc);

} anders {

// Rote Kerze

fill(200, 0, 0);

stroke(200, 0, 0);

rect(x - candleW/2, yo, candleW, yc - yo);

}

boolean baseHistorique = true;

falls ( i > 84)

for (int j = 0; j < 83; j++) {

if (lows[i-j-1] < lows[i]) {

basHistorique = false;

brechen;

}

}

sonst baseHistorique = false;

if (downHistory)

{

//if (rsiC>10 && rsiC < 50-Indikator && basHistorique){

//if (rsiC < 45 && basHistorique){

//if (rsiC < 35 && basHistorique){// && data[i]< prixHaut-20)

// Positioniere den Punkt

float xp = map(i, 0, closes.length - 1, 50, widths-50);

float y = map(lows[i], minP, maxP, height - 50, 50);

fill(255, 0, 0,150);

noStroke();

rect(xp-20, y - 40,40,40);

//ellipse(xp-5, y, 10, 10);

fill(0, 255, 0);

textAlign(CENTER);

//rect(x-decX, y - 8,10,10);

///bas[i]=1;

if ( lows[i] < lows[i-83])

text("LL", xp, y - 10);

anders

text("HL", xp, y - 10);

// bas[i]=1;

// auf einem Unbuy

//CONFIRM= true;

}

boolean HautHistorique = true;

falls ( i > 84)

for (int j = 0; j < 83; j++) {

if (highs[i-j-1] > highs[i]) {

HautHistorique = false;

brechen;

}

}

sonst HautHistorique = false;

if (HautHistorique)

{

//if (rsiC>10 && rsiC < 50-Indikator && basHistorique){

//if (rsiC < 45 && basHistorique){

//if (rsiC < 35 && basHistorique){// && data[i]< prixHaut-20)

// Position, auf die Sie zeigen

float xp = map(i, 0, closes.length - 1, 50, widths-50);

float y = map(highs[i], minP, maxP, height - 50, 50);

fill(255, 255, 0,150);

noStroke();

rect(xp-20, y - 40,40,40);

//ellipse(xp-5, y, 10, 10);

fill(0, 255, 255);

textAlign(CENTER);

//rect(x-decX, y - 8,10,10);

///bas[i]=1;

if ( highs[i] > highs[i-83])

text("HH", xp, y - 10);

anders

text("Hl", xp, y - 10);

// bas[i]=1;

if ( i<990)

{

float xi = map(i+9, 0, closes.length - 1, 50, widths-50);

float yi = map(highs[i+9], minP, maxP, height - 50, 50);

stroke(255,255,0);

line(xp, y, xi,yi);

}

// auf einem Unbuy

//CONFIRM= true;

}

//////////// die kleinen Spitzen

baseHistorique = true;

falls ( i > 9)

for (int j = 0; j < 8; j++) {

if (lows[i-j-1] < lows[i]) {

basHistorique = false;

brechen;

}

}

sonst baseHistorique = false;

if (downHistory)

{

//if (rsiC>10 && rsiC < 50-Indikator && basHistorique){

//if (rsiC < 45 && basHistorique){

//if (rsiC < 35 && basHistorique){// && data[i]< prixHaut-20)

// Positioniere den Punkt

float xp = map(i, 0, closes.length - 1, 50, widths-50);

float y = map(lows[i], minP, maxP, height - 50, 50);

fill(255, 0, 0,150);

noStroke();

//rect(xp-20, y - 40,40,40);

ellipse(xp-5, y, 10, 10);

fill(0, 255, 0);

textAlign(CENTER);

//rect(x-decX, y - 8,10,10);

///bas[i]=1;

// if ( lows[i] < lows[i-83])

//text("LL", xp, y - 10);

//anders

//text("HL", xp, y - 10);

// bas[i]=1;

// auf einem Unbuy

//CONFIRM= true;

}

TopHistorical = true;

falls ( i > 9)

for (int j = 0; j < 8; j++) {

if (highs[i-j-1] > highs[i]) {

HautHistorique = false;

brechen;

}

}

sonst HautHistorique = false;

if (HautHistorique)

{

//if (rsiC>10 && rsiC < 50-Indikator && basHistorique){

//if (rsiC < 45 && basHistorique){

//if (rsiC < 35 && basHistorique){// && data[i]< prixHaut-20)

// Position, auf die Sie zeigen

float xp = map(i, 0, closes.length - 1, 50, widths-50);

float y = map(highs[i], minP, maxP, height - 50, 50);

fill(255, 255, 0,150);

noStroke();

//rect(xp-20, y - 40,40,40);

ellipse(xp-5, y, 10, 10);

fill(0, 255, 255);

textAlign(CENTER);

//rect(x-decX, y - 8,10,10);

///bas[i]=1;

if ( highs[i] > highs[i-7])

text("HH", xp, y - 10);

anders

text("Hl", xp, y - 10);

// bas[i]=1;

/*if ( i<990)

{

float xi = map(i+9, 0, closes.length - 1, 50, widths-50);

float yi = map(highs[i+9], minP, maxP, height - 50, 50);

stroke(255,255,0);

line(xp, y, xi,yi);

}*/

// auf einem Unbuy

//CONFIRM= true;

}

// Die Widerstände, wenn der Preis nicht steigt

detectResistance(i, highs, closes);

}

/*

for (int i = 0; i < closes.length; i++) {

float x = map(i, 0, closes.length - 1, 50, width-50);

//float y = map(closes[i], minP, maxP, height - 50, 50);

float yh = map(highs[i], minP, maxP, height - 50, 50);

float yl = map(lows[i], minP, maxP, height - 50, 50);

fill(0,255,0,123);

rect(x-10, yh,10,yh-yl);

//opens = new float[n];

//highs = new float[n];

//lows = new float[n];

//closes = new float[n];

// Limit-Orders

}

stroke(0,0,255);

stroke(25, 255, 255);

*/

strokeWeight(2);

// --- Clusters de liquidation ---

stroke(255, 0, 0);

for (int i=0; i

float lvl = liquidationClusters.get(i);

float y = map(lvl, minP, maxP, height-50, 50);

line(50, y, widths-50, y);

fill(255, 0, 0);

text("LC x" + clusterCounts.get(i), widths-100, y-5);

}

/*

// --- Stützen und Unterbrechungen ---

for (int i=0; i

float lvl = supports.get(i);

float y = map(lvl, minP, maxP, height-50, 50);

if (supportBroken.get(i)) {

stroke(25, 50, 255); // break = orange

} anders {

stroke(0, 200, 255); // support = vert

}

line(50, y, width-50, y);

}*/

// --- Cluster-Heatmap ---

//drawClusters(minP, maxP);

// --- Cluster-Heatmap ---

drawClusters(minP, maxP);

// --- Stützen (grüne Bereiche) ---

drawSupports(minP, maxP);

// --- Unterbrechungen (dick orangefarbene Bereiche) ---

drawBreaks(minP, maxP);

//detectResistances();

//drawSignals(minP, maxP);

//drawClusters(minPrice, maxPrice);

drawTradeRectangles(closes, highs, lows, minP, maxP);

drawFVG(minP, maxP);

/*

int frIndex = fundingRates.length - 1; // on part du dernier funding rate

// Wir durchlaufen die Kerzen beginnend mit dem Ende

for (int i = closes.length - 1; i >= 0 && frIndex >= 0; i -= 8) {

if (fundingRates[frIndex] < 0) {

float x = map(i, 0, closes.length - 1, 50, widths - 50);

fill(255, 255, 0, 70); // gelb

rect(x-5, 0, 10, height); // gelber Balken an der entsprechenden Kerze

}

frIndex--; // Wir bewegen uns in der Finanzierungstabelle vorwärts.

}

*/

if ( i == "1h")

///// Das Zeichen des Wurms... Entschuldigung, die Shorts... xP

for (int i = 0; i < fundingRates.length; ++i) {

//for (int i = fundingRates.length; i < 1 ; --i) {

int candleIndex = i * 8; // si ech = 1h

if (fundingRates[i] < 0) {

Wir können nur 1000 Franken zurückerhalten.

// float x = map(i*8 , 0, fundingRates.length-1, 50, widths-50);

float x = map(i*8- 600 , 0, closes.length-1, 50, (widths-50) );

float y = Höhe/2;

fill(255, 255, 0, 70); // gelb

//rect(x-5, y-5, 10, 10); // kleines Quadrat

rect(x-5, 0, 10, height); // kleines Auto

textSize(33);

fill(255);

text( "SHORT ", x-5,150);

}

}

textSize(12);

popMatrix();

String[] labels = {"1s", "1m", "3m", "15m","1day","1h,","2h"}; // texte des intervalles

int wld=0;

for ( int i=0;i

{ fill(i*10,255-i*10,i);

rect(i,0,100,100);

fill(0,0,0);

text( labels[wld % labels.length], 40+i,50);

++wld;

}

fill(255,255,255);

text( me, 20, 130);

if ( mouseX < 100 && mouseY < 100 ){

i = "1s";fetchData( symbol );

}

if ( mouseX < 200 && mouseX > 100 && mouseY < 100 ){

i = "1m";fetchData( symbol );

}

if ( mouseX < 300 && mouseX > 200 && mouseY < 100 ){

i = "3m";fetchData( symbol );

}

if ( mouseX < 400 && mouseX > 300 && mouseY < 100 ){

i = "15m";

fetchData( symbol );

}

if ( mouseX < 500 && mouseX > 400 && mouseY < 100 ){

i = "1d";

fetchData( symbol ); ;

}

if ( mouseX < 600 && mouseX > 500 && mouseY < 100 ){

i = "1h";

fetchData( symbol ); ;

}

if ( mouseX < 700 && mouseX > 600 && mouseY < 100 ){

ech = "2h";

fetchData( symbol ); ;

}

if ( mouseX < 900 && mouseX > 670 && mouseY < 100 ){

i = "30m";

fetchData(symbol);

}

//rect(width-100,height-200,100,100);

//rect(width-100,height-100,100,100);

//rect(width-200,0,width,300);

text(symbols[countSymbol],width-150,150);

// textSize(30);

//fill(t13?0:255,t13?255:0,0);

text ("PRIX :" + nf(closes[999],0,2),10,height-220);

rect(width-100,height-200,100,100);

rect(width-100,height-100,100,100);

text ( gapMin, width-30, height-250);

}

// --- DATEN ABRUFEN ---

void fetchData(String symbol) {

//closes = new float[666];//[666]; // r������������init tableau de clôtures

supports.clear(); // Wir leeren die Liste der Stützstellen.

supportBreaks.clear(); // Liste der Pausen löschen

liquidationClusters.clear(); // on vide les clusters de liquidation

clusterCounts.clear();

supportBroken.clear();

String url = "https://api.binance.com/api/v3/klines?symbol=" + symbol + "&interval="+ech+"&limit=2500";

versuchen {

String raw = join(loadStrings(url), "");

candles = parseJSONArray(raw);

int n = candles.size();

println("Kerze = "+ n);

öffnet = neues float[n];

highs = new float[n];

lows = new float[n];

schließt = neues float[n];

Volumen = neue Gleitkommazahl[n];

for (int i = 0; i < n; i++) {

JSONArray c = candles.getJSONArray(i);

opens[i] = float(c.getString(1));

highs[i] = float(c.getString(2));

lows[i] = float(c.getString(3));

closes[i] = float(c.getString(4));

volumes[i] = float(c.getString(5));

// Vereinfachtes Beispiel für die Erkennung

if (supports.size() > 0) {

float lastClose = closes[i];

float prevClose = closes[i-1];

for (int s = supports.size()-1; s >= 0; s--) {

float sprice = supports.get(s);

// Abbruchbedingung: Schließen der Durchläufe unterhalb der Unterstützung

if (prevClose >= target && lastClose < target) {

supportBreaks.add(sprice);

}

}

}

}

prixActuel = closes[n-1];

ATH = max(Schließkurse);

LOW = min(Schlusskurse);

detectClusters();

detectSupports();

detectClustersAndFVG(gapMin);

} catch (Exception e) {

println("API-Fehler: " + e.getMessage());

}

}

float gapMin = 1;

// Klasse zum Speichern von Lücken mit Kerzenindizes

Klasse Lücke {

niedrig, hoch schwimmen;

int startIdx, endIdx; // Kerzenindizes

boolean bullish; // true = bullische Kurslücke, false = bärische Kurslücke

Gap(float l, float h, int start, int end, boolean bullishGap) {

niedrig = l;

hoch = h;

startIdx = start;

endIdx = end;

bullish = bullishGap;

}

}

// Globale Listen für FVG

ArrayList fvgUp = new ArrayList();

ArrayList fvgDn = new ArrayList();

// FVG-Erkennung (vereinfachte und testbare Version)

void detectClustersAndFVG(float gapMin) {

fvgUp.clear();

fvgDn.clear();

for (int i=2; i

// --- FVG bullish ---

if (lows[i] - highs[i-2] > gapMin) {

fvgUp.add(new Gap(highs[i-2], lows[i], i-2, i, true));

//ln("FVG UP:", highs[i-2], "->", lows[i], "indices", i-2, "->", i);

}

// --- FVG bärisch ---

if (lows[i-2] - highs[i] > gapMin) {

fvgDn.add(new Gap(highs[i], lows[i-2], i-2, i, false));

//println("FVG DOWN:", highs[i], "->", lows[i-2], "indices", i-2, "->", i);

}

}

}

// FVG-Zeichnung (horizontale Rechtecke „Kerze zu Kerze“)

void drawFVG(float minP, float maxP) {

noStroke();

// FVG bullish

for (Gap g : fvgUp) {

float x1 = map(g.startIdx, 0, closes.length-1, 50, widths-50);

float x2 = map(g.endIdx, 0, closes.length-1, 50, widths-50);

float y1 = map(g.high, minP, maxP, height-50, 50);

float y2 = map(g.low, minP, maxP, height-50, 50);

fill(0, 255, 0, 90); // vertikal halbtransparent

stroke(0, 180, 0);

rect(x1, min(y1,y2), max(x2-x1, 2)+100, abs(y2-y1)); // Mindestbreite 2px

noStroke();

fill(255);

textAlign(LEFT, CENTER);

text("Long FVG " + nf(g.low,0,2) + "-" + nf(g.high,0,2), x1 + 3, min(y1,y2) + abs(y2-y1)/2);

}

// FVG bärisch

for (Gap g : fvgDn) {

float x1 = map(g.startIdx, 0, closes.length-1, 50, widths-50);

float x2 = map(g.endIdx, 0, closes.length-1, 50, widths-50);

float y1 = map(g.high, minP, maxP, height-50, 50);

float y2 = map(g.low, minP, maxP, height-50, 50);

fill(0, 100, 255, 90); // halbtransparentes Blau

stroke(0, 0, 180);

rect(x1, min(y1,y2), max(x2-x1, 2)+100, abs(y2-y1)); // Mindestbreite 2px

noStroke();

fill(255);

textAlign(LEFT, CENTER);

text("Short FVG " + nf(g.low,0,2) + "-" + nf(g.high,0,2), x1 + 3, min(y1,y2) + abs(y2-y1)/2);

}

}

/*

Wir speichern die Lücken als Paare (niedrig, hoch).

Klasse Lücke {

niedrig, hoch schwimmen;

Gap(float l, float h) {

niedrig = l;

hoch = h;

}

}

ArrayList fvgUp = new ArrayList();

ArrayList fvgDn = new ArrayList();

void detectClustersAndFVG() {

liquidationClusters.clear();

clusterCounts.clear();

fvgUp.clear();

fvgDn.clear();

// einfacher Durchschnitt des Volumens

float volMA = 0;

for (int i=0; i

volMA += volumes[i];

}

volMA /= volumes.length;

for (int i=0; i

float body = abs(closes[i]-opens[i]);

Float-Kerze = Hochs[i]-Tiefs[i];

float wickUp = highs[i]-max(opens[i], closes[i]);

float wickDn = min(opens[i], closes[i]) - lows[i];

// --- Clustererkennungs-Liquidation ---

if (volumes[i] > volMA*volMult && candle > 0 && body/candle <= minBodyRatio) {

float liquidPrice = Float.NaN;

if (wickUp/candle >= wickRatio) liquidPrice = highs[i];

else if (wickDn/candle >= wickRatio) liquidPrice = lows[i];

if (!Float.isNaN(liquidPrice)) addCluster(liquidPrice);

}

*/

/*

// --- Erkennung von Fair-Value-Gaps (FVG) ---

if (i >= 2) {

// Aufwärtstrend FVG (aktuelles Tief > Hoch von vor 2 Kerzen)

if (lows[i] > highs[i-2]) {

//fvgUp.add(new Gap(highs[i-2], lows[i]));

fvgUp.add(new Gap(highs[i-2], lows[i]));

//fvgDn.add(new Gap(highs[i], lows[i-2]));

}

// FVG bärisch (aktuelles Hoch < Tief von vor 2 Kerzen)

if (highs[i] < lows[i-2]) {

// fvgDn.add(new Gap(highs[i], lows[i-2]));

// fvgUp.add(new Gap(highs[i-2], lows[i]));

fvgDn.add(new Gap(highs[i], lows[i-2]));

}

}

*/

/*

float gapMin = 1000; // Mindesttoleranz für die Berücksichtigung eines FVG

if (i >= 2) {

// FVG bullish

if (lows[i] - highs[i-2] > gapMin) {

fvgUp.add(new Gap(highs[i-2], lows[i]));

println("FVG UP:", highs[i-2], "->", lows[i]);

}

// FVG bärisch

if (lows[i-2] - highs[i] > gapMin) {

fvgDn.add(new Gap(highs[i], lows[i-2]));

println("FVG DOWN:", highs[i], "->", lows[i-2]);

}

}

}

}

void drawFVG(float minP, float maxP) {

noStroke();

// FVG bullish green

for (Gap g : fvgUp) {

float y1 = map(g.high, minP, maxP, height-50, 50);

float y2 = map(g.low, minP, maxP, height-50, 50);

stroke(255);

fill(0, 255, 0); // vertikal transparent

rect(50, y1, widths-100, y2-y1);

fill(0, 180);

text("FVG" + nf(g.low,0,2)+"-"+nf(g.high,0,2), widths-490, y1+12);

}

// FVG bärisch blau

for (Gap g : fvgDn) {

float y1 = map(g.high, minP, maxP, height-50, 50);

float y2 = map(g.low, minP, maxP, height-50, 50);

stroke(255,0,0);

fill(0, 100, 255); // blau transparent

rect(50, y1, widths-100, y2-y1);

fill(0, 180);

text("FVG" + nf(g.low,0,2)+"-"+nf(g.high,0,2), widths-490, y1+12);

}

}

*/

// --- Liquidationscluster erkennen ---

void detectClusters() {

liquidationClusters.clear();

clusterCounts.clear();

// einfacher Durchschnitt des Volumens

float volMA = 0;

for (int i=0; i

volMA += volumes[i];

}

volMA /= volumes.length;

for (int i=0; i

float body = abs(closes[i]-opens[i]);

Float-Kerze = Hochs[i]-Tiefs[i];

float wickUp = highs[i]-max(opens[i], closes[i]);

float wickDn = min(opens[i], closes[i]) - lows[i];

if (volumes[i] > volMA*volMult && candle > 0 && body/candle <= minBodyRatio) {

float liquidPrice = Float.NaN;

if (wickUp/candle >= wickRatio) liquidPrice = highs[i];

else if (wickDn/candle >= wickRatio) liquidPrice = lows[i];

if (!Float.isNaN(liquidPrice)) addCluster(liquidPrice);

}

}

}

// --- Gruppierung nahe beieinander liegender Cluster ---

void addCluster(float price) {

for (int i=0; i

if (abs(liquidationClusters.get(i) - price) <= proximityPts) {

// Inkrement

clusterCounts.set(i, clusterCounts.get(i)+1);

zurückkehren;

}

}

liquidationClusters.add(price);

clusterCounts.add(1);

}

// --- Stützen und Unterbrechungen erkennen ---

void detectSupports() {

supports.clear();

supportBroken.clear();

for (int i=pivotLeft; i

boolean isPivot = true;

for (int j=1; j<=pivotLeft; j++) if (lows[i] >= lows[i-j]) isPivot=false;

for (int j=1; j<=pivotRight; j++) if (lows[i] >= lows[i+j]) isPivot=false;

if (isPivot) {

float s = lows[i];

supports.add(s);

// brechen?

boolean broken = (closes[closes.length-1] < s);

supportBroken.add(broken);

}

}

}

// --- Liquidationscluster in der Heatmap ---

void drawClusters(float minP, float maxP) {

noStroke();

for (int i=0; i

float lvl = liquidationClusters.get(i);

int count = clusterCounts.get(i);

// Preiszuordnung zu y

float y = map(lvl, minP, maxP, height-50, 50);

// Intensität proportional zur Anzahl der Vorkommen

int alpha = constrain(40 + count*30, 40, 200);

int rectHeight = 6 + count*2; // ��������paisseur de zone

fill(255, 0, 0, alpha);

rect(50, y - rectHeight/2, widths-100, rectHeight);

// diskreter Text auf der rechten Seite

fill(255, 200);

text(lvl+ " Liquidationscluster x" + count, widths-490, y-5);

}

}

// --- Stützen (grüne Bereiche) ---

void drawSupports(float minP, float maxP) {

noStroke();

for (int i=0; i

float lvl = supports.get(i);

float y = map(lvl, minP, maxP, height-50, 50);

fill(0, 200, 0, 100); // durchscheinendes Grün

rect(50, y-3, widths-100, 6);

fill(0, 255, 0);

text(lvl+" Support", 60, y-5);

}

}

// --- Stützstellen (dick orangefarbene Bereiche) ---

void drawBreaks(float minP, float maxP) {

noStroke();

for (int i=0; i

float lvl = supportBreaks.get(i);

float y = map(lvl, minP, maxP, height-50, 50);

fill(255, 140, 0, 150); // orange halbtransparent

rect(50, y-4, widths-100, 8);

fill(255, 180, 0);

text("Support Break", 60, y-6);

}

}

///////#######

// --- Clusteranalyse für Kauf-/Verkaufsgebiete ---

float clusterZoneMargin = 5f; // Rand um den Cluster, um die Zone zu zeichnen

void drawClusterZones(float minP, float maxP) {

for (int i=0; i

float lvl = liquidationClusters.get(i);

int count = clusterCounts.get(i);

// Zuordnung Preis -> und

float y = map(lvl, minP, maxP, height-50, 50);

// Farben nach Trend definieren (z. B. starke Hervorhebungen = Verkauf, schwache Hervorhebungen = Kauf)

float wickUp = highs[i] - max(opens[i], closes[i]);

float wickDn = min(opens[i], closes[i]) - lows[i];

boolean isBuyZone = wickDn > wickUp; // größerer unterer Docht

boolean isSellZone = wickUp > wickDn; // größerer, höherer Docht

// Deckkraft und Dicke entsprechend der Anzahl der Vorkommen anpassen

int alpha = constrain(60 + count*30, 60, 200);

int rectHeight = 6 + count*2;

if (isBuyZone) {

fill(0, 0, 255, alpha);

rect(50, y - clusterZoneMargin, widths-100, clusterZoneMargin*2);

fill(0, 0, 255);

text("Achat x"+count, widths-180, y);

}

if (isSellZone) {

fill(255, 0, 0, alpha);

rect(50, y - clusterZoneMargin, widths-100, clusterZoneMargin*2);

fill(255, 0, 0);

text("Vente x"+count, widths-180, y);

}

}

}

////////€€

// --- Einstellungen ---

float rsiOverbought = 70f;

float rsiOversold = 45f;

int rsiLength = 27; // RSI-Länge

int shortTrendLength = 33; // Anzahl der Kerzen zur Berechnung des kurzfristigen Trends

float rectMargin = 10f; // Rechteckdicke

// --- Einfache RSI-Berechnung ---

float calcRSI(float[] closes, int idx, int length) {

if (idx < length) return 50; // neutraler Wert, falls nicht genügend Daten vorhanden sind

Gleitkomma-Gewinn = 0, Verlust = 0;

for (int i=idx-length+1; i<=idx; i++) {

float diff = closes[i] - closes[i-1];

if (diff > 0) gain += diff;

sonst Verlust -= Differenz;

}

if (loss == 0) return 100;

Rückgabe 100 - (100 / (1 + Gewinn/Verlust));

}

// --- Kurzfristige Trendanalyse ---

boolean isShortDowntrend(float[] closes, int idx, int len) {

if (idx < len) return false;

return closes[idx] < closes[idx-len];

}

boolean isShortUptrend(float[] closes, int idx, int len) {

if (idx < len) return false;

return closes[idx] > closes[idx-len];

}

void drawTradeRectangles(float[] closes, float[] highs, float[] lows, float minP, float maxP) {

for (int i=shortTrendLength; i

float rsi = calcRSI(closes, i, rsiLength);

// Berechnung der X-Position anhand der Zeitachse

float x = map(i, 0, closes.length-1, 50, widths-50);

// --- Verkaufssignal ---

if (rsi >= rsiOverbought && isShortDowntrend(closes, i, shortTrendLength)) {

float recentHigh = highs[i];

float y = map(recentHigh, minP, maxP, height-50, 50);

fill(255, 0, 0, 80);

rect(x-10, y-rectMargin, 20, rectMargin*2); // Rechteck zentriert auf x

fill(255, 0, 0);

text("S", x, y-rectMargin-5); // Text direkt über dem Rechteck

}

// --- Kaufsignal ---

if (rsi <= rsiOversold && isShortUptrend(closes, i, shortTrendLength)) {

float recentLow = lows[i];

float y = map(recentLow, minP, maxP, height-50, 50);

fill(0, 0, 255, 80);

rect(x-10, y-rectMargin, 20, rectMargin*2); // Rechteck zentriert auf x

fill(0, 0, 255);

text("B", x, y-rectMargin-5); // Text direkt über dem Rechteck

}

}

}