// --- BIẾN TOÀN CẦU ---

JSONArray nến;

float[] mở, cao, thấp, đóng, khối lượng;

float prixActuel, 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[] symbols = {

"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); // Tỷ lệ tài trợ 1000

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

float[] rates = new float[limit];

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

thử {

Chuỗi thô = join(loadStrings(url), "");

JSONArray arr = parseJSONArray(raw);

println( "Tên quỹ tài trợ: " + 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("Lỗi khi lấy Tỷ giá Tài trợ: " + e);

}

tỷ lệ hoàn trả;

}

// --- THAM SỐ (giống như các đầu vào Pine của bạn) ---

int lookbackVol = 50;

float volMult = 2.5;

float wickRatio = 0.6f;

float minBodyRatio = 0.1f;

float proximityPts = 20f; // dung sai để nhóm các cụm

int pivotLeft = 5;

int pivotRight = 5;

int interval = 1000; // 1000 ms = 1 giây

int lastUpdate = 0;

int widths;

// --- Tính toán EMA ---

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

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

float alpha = 2.0 / (chu kỳ + 1.0);

// Khởi tạo: chúng ta bắt đầu với giá trị thô đầu tiên

ema[0] = data[0];

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

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

}

trả lại ema;

}

// --- CÀI ĐẶT ---

void setup() {

//kích thước(1200, 800);

toàn màn hình();

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

ký hiệu = các ký hiệu[countSymbol];

fetchData( symbol );

widths = int(width * 8.7); // 8.1

fundingRates = fetchFundingRates(symbol, 1000); // 1000 tỷ lệ tài trợ gần nhất

//tốc độ khung hình(1);

// Bạn có thể thay đổi ký hiệu nếu muốn

}

float startDist;

float zoom = 1.0;

float offsetX = 0;

float offsetY = 0;

void touchStarted() {

nếu (chiều dài chạm == 2) {

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

}

}

void touchMoved() {

nếu (chiều dài chạm == 2) {

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

float d = newDist / startDist;

thu phóng *= d;

zoom = constrain(zoom, 0.1, 10); // giới hạn độ phóng to

startDist = newDist;

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

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

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

}

}

// Kéo bằng chuột (hữu ích khi thử nghiệm trên máy tính)

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

nếu ( mouseX > width-200 && mouseY < 300 && mouseY >100 )

++countSymbol;

nếu ( mouseX > width-200 && mouseY < 500 && mouseY >300 )

--countSymbol;

nếu (countSymbol<0)

countSymbol =0;

nếu (countSymbol>101)

countSymbol =0;

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

ký hiệu = các ký hiệu[countSymbol];

}

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; // giá trị mặc định nếu không đủ dữ liệu

Độ lợi của số thực = 0, độ mất mát = 0;

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

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

nếu (thay đổi > 0) thì lợi nhuận += thay đổi;

Ngược lại, tổn thất = thay đổi;

}

float avgGain = gain / period;

float avgLoss = loss / period;

if (avgLoss == 0) return 100; // RSI tối đa nếu không có tổn thất

float rs = avgGain / avgLoss;

trả về 100 - (100 / (1 + rs));

}

int n = 30; // kích thước cửa sổ

float tolerance = 100.5; // lề để chỉ ra "nó chạm trần nhà"

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

if (i < n) return; // chưa đủ dữ liệu

// Chúng ta lấy giá trị lớn nhất trong n cây nến gần nhất

float maxRecent = highs[i];

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

nếu (highs[i - j] > maxRecent) {

maxRecent = highs[i - j];

}

}

// Chúng ta đếm số lần giá "đạt" gần mức tối đa

int touchess = 0;

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

nếu (abs(highs[i - j] - maxRecent) < tolerance) {

chạm++;

}

}

// Không hiển thị kết quả tính toán RSI

// Bán ở đáy

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

// Nếu nhiệt độ thường xuyên tăng nhưng không vượt quá 100°C, hãy báo hiệu.

nếu (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);

điền(255, 255, 0, 150);

không có đột quỵ();

