98 lines
4.8 KiB
Python
98 lines
4.8 KiB
Python
import json
|
|
import pandas as pd
|
|
from collections import Counter
|
|
|
|
def analyze_trade_feedback(filepath="trade_feedback.json"):
|
|
"""
|
|
Menganalisis file trade_feedback.json untuk memberikan wawasan tentang kinerja strategi.
|
|
|
|
Karena data saat ini memiliki keterbatasan (tidak semua trade memiliki hasil 'win'/'loss'
|
|
dan data 'score_components' hilang), analisis ini akan fokus pada apa yang tersedia
|
|
dan memberikan rekomendasi untuk perbaikan pencatatan data.
|
|
"""
|
|
try:
|
|
with open(filepath, 'r') as f:
|
|
data = json.load(f)
|
|
except (FileNotFoundError, json.JSONDecodeError):
|
|
print(f"❌ Error: File '{filepath}' tidak ditemukan atau formatnya tidak valid.")
|
|
return
|
|
|
|
if not data:
|
|
print("🟡 Info: File feedback kosong, tidak ada yang bisa dianalisis.")
|
|
return
|
|
|
|
df = pd.DataFrame(data)
|
|
|
|
print("--- ANALISIS KINERJA TRADING (Berdasarkan Data yang Tersedia) ---")
|
|
print("\n1. Ringkasan Umum")
|
|
print("="*20)
|
|
print(f"Total Sinyal Tercatat: {len(df)}")
|
|
|
|
# --- Analisis Win Rate (dengan data yang ada) ---
|
|
# Filter hanya untuk trade yang memiliki hasil 'win' atau 'loss' yang jelas
|
|
result_df = df[df['result'].isin(['win', 'loss'])].copy()
|
|
|
|
if not result_df.empty:
|
|
total_trades_with_result = len(result_df)
|
|
wins = len(result_df[result_df['result'] == 'win'])
|
|
losses = len(result_df[result_df['result'] == 'loss'])
|
|
win_rate = (wins / total_trades_with_result) * 100 if total_trades_with_result > 0 else 0
|
|
|
|
print(f"Trade dengan Hasil (Win/Loss): {total_trades_with_result}")
|
|
print(f" - Menang (Win): {wins}")
|
|
print(f" - Kalah (Loss): {losses}")
|
|
print(f" - Win Rate Terhitung: {win_rate:.2f}%")
|
|
|
|
if losses == 0 and wins > 0:
|
|
print("\n⚠️ PERINGATAN: Tidak ada trade yang tercatat sebagai 'loss'.")
|
|
print(" Win rate yang ditampilkan kemungkinan besar tidak akurat. Proses pencatatan hasil")
|
|
print(" trading yang kalah (loss) tampaknya tidak berjalan dengan benar.")
|
|
|
|
else:
|
|
print("Tidak ditemukan trade dengan hasil 'win' atau 'loss' yang jelas.")
|
|
print("Analisis win rate tidak dapat dilakukan.")
|
|
|
|
# --- Analisis Komponen Sinyal (jika ada) ---
|
|
print("\n2. Analisis Komponen Sinyal (Penyebab SL)")
|
|
print("="*20)
|
|
|
|
losing_trades = result_df[result_df['result'] == 'loss']
|
|
if not losing_trades.empty and 'score_components' in losing_trades.columns:
|
|
# Filter baris di mana 'score_components' adalah list dan tidak kosong
|
|
losing_trades = losing_trades[losing_trades['score_components'].apply(lambda x: isinstance(x, list) and x)]
|
|
|
|
if not losing_trades.empty:
|
|
all_loss_components = [comp for sublist in losing_trades['score_components'] for comp in sublist]
|
|
component_counts = Counter(all_loss_components)
|
|
|
|
print("Komponen sinyal yang paling sering muncul pada trade yang KALAH:")
|
|
# Urutkan berdasarkan jumlah kemunculan, dari yang terbanyak
|
|
for component, count in component_counts.most_common():
|
|
print(f" - {component}: {count} kali")
|
|
else:
|
|
print("Tidak ada data 'score_components' yang valid pada trade yang kalah.")
|
|
print("Ini adalah data krusial untuk menganalisis penyebab stoploss.")
|
|
else:
|
|
print("Tidak ada data 'loss' atau kolom 'score_components' tidak ada.")
|
|
print("Analisis komponen penyebab stoploss tidak dapat dilakukan.")
|
|
|
|
|
|
# --- Rekomendasi ---
|
|
print("\n3. REKOMENDASI UNTUK PENGEMBANGAN")
|
|
print("="*20)
|
|
print("Untuk dapat menganalisis penyebab Stoploss secara akurat, langkah-langkah berikut sangat penting:")
|
|
print("1. **Perbaiki Pencatatan Hasil Trade**: Pastikan setiap trade yang ditutup (baik SL maupun TP)")
|
|
print(" memanggil endpoint `/api/feedback_trade` dengan hasil yang benar ('win' atau 'loss').")
|
|
print("2. **Sertakan Konteks Sinyal**: Saat sinyal dikirim ke server, pastikan seluruh konteksnya,")
|
|
print(" terutama `profile_name` dan `score_components`, ikut disimpan.")
|
|
print("3. **Jalankan Ulang Sistem**: Setelah pencatatan diperbaiki, kumpulkan data trading baru.")
|
|
print("\nDengan data yang lengkap, kita bisa menjawab pertanyaan seperti:")
|
|
print(" - Sinyal mana ('BULLISH_BOS', 'FVG_BEARISH', dll.) yang paling sering menyebabkan kerugian?")
|
|
print(" - Apakah profil 'scalping' lebih berisiko daripada 'intraday'?")
|
|
print(" - Apakah sinyal dengan skor (confidence) rendah lebih sering rugi?")
|
|
print("\nAnalisis ini akan menjadi dasar untuk menyesuaikan bobot (`weights`) dan ambang batas (`confidence_threshold`)")
|
|
print("agar strategi menjadi lebih profitabel.")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
analyze_trade_feedback()
|