// --- VARIABEL GLOBAL ---

JSONArray lilin;

float[] buka, tinggi, rendah, tutup, volume;

float hargaSaatIni, ATH , RENDAH= 0;

String ech = "1m";

ArrayList klusterLikuidasi = new ArrayList();

ArrayList jumlahKluster = new ArrayList();

//ArrayList dukungan = new ArrayList();

ArrayList dukunganPatah = new ArrayList();

int acak= 0;

ArrayList dukungan = new ArrayList();

ArrayList pemutusanDukungan = new ArrayList();

String simbol = "BTCUSDT";

int hitungSimbol=1;

String[] simbol = {

"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); // Tingkat pendanaan 1000 denier

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

float[] rates = new float[limit];

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

mencoba {

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

JSONArray arr = parseJSONArray(raw);

println(" nama pendanaan : "+ arr.size());

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

JSONObject obj = arr.getJSONObject(i);

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

jika ( rates[i] < 0) println( " terdeteksi");

}

} catch(Exception e) {

println("Error fetchFundingRates: " + e);

}

tingkat pengembalian;

}

// --- PARAMETER (seperti input Pine Anda) ---

int lookbackVol = 50;

float volMult = 2.5;

float wickRatio = 0.6f;

float minBodyRatio = 0.1f;

float proximityPts = 20f; // toleransi untuk pengelompokan klaster

int pivotLeft = 5;

int pivotRight = 5;

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

int lastUpdate = 0;

lebar bilangan bulat;

// --- Perhitungan EMA ---

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

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

float alpha = 2.0 / (periode + 1.0);

// Inisialisasi: kita mulai dengan nilai mentah pertama

ema[0] = data[0];

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

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

}

balasan email;

}

// --- PENGATURAN ---

void setup() {

//ukuran(1200, 800);

fullScreen();

//ukuran(int(lebar tampilan*2),int(tinggi tampilan));

simbol = simbol[jumlahSimbol];

ambilData( simbol );

lebar = int(lebar * 8.7); // 8.1

fundingRates = fetchFundingRates(symbol, 1000); // 1000 suku bunga pendanaan terakhir

//frameRate(1);

// Ubah simbol jika Anda mau

}

float startDist;

float zoom = 1.0;

offsetX mengambang = 0;

offsetY mengambang = 0;

void touchStarted() {

jika (panjang sentuhan == 2) {

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

}

}

void touchMoved() {

jika (panjang sentuhan == 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); // membatasi zoom

startDist = newDist;

} jika (touches.length == 1) {

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

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

}

}

// Seret dengan mouse (berguna untuk pengujian di PC)

void mouseDragged() {

offsetX += (mouseX - pmouseX) / zoom;

offsetY += (mouseY - pmouseY) / zoom;

jika ( mouseX < lebar && mouseX > lebar-100 && mouseY > tinggi-200 && mouseY < tinggi-100){

++gapMin;

}

jika (mouseX < lebar && mouseX > lebar-100 && mouseY > tinggi-100 && mouseY < tinggi){

--gapMin;

}

}

void mousePressed()

{

//++countSymbol;

//isi(255);

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

jika ( mouseX > lebar - 200 && mouseY < 300 && mouseY > 100 )

++countSymbol;

jika ( mouseX > lebar - 200 && mouseY < 500 && mouseY > 300 )

--countSymbol;

jika (countSymbol<0)

countSymbol =0;

jika (countSymbol>101)

countSymbol =0;

//teks(simbol[jumlahSimbol],lebar-150,150);

simbol = simbol[jumlahSimbol];

}

void mouseReleased()

{

jika ( mouseX < lebar && mouseX > lebar-100 && mouseY > tinggi-200 && mouseY < tinggi-100){

++gapMin;

}

jika (mouseX < lebar && mouseX > lebar-100 && mouseY > tinggi-100 && mouseY < tinggi){

--gapMin;

}

}

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

jika (i < periode) kembalikan 50; // nilai default jika data tidak cukup

float gain = 0, loss = 0;

untuk (int j = 1; j <= periode; j++) {

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

jika (perubahan > 0) perolehan += perubahan;

jika tidak, kerugian -= perubahan;

}

float avgGain = gain / period;

float avgLoss = kerugian / periode;