rect(xp, y, 30, 15);

//fill(255);

textAlign(CENTER);

văn bản("NGẮN ×100", xp, y - 10);

}

}

// --- VÒNG LẶP VẼ ---

void draw() {

ngẫu nhiên = 0;

nếu (millis() - lastUpdate >= interval) {

//fetchData(symbol); // Chúng ta làm mới dữ liệu

/*closes = new float[666]; // đặt lại mảng closures

supports.clear(); // Xóa danh sách các giá đỡ

supportBreaks.clear(); // xóa danh sách các điểm dừng

liquidationClusters.clear(); // xóa các cụm thanh lý

clusterCounts.clear();

supportBroken.clear();*/

ký hiệu = các ký hiệu[countSymbol];

fetchData( symbol );

lastUpdate = millis(); // Chúng ta đặt lại bộ đếm về 0

}

pushMatrix();

dịch chuyển(chiều rộng/2 + độ lệch X*thu phóng, chiều cao/2 + độ lệch Y*thu phóng-400);

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

tỷ lệ (thu phóng);

//fetchData("BTCUSDT");

nền (20);

đột quỵ (255);

điền(200);

// Giới hạn chiều dọc để thu phóng

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

điền(255, 25, 255, 150);

không có đột quỵ();

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

điền(25, 255, 255, 150);

không có đột quỵ();

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

}

*/

// --- KẾ TIẾP ---

stroke(255, 255, 0);

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

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

điền(255, 255, 0);

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

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

// --- KẾ TIẾP ---

stroke(25, 255, 255);

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

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

điền(255, 255, 0);

văn bản("THẤP " + THẤP, 55, yATH-5);

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

// Biểu đồ giá (biểu đồ đường đóng cửa)

/*

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

đột quỵ (180);

Độ dày nét vẽ (2);

line(x1, y1, x2, y2);

opens = new float[n];

highs = new float[n];

lows = new float[n];

đóng = new float[n];

}*/

Độ dày nét vẽ (1.3);

điền(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);

đỉnh(x, y);

// lệnh giới hạn

}

endShape();

không có đột quỵ();

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

Độ nặng đột ngột (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);

nếu (ema3[i] > ema3[i-1]) {

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

} khác {

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

}

line(x1 , y1, x2 , y2);

}

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

Độ nặng đột ngột (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);

nếu (ema3[i] > ema3[i-1]) {

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

} khác {

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

}

line(x1 , y1, x2 , y2);

}

