// --- VARIABEL GLOBAL ---
JSONArray lilin;
float[] buka, tinggi, rendah, tutup, volume;
float prixActuel, ATH , LOW= 0;
String ech = "1m";
ArrayList<Float> kelompokLikuidasi = new ArrayList<Float>();
ArrayList<Integer> jumlahKluster = new ArrayList<Integer>();
//ArrayList<Float> supports = new ArrayList<Float>();
ArrayList<Boolean> dukunganPecah = new ArrayList<Boolean>();
int acak= 0;
ArrayList<Float> supports = new ArrayList<Float>();
ArrayList<Float> dukunganPecah = new ArrayList<Float>();
String simbol = "BTCUSDT";
int countSymbol=1;
String[] symbols = {
"BTCUSDT", "PAXGUSDT", "BTCUSDC", "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<Float> resistances = new ArrayList<Float>();
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(); // Kita menghapus 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<closes.length; 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);
// order limit
}
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 penunjuk Anda
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 penunjuk Anda
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 penunjuk Anda
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<liquidationClusters.size(); 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<supports.size(); 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<width;i=i+100)
{ 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<Gap> fvgUp = new ArrayList<Gap>();
ArrayList<Gap> fvgDn = new ArrayList<Gap>();
// Deteksi FVG (versi sederhana dan dapat diuji)
void detectClustersAndFVG(float gapMin) {
fvgUp.clear();
fvgDn.clear();
untuk (int i=2; i<closes.length; ++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<Gap> fvgUp = new ArrayList<Gap>();
ArrayList<Gap> fvgDn = new ArrayList<Gap>();
void detectClustersAndFVG() {
liquidationClusters.clear();
clusterCounts.clear();
fvgUp.clear();
fvgDn.clear();
// rata-rata sederhana dari volume
float volMA = 0;
untuk (int i=0; i<volumes.length; i++) {
volMA += volume[i];
}
volMA /= volume.panjang;
untuk (int i=0; i<closes.length; 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);
}
// FVG bearish blue
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<volumes.length; i++) {
volMA += volume[i];
}
volMA /= volume.panjang;
untuk (int i=0; i<closes.length; 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<liquidationClusters.size(); 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 = lows.length - pivotRight; 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<liquidationClusters.size(); 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<supports.size(); 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<supportBreaks.size(); 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<liquidationClusters.size(); 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 = shortTrendLength; i = closes.length; 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
}
}
}