jika (avgLoss == 0) kembalikan 100; // RSI maksimum jika tidak ada kerugian

float rs = avgGain / avgLoss;

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

}

int n = 30; // ukuran jendela

toleransi float = 100.5; // margin untuk menunjukkan "mencapai batas atas"

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

jika (i < n) kembalikan; // belum cukup data

// Kita mengambil nilai maksimum dari n candle terakhir

float maxRecent = highs[i];

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

jika (nilai tertinggi[i - j] > nilai terbaru maksimum) {

maxRecent = highs[i - j];

}

}

// Kami menghitung berapa kali harga "mendekati" nilai maksimum.

int touches = 0;

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

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

sentuhan++;

}

}

// Perhitungan RSI tidak akan ditampilkan

// jual di harga terendah

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

// Jika sering terjadi tetapi suhunya tidak melebihi 100°C, beri sinyal

jika (sentuhan > 2 && closes[i] < highs[i] - toleransi && 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);

isi(255, 255, 0, 150);

tidak ada stroke();

persegi panjang (xp, y, 30, 15);

//isi(255);

textAlign(CENTER);

teks("SINGKAT ×100", xp, y - 10);

}

}

// --- LOOP GAMBAR ---

void draw() {

acak = 0;

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

//fetchData(symbol); // Kita memperbarui data

/*closes = new float[666]; // mengatur ulang array closures

supports.clear(); // Hapus daftar dukungan

supportBreaks.clear(); // hapus daftar breakpoint

liquidationClusters.clear(); // kita melihat cluster likuidasi

clusterCounts.clear();

supportBroken.clear();*/

simbol = simbol[jumlahSimbol];

ambilData( simbol );

lastUpdate = millis(); // Kita mengatur ulang penghitung ke nol

}

dorongMatriks();

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

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

skala(zoom);

//fetchData("BTCUSDT");

latar belakang(20);

langkah(255);

isi(200);

// Batasan vertikal untuk penskalaan

float maxP = max(closes);;

float minP = min(closes);

/*

untuk (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);

isi(255, 25, 255, 150);

tidak ada stroke();

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

}

untuk (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);

isi(25, 255, 255, 150);

tidak ada stroke();

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

}

*/

// --- BERIKUTNYA ---

langkah(255, 255, 0);

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

baris(50, yaTH, lebar-50, yaTH);

isi(255, 255, 0);

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

isi(255,0,0,55);persegi panjang(50,yATH,lebar,100);

// --- BERIKUTNYA ---

langkah(25, 255, 255);

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

baris(50, yaTH, lebar-50, yaTH);

isi(255, 255, 0);

teks("RENDAH " + RENDAH, 55, yATH-5);

isi(0,255,0,55);persegi panjang(50,yATH,lebar,-100);

// Grafik harga (grafik garis penutupan)

/*

untuk (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);

langkah(180);

strokeWeight(2);

garis(x1, y1, x2, y2);

opens = new float[n];

nilai tertinggi = float baru[n];

rendah = float baru[n];

menutup = float baru[n];

}*/

strokeWeight(1.3);

isi(223,12);

beginShape();

untuk (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);

titik sudut (x, y);

// pesanan batas

}

akhir bentuk();

tidak ada stroke();

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

strokeWeight(3);

noFill();

untuk (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);

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

stroke(0, 255, 0); // vertikal jika ke atas

} kalau tidak {

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

}

garis(x1 , y1, x2 , y2);

}

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

strokeWeight(3);

noFill();

untuk (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);

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

stroke(0, 255, 0); // vertikal jika ke atas

} kalau tidak {

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

}

garis(x1 , y1, x2 , y2);

}

/*

// lebar setiap lilin + spasi

lilin mengambangW = 5;

float spacing = 2; // jarak antar lilin

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

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

// X dengan spasi teratur

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

// pemetaan 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);

// --- Sumbu ---

stroke(200);

garis(x, yh, x, yl);

// --- Korps ---

jika (menutup[i] >= membuka[i]) {

isi(0, 200, 0);

langkah(0, 200, 0);

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

} kalau tidak {

isi(200, 0, 0);

langkah(200, 0, 0);

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

}

}

*/

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

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

// pemetaan 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);