/*

// Chiều rộng của mỗi cây nến + khoảng cách

float candleW = 5;

float spacing = 2; // khoảng cách giữa các cây nến

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

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

// X với khoảng cách đều đặn

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

// ánh xạ 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);

// --- Bấc ---

đột quỵ (200);

line(x, yh, x, yl);

// --- Quân đoàn ---

nếu (closes[i] >= opens[i]) {

điền(0, 200, 0);

stroke(0, 200, 0);

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

} khác {

điền(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);

// ánh xạ 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);

// chiều rộng của một cây nến

float candleW = 4.5;

// --- Bấc ---

nếu (closes[i] >= opens[i])

// Nến xanh

stroke(0,200,0);

khác

stroke(200,0,0);

Độ dày nét vẽ (1.3);

line(x, yh, x, yl);

không có đột quỵ();

// --- Quân đoàn ---

nếu (closes[i] >= opens[i]) {

// Nến xanh

điền(0, 200, 0);

stroke(0, 200, 0);

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

} khác {

// Nến đỏ

điền(200, 0, 0);

stroke(200, 0, 0);

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

}

boolean baseHistorique = true;

nếu ( i > 84)

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

nếu (lows[i-j-1] < lows[i]) {

basHistorique = false;

phá vỡ;

}

}

Ngược lại, baseHistorique = false;

nếu (downHistory)

{

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

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

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

// Định vị điểm

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

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

điền(255, 0, 0,150);

không có đột quỵ();

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

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

điền(0, 255, 0);

textAlign(CENTER);

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

///bas[i]=1;

nếu ( lows[i] < lows[i-83])

văn bản("LL", xp, y - 10);

khác

văn bản("HL", xp, y - 10);

// bas[i]=1;

// trên một giao dịch mua chưa hoàn tất

//XÁC NHẬN = true;

}

boolean HautHistorique = true;

nếu ( i > 84)

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

nếu (highs[i-j-1] > highs[i]) {

HautHistorique = false;

phá vỡ;

}

}

Ngược lại, HautHistorique = false;

nếu (HautHistorique)

{

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

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

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

// Định vị điểm bạn trỏ

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

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

điền(255, 255, 0,150);

không có đột quỵ();

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

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

điền(0, 255, 255);

textAlign(CENTER);

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

///bas[i]=1;

nếu (highs[i] > highs[i-83])

văn bản("HH", xp, y - 10);

khác

văn bản("Hl", xp, y - 10);

// bas[i]=1;

nếu ( 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);

dòng(xp, y, xi,yi);

}

// trên một giao dịch mua chưa hoàn tất

//XÁC NHẬN = true;

}

//////////// những đỉnh núi nhỏ

baseHistorique = true;

nếu ( i > 9)

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

nếu (lows[i-j-1] < lows[i]) {

basHistorique = false;

phá vỡ;

}

}

Ngược lại, baseHistorique = false;

nếu (downHistory)

{

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

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

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

// Định vị điểm bạn trỏ

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

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

điền(255, 0, 0,150);

không có đột quỵ();

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

hình elip(xp-5, y, 10, 10);

điền(0, 255, 0);

textAlign(CENTER);

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

///bas[i]=1;

// nếu ( lows[i] < lows[i-83])

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

//khác

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

// bas[i]=1;

// trên một giao dịch mua chưa hoàn tất

//XÁC NHẬN = true;

}

TopHistorical = true;

nếu ( i > 9)

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

nếu (highs[i-j-1] > highs[i]) {

HautHistorique = false;

phá vỡ;

}

}

Ngược lại, HautHistorique = false;

nếu (HautHistorique)

{

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

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

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

// Định vị điểm

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

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

điền(255, 255, 0,150);

không có đột quỵ();

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

hình elip(xp-5, y, 10, 10);

điền(0, 255, 255);

textAlign(CENTER);

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

///bas[i]=1;

nếu (highs[i] > highs[i-7])

văn bản("HH", xp, y - 10);

khác

văn bản("Hl", xp, y - 10);

// bas[i]=1;

/*nếu ( 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);

dòng(xp, y, xi,yi);

}*/

// trên một giao dịch mua chưa hoàn tất

//XÁC NHẬN = true;

}

// Các ngưỡng kháng cự khi giá không tăng

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

điền(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];

// lệnh giới hạn

}

nét vẽ (0,0,255);

stroke(25, 255, 255);

*/

Độ dày nét vẽ (2);

// --- Các cụm thanh lý ---

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

điền(255, 0, 0);

văn bản("LC x" + clusterCounts.get(i), widths-100, y-5);

}

/*

// --- Hỗ trợ và ngắt ---

for (int i=0; i

float lvl = supports.get(i);

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

nếu (supportBroken.get(i)) {

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

} khác {

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

}

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

}*/

// --- Bản đồ nhiệt các cụm ---

//drawClusters(minP, maxP);

// --- Bản đồ nhiệt các cụm ---

vẽ các cụm (minP, maxP);

// --- Các điểm hỗ trợ (vùng màu xanh lá cây) ---

vẽ các giá đỡ (minP, maxP);

// --- Ngắt quãng (vùng màu cam đậm) ---

drawBreaks(minP, maxP);

//detectResistances();

//drawSignals(minP, maxP);

//drawClusters(minPrice, maxPrice);

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

vẽFVG(minP, maxP);

