Текущая стратегия:
- Порог цены: бот ожидает изменения цены на 0,50 %, прежде чем разместить сделку.
< /li>
Скальпинг Логика: бот пытается купить по самой низкой цене и продать по самой высокой цене за определенный период. - Размещение ордеров: ордера на покупку размещаются на 0,5 % ниже последней зарегистрированной цены, а ордера на продажу — на 0,5 % выше последней цены.
- Ограниченная прибыльность. Несмотря на то, что бот совершает сделки, прибыль минимальна, и стратегия, похоже, не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия, похоже, не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия, похоже, не приносит значительной прибыли.
Ограниченная прибыльность. p> - Сроки исполнения: движения цен могут быть быстрыми, что приводит к пропущенным или задержанным ордерам.
- Колебания цен: Быстрые колебания рынка могут вызвать ложные сигналы, что приведет к убыточным сделкам.
- Управление ордерами: бот не учитывает факторы. при волатильности или проскальзывании рынка, что приводит к неэффективным сделкам.
- Процент стоп-лосса: стоп-лосс 0,5 % и скользящий стоп-лосс на 1 % ниже самой высокой цены.
- Тейк-профит: 0,05 % выше цены последней сделки.
- Риск на сделку: распределение риска 2 %.
- Рыночные индикаторы: расчеты для RSI, скользящих средних (MA) и полос Боллинджера.
- Какие торговые стратегии я могу реализовать, чтобы оптимизировать прибыльность, помимо базового скальпинга?
Вот фрагмент текущего кода:
`
import hmac
import hashlib
import time
import json
import uuid
import logging
import asyncio
import aiohttp
import websockets
import sys
import numpy as np
if sys.platform == "win32":
import asyncio
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
# Set up logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
# Constants
API_KEY = ""
API_SECRET = ""
STOP_LOSS_PERCENT = 0.995 # 0.5% stop-loss
TAKE_PROFIT_PERCENT = 1.0005 # 0.05% take-profit
TRAILING_STOP_PERCENT = 0.995 # Trailing stop of 1% below highest price
COOLDOWN_SECONDS = 5 # Time to wait between each market check (slowed down)
MAX_TRADE_AMOUNT_ZAR = 50 # Maximum capital allocated per trade
TRADE_RISK_PERCENT = 0.02 # 2% risk per trade
# Trading state variables
active_trade = False
last_trade_time = 0
last_order_price = None
price_history = []
highest_price = 0
# Calculate dynamic stop-loss and take-profit thresholds based on market volatility
def calculate_dynamic_threshold(last_price, price):
volatility_factor = 0.1 # Adjust this factor based on historical volatility
diff = abs(price - last_price)
return volatility_factor * diff
# Calculate RSI
def calculate_rsi(prices, period=14):
if len(prices) < period:
return None # Not enough data to calculate RSI
deltas = np.diff(prices)
gains = deltas[deltas > 0].sum() / period
losses = -deltas[deltas < 0].sum() / period
rs = gains / losses if losses != 0 else float('inf')
rsi = 100 - (100 / (1 + rs))
return rsi
# Calculate moving averages
def calculate_ma(prices, period):
if len(prices) < period:
return None # Not enough data for moving average
return np.mean(prices[-period:])
# Calculate Bollinger Bands
def calculate_bollinger_bands(prices, period=20, std_dev=2):
if len(prices) < period:
return None, None, None # Not enough data
sma = np.mean(prices[-period:])
std = np.std(prices[-period:])
upper_band = sma + (std_dev * std)
lower_band = sma - (std_dev * std)
return upper_band, lower_band, sma
# Generate API signature for requests
def generate_signature(api_secret, timestamp, verb, path, body=""):
body = body if body else ""
message = f"{timestamp}{verb}{path}{body}"
return hmac.new(api_secret.encode(), message.encode(), hashlib.sha512).hexdigest()
# Fetch account balance
async def get_balance():
url = "https://api.valr.com/v1/account/balance ... ances=true"
timestamp = str(int(time.time() * 1000))
signature = generate_signature(API_SECRET, timestamp, "GET", "/v1/account/balances?excludeZeroBalances=true")
headers = {
"X-VALR-API-KEY": API_KEY,
"X-VALR-SIGNATURE": signature,
"X-VALR-TIMESTAMP": timestamp,
}
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as response:
if response.status == 200:
data = await response.json()
balance = {item["currency"]: float(item["available"]) for item in data}
logging.info(f"Balance: {balance}")
return balance
else:
logging.error(f"Error fetching balance: {response.status} - {await response.text()}")
return None
except Exception as e:
logging.error(f"Error fetching balance: {e}")
return None
# Place limit order
async def place_limit_order(pair, side, price):
customer_order_id = str(uuid.uuid4())
rounded_price = round(price, 2) # Round price to two decimal places
zar_amount = MAX_TRADE_AMOUNT_ZAR
quantity = zar_amount / rounded_price # Calculate the quantity to buy/sell
balance = await get_balance()
if not balance or (side == "BUY" and balance.get("ZAR", 0) < zar_amount):
logging.warning("Insufficient balance to place order.")
return None # Insufficient balance
url = "https://api.valr.com/v1/orders/limit"
payload = json.dumps({
"side": side,
"quantity": f"{quantity:.8f}", # Limit to 8 decimal places
"price": str(rounded_price),
"pair": pair,
"postOnly": True, # Ensures the order is a limit order
"customerOrderId": customer_order_id,
})
timestamp = str(int(time.time() * 1000))
signature = generate_signature(API_SECRET, timestamp, "POST", "/v1/orders/limit", payload)
headers = {
"Content-Type": "application/json",
"X-VALR-API-KEY": API_KEY,
"X-VALR-SIGNATURE": signature,
"X-VALR-TIMESTAMP": timestamp,
}
try:
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, data=payload) as response:
if response.status in [200, 202]:
logging.info(f"Placed {side} order: {quantity} @ {rounded_price}")
# Add a small delay to allow order processing before fetching balance again
await asyncio.sleep(2)
# Fetch updated balance after order
balance = await get_balance()
if balance:
logging.info(f"Updated Balance after trade: {balance}")
return await response.json()
else:
logging.error(f"Error placing {side} order: {response.status} - {await response.text()}")
return None
except Exception as e:
logging.error(f"Error placing {side} order: {e}")
return None
# Execute advanced scalping strategy with multi-indicators
async def execute_scalping_strategy(pair, order_threshold=0.5):
global active_trade, last_trade_time, last_order_price, highest_price
ws_url = "wss://api.valr.com/ws/trade"
last_logged_price = None
while True:
try:
async with websockets.connect(ws_url) as websocket:
subscription_message = {
"type": "SUBSCRIBE",
"subscriptions": [{"event": "MARKET_SUMMARY_UPDATE", "pairs": [pair]}]
}
await websocket.send(json.dumps(subscription_message))
while True:
message = await websocket.recv()
message_data = json.loads(message)
if "data" in message_data:
data = message_data["data"]
price = float(data.get("askPrice") or data.get("bidPrice") or data.get("lastTradedPrice", 0))
if price:
# Update price history and calculate indicators
price_history.append(price)
if len(price_history) > 100: # Keep only the last 20 prices
price_history.pop(0)
# Calculate short and long moving averages
short_ma = calculate_ma(price_history, 50) # 5-period short MA
long_ma = calculate_ma(price_history, 100) # 10-period long MA
# Calculate RSI
rsi = calculate_rsi(price_history)
# Calculate Bollinger Bands
upper_band, lower_band, sma = calculate_bollinger_bands(price_history)
logging.info(f"Price: {price}, Short MA: {short_ma}, Long MA: {long_ma}, RSI: {rsi}, Upper Band: {upper_band}, Lower Band: {lower_band}")
# Check if enough data for both RSI, MAs, and Bollinger Bands
if short_ma and long_ma and rsi is not None and upper_band and lower_band:
# Implement trading logic based on RSI, MAs, and Bollinger Bands
if rsi > 70 and price > short_ma and price > long_ma and price > upper_band:
logging.info(f"Sell Signal for {pair} at {price}")
if last_order_price and price >= last_order_price * TAKE_PROFIT_PERCENT:
await place_limit_order(pair, "SELL", price)
active_trade = False
elif rsi < 30 and price < short_ma and price < long_ma and price < lower_band:
logging.info(f"Buy Signal for {pair} at {price}")
if not active_trade:
await place_limit_order(pair, "BUY", price)
active_trade = True
else:
logging.warning("No price data found.")
except Exception as e:
logging.error(f"Error in scalping strategy: {e}")
await asyncio.sleep(COOLDOWN_SECONDS) # Delay before checking market again
# Start the trading bot
async def start_trading():
pair = "ETHZAR" # Example pair
await execute_scalping_strategy(pair)
# Run the trading bot
if __name__ == "__main__":
asyncio.run(start_trading())
Я работаю над ботом для торговли криптовалютой, который интегрируется с API Valr и фокусируется на паре ETHZAR (Ethereum и южноафриканский рэнд). Бот использует WebSockets для получения рыночных данных в режиме реального времени и размещает заказы на покупку/продажу в зависимости от колебаний цен. Основная стратегия представляет собой простой скальперский подход, который пытается купить ETH по более низкой цене и продать его по более высокой цене, извлекая выгоду из небольших изменений цен.
Текущая стратегия:
- Порог цены: бот ожидает изменения цены на 0,50 %, прежде чем разместить сделку.
< /li>
Скальпинг Логика: бот пытается купить по самой низкой цене и продать по самой высокой цене за определенный период. - Размещение ордеров: ордера на покупку размещаются на 0,5 % ниже последней зарегистрированной цены, а ордера на продажу — на 0,5 % выше последней цены.
- Ограниченная прибыльность. Несмотря на то, что бот совершает сделки, прибыль минимальна, и стратегия, похоже, не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия, похоже, не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия не приносит значительной прибыли.
Ограниченная прибыльность. Хотя бот совершает сделки, доходность минимальна, и стратегия, похоже, не приносит значительной прибыли.
Ограниченная прибыльность. p> - Сроки исполнения: движения цен могут быть быстрыми, что приводит к пропущенным или задержанным ордерам.
- Колебания цен: Быстрые колебания рынка могут вызвать ложные сигналы, что приведет к убыточным сделкам.
- Управление ордерами: бот не учитывает факторы. при волатильности или проскальзывании рынка, что приводит к неэффективным сделкам.
- Процент стоп-лосса: стоп-лосс 0,5 % и скользящий стоп-лосс на 1 % ниже самой высокой цены.
- Тейк-профит: 0,05 % выше цены последней сделки.
- Риск на сделку: распределение риска 2 %.
- Рыночные индикаторы: расчеты для RSI, скользящих средних (MA) и полос Боллинджера.
- Какие торговые стратегии я могу реализовать, чтобы оптимизировать прибыльность, помимо базового скальпинга?
Вот фрагмент текущего кода:
`
import hmac
import hashlib
import time
import json
import uuid
import logging
import asyncio
import aiohttp
import websockets
import sys
import numpy as np
if sys.platform == "win32":
import asyncio
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
# Set up logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
# Constants
API_KEY = ""
API_SECRET = ""
STOP_LOSS_PERCENT = 0.995 # 0.5% stop-loss
TAKE_PROFIT_PERCENT = 1.0005 # 0.05% take-profit
TRAILING_STOP_PERCENT = 0.995 # Trailing stop of 1% below highest price
COOLDOWN_SECONDS = 5 # Time to wait between each market check (slowed down)
MAX_TRADE_AMOUNT_ZAR = 50 # Maximum capital allocated per trade
TRADE_RISK_PERCENT = 0.02 # 2% risk per trade
# Trading state variables
active_trade = False
last_trade_time = 0
last_order_price = None
price_history = []
highest_price = 0
# Calculate dynamic stop-loss and take-profit thresholds based on market volatility
def calculate_dynamic_threshold(last_price, price):
volatility_factor = 0.1 # Adjust this factor based on historical volatility
diff = abs(price - last_price)
return volatility_factor * diff
# Calculate RSI
def calculate_rsi(prices, period=14):
if len(prices) < period:
return None # Not enough data to calculate RSI
deltas = np.diff(prices)
gains = deltas[deltas > 0].sum() / period
losses = -deltas[deltas < 0].sum() / period
rs = gains / losses if losses != 0 else float('inf')
rsi = 100 - (100 / (1 + rs))
return rsi
# Calculate moving averages
def calculate_ma(prices, period):
if len(prices) < period:
return None # Not enough data for moving average
return np.mean(prices[-period:])
# Calculate Bollinger Bands
def calculate_bollinger_bands(prices, period=20, std_dev=2):
if len(prices) < period:
return None, None, None # Not enough data
sma = np.mean(prices[-period:])
std = np.std(prices[-period:])
upper_band = sma + (std_dev * std)
lower_band = sma - (std_dev * std)
return upper_band, lower_band, sma
# Generate API signature for requests
def generate_signature(api_secret, timestamp, verb, path, body=""):
body = body if body else ""
message = f"{timestamp}{verb}{path}{body}"
return hmac.new(api_secret.encode(), message.encode(), hashlib.sha512).hexdigest()
# Fetch account balance
async def get_balance():
url = "https://api.valr.com/v1/account/balance ... ances=true"
timestamp = str(int(time.time() * 1000))
signature = generate_signature(API_SECRET, timestamp, "GET", "/v1/account/balances?excludeZeroBalances=true")
headers = {
"X-VALR-API-KEY": API_KEY,
"X-VALR-SIGNATURE": signature,
"X-VALR-TIMESTAMP": timestamp,
}
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as response:
if response.status == 200:
data = await response.json()
balance = {item["currency"]: float(item["available"]) for item in data}
logging.info(f"Balance: {balance}")
return balance
else:
logging.error(f"Error fetching balance: {response.status} - {await response.text()}")
return None
except Exception as e:
logging.error(f"Error fetching balance: {e}")
return None
# Place limit order
async def place_limit_order(pair, side, price):
customer_order_id = str(uuid.uuid4())
rounded_price = round(price, 2) # Round price to two decimal places
zar_amount = MAX_TRADE_AMOUNT_ZAR
quantity = zar_amount / rounded_price # Calculate the quantity to buy/sell
balance = await get_balance()
if not balance or (side == "BUY" and balance.get("ZAR", 0) < zar_amount):
logging.warning("Insufficient balance to place order.")
return None # Insufficient balance
url = "https://api.valr.com/v1/orders/limit"
payload = json.dumps({
"side": side,
"quantity": f"{quantity:.8f}", # Limit to 8 decimal places
"price": str(rounded_price),
"pair": pair,
"postOnly": True, # Ensures the order is a limit order
"customerOrderId": customer_order_id,
})
timestamp = str(int(time.time() * 1000))
signature = generate_signature(API_SECRET, timestamp, "POST", "/v1/orders/limit", payload)
headers = {
"Content-Type": "application/json",
"X-VALR-API-KEY": API_KEY,
"X-VALR-SIGNATURE": signature,
"X-VALR-TIMESTAMP": timestamp,
}
try:
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, data=payload) as response:
if response.status in [200, 202]:
logging.info(f"Placed {side} order: {quantity} @ {rounded_price}")
# Add a small delay to allow order processing before fetching balance again
await asyncio.sleep(2)
# Fetch updated balance after order
balance = await get_balance()
if balance:
logging.info(f"Updated Balance after trade: {balance}")
return await response.json()
else:
logging.error(f"Error placing {side} order: {response.status} - {await response.text()}")
return None
except Exception as e:
logging.error(f"Error placing {side} order: {e}")
return None
# Execute advanced scalping strategy with multi-indicators
async def execute_scalping_strategy(pair, order_threshold=0.5):
global active_trade, last_trade_time, last_order_price, highest_price
ws_url = "wss://api.valr.com/ws/trade"
last_logged_price = None
while True:
try:
async with websockets.connect(ws_url) as websocket:
subscription_message = {
"type": "SUBSCRIBE",
"subscriptions": [{"event": "MARKET_SUMMARY_UPDATE", "pairs": [pair]}]
}
await websocket.send(json.dumps(subscription_message))
while True:
message = await websocket.recv()
message_data = json.loads(message)
if "data" in message_data:
data = message_data["data"]
price = float(data.get("askPrice") or data.get("bidPrice") or data.get("lastTradedPrice", 0))
if price:
# Update price history and calculate indicators
price_history.append(price)
if len(price_history) > 100: # Keep only the last 20 prices
price_history.pop(0)
# Calculate short and long moving averages
short_ma = calculate_ma(price_history, 50) # 5-period short MA
long_ma = calculate_ma(price_history, 100) # 10-period long MA
# Calculate RSI
rsi = calculate_rsi(price_history)
# Calculate Bollinger Bands
upper_band, lower_band, sma = calculate_bollinger_bands(price_history)
logging.info(f"Price: {price}, Short MA: {short_ma}, Long MA: {long_ma}, RSI: {rsi}, Upper Band: {upper_band}, Lower Band: {lower_band}")
# Check if enough data for both RSI, MAs, and Bollinger Bands
if short_ma and long_ma and rsi is not None and upper_band and lower_band:
# Implement trading logic based on RSI, MAs, and Bollinger Bands
if rsi > 70 and price > short_ma and price > long_ma and price > upper_band:
logging.info(f"Sell Signal for {pair} at {price}")
if last_order_price and price >= last_order_price * TAKE_PROFIT_PERCENT:
await place_limit_order(pair, "SELL", price)
active_trade = False
elif rsi < 30 and price < short_ma and price < long_ma and price < lower_band:
logging.info(f"Buy Signal for {pair} at {price}")
if not active_trade:
await place_limit_order(pair, "BUY", price)
active_trade = True
else:
logging.warning("No price data found.")
except Exception as e:
logging.error(f"Error in scalping strategy: {e}")
await asyncio.sleep(COOLDOWN_SECONDS) # Delay before checking market again
# Start the trading bot
async def start_trading():
pair = "ETHZAR" # Example pair
await execute_scalping_strategy(pair)
# Run the trading bot
if __name__ == "__main__":
asyncio.run(start_trading()
Подробнее здесь: https://stackoverflow.com/questions/792 ... t-strategy
Мобильная версия