Files
lm_code/bitmart/锤子线和上吊线.py
2025-12-19 19:16:41 +08:00

134 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import csv
from datetime import datetime, timezone
import matplotlib.pyplot as plt
# ---------------- 配置 ----------------
CSV_FILE = "kline_3.csv" # CSV 文件路径
LEVERAGE = 100
CAPITAL = 10000
POSITION_RATIO = 0.01
FEE_RATE = 0.0005
# ---------------- 读取 CSV ----------------
data = []
with open(CSV_FILE, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
ts = int(row['id'])
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
if dt.year == 2025 and dt.month == 1:
data.append({
'time': dt,
'open': float(row['open']),
'high': float(row['high']),
'low': float(row['low']),
'close': float(row['close']),
})
# ---------------- 策略回测 ----------------
total_profit = 0
total_fee = 0
trades = [] # 保存每笔交易详情
for i in range(len(data) - 1):
k = data[i]
k_next = data[i + 1]
body = abs(k['close'] - k['open'])
upper_shadow = k['high'] - max(k['close'], k['open'])
lower_shadow = min(k['close'], k['open']) - k['low']
position_usdt = CAPITAL * POSITION_RATIO
leveraged_position = position_usdt * LEVERAGE
# ---------------- 锤子线 → 做多 ----------------
if body != 0 and lower_shadow >= 2 * body:
profit_raw = (k_next['close'] - k['close']) / k['close'] * leveraged_position
fee_open = leveraged_position * FEE_RATE
fee_close = leveraged_position * FEE_RATE
profit_net = profit_raw - fee_open - fee_close
total_profit += profit_raw
total_fee += fee_open + fee_close
trades.append({
'方向': '',
'开仓时间': k['time'].strftime("%Y-%m-%d %H:%M"),
'开仓价格': k['close'],
'平仓时间': k_next['time'].strftime("%Y-%m-%d %H:%M"),
'平仓价格': k_next['close'],
'本金': position_usdt,
'杠杆仓位': leveraged_position,
'开仓手续费': fee_open,
'平仓手续费': fee_close,
'原始盈亏': profit_raw,
'净盈亏': profit_net
})
# ---------------- 上吊线 → 做空 ----------------
elif body != 0 and upper_shadow >= 2 * body:
profit_raw = (k['close'] - k_next['close']) / k['close'] * leveraged_position
fee_open = leveraged_position * FEE_RATE
fee_close = leveraged_position * FEE_RATE
profit_net = profit_raw - fee_open - fee_close
total_profit += profit_raw
total_fee += fee_open + fee_close
trades.append({
'方向': '',
'开仓时间': k['time'].strftime("%Y-%m-%d %H:%M"),
'开仓价格': k['close'],
'平仓时间': k_next['time'].strftime("%Y-%m-%d %H:%M"),
'平仓价格': k_next['close'],
'本金': position_usdt,
'杠杆仓位': leveraged_position,
'开仓手续费': fee_open,
'平仓手续费': fee_close,
'原始盈亏': profit_raw,
'净盈亏': profit_net
})
# ---------------- 输出统计 ----------------
print(f"1月总原始盈亏: {total_profit:.2f} USDT")
print(f"1月总手续费: {total_fee:.2f} USDT")
print(f"1月净盈亏: {total_profit - total_fee:.2f} USDT")
print("\n交易明细前10笔示例:")
n = 0
for t in trades:
if t['原始盈亏'] > 10 or t['原始盈亏'] < -10:
print(f"{t['方向']}仓 | 开仓: {t['开仓时间']} @ {t['开仓价格']:.2f} | "
f"平仓: {t['平仓时间']} @ {t['平仓价格']:.2f} | "
f"本金: {t['本金']:.2f} | 杠杆仓位: {t['杠杆仓位']:.2f} | "
f"开仓手续费: {t['开仓手续费']:.2f} | 平仓手续费: {t['平仓手续费']:.2f} | "
f"原始盈亏: {t['原始盈亏']:.2f} | 净盈亏: {t['净盈亏']:.2f}")
n += t['原始盈亏']
print(n)
# # ---------------- 绘制 K 线图 + 交易点 ----------------
# times = [k['time'] for k in data]
# closes = [k['close'] for k in data]
#
# plt.figure(figsize=(16,6))
# plt.plot(times, closes, color='black', label='ETH 收盘价')
#
# for t in trades:
# open_time = datetime.strptime(t['开仓时间'], "%Y-%m-%d %H:%M")
# close_time = datetime.strptime(t['平仓时间'], "%Y-%m-%d %H:%M")
# if t['方向'] == '多':
# plt.scatter(open_time, t['开仓价格'], color='green', marker='^', s=100, label='多开' if '多开' not in plt.gca().get_legend_handles_labels()[1] else "")
# plt.scatter(close_time, t['平仓价格'], color='red', marker='v', s=100, label='多平' if '多平' not in plt.gca().get_legend_handles_labels()[1] else "")
# else:
# plt.scatter(open_time, t['开仓价格'], color='red', marker='v', s=100, label='空开' if '空开' not in plt.gca().get_legend_handles_labels()[1] else "")
# plt.scatter(close_time, t['平仓价格'], color='green', marker='^', s=100, label='空平' if '空平' not in plt.gca().get_legend_handles_labels()[1] else "")
#
# plt.xlabel('时间')
# plt.ylabel('价格(USDT)')
# plt.title('ETH 永续合约 1 月交易回测100倍杠杆')
# plt.legend()
# plt.grid(True)
# plt.gcf().autofmt_xdate()
# plt.show()