/*

int frIndex = fundingRates.length - 1; // phần của tỷ lệ tài trợ cuối cùng

// Chúng ta lặp qua các cây nến bắt đầu từ cuối

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

nếu (fundingRates[frIndex] < 0) {

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

fill(255, 255, 0, 70); // màu vàng

rect(x-5, 0, 10, height); // thanh màu vàng trên cây nến tương ứng

}

frIndex--; // chúng ta tiến lên trong bảng phân bổ kinh phí

}

*/

nếu ( i == "1h")

///// Dấu hiệu của con sâu... à nhầm, cái quần short... xP

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

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

//int candleIndex = i * 8; // nếu ech = 1h

nếu (fundingRates[i] < 0) {

// Chúng ta chỉ có thể thu hồi được 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 = chiều cao/2;

fill(255, 255, 0, 70); // màu vàng

//rect(x-5, y-5, 10, 10); // hình vuông nhỏ

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

textSize(33);

điền(255);

văn bản( "NGẮN ", x-5,150);

}

}

textSize(12);

popMatrix();

String[] labels = {"1s", "1m", "3m", "15m","1day","1h","2h"}; // văn bản của các khoảng

int wld=0;

for ( int i=0;i

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

hình chữ nhật(i,0,100,100);

điền(0,0,0);

văn bản( nhãn[wld % nhãn.length], 40+i,50);

++wld;

}

điền(255,255,255);

văn bản( tôi, 20, 130);

nếu (mouseX < 100 && mouseY < 100) {

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

}

nếu ( mouseX < 200 && mouseX > 100 && mouseY < 100 ){

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

}

nếu ( mouseX < 300 && mouseX > 200 && mouseY < 100 ){

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

}

nếu ( mouseX < 400 && mouseX > 300 && mouseY < 100 ){

i = "15m";

fetchData( symbol );

}

nếu ( mouseX < 500 && mouseX > 400 && mouseY < 100 ){

i = "1d";

fetchData( symbol ); ;

}

nếu ( mouseX < 600 && mouseX > 500 && mouseY < 100 ){

i = "1h";

fetchData( symbol ); ;

}

nếu ( mouseX < 700 && mouseX > 600 && mouseY < 100 ){

ech = "2h";

fetchData( symbol ); ;

}

nếu ( 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);

văn bản(ký hiệu[countSymbol], chiều rộng - 150, 150);

// textSize(30);

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

văn bản ("PRIX :" + nf(closes[999],0,2),10,height-220);

hình chữ nhật(chiều rộng - 100, chiều cao - 200, 100, 100);

hình chữ nhật(chiều rộng - 100, chiều cao - 100, 100, 100);

văn bản ( gapMin, chiều rộng-30, chiều cao-250);

}

// --- LẤY DỮ LIỆU ---

void fetchData(String symbol) {

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

supports.clear(); // Xóa danh sách các giá đỡ

supportBreaks.clear(); // xóa danh sách các điểm dừng

liquidationClusters.clear(); // xóa các cụm thanh lý

clusterCounts.clear();

supportBroken.clear();

Chuỗi url = "https://api.binance.com/api/v3/klines?symbol=" + biểu tượng + "&interval="+ech+"&limit=2500";

thử {

Chuỗi thô = join(loadStrings(url), "");

nến = phân tích mảng JSON(raw);

int n = candles.size();

println("nến = " + n);

opens = new float[n];

highs = new float[n];

lows = new float[n];

đóng = new float[n];

khối lượng = new float[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));

// Ví dụ đơn giản về phát hiện

nếu (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);

// Điều kiện phá vỡ: các đường chuyền gần dưới mức hỗ trợ

nếu (prevClose >= target && lastClose < target) {

supportBreaks.add(sprice);

}

}

}

}

prixActuel = closes[n-1];

ATH = max(closes);

THẤP = min(giá đóng cửa);

detectClusters();

detectSupports();

detectClustersAndFVG(gapMin);

} catch (Exception e) {

println("Lỗi API: " + e.getMessage());

}

}

float gapMin = 1;

// Lớp dùng để lưu trữ các khoảng trống với chỉ số nến

