173 lines
No EOL
5.6 KiB
Python
173 lines
No EOL
5.6 KiB
Python
'''
|
|
VWAP Trading Strategy Overview:
|
|
|
|
VWAP Signal Logic:
|
|
- Uses Volume Weighted Average Price as primary trend indicator
|
|
- Price > VWAP: Bullish bias (70% chance to go long)
|
|
- Price < VWAP: Bearish bias (30% chance to go long)
|
|
- Incorporates randomization to avoid predictable patterns
|
|
|
|
Order Placement Strategy:
|
|
- Uses 11th level bid/ask for better fill probability
|
|
- Avoids competing at best bid/offer for improved execution
|
|
- Places limit orders to capture spread while getting fills
|
|
|
|
Position Management:
|
|
- Maximum 1 position at a time
|
|
- Leverage: 3x (adjustable)
|
|
- Profit target: 5% gain
|
|
- Stop loss: 10% loss
|
|
- Dynamic position sizing based on leverage
|
|
|
|
Risk Management:
|
|
- Automatic position and PnL monitoring
|
|
- Order cancellation and re-placement system
|
|
- Maximum position limits to control exposure
|
|
- Ethereum account-based execution with private key security
|
|
|
|
Technical Setup:
|
|
- Symbol: LINK (configurable)
|
|
- Timeframe: 1 minute
|
|
- VWAP calculation: Real-time volume weighted average
|
|
- Execution: DeFi/on-chain trading platform
|
|
|
|
WARNING: Do not run without thorough backtesting and understanding!
|
|
'''
|
|
|
|
import Functions.funcs as func
|
|
import eth_account
|
|
import time, random
|
|
import schedule
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
# Configuration
|
|
symbol = 'LINK'
|
|
timeframe = '1m'
|
|
sma_window = 20
|
|
lookback_days = 1
|
|
size = 1
|
|
target = 5
|
|
max_loss = -10
|
|
leverage = 3
|
|
max_positions = 1
|
|
|
|
def get_account():
|
|
"""Initialize trading account from private key"""
|
|
secret = os.getenv('PRIVATE_KEY')
|
|
return eth_account.Account.from_key(secret)
|
|
|
|
def get_vwap_signal(symbol):
|
|
"""Calculate VWAP signal and determine trade direction"""
|
|
try:
|
|
ask, bid, l2_data = func.ask_bid(symbol)
|
|
|
|
# Get 11th level bid and ask for better execution
|
|
bid_11 = float(l2_data[0][10]['px'])
|
|
ask_11 = float(l2_data[1][10]['px'])
|
|
|
|
# Get current VWAP
|
|
latest_vwap = func.calculate_vwap_with_symbol(symbol)[1]
|
|
|
|
print(f'Market Data - Bid: {bid:.4f} | Ask: {ask:.4f} | VWAP: {latest_vwap:.4f}')
|
|
print(f'11th Level - Bid: {bid_11:.4f} | Ask: {ask_11:.4f}')
|
|
|
|
# Randomization factor for signal variation
|
|
random_chance = random.random()
|
|
|
|
# VWAP-based signal logic
|
|
if bid > latest_vwap:
|
|
# Price above VWAP - bullish bias
|
|
go_long = random_chance <= 0.7 # 70% chance
|
|
signal_strength = "Strong Bullish" if go_long else "Weak Bullish"
|
|
print(f'Price > VWAP: {signal_strength} (Random: {random_chance:.2f})')
|
|
else:
|
|
# Price below VWAP - bearish bias
|
|
go_long = random_chance <= 0.3 # 30% chance
|
|
signal_strength = "Contrarian Long" if go_long else "Bearish"
|
|
print(f'Price < VWAP: {signal_strength} (Random: {random_chance:.2f})')
|
|
|
|
return go_long, bid_11, ask_11, latest_vwap
|
|
|
|
except Exception as e:
|
|
print(f'Error getting VWAP signal: {e}')
|
|
return False, 0, 0, 0
|
|
|
|
def manage_position(symbol, account):
|
|
"""Check and manage existing positions"""
|
|
try:
|
|
positions, in_position, position_size, pos_symbol, entry_price, pnl_percent, is_long, num_positions = func.get_position_andmaxpos(
|
|
symbol, account, max_positions
|
|
)
|
|
|
|
print(f'Position Status - In position: {in_position} | Size: {position_size} | PnL: {pnl_percent}%')
|
|
|
|
if in_position:
|
|
func.cancel_all_orders(account)
|
|
print('Managing existing position - checking PnL')
|
|
func.pnl_close(symbol, target, max_loss, account)
|
|
return True
|
|
else:
|
|
print('No position - ready for new trade')
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f'Error managing position: {e}')
|
|
return False
|
|
|
|
def place_trade(symbol, go_long, bid_11, ask_11, account):
|
|
"""Place trade order based on signal"""
|
|
try:
|
|
# Adjust leverage and position size
|
|
leverage_set, position_size = func.adjust_leverage_size_signal(symbol, leverage, account)
|
|
|
|
func.cancel_all_orders(account)
|
|
print('Canceled all existing orders')
|
|
|
|
if go_long:
|
|
# Place buy order at 11th bid level
|
|
func.limit_order(symbol, True, position_size, bid_11, False, account)
|
|
print(f'LONG order placed: {position_size} at {bid_11:.4f}')
|
|
else:
|
|
# Place sell order at 11th ask level
|
|
func.limit_order(symbol, False, position_size, ask_11, False, account)
|
|
print(f'SHORT order placed: {position_size} at {ask_11:.4f}')
|
|
|
|
except Exception as e:
|
|
print(f'Error placing trade: {e}')
|
|
|
|
def bot():
|
|
try:
|
|
print(f'\n---- VWAP Strategy Running for {symbol} ----')
|
|
|
|
# Initialize account
|
|
account = get_account()
|
|
|
|
# Check existing positions first
|
|
in_position = manage_position(symbol, account)
|
|
|
|
if not in_position:
|
|
# Get VWAP signal and market data
|
|
go_long, bid_11, ask_11, vwap = get_vwap_signal(symbol)
|
|
|
|
if bid_11 > 0 and ask_11 > 0: # Valid market data
|
|
place_trade(symbol, go_long, bid_11, ask_11, account)
|
|
else:
|
|
print('Invalid market data - skipping trade')
|
|
|
|
print('=' * 50)
|
|
|
|
except Exception as e:
|
|
print(f'Bot error: {e}')
|
|
|
|
schedule.every(3).seconds.do(bot)
|
|
|
|
while True:
|
|
try:
|
|
schedule.run_pending()
|
|
time.sleep(10)
|
|
except Exception as e:
|
|
print(f'Schedule error: {e} - Sleeping 30 seconds')
|
|
time.sleep(30) |