''' 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)