lớp Gap {

Nổi thấp, nổi cao;

int startIdx, endIdx; // chỉ số nến

boolean bullish; // true = khoảng trống tăng giá, false = khoảng trống giảm giá

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

thấp = l;

cao = h;

startIdx = start;

endIdx = end;

tăng giá = khoảng cách tăng giá;

}

}

// Danh sách toàn cầu cho FVG

ArrayList fvgUp = new ArrayList();

ArrayList fvgDn = new ArrayList();

// Phát hiện FVG (phiên bản đơn giản hóa và có thể kiểm thử)

void detectClustersAndFVG(float gapMin) {

fvgUp.clear();

fvgDn.clear();

for (int i=2; i

// --- FVG tăng giá ---

nếu (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 giảm giá ---

nếu (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);

}

}

}

// Bản vẽ FVG (hình chữ nhật nằm ngang "từ ngọn nến này đến ngọn nến kia")

void drawFVG(float minP, float maxP) {

không có đột quỵ();

// FVG tăng giá

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); // bán trong suốt theo chiều dọc

stroke(0, 180, 0);

rect(x1, min(y1,y2), max(x2-x1, 2)+100, abs(y2-y1)); // chiều rộng tối thiểu 2px

không có đột quỵ();

điền(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 giảm giá

đối với (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); // màu xanh lam bán trong suốt

nét vẽ (0, 0, 180);

rect(x1, min(y1,y2), max(x2-x1, 2)+100, abs(y2-y1)); // chiều rộng tối thiểu 2px

không có đột quỵ();

điền(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);

}

}

/*

Chúng ta lưu trữ các khoảng trống dưới dạng các cặp (thấp, cao).

lớp Gap {

Nổi thấp, nổi cao;

Khoảng cách (float l, float h) {

thấp = l;

cao = h;

}

}

ArrayList fvgUp = new ArrayList();

ArrayList fvgDn = new ArrayList();

void detectClustersAndFVG() {

liquidationClusters.clear();

clusterCounts.clear();

fvgUp.clear();

fvgDn.clear();

// trung bình cộng đơn giản của khối lượng

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 candle = highs[i]-lows[i];

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

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

// --- Phát hiện cụm và thanh lý ---

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

}

*/

/*

// --- Phát hiện chênh lệch giá trị hợp lý (FVG) ---

nếu (i >= 2) {

// Xu hướng tăng giá của FVG (mức thấp hiện tại > mức cao của 2 nến trước)

nếu (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 đang giảm giá (mức cao hiện tại ở mức thấp của 2 nến trước đó)

nếu (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; // dung sai tối thiểu để xem xét FVG

nếu (i >= 2) {

// FVG tăng giá

nếu (lows[i] - highs[i-2] > gapMin) {

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

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

}

// FVG giảm giá

nếu (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) {

không có đột quỵ();

// FVG tăng giá xanh

for (Gap g : fvgUp) {

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

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

đột quỵ (255);

fill(0, 255, 0); // trong suốt theo chiều dọc

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

điền(0, 180);

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

}

// FVG giảm giá xanh

đối với (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); // màu xanh lam trong suốt

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

điền(0, 180);

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

}

}

*/

// --- PHÁT HIỆN CÁC CỤM THANH LÝ ---

void detectClusters() {

liquidationClusters.clear();

clusterCounts.clear();

// trung bình cộng đơn giản của khối lượng

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 candle = highs[i]-lows[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);

}

}

}

// --- Nhóm các cụm lân cận ---

void addCluster(float price) {

for (int i=0; i

nếu (abs(liquidationClusters.get(i) - price) <= proximityPts) {

// tăng

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

trở lại;

}

}

liquidationClusters.add(price);

clusterCounts.add(1);

}

// --- PHÁT HIỆN CÁC ĐIỂM HỖ TRỢ + ĐIỂM GÃY ---

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;

nếu (isPivot) {

float s = lows[i];

supports.add(s);

// phá vỡ?

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

supportBroken.add(broken);

}

}

}

// --- Các cụm thanh lý trong bản đồ nhiệt ---

