first commit
This commit is contained in:
commit
dc64e230c0
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
bin/*
|
||||
include/*
|
||||
lib/*
|
||||
lib64/*
|
||||
share/*
|
||||
.env
|
||||
.git
|
||||
pyvenv.cfg
|
||||
176
bot.py
Normal file
176
bot.py
Normal file
@ -0,0 +1,176 @@
|
||||
import ccxt
|
||||
import time
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import ta
|
||||
import matplotlib.pyplot as plt
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
# Connect to Binance exchange
|
||||
exchange = ccxt.binance({
|
||||
'apiKey': os.getenv("API_KEY"),
|
||||
'secret': os.getenv("API_SECRET"),
|
||||
})
|
||||
|
||||
# Fetch historical data with pagination
|
||||
def fetch_full_ohlcv(symbol, timeframe, since):
|
||||
all_data = []
|
||||
while True:
|
||||
try:
|
||||
data = exchange.fetch_ohlcv(symbol, timeframe, since=since, limit=1000)
|
||||
print(f"Fetched {len(data)} records from {exchange.iso8601(since)}")
|
||||
if not data:
|
||||
break
|
||||
all_data.extend(data)
|
||||
since = data[-1][0] + 1
|
||||
time.sleep(0.2)
|
||||
except Exception as e:
|
||||
print(f"Error fetching data: {e}")
|
||||
break
|
||||
return all_data
|
||||
|
||||
# Fetch historical data
|
||||
timeframe = '1m'
|
||||
symbol = 'BTC/USDC'
|
||||
since = exchange.parse8601('2025-04-01T00:00:00Z')
|
||||
historical_data = fetch_full_ohlcv(symbol, timeframe, since)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Load historical data into DataFrame
|
||||
df = pd.DataFrame(historical_data, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
|
||||
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
|
||||
|
||||
virtual_balance = 50
|
||||
open_trades = []
|
||||
trade_log = []
|
||||
|
||||
def calculate_indicators(df):
|
||||
df['rsi'] = ta.momentum.RSIIndicator(df['close'], window=14).rsi()
|
||||
macd = ta.trend.MACD(df['close'])
|
||||
df['macd'] = macd.macd()
|
||||
df['signal'] = macd.macd_signal()
|
||||
return df
|
||||
|
||||
df = calculate_indicators(df)
|
||||
|
||||
RISK_PER_TRADE = 0.3
|
||||
STOP_LOSS = 0.02 # 100%
|
||||
TAKE_PROFIT = 0.03 # 5%
|
||||
|
||||
|
||||
# Open new trades with investment tracking
|
||||
for index, row in df.iterrows():
|
||||
current_price = row['close']
|
||||
|
||||
# Close existing trades
|
||||
for trade in open_trades[:]:
|
||||
if current_price >= trade['entry_price'] * (1 + TAKE_PROFIT) or \
|
||||
current_price <= trade['entry_price'] * (1 - STOP_LOSS):
|
||||
open_trades.remove(trade)
|
||||
profit_pct = (current_price / trade['entry_price'] - 1)
|
||||
trade_log.append({
|
||||
'entry_time': trade['entry_time'],
|
||||
'exit_time': row['timestamp'],
|
||||
'profit': profit_pct * 100,
|
||||
'success': profit_pct > 0,
|
||||
'investment_usd': trade['size']
|
||||
})
|
||||
virtual_balance += trade['size'] * profit_pct
|
||||
|
||||
# Calculate available capital for new trades
|
||||
allocated_capital = sum(trade['size'] for trade in open_trades)
|
||||
available_capital = max(0, virtual_balance - allocated_capital)
|
||||
|
||||
# Open new trades with capital check
|
||||
if available_capital > 0 and len(open_trades) < 15:
|
||||
if row['rsi'] < 30 and row['macd'] > row['signal']:
|
||||
position_size = min(
|
||||
RISK_PER_TRADE * virtual_balance, # Normal risk amount
|
||||
available_capital # Never exceed remaining balance
|
||||
)
|
||||
open_trades.append({
|
||||
'entry_time': row['timestamp'],
|
||||
'entry_price': current_price,
|
||||
'size': position_size,
|
||||
'investment_usd': position_size # Track investment in USD
|
||||
})
|
||||
|
||||
|
||||
print(open_trades)
|
||||
# Calculate Performance Metrics
|
||||
total_trades = len(trade_log)
|
||||
winning_trades = sum(1 for trade in trade_log if trade['success'])
|
||||
win_rate = (winning_trades / total_trades) * 100 if total_trades > 0 else 0
|
||||
total_return = ((virtual_balance / 50) - 1) * 100
|
||||
returns = [trade['profit'] for trade in trade_log]
|
||||
sharpe_ratio = np.mean(returns) / np.std(returns) if len(returns) > 1 else 0
|
||||
|
||||
# Print Results
|
||||
print(f"""
|
||||
Backtest Results:
|
||||
- Starting Capital: $50 USDC
|
||||
- Ending Balance: ${virtual_balance:.2f} USDC
|
||||
- Total Return: {total_return:.2f}%
|
||||
- Win Rate: {win_rate:.2f}%
|
||||
- Trades Executed: {total_trades}
|
||||
- Sharpe Ratio: {sharpe_ratio:.2f}
|
||||
""")
|
||||
|
||||
|
||||
|
||||
# Visualization
|
||||
plt.figure(figsize=(16, 12))
|
||||
|
||||
# Price Chart
|
||||
ax1 = plt.subplot(3, 1, 1)
|
||||
plt.plot(df['timestamp'], df['close'], label='Price', color='black')
|
||||
for trade in trade_log:
|
||||
entry_idx = df[df['timestamp'] == trade['entry_time']].index[0]
|
||||
exit_idx = df[df['timestamp'] == trade['exit_time']].index[0]
|
||||
plt.plot([trade['entry_time'], trade['exit_time']],
|
||||
[df.loc[entry_idx, 'close'], df.loc[exit_idx, 'close']],
|
||||
color='green' if trade['success'] else 'red', alpha=0.3)
|
||||
plt.scatter(trade['entry_time'], df.loc[entry_idx, 'close'],
|
||||
marker='^', color='green', s=100)
|
||||
plt.scatter(trade['exit_time'], df.loc[exit_idx, 'close'],
|
||||
marker='v', color='red', s=100)
|
||||
|
||||
# Annotate investment amount
|
||||
plt.text(trade['entry_time'], df.loc[entry_idx, 'close'],
|
||||
f"${trade['investment_usd']:.2f}", fontsize=8, color='blue')
|
||||
|
||||
plt.title('Trading Strategy Performance')
|
||||
plt.ylabel('Price')
|
||||
|
||||
# Plot open trades with orange and annotate investments
|
||||
for trade in open_trades:
|
||||
entry_idx = df[df['timestamp'] == trade['entry_time']].index[0]
|
||||
plt.plot([trade['entry_time'], df['timestamp'].iloc[-1]],
|
||||
[df.loc[entry_idx, 'close'], df.iloc[-1]['close']],
|
||||
color='orange', alpha=0.3)
|
||||
plt.scatter(trade['entry_time'], df.loc[entry_idx, 'close'],
|
||||
marker='^', color='orange', s=100)
|
||||
|
||||
# Annotate investment amount for open trades
|
||||
plt.text(trade['entry_time'], df.loc[entry_idx, 'close'],
|
||||
f"${trade['investment_usd']:.2f}", fontsize=8, color='blue')
|
||||
|
||||
# Indicators
|
||||
plt.subplot(3, 1, 2, sharex=ax1)
|
||||
plt.plot(df['timestamp'], df['rsi'], label='RSI', color='purple')
|
||||
plt.axhline(30, linestyle='--', color='green')
|
||||
plt.axhline(70, linestyle='--', color='red')
|
||||
plt.ylabel('RSI')
|
||||
|
||||
plt.subplot(3, 1, 3, sharex=ax1)
|
||||
plt.plot(df['timestamp'], df['macd'], label='MACD', color='blue')
|
||||
plt.plot(df['timestamp'], df['signal'], label='Signal', color='orange')
|
||||
plt.ylabel('MACD')
|
||||
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
Loading…
x
Reference in New Issue
Block a user