// lebar lilin

float candleW = 4.5;

// --- Sumbu ---

jika (menutup[i] >= membuka[i])

// Lilin hijau

langkah(0,200,0);

kalau tidak

langkah(200,0,0);

strokeWeight(1.3);

garis(x, yh, x, yl);

tidak ada stroke();

// --- Korps ---

jika (menutup[i] >= membuka[i]) {

// Lilin hijau

isi(0, 200, 0);

langkah(0, 200, 0);

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

} kalau tidak {

// Lilin merah

isi(200, 0, 0);

langkah(200, 0, 0);

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

}

boolean baseHistorique = true;

jika (i > 84)

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

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

basHistorique = false;

merusak;

}

}

jika tidak, baseHistorique = false;

jika (downHistory)

{

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

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

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

// Posisikan titik

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

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

isi(255, 0, 0,150);

tidak ada stroke();

persegi panjang (xp-20, y - 40,40,40);

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

isi(0, 255, 0);

textAlign(CENTER);

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

///bas[i]=1;

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

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

kalau tidak

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

// bas[i]=1;

// pada pembelian yang tidak dilakukan

//KONFIRMASI= benar;

}

boolean HautHistorique = true;

jika (i > 84)

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

jika (tinggi[i-j-1] > tinggi[i]) {

HautHistorique = false;

merusak;

}

}

jika tidak, HautHistorique = false;

jika (HautHistorique)

{

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

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

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

// Posisikan titik

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

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

isi(255, 255, 0,150);

tidak ada stroke();

persegi panjang (xp-20, y - 40,40,40);

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

isi(0, 255, 255);

textAlign(CENTER);

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

///bas[i]=1;

jika (tinggi[i] > tinggi[i-83])

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

kalau tidak

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

// bas[i]=1;

jika ( i<990)

{

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

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

langkah(255,255,0);

baris(xp,y,xi,yi);

}

// pada pembelian yang tidak dilakukan

//KONFIRMASI= benar;

}

//////////// puncak-puncak kecil

baseHistorique = true;

jika ( i > 9)

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

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

basHistorique = false;

merusak;

}

}

jika tidak, baseHistorique = false;

jika (downHistory)

{

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

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

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

// Posisikan titik

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

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

isi(255, 0, 0,150);

tidak ada stroke();

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

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

isi(0, 255, 0);

textAlign(CENTER);

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

///bas[i]=1;

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

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

//kalau tidak

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

// bas[i]=1;

// pada pembelian yang tidak dilakukan

//KONFIRMASI= benar;

}

TopHistorical = true;

jika ( i > 9)

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

jika (tinggi[i-j-1] > tinggi[i]) {

HautHistorique = false;

merusak;

}

}

jika tidak, HautHistorique = false;

jika (HautHistorique)

{

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

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

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

// Posisikan titik

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

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

isi(255, 255, 0,150);

tidak ada stroke();

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

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

isi(0, 255, 255);

textAlign(CENTER);

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

///bas[i]=1;

jika (tinggi[i] > tinggi[i-7])

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

kalau tidak

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

// bas[i]=1;

/*jika ( i<990)

{

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

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

langkah(255,255,0);

baris(xp,y,xi,yi);

}*/

// pada pembelian yang tidak dilakukan

//KONFIRMASI= benar;

}

// Hambatan ketika harga gagal naik

deteksiResistensi(i, highs, closes);

}

/*

untuk (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);

isi(0,255,0,123);

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

//opens = new float[n];

//nilai tertinggi = float baru[n];

//lows = new float[n];

//menutup = float baru[n];

// pesanan batas

}

goresan(0,0,255);

langkah(25, 255, 255);

*/

strokeWeight(2);

// --- Likuidasi Klaster ---

langkah(255, 0, 0);

untuk (int i=0; i

float lvl = liquidationClusters.get(i);

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

garis(50, y, lebar-50, y);

isi(255, 0, 0);

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

}

/*

// --- Mendukung dan memutus ---

untuk (int i=0; i

float lvl = supports.get(i);

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

jika (supportBroken.get(i)) {

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

} kalau tidak {

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

}

garis(50, y, lebar-50, y);

}*/

// --- Peta Panas Klaster ---

//drawClusters(minP, maxP);

