1
Fork 0
crypto_bot_training/Session_05/bots/Breakout.py
2025-06-26 15:46:49 +02:00

174 lines
No EOL
5.8 KiB
Python

'''
Breakout Trading Strategy Overview:
Support/Resistance Calculation:
- Uses 3 days of 15-minute data (289 periods) for range analysis
- Calculates support (lowest close) and resistance (highest close) levels
- Establishes key levels based on recent price action
Breakout Detection:
- BULLISH breakout: Current bid > recent resistance level
- BEARISH breakdown: Current bid < recent support level
- Confirms momentum before placing trades
Entry Strategy:
- LONG: Place buy order 0.1% above broken resistance (retest entry)
- SHORT: Place sell order 0.1% below broken support (retest entry)
- Waits for price to break key levels before entering
Retest Logic:
- Enters on pullbacks to previously broken levels
- Resistance becomes support after bullish breakout
- Support becomes resistance after bearish breakdown
- Higher probability entries on retests vs initial breakouts
Risk Management:
- Profit target: 9% gain
- Stop loss: 8% loss
- Position size management with limits
- Trade pause system to avoid overtrading
Technical Setup:
- Timeframe: 15 minutes
- Lookback: 3 days (289 periods)
- Uses close-based support/resistance (more reliable than wicks)
- Breakout confirmation with 0.1% threshold for noise filtering
WARNING: Do not run without thorough backtesting and understanding!
'''
import ccxt
import time, schedule
import Functions.funcs as func
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv('BINANCE_API_KEY')
api_secret = os.getenv('BINANCE_SECRET_KEY')
exchange = ccxt.binance({
'apiKey': api_key,
'secret': api_secret,
'enableRateLimit': True,
'options': {
'defaultType': 'future',
}
})
# Configuration
symbol = 'BTCUSDT'
pos_size = 30
target = 9
max_loss = -8
pause_time = 10
vol_repeat = 11
vol_time = 5
vol_decimal = 0.4
params = {'timeInForce': 'GTC'}
def get_support_resistance(symbol):
"""Calculate support and resistance from 3 days of 15m data"""
df = func.df_sma(symbol, '15m', 289, 20) # 3 days of 15m data
support = df['close'].min()
resistance = df['close'].max()
# Also get recent support/resistance for comparison
recent_support = df['support'].iloc[-1]
recent_resistance = df['resis'].iloc[-1]
print(f'Levels - Support: {support:.2f} | Resistance: {resistance:.2f}')
print(f'Recent - Support: {recent_support:.2f} | Resistance: {recent_resistance:.2f}')
return support, resistance, recent_support, recent_resistance, df
def detect_breakout(symbol):
"""Detect if price is breaking above resistance or below support"""
support, resistance, recent_support, recent_resistance, df = get_support_resistance(symbol)
ask, bid = func.ask_bid(symbol)
buy_breakout = False
sell_breakdown = False
breakout_price = False
breakdown_price = False
# Check for breakout above recent resistance
if bid > recent_resistance:
print(f'BULLISH BREAKOUT detected - Bid {bid:.2f} > Resistance {recent_resistance:.2f}')
buy_breakout = True
breakout_price = recent_resistance * 1.001 # 0.1% above broken resistance
# Check for breakdown below recent support
elif bid < recent_support:
print(f'BEARISH BREAKDOWN detected - Bid {bid:.2f} < Support {recent_support:.2f}')
sell_breakdown = True
breakdown_price = recent_support * 0.999 # 0.1% below broken support
else:
print(f'Price {bid:.2f} within range [{recent_support:.2f} - {recent_resistance:.2f}]')
return buy_breakout, sell_breakdown, breakout_price, breakdown_price
def bot():
try:
# Check PnL and manage existing positions
func.pnl_close(symbol, target, max_loss)
# Check sleep on close (pause between trades)
func.sleep_on_close(symbol, pause_time)
# Get current prices
ask, bid = func.ask_bid(symbol)
# Detect breakout signals
buy_breakout, sell_breakdown, breakout_price, breakdown_price = detect_breakout(symbol)
# Get position info
_, in_position, position_size, _ = func.open_positions(symbol)
current_size = int(position_size) if position_size else 0
print(f'Status - In position: {in_position} | Size: {current_size} | Price: {bid:.2f}')
print(f'Signals - Breakout: {buy_breakout} | Breakdown: {sell_breakdown}')
# Only trade if not in position and size within limits
if not in_position and current_size < pos_size:
exchange.cancel_all_orders(symbol)
# Refresh prices after canceling orders
ask, bid = func.ask_bid(symbol)
if buy_breakout and breakout_price:
print(f'Placing LONG order - Size: {pos_size} at {breakout_price:.2f}')
exchange.create_limit_buy_order(symbol, pos_size, breakout_price, params)
print('BUY order placed - Sleeping 2 minutes...')
time.sleep(120)
elif sell_breakdown and breakdown_price:
print(f'Placing SHORT order - Size: {pos_size} at {breakdown_price:.2f}')
exchange.create_limit_sell_order(symbol, pos_size, breakdown_price, params)
print('SELL order placed - Sleeping 2 minutes...')
time.sleep(120)
else:
print('No breakout signal - Sleeping 1 minute...')
time.sleep(60)
else:
if in_position:
print('Already in position - Monitoring...')
else:
print('Position size at limit - No new trades')
except Exception as e:
print(f'Bot error: {e}')
schedule.every(28).seconds.do(bot)
while True:
try:
schedule.run_pending()
except Exception as e:
print(f'Schedule error: {e} - Sleeping 30 seconds')
time.sleep(30)