diff --git a/bieget/main.py b/bieget/main.py new file mode 100644 index 0000000..d8a692c --- /dev/null +++ b/bieget/main.py @@ -0,0 +1,139 @@ +import requests +import datetime + +cookies = { + 'bitget_lang': 'zh-CN', + '_dx_kvani5r': '24e0dceb12f85d9a1279183ca29c09f772f8c61124e4eca228d8dd909c9b24b0019c2b9a', + 'OptanonAlertBoxClosed': 'Wed%20Sep%2024%202025%2017:12:32%20GMT+0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)', + 'OptanonConsent': 'isMarketing=1&isStatistic=1', + '_cfuvid': 'IHXjOVVjx5iewfwL1nrgeHsZ6whu9s4iYYYvNvJvOQM-1758867462928-0.0.1.1-604800000', + 'dy_token': '68d630093VQFDNL1nUkv46lfDdhjHGYpoz9dddX1', + 'g_state': '{"i_l":0}', + 'theme': 'white', + 'BITGET_LOCAL_COOKIE': '{%22bitget_lang%22:%22zh-CN%22%2C%22bitget_unit%22:%22CNY%22%2C%22bitget_showasset%22:true%2C%22bitget_theme%22:%22white%22%2C%22bitget_layout%22:%22right%22%2C%22bitget_valuationunit%22:0%2C%22bitget_valuationunit_new%22:1%2C%22bitget_valuationunitandfiat%22:1%2C%22bitgt_login%22:false%2C%22theme%22:%22black%22%2C%22brand_simulation_trade%22:false%2C%22bitget_currency%22:%22%22}', + 'bt_rtoken': 'upex:session:id:1d00ce6487e37f4d7230a5aafe3ffc82e799156a86e9778bacb2310c7cf39b98', + 'bt_uid': '619BB9EC4D4A3F9FC1AC092D38818A00', + 'bt_sessonid': '0bf4ef42-798c-4f8d-8fe5-c07364d3b6b5', + 'bt_newsessionid': 'eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ZjJmNDBjYS0zNTkyLTRiNmItOTdiMy01OWQ5MTU5Y2E2YmQ0NzQ5ODIwMTAiLCJ1aWQiOiIxV00rVjRqcTJYSVRQemdJVWhUMnNRPT0iLCJzdWIiOiJsenoqKipvbSIsImlwIjoiM3dNK05yTkxjQXVQTG95dWZkWkI1QT09IiwiZGlkIjoiSjBZZjQ1NkV5RUxaSGhaa2tWYnNQZTVlSFVYYUNKZS9CM21wTHJ5SHJWMTEyUklzWlFLTTVIQmtTNHlUUmhuVyIsInN0cyI6MCwiaWF0IjoxNzU4ODY3NTgxLCJleHAiOjE3NTkyOTk1ODEsInB1c2hpZCI6ImRka1NMR1VDak9Sd1pFdU1rMFlaMWc9PSIsImlzcyI6InVwZXgifQ.Buwhs7UF7dOnOAso8l-RIyc_A47UdWSeVMiwIonOdiY', + 'USD': 'CNY', + '__cf_bm': '3AMy5P3a.qp5uEqe9d_DonCDcL621CKULNKaUpfn2rE-1758868368-1.0.1.1-JzjFQidqwDxVV3gJH8ls0NeCGe.nsK.SFYP0hPXUcupuLTBpscmBYQRMfAjeOlnaZRBsQROFL2fETfXatDwQwDHU7aHOT4IMwECKB3sTIN4', +} + +headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7', + 'baggage': 'sentry-environment=online,sentry-release=905e3a416e2b0ad3c98a82ab9b94dd87f1a5c1fd,sentry-public_key=8aeef93d782e4ef5ae75634bfee9b590,sentry-trace_id=e7afec8af26a4480893c8b58257af49b', + 'cache-control': 'no-cache', + 'custom-token': '765eb29bf89843258756f8851ed5a48f', + 'deviceid': '7c88d47fdc39e5c422eff197b10d3485', + 'dy-token': '68d630093VQFDNL1nUkv46lfDdhjHGYpoz9dddX1', + 'language': 'zh_CN', + 'locale': 'zh_CN', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://www.bitget.com/zh-CN/futures/usdt/ETHUSDT', + 'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'sentry-trace': 'e7afec8af26a4480893c8b58257af49b-8aacec1747b38bd7-0', + 'terminalcode': 'cc98a9dd01af7e2d50d9b9858723b25e', + 'terminaltype': '1', + 'tm': '1758868503025', + 'uhti': 'w17588685039139806ab12716', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', + 'website': 'mix', + # 'cookie': 'bitget_lang=zh-CN; _dx_kvani5r=24e0dceb12f85d9a1279183ca29c09f772f8c61124e4eca228d8dd909c9b24b0019c2b9a; OptanonAlertBoxClosed=Wed%20Sep%2024%202025%2017:12:32%20GMT+0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4); OptanonConsent=isMarketing=1&isStatistic=1; _cfuvid=IHXjOVVjx5iewfwL1nrgeHsZ6whu9s4iYYYvNvJvOQM-1758867462928-0.0.1.1-604800000; dy_token=68d630093VQFDNL1nUkv46lfDdhjHGYpoz9dddX1; g_state={"i_l":0}; theme=white; BITGET_LOCAL_COOKIE={%22bitget_lang%22:%22zh-CN%22%2C%22bitget_unit%22:%22CNY%22%2C%22bitget_showasset%22:true%2C%22bitget_theme%22:%22white%22%2C%22bitget_layout%22:%22right%22%2C%22bitget_valuationunit%22:0%2C%22bitget_valuationunit_new%22:1%2C%22bitget_valuationunitandfiat%22:1%2C%22bitgt_login%22:false%2C%22theme%22:%22black%22%2C%22brand_simulation_trade%22:false%2C%22bitget_currency%22:%22%22}; bt_rtoken=upex:session:id:1d00ce6487e37f4d7230a5aafe3ffc82e799156a86e9778bacb2310c7cf39b98; bt_uid=619BB9EC4D4A3F9FC1AC092D38818A00; bt_sessonid=0bf4ef42-798c-4f8d-8fe5-c07364d3b6b5; bt_newsessionid=eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ZjJmNDBjYS0zNTkyLTRiNmItOTdiMy01OWQ5MTU5Y2E2YmQ0NzQ5ODIwMTAiLCJ1aWQiOiIxV00rVjRqcTJYSVRQemdJVWhUMnNRPT0iLCJzdWIiOiJsenoqKipvbSIsImlwIjoiM3dNK05yTkxjQXVQTG95dWZkWkI1QT09IiwiZGlkIjoiSjBZZjQ1NkV5RUxaSGhaa2tWYnNQZTVlSFVYYUNKZS9CM21wTHJ5SHJWMTEyUklzWlFLTTVIQmtTNHlUUmhuVyIsInN0cyI6MCwiaWF0IjoxNzU4ODY3NTgxLCJleHAiOjE3NTkyOTk1ODEsInB1c2hpZCI6ImRka1NMR1VDak9Sd1pFdU1rMFlaMWc9PSIsImlzcyI6InVwZXgifQ.Buwhs7UF7dOnOAso8l-RIyc_A47UdWSeVMiwIonOdiY; USD=CNY; __cf_bm=3AMy5P3a.qp5uEqe9d_DonCDcL621CKULNKaUpfn2rE-1758868368-1.0.1.1-JzjFQidqwDxVV3gJH8ls0NeCGe.nsK.SFYP0hPXUcupuLTBpscmBYQRMfAjeOlnaZRBsQROFL2fETfXatDwQwDHU7aHOT4IMwECKB3sTIN4', +} +if __name__ == '__main__': + + params = { + 'symbolId': 'ETHUSDT_UMCBL', + 'kLineStep': '1m', + 'kLineType': '1', + 'endTime': '1758864600000', + } + + response = requests.get( + 'https://www.bitget.com/v1/kline/getMoreKlineDataV2', + params=params, cookies=cookies, headers=headers + ) + + raw_data = response.json()["data"] + + print(raw_data) + + # 转换成字典格式,方便后续处理 + data = [] + for i in raw_data: + data.append({ + 'id': int(i[0]) // 1000, # 秒级时间戳 + 'open': float(i[1]), + 'high': float(i[2]), + 'low': float(i[3]), + 'close': float(i[4]), + }) + + print(i) + + print(data) + + # 按时间排序 + sorted_data = sorted(data, key=lambda x: x['id']) + + print(sorted_data) + + signals = 0 + wins = 0 + lig_price = 0 + low_price = 0 + + for idx in range(1, len(sorted_data) - 2): # 至少留两根 K 线验证 + prev = sorted_data[idx - 1] + curr = sorted_data[idx] + future = sorted_data[idx + 2] + + prev_open, prev_close = prev['open'], prev['close'] + curr_open, curr_close = curr['open'], curr['close'] + future_close = future['close'] + + # 当前为涨 + if curr_close > curr_open: + # 前一笔涨 + 包裹 + if prev_close > prev_open and curr_open < prev_open and curr_close > prev_close: + signals += 1 + lig_price += (future_close - curr_close) + if future_close > curr_close: + wins += 1 + # 前一笔跌 + 反包 + elif prev_close < prev_open and curr_open < prev_close and curr_close > prev_open: + signals += 1 + lig_price += (future_close - curr_close) + if future_close > curr_close: + wins += 1 + + # 当前为跌 + elif curr_close < curr_open: + # 前一笔跌 + 包裹 + if prev_close < prev_open and curr_open > prev_open and curr_close < prev_close: + signals += 1 + low_price += (curr_close - future_close) + if future_close < curr_close: + wins += 1 + # 前一笔涨 + 反包 + elif prev_close > prev_open and curr_open > prev_close and curr_close < prev_open: + signals += 1 + low_price += (curr_close - future_close) + if future_close < curr_close: + wins += 1 + + if signals > 0: + win_rate = wins / signals * 100 + print(f"信号数={signals}, 胜率={win_rate:.2f}%") + else: + print("没有找到符合条件的形态") + + print("上涨盈亏合计:", lig_price) + print("下跌盈亏合计:", low_price) diff --git a/回测数据/test1.py b/回测数据/test1.py index a76bcba..e05c5d3 100644 --- a/回测数据/test1.py +++ b/回测数据/test1.py @@ -1,6 +1,6 @@ import datetime import requests -import plotly.graph_objects as go +from loguru import logger headers = { 'accept': 'application/json, text/plain, */*', @@ -20,76 +20,119 @@ headers = { } if __name__ == '__main__': - time_ser = datetime.datetime(2025, 9, 25) - start_of_day = time_ser.replace(hour=0, minute=0, second=0, microsecond=0) - end_of_day = time_ser.replace(hour=23, minute=59, second=59, microsecond=0) - start_timestamp = start_of_day.timestamp() - end_timestamp = end_of_day.timestamp() + zh_project = 0 + all_trades = [] # 存放所有交易记录 - params = { - 'symbol': 'ETH-USDT', - 'period': '1min', - 'start': int(start_timestamp), - 'end': int(end_timestamp), - } + for i in range(1, 29): - response = requests.get('https://capi.websea.com/webApi/market/getKline', params=params, headers=headers) - data = response.json()['result']['data'] - sorted_data = sorted(data, key=lambda x: x['id']) + # 请求数据 + time_ser = datetime.datetime(2025, 9, i) + start_of_day = time_ser.replace(hour=0, minute=0, second=0, microsecond=0) + end_of_day = time_ser.replace(hour=23, minute=59, second=59, microsecond=0) + params = { + 'symbol': 'ETH-USDT', + 'period': '1min', + 'start': int(start_of_day.timestamp()), + 'end': int(end_of_day.timestamp()), + } - # 处理成列表 - times = [datetime.datetime.fromtimestamp(d['id']) for d in sorted_data] - opens = [float(d['open']) for d in sorted_data] - highs = [float(d['high']) for d in sorted_data] - lows = [float(d['low']) for d in sorted_data] - closes = [float(d['close']) for d in sorted_data] + response = requests.get('https://capi.websea.com/webApi/market/getKline', params=params, headers=headers) + data = response.json()['result']['data'] + sorted_data = sorted(data, key=lambda x: x['id']) - # 找到策略点位 - signal_times = [] - signal_prices = [] + signals = 0 + wins = 0 - for i in range(1, len(sorted_data)): - current_data = sorted_data[i] - prev_data = sorted_data[i - 1] + lig_price = 0 + low_price = 0 - if float(current_data['open']) < float(current_data['close']): # 当前上涨 - if float(prev_data['open']) < float(prev_data['close']): # 前一笔上涨 - if float(current_data['open']) < float(prev_data['open']) and float(current_data['close']) > float(prev_data['close']): - signal_times.append(datetime.datetime.fromtimestamp(current_data['id'])) - signal_prices.append(float(current_data['close'])) - else: # 前一笔下跌 - if float(current_data['open']) < float(prev_data['close']) and float(current_data['close']) > float(prev_data['open']): - signal_times.append(datetime.datetime.fromtimestamp(current_data['id'])) - signal_prices.append(float(current_data['close'])) + for idx in range(1, len(sorted_data) - 5): # 需要至少留两根K线做验证 + prev = sorted_data[idx - 1] # 前一笔 + curr = sorted_data[idx] # 当前这笔 + future = sorted_data[idx + 5] # 两根后的K线 - # 绘制K线图 - fig = go.Figure(data=[ - go.Candlestick( - x=times, - open=opens, - high=highs, - low=lows, - close=closes, - name="K线" + prev_open, prev_close = float(prev['open']), float(prev['close']) + curr_open, curr_close = float(curr['open']), float(curr['close']) + future_close = float(future['close']) + + # 当前为涨 + if curr_close > curr_open: + # 前一笔涨 + 包裹 + if prev_close > prev_open and curr_open < prev_open and curr_close > prev_close: + signals += 1 + diff = future_close - curr_close + lig_price += diff + all_trades.append((f"{i}号", curr["id"], "做多", curr_close, future_close, diff, future["id"])) + + if future_close > curr_close: + wins += 1 + + # 前一笔跌 + 反包 + elif prev_close < prev_open and curr_open < prev_close and curr_close > prev_open: + signals += 1 + diff = future_close - curr_close + lig_price += diff + all_trades.append((f"{i}号", curr["id"], "做多", curr_close, future_close, diff, future["id"])) + + if future_close > curr_close: + wins += 1 + + # 当前为跌 + elif curr_close < curr_open: + # 前一笔跌 + 包裹 + if prev_close < prev_open and curr_open > prev_open and curr_close < prev_close: + signals += 1 + diff = curr_close - future_close + low_price += diff + all_trades.append((f"{i}号", curr["id"], "做空", curr_close, future_close, diff, future["id"])) + + if future_close < curr_close: + wins += 1 + + # 前一笔涨 + 反包 + elif prev_close > prev_open and curr_open > prev_close and curr_close < prev_open: + signals += 1 + diff = curr_close - future_close + low_price += diff + all_trades.append((f"{i}号", curr["id"], "做空", curr_close, future_close, diff, future["id"])) + + if future_close < curr_close: + wins += 1 + + if signals > 0: + logger.info( + f"日期:{i}号,信号数={signals}, 胜率={wins / signals * 100:.2f}%,上涨方向:{lig_price:.2f},下跌方向:{low_price:.2f},综合价格:{(lig_price + low_price):.2f}" + ) + else: + logger.info(f"日期:{i}号,没有信号") + + zh_project += (lig_price + low_price) + + logger.success(f"综合价格:{zh_project:.2f}") + + # 输出每笔交易 + logger.info("===== 每笔交易详情 =====") + + n = 0 + n1 = 0 + for trade in all_trades: + date, time_str, direction, entry, exit, diff, end_time = trade + + # logger.info(f"{date} {direction} 入场={entry:.2f} 出场={exit:.2f} 差价={diff:.2f} 盈利:{diff / entry * 10000}") + logger.info( + f"{date} {time_str} {direction} 入场={entry:.2f} 出场={exit:.2f} 出场时间:{end_time} 差价={diff:.2f} 盈利:{diff / entry * 10000} 开仓手续费:5u 平仓手续费:{10000 / entry * exit * 0.0005}" ) - ]) - # 添加信号点 - fig.add_trace(go.Scatter( - x=signal_times, - y=signal_prices, - mode="markers", - marker=dict(color="red", size=10, symbol="triangle-up"), - name="做多信号" - )) + # 手续费率是在 0.06% + # 开仓手续费 + # 平仓手续费 + # 10000 / entry * exit * 0.0006 - fig.update_layout( - title="ETH-USDT 1分钟K线图 (含做多信号)", - xaxis_title="时间", - yaxis_title="价格", - xaxis_rangeslider_visible=False, - template="plotly_dark" - ) + n1 += 5 + (10000 / entry * exit * 0.0005) - fig.show() + n += ((diff / entry) * 10000) + + print(len(all_trades)) + print(n) + print(n1) diff --git a/回测数据/test2.py b/回测数据/test2.py new file mode 100644 index 0000000..a6ef46f --- /dev/null +++ b/回测数据/test2.py @@ -0,0 +1,134 @@ +import datetime +import requests +from loguru import logger + +headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7', + 'cache-control': 'no-cache', + 'origin': 'https://www.websea.com', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://www.websea.com/', + 'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', +} + + +def fetch_kline(day: int): + """获取某一天的分钟K线数据""" + time_ser = datetime.datetime(2025, 9, day) + start_of_day = time_ser.replace(hour=0, minute=0, second=0, microsecond=0) + end_of_day = time_ser.replace(hour=23, minute=59, second=59, microsecond=0) + params = { + 'symbol': 'ETH-USDT', + 'period': '1min', + 'start': int(start_of_day.timestamp()), + 'end': int(end_of_day.timestamp()), + } + response = requests.get('https://capi.websea.com/webApi/market/getKline', params=params, headers=headers) + data = response.json()['result']['data'] + return sorted(data, key=lambda x: x['id']) + + +if __name__ == '__main__': + + zh_project = 0 + all_trades = [] # 存放所有交易记录 + + for i in range(30, 31): + + sorted_data = fetch_kline(i) + + signals = wins = 0 + lig_price = low_price = 0 + + for idx in range(1, len(sorted_data) - 6): + prev = sorted_data[idx - 1] # 前一根K + curr = sorted_data[idx] # 当前K + entry_candle = sorted_data[idx + 1] # ✅ 下一根K线作为开仓点 + future = sorted_data[idx + 5] # 5根后的K线 + + prev_open, prev_close = float(prev['open']), float(prev['close']) + curr_open, curr_close = float(curr['open']), float(curr['close']) + entry_open = float(entry_candle['open']) + future_close = float(future['close']) + + # 当前为涨 + if curr_close > curr_open: + # 前一笔涨 + 包裹 + if prev_close > prev_open and curr_open < prev_open and curr_close > prev_close: + signals += 1 + diff = future_close - entry_open + lig_price += diff + all_trades.append((f"{i}号", entry_candle["id"], "做多", entry_open, future_close, diff, future["id"])) + + if future_close > entry_open: + wins += 1 + + # # 前一笔跌 + 反包 + # elif prev_close < prev_open and curr_open < prev_close and curr_close > prev_open: + # signals += 1 + # diff = future_close - entry_open + # lig_price += diff + # all_trades.append((f"{i}号", entry_candle["id"], "做多", entry_open, future_close, diff, future["id"])) + # + # if future_close > entry_open: + # wins += 1 + # + # # 当前为跌 + # elif curr_close < curr_open: + # # 前一笔跌 + 包裹 + # if prev_close < prev_open and curr_open > prev_open and curr_close < prev_close: + # signals += 1 + # diff = entry_open - future_close + # low_price += diff + # all_trades.append((f"{i}号", entry_candle["id"], "做空", entry_open, future_close, diff, future["id"])) + # + # if future_close < entry_open: + # wins += 1 + # + # # 前一笔涨 + 反包 + # elif prev_close > prev_open and curr_open > prev_close and curr_close < prev_open: + # signals += 1 + # diff = entry_open - future_close + # low_price += diff + # all_trades.append((f"{i}号", entry_candle["id"], "做空", entry_open, future_close, diff, future["id"])) + # + # if future_close < entry_open: + # wins += 1 + + if signals > 0: + logger.info( + f"日期:{i}号,信号数={signals}, 胜率={wins / signals * 100:.2f}%,上涨方向:{lig_price:.2f},下跌方向:{low_price:.2f},综合价格:{(lig_price + low_price):.2f}" + ) + else: + logger.info(f"日期:{i}号,没有信号") + + zh_project += (lig_price + low_price) + + logger.success(f"综合价格:{zh_project:.2f}") + + # 输出每笔交易 + logger.info("===== 每笔交易详情 =====") + + n = n1 = 0 + for trade in all_trades: + date, time_str, direction, entry, exit, diff, end_time = trade + + logger.info( + f"{date} {time_str} {direction} 入场={entry:.2f} 出场={exit:.2f} 出场时间:{end_time} 差价={diff:.2f} 盈利:{diff / entry * 10000} " + f"开仓手续费:5u 平仓手续费:{10000 / entry * exit * 0.0005}" + ) + + n1 += 5 + (10000 / entry * exit * 0.0005) + n += (diff / entry) * 10000 + + print(len(all_trades)) + print(n) + print(n1) diff --git a/回测数据/接口分析,回测胜率.py b/回测数据/接口分析,回测胜率.py index f91a8b7..f28002d 100644 --- a/回测数据/接口分析,回测胜率.py +++ b/回测数据/接口分析,回测胜率.py @@ -21,7 +21,7 @@ headers = { if __name__ == '__main__': # 请求数据 - time_ser = datetime.datetime(2025, 9, 24) + time_ser = datetime.datetime(2025, 9, 22) start_of_day = time_ser.replace(hour=0, minute=0, second=0, microsecond=0) end_of_day = time_ser.replace(hour=23, minute=59, second=59, microsecond=0) params = { @@ -38,6 +38,9 @@ if __name__ == '__main__': signals = 0 wins = 0 + lig_price = 0 + low_price = 0 + for idx in range(1, len(sorted_data) - 2): # 需要至少留两根K线做验证 prev = sorted_data[idx - 1] # 前一笔 curr = sorted_data[idx] # 当前这笔 @@ -52,24 +55,41 @@ if __name__ == '__main__': # 前一笔涨 + 包裹 if prev_close > prev_open and curr_open < prev_open and curr_close > prev_close: signals += 1 + + lig_price += (future_close - curr_close) + if future_close > curr_close: wins += 1 + + + # 前一笔跌 + 反包 elif prev_close < prev_open and curr_open < prev_close and curr_close > prev_open: signals += 1 + + lig_price += (future_close - curr_close) + if future_close > curr_close: wins += 1 + # 当前为跌 elif curr_close < curr_open: # 前一笔跌 + 包裹 if prev_close < prev_open and curr_open > prev_open and curr_close < prev_close: signals += 1 + + low_price += (curr_close - future_close) + if future_close < curr_close: wins += 1 + + # 前一笔涨 + 反包 elif prev_close > prev_open and curr_open > prev_close and curr_close < prev_open: signals += 1 + + low_price += (curr_close - future_close) if future_close < curr_close: wins += 1 @@ -78,3 +98,6 @@ if __name__ == '__main__': print(f"信号数={signals}, 胜率={win_rate:.2f}%") else: print("没有找到符合条件的形态") + + print(lig_price) + print(low_price) diff --git a/回测数据/接口分析,批量回测数据.py b/回测数据/接口分析,批量回测数据.py new file mode 100644 index 0000000..e75a520 --- /dev/null +++ b/回测数据/接口分析,批量回测数据.py @@ -0,0 +1,111 @@ +import datetime +import requests + +from loguru import logger + +headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7', + 'cache-control': 'no-cache', + 'origin': 'https://www.websea.com', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://www.websea.com/', + 'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', +} + +if __name__ == '__main__': + + zh_project = 0 + + for i in range(1, 31): + + # 请求数据 + time_ser = datetime.datetime(2025, 8, i) + start_of_day = time_ser.replace(hour=0, minute=0, second=0, microsecond=0) + end_of_day = time_ser.replace(hour=23, minute=59, second=59, microsecond=0) + params = { + 'symbol': 'ETH-USDT', + 'period': '1min', + 'start': int(start_of_day.timestamp()), + 'end': int(end_of_day.timestamp()), + } + + response = requests.get('https://capi.websea.com/webApi/market/getKline', params=params, headers=headers) + data = response.json()['result']['data'] + sorted_data = sorted(data, key=lambda x: x['id']) + + signals = 0 + wins = 0 + + lig_price = 0 + low_price = 0 + + for idx in range(1, len(sorted_data) - 2): # 需要至少留两根K线做验证 + prev = sorted_data[idx - 1] # 前一笔 + curr = sorted_data[idx] # 当前这笔 + future = sorted_data[idx + 2] # 两根后的K线 + + prev_open, prev_close = float(prev['open']), float(prev['close']) + curr_open, curr_close = float(curr['open']), float(curr['close']) + future_close = float(future['close']) + + # 当前为涨 + if curr_close > curr_open: + # 前一笔涨 + 包裹 + if prev_close > prev_open and curr_open < prev_open and curr_close > prev_close: + signals += 1 + + lig_price += (future_close - curr_close) + + if future_close > curr_close: + wins += 1 + + # 前一笔跌 + 反包 + elif prev_close < prev_open and curr_open < prev_close and curr_close > prev_open: + signals += 1 + + lig_price += (future_close - curr_close) + + if future_close > curr_close: + wins += 1 + + + # 当前为跌 + elif curr_close < curr_open: + # 前一笔跌 + 包裹 + if prev_close < prev_open and curr_open > prev_open and curr_close < prev_close: + signals += 1 + + low_price += (curr_close - future_close) + + if future_close < curr_close: + wins += 1 + + + # 前一笔涨 + 反包 + elif prev_close > prev_open and curr_open > prev_close and curr_close < prev_open: + signals += 1 + + low_price += (curr_close - future_close) + if future_close < curr_close: + wins += 1 + + # if signals > 0: + # win_rate = wins / signals * 100 + # print(f"信号数={signals}, 胜率={win_rate:.2f}%") + # else: + # print("没有找到符合条件的形态") + + logger.info( + f"日期:{i}号,信号数={signals}, 胜率={wins / signals * 100:.2f}%,上涨方向:{lig_price:.2f},下跌方向:{low_price:.2f},综合价格:{(lig_price - low_price):.2f}") + + zh_project += (lig_price - low_price) + + logger.success(f"综合价格:{zh_project:.2f}")