// --- Peta Panas Klaster ---

menggambar Klaster(minP, maxP);

// --- Mendukung (area hijau) ---

menggambar Dukungan (minP, maxP);

// --- Jeda (area oranye tebal) ---

drawBreaks(minP, maxP);

//deteksiResistansi();

//drawSignals(minP, maxP);

//drawClusters(minPrice, maxPrice);

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

gambarFVG(minP, maxP);

/*

int frIndex = fundingRates.length - 1; // pada bagian tingkat pendanaan terakhir

// Kita melakukan perulangan melalui lilin-lilin mulai dari ujung.

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

jika (fundingRates[frIndex] < 0) {

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

isi(255, 255, 0, 70); // kuning

rect(x-5, 0, 10, height); // batang kuning pada candle yang sesuai

}

frIndex--; // kita bergerak maju dalam tabel pendanaan

}

*/

jika ( i == "1 jam")

///// tanda cacing... maaf, celana pendek... xP

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

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

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

jika (fundingRates[i] < 0) {

// Kami hanya dapat memulihkan 1000 franc

// 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 = tinggi/2;

isi(255, 255, 0, 70); // kuning

//rect(x-5, y-5, 10, 10); // persegi kecil

rect(x-5, 0, 10, height); // petit carré

Ukuran teks(33);

isi(255);

teks("PENDEK", x-5,150);

}

}

Ukuran teks(12);

popMatrix();

String[] labels = {"1s", "1m", "3m", "15m","1day","1h","2h"}; // teks interval

int wld=0;

untuk (int i=0;i)

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

persegi panjang(i,0,100,100);

isi(0,0,0);

teks( label[wld % label.length], 40+i,50);

++wld;

}

isi(255,255,255);

teks(saya, 20, 130);

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

i = "1s";ambilData( simbol );

}

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

i = "1m";ambilData( simbol );

}

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

i = "3m";ambilData( simbol );

}

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

i = "15m";

ambilData( simbol );

}

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

i = "1d";

fetchData( symbol ); ;

}

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

i = "1 jam";

fetchData( symbol ); ;

}

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

ech = "2 jam";

fetchData( symbol ); ;

}

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

i = "30m";

ambilData(simbol);

}

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

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

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

teks(simbol[jumlahSimbol],lebar-150,150);

// textSize(30);

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

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

persegi panjang(lebar-100,tinggi-200,100,100);

persegi panjang(lebar-100,tinggi-100,100,100);

teks (gapMin, lebar-30, tinggi-250);

}

// --- MENGAMBIL DATA ---

void fetchData(String symbol) {

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

supports.clear(); // Kita menghapus daftar dukungan

supportBreaks.clear(); // hapus daftar breakpoint

liquidationClusters.clear(); // kita melihat cluster likuidasi

clusterCounts.clear();

supportBroken.clear();

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

mencoba {

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

lilin = parseJSONArray(raw);

int n = candles.size();

println("lilin = "+ n);

opens = new float[n];

nilai tertinggi = float baru[n];

rendah = float baru[n];

menutup = float baru[n];

volume = float baru[n];

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

JSONArray c = candles.getJSONArray(i);

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

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

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

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

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

// Contoh deteksi yang disederhanakan

jika (supports.size() > 0) {

float lastClose = closes[i];

float prevClose = closes[i-1];

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

float sprice = supports.get(s);

// Kondisi berhenti: lintasan tertutup di bawah penyangga

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

supportBreaks.add(harga);

}

}

}

}

prixActuel = closes[n-1];

ATH = max(closes);

RENDAH = min(penutupan);

mendeteksiKluster();

mendeteksi Dukungan();

deteksiKlusterDanFVG(gapMin);

} catch (Exception e) {

println("Kesalahan API: " + e.getMessage());

}

}

float gapMin = 1;

// Kelas untuk menyimpan gap dengan indeks candlestick

kelas Gap {

mengapung rendah, tinggi;

int startIdx, endIdx; // indeks lilin

boolean bullish; // true = gap bullish, false = bearish

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

rendah = l;

tinggi = h;

startIdx = start;

endIdx = end;

bullish = bullishGap;

}

}

// Daftar global untuk FVG

ArrayList fvgUp = new ArrayList();

