105 lines
2.7 KiB
Python
105 lines
2.7 KiB
Python
|
|
import pandas as pd
|
||
|
|
import numpy as np
|
||
|
|
import os
|
||
|
|
|
||
|
|
# Load 2022 EURUSD 1m data
|
||
|
|
df = pd.read_excel("data/DAT_XLSX_EURUSD_M1_2021.xlsx", header=None, names=[
|
||
|
|
'timestamp', 'open', 'high', 'low', 'close', 'volume'
|
||
|
|
])
|
||
|
|
df['timestamp'] = pd.to_datetime(df['timestamp'])
|
||
|
|
df.set_index('timestamp', inplace=True)
|
||
|
|
|
||
|
|
# Resample to 15-minute intervals
|
||
|
|
df = df.resample('15min').agg({
|
||
|
|
'open': 'first',
|
||
|
|
'high': 'max',
|
||
|
|
'low': 'min',
|
||
|
|
'close': 'last',
|
||
|
|
'volume': 'sum'
|
||
|
|
}).dropna()
|
||
|
|
|
||
|
|
# Create perfect actions
|
||
|
|
lookahead = 4 # ~1 hour
|
||
|
|
profit_threshold = 0.001
|
||
|
|
loss_threshold = 0.001
|
||
|
|
|
||
|
|
labels = []
|
||
|
|
for i in range(len(df) - lookahead):
|
||
|
|
current_close = df.iloc[i]['close']
|
||
|
|
future_window = df.iloc[i + 1:i + 1 + lookahead]
|
||
|
|
max_future_price = future_window['high'].max()
|
||
|
|
min_future_price = future_window['low'].min()
|
||
|
|
|
||
|
|
if max_future_price >= current_close * (1 + profit_threshold):
|
||
|
|
labels.append(1)
|
||
|
|
elif min_future_price <= current_close * (1 - loss_threshold):
|
||
|
|
labels.append(-1)
|
||
|
|
else:
|
||
|
|
labels.append(0)
|
||
|
|
|
||
|
|
labels += [0] * lookahead
|
||
|
|
df['perfect_action'] = labels
|
||
|
|
|
||
|
|
# Simulate perfect trader
|
||
|
|
balance = 10000.0
|
||
|
|
position = 0.0
|
||
|
|
entry_price = 0.0
|
||
|
|
win_count = 0
|
||
|
|
loss_count = 0
|
||
|
|
trades_count = 0
|
||
|
|
trades = []
|
||
|
|
|
||
|
|
for i in range(len(df)):
|
||
|
|
price = df.iloc[i]['close']
|
||
|
|
action = df.iloc[i]['perfect_action']
|
||
|
|
|
||
|
|
if action == 1 and position == 0:
|
||
|
|
position = balance / price
|
||
|
|
entry_price = price
|
||
|
|
trades.append({
|
||
|
|
"timestamp": df.index[i],
|
||
|
|
"action": "buy",
|
||
|
|
"price": price,
|
||
|
|
"balance": balance
|
||
|
|
})
|
||
|
|
balance = 0
|
||
|
|
trades_count += 1
|
||
|
|
|
||
|
|
elif action == -1 and position > 0:
|
||
|
|
exit_value = position * price
|
||
|
|
pnl = exit_value - (position * entry_price)
|
||
|
|
if pnl > 0:
|
||
|
|
win_count += 1
|
||
|
|
else:
|
||
|
|
loss_count += 1
|
||
|
|
balance = exit_value
|
||
|
|
trades.append({
|
||
|
|
"timestamp": df.index[i],
|
||
|
|
"action": "sell",
|
||
|
|
"price": price,
|
||
|
|
"balance": balance
|
||
|
|
})
|
||
|
|
position = 0
|
||
|
|
entry_price = 0
|
||
|
|
|
||
|
|
# Finalize any open position
|
||
|
|
if position > 0:
|
||
|
|
balance = position * df.iloc[-1]['close']
|
||
|
|
|
||
|
|
# Results
|
||
|
|
print("\n📊 Perfect Trader Simulation:")
|
||
|
|
print(f"🟢 Starting Balance: $10,000.00")
|
||
|
|
print(f"🔚 Ending Balance: ${balance:,.2f}")
|
||
|
|
print(f"💼 Total Trades: {trades_count}")
|
||
|
|
print(f"✅ Wins: {win_count} | ❌ Losses: {loss_count}")
|
||
|
|
if trades_count > 0:
|
||
|
|
print(f"📈 Win Rate: {win_count / trades_count * 100:.2f}%")
|
||
|
|
|
||
|
|
# Save trade log
|
||
|
|
output_path = "ml/perfect_trades.csv"
|
||
|
|
os.makedirs("ml", exist_ok=True)
|
||
|
|
|
||
|
|
trades_df = pd.DataFrame(trades)
|
||
|
|
trades_df.to_csv(output_path, index=False)
|
||
|
|
print(f"📁 Perfect trades saved to: {output_path}")
|