Update app.py
Browse files
app.py
CHANGED
|
@@ -449,6 +449,243 @@ Top Features:
|
|
| 449 |
|
| 450 |
return f"โ ERROR:\n\n{e}"
|
| 451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
# ============================================================
|
| 453 |
# PREDICT
|
| 454 |
# ============================================================
|
|
|
|
| 449 |
|
| 450 |
return f"โ ERROR:\n\n{e}"
|
| 451 |
|
| 452 |
+
|
| 453 |
+
|
| 454 |
+
```python id="wrv7sj"
|
| 455 |
+
# ============================================================
|
| 456 |
+
# ADD THIS AFTER run_predict()
|
| 457 |
+
# ============================================================
|
| 458 |
+
|
| 459 |
+
def calculate_trade_levels(df, signal):
|
| 460 |
+
|
| 461 |
+
latest = df.iloc[-1]
|
| 462 |
+
|
| 463 |
+
close_price = float(latest["close"])
|
| 464 |
+
|
| 465 |
+
recent_high = float(df["high"].tail(20).max())
|
| 466 |
+
recent_low = float(df["low"].tail(20).min())
|
| 467 |
+
|
| 468 |
+
fib_range = recent_high - recent_low
|
| 469 |
+
|
| 470 |
+
fib_236 = recent_high - fib_range * 0.236
|
| 471 |
+
fib_382 = recent_high - fib_range * 0.382
|
| 472 |
+
fib_500 = recent_high - fib_range * 0.5
|
| 473 |
+
fib_618 = recent_high - fib_range * 0.618
|
| 474 |
+
|
| 475 |
+
atr = (
|
| 476 |
+
(df["high"] - df["low"])
|
| 477 |
+
.rolling(14)
|
| 478 |
+
.mean()
|
| 479 |
+
.iloc[-1]
|
| 480 |
+
)
|
| 481 |
+
|
| 482 |
+
if signal == "BUY":
|
| 483 |
+
|
| 484 |
+
entry = close_price
|
| 485 |
+
|
| 486 |
+
tp1 = fib_236
|
| 487 |
+
tp2 = fib_382
|
| 488 |
+
tp3 = recent_high
|
| 489 |
+
|
| 490 |
+
sl = close_price - (atr * 1.5)
|
| 491 |
+
|
| 492 |
+
else:
|
| 493 |
+
|
| 494 |
+
entry = close_price
|
| 495 |
+
|
| 496 |
+
tp1 = fib_618
|
| 497 |
+
tp2 = fib_500
|
| 498 |
+
tp3 = recent_low
|
| 499 |
+
|
| 500 |
+
sl = close_price + (atr * 1.5)
|
| 501 |
+
|
| 502 |
+
return {
|
| 503 |
+
"entry": entry,
|
| 504 |
+
"tp1": tp1,
|
| 505 |
+
"tp2": tp2,
|
| 506 |
+
"tp3": tp3,
|
| 507 |
+
"sl": sl,
|
| 508 |
+
"fib_236": fib_236,
|
| 509 |
+
"fib_382": fib_382,
|
| 510 |
+
"fib_500": fib_500,
|
| 511 |
+
"fib_618": fib_618
|
| 512 |
+
}
|
| 513 |
+
|
| 514 |
+
|
| 515 |
+
# ============================================================
|
| 516 |
+
# REPLACE run_predict()
|
| 517 |
+
# ============================================================
|
| 518 |
+
|
| 519 |
+
def run_predict():
|
| 520 |
+
|
| 521 |
+
try:
|
| 522 |
+
|
| 523 |
+
if not os.path.exists(MODEL_PATH):
|
| 524 |
+
return "โ ๏ธ Train model terlebih dahulu"
|
| 525 |
+
|
| 526 |
+
X, y, df, feat_cols, is_real = fetch_and_prepare()
|
| 527 |
+
|
| 528 |
+
scaler = joblib.load(SCALER_PATH)
|
| 529 |
+
model = joblib.load(MODEL_PATH)
|
| 530 |
+
|
| 531 |
+
latest = df.iloc[
|
| 532 |
+
-WINDOW:
|
| 533 |
+
][feat_cols].values.flatten()
|
| 534 |
+
|
| 535 |
+
latest = latest.reshape(1, -1)
|
| 536 |
+
|
| 537 |
+
latest = np.nan_to_num(latest)
|
| 538 |
+
|
| 539 |
+
latest_scaled = scaler.transform(latest)
|
| 540 |
+
|
| 541 |
+
pred = model.predict(latest_scaled)[0]
|
| 542 |
+
|
| 543 |
+
proba = model.predict_proba(
|
| 544 |
+
latest_scaled
|
| 545 |
+
)[0]
|
| 546 |
+
|
| 547 |
+
confidence = float(np.max(proba)) * 100
|
| 548 |
+
|
| 549 |
+
signal = "BUY" if pred == 1 else "SELL"
|
| 550 |
+
|
| 551 |
+
levels = calculate_trade_levels(df, signal)
|
| 552 |
+
|
| 553 |
+
price = float(df.iloc[-1]["close"])
|
| 554 |
+
|
| 555 |
+
rsi = float(df.iloc[-1]["rsi"])
|
| 556 |
+
macd = float(df.iloc[-1]["macd"])
|
| 557 |
+
|
| 558 |
+
return f"""
|
| 559 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 560 |
+
AI SIGNAL
|
| 561 |
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 562 |
+
|
| 563 |
+
๐ฎ Signal : {signal}
|
| 564 |
+
๐ Confidence : {confidence:.2f}%
|
| 565 |
+
|
| 566 |
+
๐ฐ Current Price : ${price:,.2f}
|
| 567 |
+
|
| 568 |
+
โโโโโโโโโโโโโโโโโโ
|
| 569 |
+
๐ ENTRY / TP / SL
|
| 570 |
+
โโโโโโโโโโโโโโโโโโ
|
| 571 |
+
|
| 572 |
+
๐ฏ Entry : ${levels['entry']:,.2f}
|
| 573 |
+
|
| 574 |
+
โ
TP1 : ${levels['tp1']:,.2f}
|
| 575 |
+
โ
TP2 : ${levels['tp2']:,.2f}
|
| 576 |
+
โ
TP3 : ${levels['tp3']:,.2f}
|
| 577 |
+
|
| 578 |
+
๐ Stop Loss : ${levels['sl']:,.2f}
|
| 579 |
+
|
| 580 |
+
โโโโโโโโโโโโโโโโโโ
|
| 581 |
+
๐ Fibonacci Levels
|
| 582 |
+
โโโโโโโโโโโโโโโโโโ
|
| 583 |
+
|
| 584 |
+
Fib 0.236 : ${levels['fib_236']:,.2f}
|
| 585 |
+
Fib 0.382 : ${levels['fib_382']:,.2f}
|
| 586 |
+
Fib 0.500 : ${levels['fib_500']:,.2f}
|
| 587 |
+
Fib 0.618 : ${levels['fib_618']:,.2f}
|
| 588 |
+
|
| 589 |
+
โโโโโโโโโโโโโโโโโโ
|
| 590 |
+
๐ Indicators
|
| 591 |
+
โโโโโโโโโโโโโโโโโโ
|
| 592 |
+
|
| 593 |
+
RSI : {rsi:.2f}
|
| 594 |
+
MACD : {macd:.2f}
|
| 595 |
+
|
| 596 |
+
๐ก Source:
|
| 597 |
+
{"LIVE DATA" if is_real else "SIMULATED"}
|
| 598 |
+
"""
|
| 599 |
+
|
| 600 |
+
except Exception as e:
|
| 601 |
+
|
| 602 |
+
logger.error(traceback.format_exc())
|
| 603 |
+
|
| 604 |
+
return f"โ ERROR:\n\n{e}"
|
| 605 |
+
|
| 606 |
+
|
| 607 |
+
# ============================================================
|
| 608 |
+
# ADD THIS BEFORE UI
|
| 609 |
+
# ============================================================
|
| 610 |
+
|
| 611 |
+
TRADINGVIEW_HTML = """
|
| 612 |
+
<div style="width:100%;height:600px;border-radius:12px;overflow:hidden;
|
| 613 |
+
border:1px solid #2B3139;background:#181A20;">
|
| 614 |
+
|
| 615 |
+
<iframe
|
| 616 |
+
src="https://s.tradingview.com/widgetembed/?symbol=BINANCE:ETHUSDT&interval=240&theme=dark&style=1&toolbarbg=%23181A20&hide_top_toolbar=0&saveimage=1&studies=%5B%22RSI%40tv-basicstudies%22,%22MACD%40tv-basicstudies%22,%22BB%40tv-basicstudies%22%5D"
|
| 617 |
+
style="width:100%;height:100%;border:none;"
|
| 618 |
+
allowfullscreen>
|
| 619 |
+
</iframe>
|
| 620 |
+
|
| 621 |
+
</div>
|
| 622 |
+
"""
|
| 623 |
+
|
| 624 |
+
|
| 625 |
+
# ============================================================
|
| 626 |
+
# REPLACE UI SECTION
|
| 627 |
+
# ============================================================
|
| 628 |
+
|
| 629 |
+
with gr.Blocks(
|
| 630 |
+
title="CryptoML PRO"
|
| 631 |
+
) as demo:
|
| 632 |
+
|
| 633 |
+
gr.Markdown("""
|
| 634 |
+
# ๐ CryptoML PRO Terminal
|
| 635 |
+
|
| 636 |
+
### ETH/USDT AI Trading System
|
| 637 |
+
""")
|
| 638 |
+
|
| 639 |
+
gr.HTML(TRADINGVIEW_HTML)
|
| 640 |
+
|
| 641 |
+
market_box = gr.Textbox(
|
| 642 |
+
label="Market Info",
|
| 643 |
+
value=get_market_info(),
|
| 644 |
+
lines=5
|
| 645 |
+
)
|
| 646 |
+
|
| 647 |
+
with gr.Row():
|
| 648 |
+
|
| 649 |
+
train_btn = gr.Button(
|
| 650 |
+
"โก Train AI Model",
|
| 651 |
+
variant="primary"
|
| 652 |
+
)
|
| 653 |
+
|
| 654 |
+
predict_btn = gr.Button(
|
| 655 |
+
"๐ฎ Generate Signal",
|
| 656 |
+
variant="secondary"
|
| 657 |
+
)
|
| 658 |
+
|
| 659 |
+
refresh_btn = gr.Button(
|
| 660 |
+
"๐ Refresh Market",
|
| 661 |
+
variant="secondary"
|
| 662 |
+
)
|
| 663 |
+
|
| 664 |
+
train_output = gr.Textbox(
|
| 665 |
+
label="AI Training Result",
|
| 666 |
+
lines=15
|
| 667 |
+
)
|
| 668 |
+
|
| 669 |
+
predict_output = gr.Textbox(
|
| 670 |
+
label="AI Trading Signal",
|
| 671 |
+
lines=30
|
| 672 |
+
)
|
| 673 |
+
|
| 674 |
+
train_btn.click(
|
| 675 |
+
fn=run_train,
|
| 676 |
+
outputs=train_output
|
| 677 |
+
)
|
| 678 |
+
|
| 679 |
+
predict_btn.click(
|
| 680 |
+
fn=run_predict,
|
| 681 |
+
outputs=predict_output
|
| 682 |
+
)
|
| 683 |
+
|
| 684 |
+
refresh_btn.click(
|
| 685 |
+
fn=get_market_info,
|
| 686 |
+
outputs=market_box
|
| 687 |
+
)
|
| 688 |
+
|
| 689 |
# ============================================================
|
| 690 |
# PREDICT
|
| 691 |
# ============================================================
|