void drawClusters(float minP, float maxP) {

không có đột quỵ();

for (int i=0; i

float lvl = liquidationClusters.get(i);

int count = clusterCounts.get(i);

// ánh xạ giá sang y

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

// Cường độ tỷ lệ thuận với số lần xuất hiện

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

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

điền(255, 0, 0, alpha);

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

// Văn bản kín đáo ở bên phải

điền(255, 200);

văn bản(lvl+ " Cụm thanh lý x" + count, widths-490, y-5);

}

}

// --- Các điểm hỗ trợ (vùng màu xanh lá cây) ---

void drawSupports(float minP, float maxP) {

không có đột quỵ();

for (int i=0; i

float lvl = supports.get(i);

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

fill(0, 200, 0, 100); // màu xanh lục trong mờ

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

điền(0, 255, 0);

văn bản(lvl+"Hỗ trợ", 60, y-5);

}

}

// --- Vùng hỗ trợ bị ngắt quãng (vùng màu cam dày) ---

void drawBreaks(float minP, float maxP) {

không có đột quỵ();

for (int i=0; i

float lvl = supportBreaks.get(i);

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

fill(255, 140, 0, 150); // màu cam bán trong suốt

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

điền(255, 180, 0);

văn bản("Hỗ trợ ngắt quãng", 60, y-6);

}

}

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

// --- Phân tích cụm khu vực mua/bán ---

float clusterZoneMargin = 5f; // lề xung quanh cụm để vẽ vùng

void drawClusterZones(float minP, float maxP) {

for (int i=0; i

float lvl = liquidationClusters.get(i);

int count = clusterCounts.get(i);

// Ánh xạ giá -> và

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

// Xác định màu sắc theo xu hướng (ví dụ: độ sáng cao = giảm giá, độ sáng thấp = mua hàng)

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

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

boolean isBuyZone = wickDn > wickUp; // bấc dưới lớn hơn

boolean isSellZone = wickUp > wickDn; // bấc cao hơn, lớn hơn

// Điều chỉnh độ mờ và độ dày theo số lần xuất hiện

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

int rectHeight = 6 + count*2;

nếu (làKhuVựcMuaHàng) {

điền(0, 0, 255, alpha);

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

điền(0, 0, 255);

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

}

nếu (isSellZone) {

điền(255, 0, 0, alpha);

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

điền(255, 0, 0);

văn bản("Vente x"+count, chiều rộng-180, y);

}

}

}

///////€€

// --- Cài đặt ---

float rsiOverbought = 70f;

float rsiOversold = 45f;

int rsiLength = 27; // Độ dài RSI

int shortTrendLength = 33; // số lượng nến để tính xu hướng ngắn hạn

float rectMargin = 10f; // độ dày hình chữ nhật

// --- Cách tính RSI đơn giản ---

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

if (idx < length) return 50; // giá trị trung lập nếu không đủ dữ liệu

Độ lợi của số thực = 0, độ mất mát = 0;

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

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

nếu (hiệu > 0) thì lợi nhuận cộng hoặc bằng hiệu;

Ngược lại, loss = diff;

}

nếu (mất mát == 0) trả về 100;

trả về 100 - (100 / (1 + lãi/lỗ));

}

// --- Phát hiện xu hướng ngắn hạn ---

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

// Tính toán vị trí X theo dòng thời gian

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

// --- Tín hiệu bán hàng ---

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

float recentHigh = highs[i];

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

điền(255, 0, 0, 80);

rect(x-10, y-rectMargin, 20, rectMargin*2); // hình chữ nhật căn giữa tại x

điền(255, 0, 0);

text("S", x, y-rectMargin-5); // văn bản ngay phía trên hình chữ nhật

}

// --- Tín hiệu mua ---

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

float recentLow = lows[i];

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

điền(0, 0, 255, 80);

rect(x-10, y-rectMargin, 20, rectMargin*2); // hình chữ nhật căn giữa tại x

điền(0, 0, 255);

text("B", x, y-rectMargin-5); // văn bản ngay phía trên hình chữ nhật

}

}

}