174 lines
No EOL
5.8 KiB
Python
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) |