commit dc64e230c0fd752e99c809862b77c57854e0b225 Author: arch_enjoyer Date: Sun Apr 13 13:59:00 2025 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..72a83ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +bin/* +include/* +lib/* +lib64/* +share/* +.env +.git +pyvenv.cfg \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..2274c67 --- /dev/null +++ b/bot.py @@ -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() \ No newline at end of file