ArrayList fvgDn = new ArrayList();

// Deteksi FVG (versi sederhana dan dapat diuji)

void detectClustersAndFVG(float gapMin) {

fvgUp.clear();

fvgDn.clear();

untuk (int i=2; i

// --- FVG bullish ---

jika (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 bearish ---

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

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

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

}

}

}

// Gambar FVG (persegi panjang horizontal "dari lilin ke lilin")

void drawFVG(float minP, float maxP) {

tidak ada stroke();

// FVG bullish

untuk (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); // vert semi-transparan

langkah(0, 180, 0);

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

tidak ada stroke();

isi(255);

textAlign(LEFT, CENTER);

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

}

// FVG bearish

untuk (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); // biru semi-transparan

langkah(0, 0, 180);

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

tidak ada stroke();

isi(255);

textAlign(LEFT, CENTER);

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

}

}

/*

Kami menyimpan selisihnya sebagai pasangan (rendah, tinggi)

kelas Gap {

mengapung rendah, tinggi;

Gap(float l, float h) {

rendah = l;

tinggi = h;

}

}

ArrayList fvgUp = new ArrayList();

ArrayList fvgDn = new ArrayList();

void detectClustersAndFVG() {

liquidationClusters.clear();

clusterCounts.clear();

fvgUp.clear();

fvgDn.clear();

// rata-rata sederhana dari volume

float volMA = 0;

untuk (int i=0; i

volMA += volume[i];

}

volMA /= volume.panjang;

untuk (int i=0; i

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

float candle = highs[i]-lows[i];

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

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

// --- Likuidasi deteksi klaster ---

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

Harga cair mengambang = Float.NaN;

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

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

jika (!Float.isNaN(liquidPrice)) tambahkan Cluster(liquidPrice);

}

*/

/*

// --- Deteksi Kesenjangan Nilai Wajar (FVG) ---

jika (i >= 2) {

// FVG Bullish (terendah saat ini > tertinggi 2 candle sebelumnya)

jika (nilai terendah[i] > nilai tertinggi[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 bearish (harga tertinggi saat ini < harga terendah 2 candle sebelumnya)

jika (tinggi[i] < rendah[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; // toleransi minimum untuk mempertimbangkan FVG

jika (i >= 2) {

// FVG bullish

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

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

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

}

// FVG bearish

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

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

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

}

}

}

}

void drawFVG(float minP, float maxP) {

tidak ada stroke();

// FVG bullish hijau

untuk (Gap g : fvgUp) {

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

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

langkah(255);

isi(0, 255, 0); // transparan vertikal

persegi panjang(50, y1, lebar-100, y2-y1);

isi(0, 180);

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

}

// Beruang biru FVG

untuk (Gap g : fvgDn) {

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

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

langkah(255,0,0);

isi(0, 100, 255); // biru transparan

persegi panjang(50, y1, lebar-100, y2-y1);

isi(0, 180);

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

}

}

*/

// --- MENDETEKSI KLUSTER LIKUIDASI ---

void detectClusters() {

liquidationClusters.clear();

clusterCounts.clear();

// rata-rata sederhana dari volume

float volMA = 0;

untuk (int i=0; i

volMA += volume[i];

}

volMA /= volume.panjang;

untuk (int i=0; i

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

float candle = highs[i]-lows[i];

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

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

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

Harga cair mengambang = Float.NaN;

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

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

jika (!Float.isNaN(liquidPrice)) tambahkan Cluster(liquidPrice);

}

}

}

// --- Kelompokkan klaster terdekat ---

void addCluster(float price) {

untuk (int i=0; i

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

// tambah

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

kembali;

}

}

liquidationClusters.add(price);

clusterCounts.add(1);

}

// --- DETEKSI DUKUNGAN + PEMUTUSAN ---

void detectSupports() {

mendukung.bersihkan();

supportBroken.clear();

untuk (int i=pivotLeft; i

boolean isPivot = true;

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

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

jika (isPivot) {

float s = lows[i];

mendukung.menambahkan;

// merusak?

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

supportBroken.add(broken);

}

}

}

// --- Klaster likuidasi dalam peta panas ---

