mirror of
https://github.com/chrisnov-it/quantumbotx.git
synced 2026-07-28 11:17:44 +00:00
136 lines
4.9 KiB
Python
136 lines
4.9 KiB
Python
|
|
import logging
|
||
|
|
import time
|
||
|
|
import pandas as pd
|
||
|
|
import random
|
||
|
|
from core.bots.trading_bot import TradingBot
|
||
|
|
from core.interfaces.broker_interface import BrokerInterface
|
||
|
|
from core.strategies.strategy_map import STRATEGY_MAP
|
||
|
|
|
||
|
|
# 1. Setup Logging yang Cantik
|
||
|
|
logging.basicConfig(
|
||
|
|
level=logging.INFO,
|
||
|
|
format='%(asctime)s | %(levelname)-7s | %(message)s',
|
||
|
|
datefmt='%H:%M:%S'
|
||
|
|
)
|
||
|
|
logger = logging.getLogger("QuantumSim")
|
||
|
|
|
||
|
|
# 2. MockBroker yang Lebih Hebat (Bisa update harga)
|
||
|
|
class AdvancedMockBroker(BrokerInterface):
|
||
|
|
def __init__(self):
|
||
|
|
self.positions = []
|
||
|
|
self._ticket_counter = 5000
|
||
|
|
self.current_price = 88000.0
|
||
|
|
self.history = []
|
||
|
|
# Generate some initial history
|
||
|
|
for i in range(100):
|
||
|
|
self.current_price += random.uniform(-100, 100)
|
||
|
|
self.history.append(self.current_price)
|
||
|
|
|
||
|
|
def initialize(self, credentials): return True
|
||
|
|
def get_account_info(self): return {'balance': 100000, 'equity': 100000}
|
||
|
|
|
||
|
|
def get_rates(self, symbol, timeframe, count=100):
|
||
|
|
# Update harga sedikit setiap kali dipanggil agar simulasi terasa hidup
|
||
|
|
self.current_price += random.uniform(-150, 150)
|
||
|
|
self.history.append(self.current_price)
|
||
|
|
last_prices = self.history[-count:]
|
||
|
|
|
||
|
|
df = pd.DataFrame({
|
||
|
|
'time': pd.date_range(end=pd.Timestamp.now(), periods=len(last_prices), freq='H'),
|
||
|
|
'open': [p * 0.999 for p in last_prices],
|
||
|
|
'high': [p * 1.002 for p in last_prices],
|
||
|
|
'low': [p * 0.998 for p in last_prices],
|
||
|
|
'close': last_prices,
|
||
|
|
'tick_volume': [random.randint(1000, 5000) for _ in last_prices]
|
||
|
|
})
|
||
|
|
return df
|
||
|
|
|
||
|
|
def get_open_positions(self): return self.positions
|
||
|
|
|
||
|
|
def place_order(self, symbol, order_type, volume, price=0.0, sl=0.0, tp=0.0, comment=""):
|
||
|
|
self._ticket_counter += 1
|
||
|
|
magic = int(comment.split('-')[1]) if 'Bot-' in comment else 0
|
||
|
|
new_pos = {
|
||
|
|
'ticket': self._ticket_counter,
|
||
|
|
'symbol': symbol,
|
||
|
|
'type': order_type,
|
||
|
|
'volume': volume,
|
||
|
|
'price': self.current_price,
|
||
|
|
'sl': sl, 'tp': tp, 'magic': magic,
|
||
|
|
'profit': 0.0
|
||
|
|
}
|
||
|
|
self.positions.append(new_pos)
|
||
|
|
logger.info(f"✨ [BROKER] ORDER BERHASIL: {order_type} {symbol} @ {self.current_price:.2f}")
|
||
|
|
return True
|
||
|
|
|
||
|
|
def close_position(self, position_id, volume=0.0):
|
||
|
|
self.positions = [p for p in self.positions if str(p['ticket']) != str(position_id)]
|
||
|
|
logger.info(f"🛑 [BROKER] POSISI DITUTUP: ID {position_id}")
|
||
|
|
return True
|
||
|
|
|
||
|
|
def get_symbol_info(self, symbol): return {'name': symbol, 'digits': 2}
|
||
|
|
def get_todays_profit(self): return 120.50
|
||
|
|
|
||
|
|
# 3. Script Simulasi Utama
|
||
|
|
def run_visual_simulation():
|
||
|
|
print("\n" + "="*60)
|
||
|
|
print(" QUANTUM BOT X - LIVE SIMULATION MODE (MOCK) ")
|
||
|
|
print("="*60)
|
||
|
|
|
||
|
|
broker = AdvancedMockBroker()
|
||
|
|
|
||
|
|
bot = TradingBot(
|
||
|
|
id=1337,
|
||
|
|
name="UltraBot-Sim",
|
||
|
|
market="BTC/USDT",
|
||
|
|
risk_percent=0.05,
|
||
|
|
sl_pips=1000,
|
||
|
|
tp_pips=2000,
|
||
|
|
timeframe="H1",
|
||
|
|
check_interval=2, # Cek setiap 2 detik
|
||
|
|
strategy="MA_CROSSOVER", # Pake strategi asli
|
||
|
|
broker=broker
|
||
|
|
)
|
||
|
|
|
||
|
|
# Kita jalankan loop bot secara manual agar bisa kita batasi jumlah iterasinya
|
||
|
|
# (Biasanya bot.start() akan jalan selamanya di thread terpisah)
|
||
|
|
|
||
|
|
# Setup Strategy Instance (biasanya dilakukan di bot.run())
|
||
|
|
bot.market_for_mt5 = "BTC/USDT"
|
||
|
|
bot.strategy_instance = STRATEGY_MAP["MA_CROSSOVER"](bot_instance=bot)
|
||
|
|
|
||
|
|
print(f"Bot '{bot.name}' Ready. Menggunakan Strategi: {bot.strategy_name}")
|
||
|
|
print("Memulai simulasi 10 iterasi...\n")
|
||
|
|
|
||
|
|
for i in range(1, 11):
|
||
|
|
print(f"\n--- Iterasi {i}/10 | Harga Saat Ini: {broker.current_price:.2f} ---")
|
||
|
|
|
||
|
|
# Ambil data kandel
|
||
|
|
df = broker.get_rates(bot.market_for_mt5, bot.timeframe, 50)
|
||
|
|
|
||
|
|
# Analisis Strategi
|
||
|
|
bot.last_analysis = bot.strategy_instance.analyze(df)
|
||
|
|
|
||
|
|
# PAKSA SINYAL untuk demo agar terlihat log-nya
|
||
|
|
if i == 2: signal = 'BUY'
|
||
|
|
elif i == 5: signal = 'SELL'
|
||
|
|
elif i == 8: signal = 'BUY'
|
||
|
|
else: signal = bot.last_analysis.get('signal', 'HOLD')
|
||
|
|
|
||
|
|
logger.info(f"Analisis: {signal} | Penjelasan: {bot.last_analysis.get('explanation', 'Manual Override for Demo' if i in [2,5,8] else '')}")
|
||
|
|
|
||
|
|
# Eksekusi (Logika di TradingBot._handle_trade_signal)
|
||
|
|
posisi_sekarang = bot._get_open_position()
|
||
|
|
bot._handle_trade_signal(signal, posisi_sekarang)
|
||
|
|
|
||
|
|
# Kasih jeda biar enak dilihat
|
||
|
|
time.sleep(1.5)
|
||
|
|
|
||
|
|
print("\n" + "="*60)
|
||
|
|
print(" SIMULASI SELESAI! ")
|
||
|
|
print("="*60)
|
||
|
|
print("Bot berhasil mensimulasikan logika trading tanpa menyentuh dana asli.")
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
run_visual_simulation()
|