Вот пример бычьего дисбаланса:
На этом графике видно, что часть свечи 2 не ограничена ни до, ни после: это зона дисбаланса.
Этот краткий теоретический раздел носит исключительно информационный характер, поскольку на практике для понимания моей логики требуется только математика. Чтобы найти дисбаланс, просто сравните минимум свечи 3 (самой последней) с максимумом свечи 1 (самой старой). Если разница между ними больше 0, то мы имеем бычий дисбаланс, а ценовой диапазон между этими двумя точками представляет собой тело этого дисбаланса. В приведенном выше примере у нас будет 2,5983 – 2,3737 > 0. Если разница равна или меньше 0, между этими двумя точками не будет разрыва.
Теперь, когда объяснения есть, я расскажу немного предыстории моего исследования. Чтобы продолжить проверку теории, которая меня утомляет, требуя оставаться перед экраном по 16 часов в день, я пытаюсь уберечь себя от утомления, используя сценарий, который позволил бы мне обнаружить ключевые моменты для себя. так что я присутствую перед экраном только тогда, когда наступает момент. Это то, что я уже протестировал, но хочу протестировать в реальном времени в течение длительного периода, поэтому мне нужен код.
Цель сценария:
- Получение данных OHLC за несколько таймфреймов с помощью BingX API.
- Обнаружение дисбалансов на разных таймфреймах.
Таймфреймы: 30 минут, 1 час, 2 часа и 4 часа.
< li>Объединить перекрывающиеся дисбалансы как минимум на трех разных таймфреймах одновременно.
Принцип состоит в том, чтобы просмотреть набор данных из предыдущего шага и проверить, есть ли хотя бы часть дисбаланс частично перекрывается с двумя другими дисбалансами. Пример: первый дисбаланс за 30 минут составляет от 106 до 110, второй дисбаланс за 1 час — от 105 до 111, третий дисбаланс за 2 часа — от 110 до 112 и четвертый дисбаланс — от 99 до 110. Затем дисбалансы будут объединены. , создавая «объединенную зону», простирающуюся от 99 до 112. - Получить текущую рыночную цену.
< /li>
Проверьте, находится ли текущая цена отметки в одной из «объединённых зон».
Здесь цель состоит в том, чтобы проверить, находится ли текущая цена отметки в одной из «объединённых зон». цена составляет не менее 50 % от цены одной или нескольких «объединённых зон». Пример: для выполнения условия «объединенная зона», простирающаяся от 99 до 112, потребует цены маркировки от 105,5 до 99.
Код: Выделить всё
import time
import requests
import hmac
from hashlib import sha256
import pandas as pd
from tabulate import tabulate
# BingX API information
APIURL = "https://open-api.bingx.com"
APIKEY = "API_KEY" # even if what I'm asking for doesn't need it
SECRETKEY = "SECRET_KEY" # even if what I'm asking for doesn't need it
# HMAC signature calculation
def get_sign(api_secret, payload):
signature = hmac.new(api_secret.encode("utf-8"), payload.encode("utf-8"), digestmod=sha256).hexdigest()
return signature
# Send the API request
def send_request(method, path, urlpa, payload=""):
url = f"{APIURL}{path}?{urlpa}&signature={get_sign(SECRETKEY, urlpa)}"
headers = {'X-BX-APIKEY': APIKEY}
response = requests.request(method, url, headers=headers, data=payload)
return response
# OHLC data retrieval for multiple timeframes
def get_ohlc_data_multi(symbol, intervals, limit=50):
ohlc_data = {}
for interval in intervals:
df = get_ohlc_data(symbol, interval=interval, limit=limit)
if df is not None:
# Convert 'high' and 'low' columns to float, with error handling
df['high'] = pd.to_numeric(df['high'], errors='coerce')
df['low'] = pd.to_numeric(df['low'], errors='coerce')
# Delete lines where 'top' or 'bottom' would be NaN (non-numeric)
df.dropna(subset=['low', 'high'], inplace=True)
# Keep only the necessary columns
ohlc_data[interval] = df[['timestamp','low', 'high']]
print(f"Data formatted for {interval} :")
print(ohlc_data[interval].head()) # Displays first lines for verification
else:
print(f"No data available for timeframe {interval}")
return ohlc_data
# Retrieve OHLC data for a single timeframe
def get_ohlc_data(symbol, interval='1h', limit=24, start_time=None):
path = '/openApi/swap/v3/quote/klines'
current_time = int(time.time() * 1000)
if start_time is None:
start_time = current_time - (3600000 * 24) # 24 hours before
paramsMap = {
"symbol": symbol,
"interval": interval,
"limit": limit,
"startTime": start_time
}
paramsStr = parseParam(paramsMap)
response = send_request('GET', path, paramsStr)
if response.status_code == 200:
data = response.json().get("data", [])
if len(data) > 0:
df = pd.DataFrame(data)
df['timestamp'] = pd.to_datetime(df['time'], unit='ms')
df['timestamp'] = df['timestamp'].dt.tz_localize('UTC').dt.tz_convert('Europe/Paris')
df = df[['timestamp', 'low', 'high']]
# Check for valid data before returning the DataFrame
if df['high'].isnull().sum() > 0 or df['low'].isnull().sum() > 0:
print("Incomplete OHLC data detected.")
return None
return df
else:
print("No OHLC data available.")
return None
else:
print(f"Query error: {response.status_code}, message: {response.text}")
return None
# Extract the Mark Price
def get_mark_price(symbol):
path = '/openApi/swap/v2/quote/premiumIndex'
paramsMap = {"symbol": symbol}
paramsStr = parseParam(paramsMap)
# Send request
response = send_request('GET', path, paramsStr)
# Check and return the Mark Price
if response.status_code == 200:
data = response.json()
if 'data' in data and 'markPrice' in data['data']:
mark_price = float(data['data']['markPrice'])
print(f"Mark Price for {symbol}: {mark_price}")
return mark_price
else:
print(f"Mark Price not available for {symbol}")
return None
else:
print(f"Query error: {response.status_code}, message: {response.text}")
return None
# Detecting only bullish imbalances in OHLC data
def detect_imbalances(df, interval):
imbalances = []
for i in range(2, len(df)):
high_bougie_1 = df['high'][i] # High of the first candle
low_bougie_3 = df['low'][i - 2] # Low of the third candle
# Conditions for detecting a bullish imbalance
if low_bougie_3 - high_bougie_1 > 0:
imbalance = {
'index': i - 2, # First candle index
'high_bougie_1': high_bougie_1,
'low_bougie_3': low_bougie_3,
'timestamp': df['timestamp'][i - 1], # Add second candle timestamp
'interval': interval # Add interval (timeframe)
}
imbalances.append(imbalance)
print(f"Imbalance in {interval} @ ({df['timestamp'][i - 1]}) between {high_bougie_1} and {low_bougie_3}")
return pd.DataFrame(imbalances)
# Detecting imbalances on multiple timeframes
def detect_imbalances_multi(ohlc_data):
imbalances_multi = {}
for interval, df in ohlc_data.items():
imbalances_multi[interval] = detect_imbalances(df, interval)
# Display imbalances in tabular form
for interval, imbalances in imbalances_multi.items():
print(f"Imbalances detected @ {interval}:")
# Use tabulate to add rows and format the table
print(tabulate(pd.DataFrame(imbalances), headers='keys', tablefmt='outline', numalign='center'))
return imbalances_multi
# Prepare parameters for API
def parseParam(paramsMap):
sortedKeys = sorted(paramsMap)
paramsStr = "&".join([f"{x}={paramsMap[x]}" for x in sortedKeys])
return paramsStr + "×tamp=" + str(int(time.time() * 1000))
# Main script
if __name__ == '__main__':
symbol = 'TAO-USDT'
# Retrieve OHLC from multiple timeframes (30m, 45m, 1h, 2h)
intervals = ['30m', '1h', '2h', '4h']
ohlc_data_multi = get_ohlc_data_multi(symbol, intervals, limit=50)
# Detect imbalances for each timeframe
imbalances_multi = detect_imbalances_multi(ohlc_data_multi)
# Recovering the Mark Price
mark_price = get_mark_price(symbol)
Код: Выделить всё
Data formatted for 30m :
timestamp low high
0 2024-09-23 18:00:00+02:00 539.33 547.70
1 2024-09-23 17:30:00+02:00 538.25 544.37
2 2024-09-23 17:00:00+02:00 533.44 544.49
3 2024-09-23 16:30:00+02:00 528.03 544.70
4 2024-09-23 16:00:00+02:00 525.61 544.15
Data formatted for 1h :
timestamp low high
0 2024-09-23 18:00:00+02:00 539.33 547.70
1 2024-09-23 17:00:00+02:00 533.44 544.49
2 2024-09-23 16:00:00+02:00 525.61 544.70
3 2024-09-23 15:00:00+02:00 520.11 530.73
4 2024-09-23 14:00:00+02:00 521.28 541.39
Data formatted for 2h :
timestamp low high
0 2024-09-23 18:00:00+02:00 539.33 547.70
1 2024-09-23 16:00:00+02:00 525.61 544.70
2 2024-09-23 14:00:00+02:00 520.11 541.39
3 2024-09-23 12:00:00+02:00 537.24 556.24
4 2024-09-23 10:00:00+02:00 541.57 561.12
Data formatted for 4h :
timestamp low high
0 2024-09-23 18:00:00+02:00 539.33 547.70
1 2024-09-23 14:00:00+02:00 520.11 544.70
2 2024-09-23 10:00:00+02:00 537.24 561.12
3 2024-09-23 06:00:00+02:00 530.43 581.88
4 2024-09-23 02:00:00+02:00 459.84 547.19
Imbalance in 30m @ (2024-09-23 07:00:00+02:00) between 559.56 and 571.0
Imbalance in 30m @ (2024-09-23 06:00:00+02:00) between 538.68 and 547.59
Imbalance in 30m @ (2024-09-23 05:00:00+02:00) between 504.71 and 524.59
Imbalance in 30m @ (2024-09-23 04:30:00+02:00) between 499.26 and 503.8
Imbalance in 30m @ (2024-09-23 03:00:00+02:00) between 479.79 and 489.73
Imbalance in 30m @ (2024-09-23 02:30:00+02:00) between 470.37 and 475.75
Imbalance in 30m @ (2024-09-23 00:30:00+02:00) between 466.04 and 469.15
Imbalance in 30m @ (2024-09-22 21:30:00+02:00) between 461.19 and 464.21
Imbalance in 30m @ (2024-09-22 19:00:00+02:00) between 454.78 and 458.23
Imbalance in 1h @ (2024-09-23 16:00:00+02:00) between 530.73 and 533.44
Imbalance in 1h @ (2024-09-23 06:00:00+02:00) between 547.19 and 550.21
Imbalance in 1h @ (2024-09-23 05:00:00+02:00) between 504.71 and 530.43
Imbalance in 1h @ (2024-09-23 04:00:00+02:00) between 500.0 and 503.8
Imbalance in 1h @ (2024-09-23 03:00:00+02:00) between 479.79 and 491.98
Imbalance in 2h @ (2024-09-23 06:00:00+02:00) between 547.19 and 548.53
Imbalance in 2h @ (2024-09-23 04:00:00+02:00) between 500.0 and 530.43
Imbalance in 2h @ (2024-09-23 02:00:00+02:00) between 483.9 and 491.98
Imbalance in 4h @ (2024-09-23 02:00:00+02:00) between 483.9 and 530.43
Imbalances detected @ 30m:
+----+---------+-----------------+----------------+---------------------------+------------+
| | index | high_bougie_1 | low_bougie_3 | timestamp | interval |
+====+=========+=================+================+===========================+============+
| 0 | 21 | 559.56 | 571 | 2024-09-23 07:00:00+02:00 | 30m |
| 1 | 23 | 538.68 | 547.59 | 2024-09-23 06:00:00+02:00 | 30m |
| 2 | 25 | 504.71 | 524.59 | 2024-09-23 05:00:00+02:00 | 30m |
| 3 | 26 | 499.26 | 503.8 | 2024-09-23 04:30:00+02:00 | 30m |
| 4 | 29 | 479.79 | 489.73 | 2024-09-23 03:00:00+02:00 | 30m |
| 5 | 30 | 470.37 | 475.75 | 2024-09-23 02:30:00+02:00 | 30m |
| 6 | 34 | 466.04 | 469.15 | 2024-09-23 00:30:00+02:00 | 30m |
| 7 | 40 | 461.19 | 464.21 | 2024-09-22 21:30:00+02:00 | 30m |
| 8 | 45 | 454.78 | 458.23 | 2024-09-22 19:00:00+02:00 | 30m |
+----+---------+-----------------+----------------+---------------------------+------------+
Imbalances detected @ 1h:
+----+---------+-----------------+----------------+---------------------------+------------+
| | index | high_bougie_1 | low_bougie_3 | timestamp | interval |
+====+=========+=================+================+===========================+============+
| 0 | 1 | 530.73 | 533.44 | 2024-09-23 16:00:00+02:00 | 1h |
| 1 | 11 | 547.19 | 550.21 | 2024-09-23 06:00:00+02:00 | 1h |
| 2 | 12 | 504.71 | 530.43 | 2024-09-23 05:00:00+02:00 | 1h |
| 3 | 13 | 500 | 503.8 | 2024-09-23 04:00:00+02:00 | 1h |
| 4 | 14 | 479.79 | 491.98 | 2024-09-23 03:00:00+02:00 | 1h |
+----+---------+-----------------+----------------+---------------------------+------------+
Imbalances detected @ 2h:
+----+---------+-----------------+----------------+---------------------------+------------+
| | index | high_bougie_1 | low_bougie_3 | timestamp | interval |
+====+=========+=================+================+===========================+============+
| 0 | 5 | 547.19 | 548.53 | 2024-09-23 06:00:00+02:00 | 2h |
| 1 | 6 | 500 | 530.43 | 2024-09-23 04:00:00+02:00 | 2h |
| 2 | 7 | 483.9 | 491.98 | 2024-09-23 02:00:00+02:00 | 2h |
+----+---------+-----------------+----------------+---------------------------+------------+
Imbalances detected @ 4h:
+----+---------+-----------------+----------------+---------------------------+------------+
| | index | high_bougie_1 | low_bougie_3 | timestamp | interval |
+====+=========+=================+================+===========================+============+
| 0 | 3 | 483.9 | 530.43 | 2024-09-23 02:00:00+02:00 | 4h |
+----+---------+-----------------+----------------+---------------------------+------------+
Mark Price for TAO-USDT: 546.31
Код: Выделить всё
import pandas as pd
# Test data
imb_30m = pd.DataFrame({
'imb_high': [110, 87],
'imb_low': [106, 77]
})
imb_1h = pd.DataFrame({
'imb_high': [111, 93],
'imb_low': [105, 84]
})
imb_2h = pd.DataFrame({
'imb_high': [112, 84],
'imb_low': [110, 66]
})
imb_4h = pd.DataFrame({
'imb_high': [110, 85],
'imb_low': [99, 30]
})
# Detect overlaps and merge imbalances
def merge_imb(*imb_list, tolerance=0.01):
merge_imb = []
checked_imb = set() # Used to keep track of mergers already completed
for i, imb_df in enumerate(imb_list):
for index, row in imb_df.iterrows():
high = row['imb_high']
low = row['imb_low']
overlaps = [row]
# Search for overlaps in other timeframes
for other_imb in imb_list[:i] + imb_list[i + 1:]:
for _, other_row in other_imb.iterrows():
if other_row['imb_low'] = low:
overlaps.append(other_row)
if len(overlaps) >= 3:
merge_high = max([ch['imb_high'] for ch in overlaps])
merge_low = min([ch['imb_low'] for ch in overlaps])
# Avoid duplicates
merge_key = (merge_high, merge_low)
if merge_key not in checked_imb: # Check if already merged
merge_imb.append({'imb_low': merge_low, 'imb_high': merge_high})
checked_imb.add(merge_key) # Mark as processed
return pd.DataFrame(merge_imb)
# Call up the merge function with test data
imb_merged = merge_imb(imb_30m, imb_1h, imb_2h, imb_4h)
# Show merged imbalances
print(imb_merged)
def check_completion(imb_merged, actual_price):
for index, row in imb_merged.iterrows():
high = row['imb_high']
low = row['imb_low']
plage = high - low
level_50 = low + 0.5 * plage
# Check if current price exceeds 50% completion level
if low
Подробнее здесь: [url]https://stackoverflow.com/questions/79015578/need-help-merging-two-working-codes-together[/url]