void drawClusters(float minP, float maxP) {

tidak ada stroke();

untuk (int i=0; i

float lvl = liquidationClusters.get(i);

int count = clusterCounts.get(i);

// pemetaan harga ke y

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

// Intensitas sebanding dengan jumlah kemunculan

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

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

isi(255, 0, 0, alpha);

persegi panjang(50, y - tinggi persegi panjang/2, lebar-100, tinggi persegi panjang);

// teks tersembunyi di sebelah kanan

isi(255, 200);

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

}

}

// --- Mendukung (area hijau) ---

void drawSupports(float minP, float maxP) {

tidak ada stroke();

untuk (int i=0; i

float lvl = supports.get(i);

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

fill(0, 200, 0, 100); // hijau transparan

persegi panjang(50, y-3, lebar-100, 6);

isi(0, 255, 0);

teks(lvl+" Dukungan", 60, y-5);

}

}

// --- Garis penyangga (area oranye tebal) ---

void drawBreaks(float minP, float maxP) {

tidak ada stroke();

untuk (int i=0; i

float lvl = supportBreaks.get(i);

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

fill(255, 140, 0, 150); // oranye semi-buram

persegi panjang(50, y-4, lebar-100, 8);

isi(255, 180, 0);

teks("Dukungan Jeda", 60, y-6);

}

}

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

// --- Analisis klaster untuk area jual beli ---

float clusterZoneMargin = 5f; // margin di sekitar cluster untuk menggambar zona

void drawClusterZones(float minP, float maxP) {

untuk (int i=0; i

float lvl = liquidationClusters.get(i);

int count = clusterCounts.get(i);

// Memetakan harga -> dan

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

// Tentukan warna sesuai tren (misalnya, highlight tinggi = diskon, highlight rendah = pembelian)

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

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

boolean isBuyZone = wickDn > wickUp; // sumbu bawah lebih besar

boolean isSellZone = wickUp > wickDn; // sumbu lebih besar dan lebih tinggi

// Sesuaikan opasitas dan ketebalan sesuai dengan jumlah kemunculannya

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

int rectHeight = 6 + count*2;

jika (isBuyZone) {

isi(0, 0, 255, alpha);

persegi panjang(50, y - clusterZoneMargin, lebar-100, clusterZoneMargin*2);

isi(0, 0, 255);

teks("Beli x"+jumlah, lebar-180, y);

}

jika (isSellZone) {

isi(255, 0, 0, alpha);

persegi panjang(50, y - clusterZoneMargin, lebar-100, clusterZoneMargin*2);

isi(255, 0, 0);

teks("Ventilasi x"+jumlah, lebar-180, y);

}

}

}

////////€€

// --- Pengaturan ---

float rsiOverbought = 70f;

float rsiOversold = 45f;

int rsiLength = 27; // Panjang RSI

int shortTrendLength = 33; // jumlah candle untuk menghitung tren pendek

float rectMargin = 10f; // ketebalan persegi panjang

// --- Perhitungan RSI sederhana ---

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

jika (idx < length) kembalikan 50; // nilai netral jika data tidak cukup

float gain = 0, loss = 0;

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

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

jika (selisih > 0) maka gain += selisih;

jika tidak, kerugian -= selisih;

}

jika (kerugian == 0) kembalikan 100;

kembalikan 100 - (100 / (1 + keuntungan/kerugian));

}

// --- Deteksi tren jangka pendek ---

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

jika (idx < len) kembalikan false;

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

}

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

jika (idx < len) kembalikan false;

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

}

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

untuk (int i=panjangTrenpendek; i

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

// Menghitung posisi X sesuai dengan garis waktu

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

// --- Sinyal penjualan ---

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

float recentHigh = highs[i];

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

isi(255, 0, 0, 80);

rect(x-10, y-rectMargin, 20, rectMargin*2); // persegi panjang berpusat di x

isi(255, 0, 0);

teks("S", x, y-rectMargin-5); // teks tepat di atas persegi panjang

}

// --- Sinyal beli ---

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

float recentLow = lows[i];

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

isi(0, 0, 255, 80);

rect(x-10, y-rectMargin, 20, rectMargin*2); // persegi panjang berpusat di x

isi(0, 0, 255);

teks("B", x, y-rectMargin-5); // teks tepat di atas persegi panjang

}

}

}