From 72b3b5309d34f36eb5a760b0d164962ef6a6d283 Mon Sep 17 00:00:00 2001 From: 27942 <2794236280@qq.com> Date: Tue, 21 Oct 2025 15:38:57 +0800 Subject: [PATCH] dededdew --- models/database.db | Bin 31891456 -> 31891456 bytes models/weex.py | 11 + weex/自动化抓取数据.py | 6 +- weex/长期持有信号/读取数据库数据-15分钟版.py | 259 +++++++++++++++++ .../读取数据库数据-15分钟版,不判断信号.py | 265 ++++++++++++++++++ weex/长期持有信号/读取数据库数据-1小时版.py | 259 +++++++++++++++++ .../读取数据库数据-1小时版,不判断信号.py | 265 ++++++++++++++++++ weex/长期持有信号/读取数据库数据-30分钟版.py | 259 +++++++++++++++++ .../读取数据库数据-30分钟版,不判断信号.py | 265 ++++++++++++++++++ 9 files changed, 1586 insertions(+), 3 deletions(-) create mode 100644 weex/长期持有信号/读取数据库数据-15分钟版.py create mode 100644 weex/长期持有信号/读取数据库数据-15分钟版,不判断信号.py create mode 100644 weex/长期持有信号/读取数据库数据-1小时版.py create mode 100644 weex/长期持有信号/读取数据库数据-1小时版,不判断信号.py create mode 100644 weex/长期持有信号/读取数据库数据-30分钟版.py create mode 100644 weex/长期持有信号/读取数据库数据-30分钟版,不判断信号.py diff --git a/models/database.db b/models/database.db index d07c4c547d00770b15bdc15949c7e72320dd1c6c..f1f8945180afa62bc0efc331f157f8d4f4d84bba 100644 GIT binary patch delta 247924 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

+1WpSWF0UG@?SCOyI9izh^S7) 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 delta 7109 zcmeI!hj)#49LMqJ$;}e7kw}baX|>eq(nYjJ5NT>A1Q8Jd++%^=iKv4F3#~xMrMFd+*!k@IoL1) zIvIx3dc!bW=Qn6tnX3)ceB3#;c=#Efqdks$_!afdbFSrDl#u5<)2YDEXL({NvE*2WT7oUU4tJe57Z%RG9OP`c^3q9hY4Cq11!Y0L4rb4SX-&GD z?%dg0T5kMzCnc;-YFHf;4zR!xPH=_`Tu}jTsEA5%hX*|21#kGk7nM;3RpAGJR6_s) zQ5`i<6SWY8+IR^sL%*jkUcsxVhu82r>Z1YPKtnV_V>CfiyotB)Hr~OzXomOjK0d&Q z_z2C>qA09R@UHr1tD;Kb!SSXgq(Udnyq`<<)rjC>-far37akr6GK{LN3#|9A?GH+g ziVQ|ee2h=f3a!xwZ4rWYXpasEMMs3;Q-tF)bV6rzL05D`cSIl(JGd_jCc&ePz=LxBwz$aViZPW48~#{#$y5|ViG1}3KEfoWK6|0q+mK` zU?x&A3$u}iIhc!iNJj=TF&_(%g@ssz#mL4IEJY5MVL4VH7gpq9C01cI)*v6BV=dO< z3#`YN*nqFF5np2yHe(A4@C~-25JmVF+prxwuoJtm8#WYU5B6do_TvB!q6CL<7)Njv z$8a1ca1y6*8l^acvp9z`oW})R#3fwD6MISDH8x~7x+>k2?n;F6;^Fnss;3gA^ip~& zeUxaWuM%V0_=hpql@&Rj+BC-1TDwtyv#u>SBG!CrTH{;io8Gp_wy|ax(^_(`+zhn& zhQ^wYEZL@4cCgDsw_>*}w;|b?k7N7`q8~qVv2F;7HLqL4bMwtw*7faT&E_`0rm<$6 zbD>v@L|0p4vsg35CBux4HA#OZP8pyKR0b)7m3U={GE^C+3|A7A5z0tqlrmZwql{I? zDdUw1%0y+7GFh3TBq~WtvNBbfrlcs-l^M!RB~_WF%vRErIm%pRo|3L)D4EK9Wr32V zEL0XLi*O*S5lFUtpQR4ybv&ra+Zs?8( zM4|_Jq8ECj52Dc*G3bX_^hX>9U?2uT8<%(t!B7mta3o*^MjA;*z$g}@F$QBX4&yNa z6EO*sF$IZ8LNcae8d5MFGcXgWn1$I$!yL@TJftH7nV63S`mii4#3C$4HkM#1a!fUA`dIE3ahaO`S=`bu?}B=EnC2s*nqFF5nqF;2W&>t7E*w3uoZUcaz9^0r;D(B*1b2AA6JCvpH+@Pj|9Apm@1 zV0CM#cfPr{MjO^`5rTGTj}8b$M{5JGeDkFBISqGT%#~~`!BT62f4;fbmgbjlt}|a8 z#?~u}$#bsxV&m>*uYCgc3D_rKpMZS=_6gW0V4r|}0`>{mCt#m|eFFc>32bpm&)jCF zXKu$1?8GkYh7HBogT2^?{WySwD8V5d#t|IFF&xJUoWv=dMk&tVEY6_}=WziSaS4}k Y1y^wm*Kq?kaSOLmjyvYY%)6%7zt5t@=l}o! diff --git a/models/weex.py b/models/weex.py index de83bb6..52d161e 100644 --- a/models/weex.py +++ b/models/weex.py @@ -38,6 +38,17 @@ class Weex1Hour(Model): database = db table_name = 'weex_1_hour' +class Weex30(Model): + id = IntegerField(primary_key=True) + open = FloatField(null=True) + high = FloatField(null=True) + low = FloatField(null=True) + close = FloatField(null=True) + + class Meta: + database = db + table_name = 'weex_30' + # 连接到数据库 db.connect() diff --git a/weex/自动化抓取数据.py b/weex/自动化抓取数据.py index cacc96f..1b0103a 100644 --- a/weex/自动化抓取数据.py +++ b/weex/自动化抓取数据.py @@ -1,7 +1,7 @@ from DrissionPage import ChromiumPage, ChromiumOptions from bit_tools import openBrowser -from models.weex import Weex1, Weex1Hour +from models.weex import Weex1, Weex1Hour, Weex15, Weex30 if __name__ == '__main__': @@ -17,7 +17,7 @@ if __name__ == '__main__': page.set.window.max() - page.listen.start("https://http-gateway1.janapw.com/api/v1/public/quote/v1/getKlineV2") + page.listen.start("https://http-gateway1.ngsvsfx.cn/api/v1/public/quote/v1/getKlineV2") page.get(url="https://www.weeaxs.site/zh-CN/futures/ETH-USDT") @@ -28,7 +28,7 @@ if __name__ == '__main__': print(res.response.url) for data in res.response.body['data']["dataList"]: - Weex1Hour.get_or_create( + Weex30.get_or_create( id=int(data[4]), defaults={ 'open': float(data[3]), diff --git a/weex/长期持有信号/读取数据库数据-15分钟版.py b/weex/长期持有信号/读取数据库数据-15分钟版.py new file mode 100644 index 0000000..06f62b6 --- /dev/null +++ b/weex/长期持有信号/读取数据库数据-15分钟版.py @@ -0,0 +1,259 @@ +""" +量化交易回测系统 - 仅15分钟K线 & 信号续持/反手/单根反色平仓逻辑(完整版) +""" + +import datetime +from dataclasses import dataclass +from typing import List, Dict, Optional +from loguru import logger +from models.weex import Weex15 # 替换为你的15分钟K线模型 + + +# ========================= 工具函数 ========================= + +def is_bullish(c): # 阳线 + return float(c['close']) > float(c['open']) + + +def is_bearish(c): # 阴线 + return float(c['close']) < float(c['open']) + + +def check_signal(prev, curr): + """ + 包住形态信号判定(仅15分钟K线): + - 前跌后涨包住 -> 做多 + - 前涨后跌包住 -> 做空 + """ + p_open, p_close = float(prev['open']), float(prev['close']) + c_open, c_close = float(curr['open']), float(curr['close']) + + # 前跌后涨包住 -> 做多 + if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open: + return "long", "bear_bull_engulf" + + # 前涨后跌包住 -> 做空 + if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open: + return "short", "bull_bear_engulf" + + return None, None + + +def get_data_by_date(model, date_str: str): + """按天获取指定表的数据(15分钟)""" + try: + target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d') + except ValueError: + logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。") + return [] + + start_ts = int(target_date.timestamp() * 1000) + end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1 + + query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc()) + return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query] + + +# ========================= 回测逻辑 ========================= + +def backtest_15m_trend_optimized(dates: List[str]): + all_data: List[Dict] = [] + for d in dates: + all_data.extend(get_data_by_date(Weex15, d)) + if not all_data: + return [], { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + all_data.sort(key=lambda x: x['id']) + + stats = { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + trades: List[Dict] = [] + current_position: Optional[Dict] = None + idx = 1 + + while idx < len(all_data) - 1: + prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1] + direction, signal_key = check_signal(prev, curr) + + # 空仓 -> 碰到信号则开仓 + if current_position is None and direction: + entry_price = float(next_bar['open']) + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': entry_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + if current_position: + pos_dir = current_position['direction'] + pos_sig_key = current_position['signal_key'] + + # 反向信号 -> 下一根开盘平仓 + 同价反手 + if direction and direction != pos_dir: + exit_price = float(next_bar['open']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: stats[pos_sig_key]['wins'] += 1 + + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': exit_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + # 同向信号 -> 续持 + if direction and direction == pos_dir: + idx += 1 + continue + + # 单根反色K线 -> 判断后续是否能组成信号 + curr_is_opposite = (pos_dir == 'long' and is_bearish(curr)) or (pos_dir == 'short' and is_bullish(curr)) + if curr_is_opposite: + can_peek = idx + 1 < len(all_data) + if can_peek: + lookahead_dir, _ = check_signal(curr, all_data[idx + 1]) + if lookahead_dir is not None: + idx += 1 + continue # 后续可组成信号,等待信号处理 + + # 否则按收盘价平仓 + exit_price = float(next_bar['close']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: stats[pos_sig_key]['wins'] += 1 + current_position = None + + idx += 1 + + # 尾仓:最后一根收盘价平仓 + if current_position: + last = all_data[-1] + exit_price = float(last['close']) + pos_dir = current_position['direction'] + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[current_position['signal_key']]['total_profit'] += diff + if diff > 0: stats[current_position['signal_key']]['wins'] += 1 + + return trades, stats + + +# ========================= 运行示例(优化版盈利计算) ========================= +if __name__ == '__main__': + dates = [] + for i in range(1, 11): + for i1 in range(1, 31): + dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{i1}") + # + # print(dates) + + # dates = [f"2025-10-{i}" for i in range(1, 31)] + trades, stats = backtest_15m_trend_optimized(dates) + + logger.info("===== 每笔交易详情 =====") + + # === 参数设定 === + contract_size = 10000 # 合约规模(1手对应多少基础货币) + open_fee_fixed = 5 # 固定开仓手续费 + close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率 + + total_points_profit = 0 # 累计点差 + total_money_profit = 0 # 累计金额盈利 + total_fee = 0 # 累计手续费 + + for t in trades: + entry = t['entry'] + exit = t['exit'] + direction = t['direction'] + + # === 1️⃣ 原始价差(点差) === + point_diff = (exit - entry) if direction == '做多' else (entry - exit) + + # === 2️⃣ 金额盈利(考虑合约规模) === + money_profit = point_diff / entry * contract_size # 利润以基础货币计(例如USD) + + # === 3️⃣ 手续费计算 === + # 开仓 + 平仓手续费(按比例计算 + 固定) + fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate) + + # === 4️⃣ 净利润 === + net_profit = money_profit - fee + + # 保存计算结果 + t.update({ + 'point_diff': point_diff, + 'raw_profit': money_profit, + 'fee': fee, + 'net_profit': net_profit + }) + + total_points_profit += point_diff + total_money_profit += money_profit + total_fee += fee + + # if net_profit > 500 or net_profit < -500: + logger.info( + f"{t['entry_time']} {direction}({t['signal']}) " + f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} " + f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}" + ) + + # === 汇总统计 === + total_net_profit = total_money_profit - total_fee + print(f"\n一共交易笔数:{len(trades)}") + print(f"总点差:{total_points_profit:.2f}") + print(f"总原始盈利(未扣费):{total_money_profit:.2f}") + print(f"总手续费:{total_fee:.2f}") + print(f"总净利润:{total_net_profit:.2f}\n") + + print("===== 信号统计 =====") + for k, v in stats.items(): + name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit'] + win_rate = (wins / count * 100) if count > 0 else 0.0 + avg_p = (total_p / count) if count > 0 else 0.0 + print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}") diff --git a/weex/长期持有信号/读取数据库数据-15分钟版,不判断信号.py b/weex/长期持有信号/读取数据库数据-15分钟版,不判断信号.py new file mode 100644 index 0000000..c58336b --- /dev/null +++ b/weex/长期持有信号/读取数据库数据-15分钟版,不判断信号.py @@ -0,0 +1,265 @@ +""" +量化交易回测系统 - 仅15分钟K线 & 反向K线即时平仓逻辑(完整版) +""" + +import datetime +from dataclasses import dataclass +from typing import List, Dict, Optional +from loguru import logger +from models.weex import Weex15 # 替换为你的15分钟K线模型 + + +# ========================= 工具函数 ========================= + +def is_bullish(c): # 阳线 + return float(c['close']) > float(c['open']) + + +def is_bearish(c): # 阴线 + return float(c['close']) < float(c['open']) + + +def check_signal(prev, curr): + """ + 包住形态信号判定: + - 前跌后涨包住 -> 做多 + - 前涨后跌包住 -> 做空 + """ + p_open, p_close = float(prev['open']), float(prev['close']) + c_open, c_close = float(curr['open']), float(curr['close']) + + if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open: + return "long", "bear_bull_engulf" + if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open: + return "short", "bull_bear_engulf" + + return None, None + + +def get_data_by_date(model, date_str: str): + """按天获取指定表的数据(15分钟K线)""" + try: + target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d') + except ValueError: + logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。") + return [] + + start_ts = int(target_date.timestamp() * 1000) + end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1 + + query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc()) + return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query] + + +# ========================= 回测逻辑 ========================= + +def backtest_15m_trend_simplified(dates: List[str]): + all_data: List[Dict] = [] + for d in dates: + all_data.extend(get_data_by_date(Weex15, d)) + if not all_data: + return [], { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + all_data.sort(key=lambda x: x['id']) + + stats = { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + trades: List[Dict] = [] + current_position: Optional[Dict] = None + idx = 1 + + while idx < len(all_data) - 1: + prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1] + direction, signal_key = check_signal(prev, curr) + + # 空仓 -> 碰到信号则开仓 + if current_position is None and direction: + entry_price = float(next_bar['open']) + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': entry_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + if current_position: + pos_dir = current_position['direction'] + pos_sig_key = current_position['signal_key'] + + # 反向信号 -> 平仓 + 反手 + if direction and direction != pos_dir: + exit_price = float(next_bar['open']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + + # 反手开仓 + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': exit_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + # === 新逻辑:遇到反向K线立即平仓 === + if pos_dir == 'long' and is_bearish(curr): + exit_price = float(curr['close']) + diff = exit_price - current_position['entry_price'] + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + current_position = None + idx += 1 + continue + + if pos_dir == 'short' and is_bullish(curr): + exit_price = float(curr['close']) + diff = current_position['entry_price'] - exit_price + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + current_position = None + idx += 1 + continue + + idx += 1 + + # 尾仓平仓 + if current_position: + last = all_data[-1] + exit_price = float(last['close']) + pos_dir = current_position['direction'] + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[current_position['signal_key']]['total_profit'] += diff + if diff > 0: + stats[current_position['signal_key']]['wins'] += 1 + + return trades, stats + + +# ========================= 运行示例 ========================= +if __name__ == '__main__': + # dates = [f"2025-06-{i}" for i in range(1, 31)] + + dates = [] + for i in range(1, 11): + for i1 in range(1, 31): + dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{f'0{i1}' if len(str(i1)) < 2 else i1}") + + + + trades, stats = backtest_15m_trend_simplified(dates) + + logger.info("===== 每笔交易详情 =====") + + # === 参数设定 === + contract_size = 10000 # 合约规模(1手对应多少基础货币) + open_fee_fixed = 5 # 固定开仓手续费 + close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率 + + total_points_profit = 0 # 累计点差 + total_money_profit = 0 # 累计金额盈利 + total_fee = 0 # 累计手续费 + + for t in trades: + entry = t['entry'] + exit = t['exit'] + direction = t['direction'] + + # === 1️⃣ 原始价差(点差) === + point_diff = (exit - entry) if direction == '做多' else (entry - exit) + + # === 2️⃣ 金额盈利(考虑合约规模) === + money_profit = point_diff / entry * contract_size # 利润以基础货币计(例如USD) + + # === 3️⃣ 手续费计算 === + fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate) + + # === 4️⃣ 净利润 === + net_profit = money_profit - fee + + # 保存计算结果 + t.update({ + 'point_diff': point_diff, + 'raw_profit': money_profit, + 'fee': fee, + 'net_profit': net_profit + }) + + total_points_profit += point_diff + total_money_profit += money_profit + total_fee += fee + + logger.info( + f"{t['entry_time']} {direction}({t['signal']}) " + f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} " + f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}" + ) + + # === 汇总统计 === + total_net_profit = total_money_profit - total_fee + print(f"\n一共交易笔数:{len(trades)}") + print(f"总点差:{total_points_profit:.2f}") + print(f"总原始盈利(未扣费):{total_money_profit:.2f}") + print(f"总手续费:{total_fee:.2f}") + print(f"总净利润:{total_net_profit:.2f}\n") + + print("===== 信号统计 =====") + for k, v in stats.items(): + name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit'] + win_rate = (wins / count * 100) if count > 0 else 0.0 + avg_p = (total_p / count) if count > 0 else 0.0 + print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}") diff --git a/weex/长期持有信号/读取数据库数据-1小时版.py b/weex/长期持有信号/读取数据库数据-1小时版.py new file mode 100644 index 0000000..3a59a3c --- /dev/null +++ b/weex/长期持有信号/读取数据库数据-1小时版.py @@ -0,0 +1,259 @@ +""" +量化交易回测系统 - 仅15分钟K线 & 信号续持/反手/单根反色平仓逻辑(完整版) +""" + +import datetime +from dataclasses import dataclass +from typing import List, Dict, Optional +from loguru import logger +from models.weex import Weex1Hour # 替换为你的15分钟K线模型 + + +# ========================= 工具函数 ========================= + +def is_bullish(c): # 阳线 + return float(c['close']) > float(c['open']) + + +def is_bearish(c): # 阴线 + return float(c['close']) < float(c['open']) + + +def check_signal(prev, curr): + """ + 包住形态信号判定(仅15分钟K线): + - 前跌后涨包住 -> 做多 + - 前涨后跌包住 -> 做空 + """ + p_open, p_close = float(prev['open']), float(prev['close']) + c_open, c_close = float(curr['open']), float(curr['close']) + + # 前跌后涨包住 -> 做多 + if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open: + return "long", "bear_bull_engulf" + + # 前涨后跌包住 -> 做空 + if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open: + return "short", "bull_bear_engulf" + + return None, None + + +def get_data_by_date(model, date_str: str): + """按天获取指定表的数据(15分钟)""" + try: + target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d') + except ValueError: + logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。") + return [] + + start_ts = int(target_date.timestamp() * 1000) + end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1 + + query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc()) + return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query] + + +# ========================= 回测逻辑 ========================= + +def backtest_15m_trend_optimized(dates: List[str]): + all_data: List[Dict] = [] + for d in dates: + all_data.extend(get_data_by_date(Weex1Hour, d)) + if not all_data: + return [], { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + all_data.sort(key=lambda x: x['id']) + + stats = { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + trades: List[Dict] = [] + current_position: Optional[Dict] = None + idx = 1 + + while idx < len(all_data) - 1: + prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1] + direction, signal_key = check_signal(prev, curr) + + # 空仓 -> 碰到信号则开仓 + if current_position is None and direction: + entry_price = float(next_bar['open']) + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': entry_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + if current_position: + pos_dir = current_position['direction'] + pos_sig_key = current_position['signal_key'] + + # 反向信号 -> 下一根开盘平仓 + 同价反手 + if direction and direction != pos_dir: + exit_price = float(next_bar['open']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: stats[pos_sig_key]['wins'] += 1 + + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': exit_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + # 同向信号 -> 续持 + if direction and direction == pos_dir: + idx += 1 + continue + + # 单根反色K线 -> 判断后续是否能组成信号 + curr_is_opposite = (pos_dir == 'long' and is_bearish(curr)) or (pos_dir == 'short' and is_bullish(curr)) + if curr_is_opposite: + can_peek = idx + 1 < len(all_data) + if can_peek: + lookahead_dir, _ = check_signal(curr, all_data[idx + 1]) + if lookahead_dir is not None: + idx += 1 + continue # 后续可组成信号,等待信号处理 + + # 否则按收盘价平仓 + exit_price = float(next_bar['close']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: stats[pos_sig_key]['wins'] += 1 + current_position = None + + idx += 1 + + # 尾仓:最后一根收盘价平仓 + if current_position: + last = all_data[-1] + exit_price = float(last['close']) + pos_dir = current_position['direction'] + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[current_position['signal_key']]['total_profit'] += diff + if diff > 0: stats[current_position['signal_key']]['wins'] += 1 + + return trades, stats + + +# ========================= 运行示例(优化版盈利计算) ========================= +if __name__ == '__main__': + dates = [] + for i in range(1, 11): + for i1 in range(1, 31): + dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{i1}") + # + # print(dates) + + # dates = [f"2025-10-{i}" for i in range(1, 31)] + trades, stats = backtest_15m_trend_optimized(dates) + + logger.info("===== 每笔交易详情 =====") + + # === 参数设定 === + contract_size = 10000 # 合约规模(1手对应多少基础货币) + open_fee_fixed = 5 # 固定开仓手续费 + close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率 + + total_points_profit = 0 # 累计点差 + total_money_profit = 0 # 累计金额盈利 + total_fee = 0 # 累计手续费 + + for t in trades: + entry = t['entry'] + exit = t['exit'] + direction = t['direction'] + + # === 1️⃣ 原始价差(点差) === + point_diff = (exit - entry) if direction == '做多' else (entry - exit) + + # === 2️⃣ 金额盈利(考虑合约规模) === + money_profit = point_diff / entry * contract_size # 利润以基础货币计(例如USD) + + # === 3️⃣ 手续费计算 === + # 开仓 + 平仓手续费(按比例计算 + 固定) + fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate) + + # === 4️⃣ 净利润 === + net_profit = money_profit - fee + + # 保存计算结果 + t.update({ + 'point_diff': point_diff, + 'raw_profit': money_profit, + 'fee': fee, + 'net_profit': net_profit + }) + + total_points_profit += point_diff + total_money_profit += money_profit + total_fee += fee + + # if net_profit > 500 or net_profit < -500: + logger.info( + f"{t['entry_time']} {direction}({t['signal']}) " + f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} " + f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}" + ) + + # === 汇总统计 === + total_net_profit = total_money_profit - total_fee + print(f"\n一共交易笔数:{len(trades)}") + print(f"总点差:{total_points_profit:.2f}") + print(f"总原始盈利(未扣费):{total_money_profit:.2f}") + print(f"总手续费:{total_fee:.2f}") + print(f"总净利润:{total_net_profit:.2f}\n") + + print("===== 信号统计 =====") + for k, v in stats.items(): + name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit'] + win_rate = (wins / count * 100) if count > 0 else 0.0 + avg_p = (total_p / count) if count > 0 else 0.0 + print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}") diff --git a/weex/长期持有信号/读取数据库数据-1小时版,不判断信号.py b/weex/长期持有信号/读取数据库数据-1小时版,不判断信号.py new file mode 100644 index 0000000..7cff7d5 --- /dev/null +++ b/weex/长期持有信号/读取数据库数据-1小时版,不判断信号.py @@ -0,0 +1,265 @@ +""" +量化交易回测系统 - 仅15分钟K线 & 反向K线即时平仓逻辑(完整版) +""" + +import datetime +from dataclasses import dataclass +from typing import List, Dict, Optional +from loguru import logger +from models.weex import Weex1Hour # 替换为你的15分钟K线模型 + + +# ========================= 工具函数 ========================= + +def is_bullish(c): # 阳线 + return float(c['close']) > float(c['open']) + + +def is_bearish(c): # 阴线 + return float(c['close']) < float(c['open']) + + +def check_signal(prev, curr): + """ + 包住形态信号判定: + - 前跌后涨包住 -> 做多 + - 前涨后跌包住 -> 做空 + """ + p_open, p_close = float(prev['open']), float(prev['close']) + c_open, c_close = float(curr['open']), float(curr['close']) + + if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open: + return "long", "bear_bull_engulf" + if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open: + return "short", "bull_bear_engulf" + + return None, None + + +def get_data_by_date(model, date_str: str): + """按天获取指定表的数据(15分钟K线)""" + try: + target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d') + except ValueError: + logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。") + return [] + + start_ts = int(target_date.timestamp() * 1000) + end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1 + + query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc()) + return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query] + + +# ========================= 回测逻辑 ========================= + +def backtest_15m_trend_simplified(dates: List[str]): + all_data: List[Dict] = [] + for d in dates: + all_data.extend(get_data_by_date(Weex1Hour, d)) + if not all_data: + return [], { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + all_data.sort(key=lambda x: x['id']) + + stats = { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + trades: List[Dict] = [] + current_position: Optional[Dict] = None + idx = 1 + + while idx < len(all_data) - 1: + prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1] + direction, signal_key = check_signal(prev, curr) + + # 空仓 -> 碰到信号则开仓 + if current_position is None and direction: + entry_price = float(next_bar['open']) + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': entry_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + if current_position: + pos_dir = current_position['direction'] + pos_sig_key = current_position['signal_key'] + + # 反向信号 -> 平仓 + 反手 + if direction and direction != pos_dir: + exit_price = float(next_bar['open']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + + # 反手开仓 + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': exit_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + # === 新逻辑:遇到反向K线立即平仓 === + if pos_dir == 'long' and is_bearish(curr): + exit_price = float(curr['close']) + diff = exit_price - current_position['entry_price'] + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + current_position = None + idx += 1 + continue + + if pos_dir == 'short' and is_bullish(curr): + exit_price = float(curr['close']) + diff = current_position['entry_price'] - exit_price + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + current_position = None + idx += 1 + continue + + idx += 1 + + # 尾仓平仓 + if current_position: + last = all_data[-1] + exit_price = float(last['close']) + pos_dir = current_position['direction'] + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[current_position['signal_key']]['total_profit'] += diff + if diff > 0: + stats[current_position['signal_key']]['wins'] += 1 + + return trades, stats + + +# ========================= 运行示例 ========================= +if __name__ == '__main__': + # dates = [f"2025-06-{i}" for i in range(1, 31)] + + dates = [] + for i in range(1, 11): + for i1 in range(1, 31): + dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{f'0{i1}' if len(str(i1)) < 2 else i1}") + + + + trades, stats = backtest_15m_trend_simplified(dates) + + logger.info("===== 每笔交易详情 =====") + + # === 参数设定 === + contract_size = 10000 # 合约规模(1手对应多少基础货币) + open_fee_fixed = 5 # 固定开仓手续费 + close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率 + + total_points_profit = 0 # 累计点差 + total_money_profit = 0 # 累计金额盈利 + total_fee = 0 # 累计手续费 + + for t in trades: + entry = t['entry'] + exit = t['exit'] + direction = t['direction'] + + # === 1️⃣ 原始价差(点差) === + point_diff = (exit - entry) if direction == '做多' else (entry - exit) + + # === 2️⃣ 金额盈利(考虑合约规模) === + money_profit = point_diff / entry * contract_size # 利润以基础货币计(例如USD) + + # === 3️⃣ 手续费计算 === + fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate) + + # === 4️⃣ 净利润 === + net_profit = money_profit - fee + + # 保存计算结果 + t.update({ + 'point_diff': point_diff, + 'raw_profit': money_profit, + 'fee': fee, + 'net_profit': net_profit + }) + + total_points_profit += point_diff + total_money_profit += money_profit + total_fee += fee + + logger.info( + f"{t['entry_time']} {direction}({t['signal']}) " + f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} " + f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}" + ) + + # === 汇总统计 === + total_net_profit = total_money_profit - total_fee + print(f"\n一共交易笔数:{len(trades)}") + print(f"总点差:{total_points_profit:.2f}") + print(f"总原始盈利(未扣费):{total_money_profit:.2f}") + print(f"总手续费:{total_fee:.2f}") + print(f"总净利润:{total_net_profit:.2f}\n") + + print("===== 信号统计 =====") + for k, v in stats.items(): + name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit'] + win_rate = (wins / count * 100) if count > 0 else 0.0 + avg_p = (total_p / count) if count > 0 else 0.0 + print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}") diff --git a/weex/长期持有信号/读取数据库数据-30分钟版.py b/weex/长期持有信号/读取数据库数据-30分钟版.py new file mode 100644 index 0000000..8ecc0ee --- /dev/null +++ b/weex/长期持有信号/读取数据库数据-30分钟版.py @@ -0,0 +1,259 @@ +""" +量化交易回测系统 - 仅15分钟K线 & 信号续持/反手/单根反色平仓逻辑(完整版) +""" + +import datetime +from dataclasses import dataclass +from typing import List, Dict, Optional +from loguru import logger +from models.weex import Weex30 # 替换为你的15分钟K线模型 + + +# ========================= 工具函数 ========================= + +def is_bullish(c): # 阳线 + return float(c['close']) > float(c['open']) + + +def is_bearish(c): # 阴线 + return float(c['close']) < float(c['open']) + + +def check_signal(prev, curr): + """ + 包住形态信号判定(仅15分钟K线): + - 前跌后涨包住 -> 做多 + - 前涨后跌包住 -> 做空 + """ + p_open, p_close = float(prev['open']), float(prev['close']) + c_open, c_close = float(curr['open']), float(curr['close']) + + # 前跌后涨包住 -> 做多 + if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open: + return "long", "bear_bull_engulf" + + # 前涨后跌包住 -> 做空 + if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open: + return "short", "bull_bear_engulf" + + return None, None + + +def get_data_by_date(model, date_str: str): + """按天获取指定表的数据(15分钟)""" + try: + target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d') + except ValueError: + logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。") + return [] + + start_ts = int(target_date.timestamp() * 1000) + end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1 + + query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc()) + return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query] + + +# ========================= 回测逻辑 ========================= + +def backtest_15m_trend_optimized(dates: List[str]): + all_data: List[Dict] = [] + for d in dates: + all_data.extend(get_data_by_date(Weex30, d)) + if not all_data: + return [], { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + all_data.sort(key=lambda x: x['id']) + + stats = { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + trades: List[Dict] = [] + current_position: Optional[Dict] = None + idx = 1 + + while idx < len(all_data) - 1: + prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1] + direction, signal_key = check_signal(prev, curr) + + # 空仓 -> 碰到信号则开仓 + if current_position is None and direction: + entry_price = float(next_bar['open']) + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': entry_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + if current_position: + pos_dir = current_position['direction'] + pos_sig_key = current_position['signal_key'] + + # 反向信号 -> 下一根开盘平仓 + 同价反手 + if direction and direction != pos_dir: + exit_price = float(next_bar['open']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: stats[pos_sig_key]['wins'] += 1 + + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': exit_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + # 同向信号 -> 续持 + if direction and direction == pos_dir: + idx += 1 + continue + + # 单根反色K线 -> 判断后续是否能组成信号 + curr_is_opposite = (pos_dir == 'long' and is_bearish(curr)) or (pos_dir == 'short' and is_bullish(curr)) + if curr_is_opposite: + can_peek = idx + 1 < len(all_data) + if can_peek: + lookahead_dir, _ = check_signal(curr, all_data[idx + 1]) + if lookahead_dir is not None: + idx += 1 + continue # 后续可组成信号,等待信号处理 + + # 否则按收盘价平仓 + exit_price = float(next_bar['close']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: stats[pos_sig_key]['wins'] += 1 + current_position = None + + idx += 1 + + # 尾仓:最后一根收盘价平仓 + if current_position: + last = all_data[-1] + exit_price = float(last['close']) + pos_dir = current_position['direction'] + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[current_position['signal_key']]['total_profit'] += diff + if diff > 0: stats[current_position['signal_key']]['wins'] += 1 + + return trades, stats + + +# ========================= 运行示例(优化版盈利计算) ========================= +if __name__ == '__main__': + dates = [] + for i in range(1, 11): + for i1 in range(1, 31): + dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{i1}") + # + # print(dates) + + # dates = [f"2025-10-{i}" for i in range(1, 31)] + trades, stats = backtest_15m_trend_optimized(dates) + + logger.info("===== 每笔交易详情 =====") + + # === 参数设定 === + contract_size = 10000 # 合约规模(1手对应多少基础货币) + open_fee_fixed = 5 # 固定开仓手续费 + close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率 + + total_points_profit = 0 # 累计点差 + total_money_profit = 0 # 累计金额盈利 + total_fee = 0 # 累计手续费 + + for t in trades: + entry = t['entry'] + exit = t['exit'] + direction = t['direction'] + + # === 1️⃣ 原始价差(点差) === + point_diff = (exit - entry) if direction == '做多' else (entry - exit) + + # === 2️⃣ 金额盈利(考虑合约规模) === + money_profit = point_diff / entry * contract_size # 利润以基础货币计(例如USD) + + # === 3️⃣ 手续费计算 === + # 开仓 + 平仓手续费(按比例计算 + 固定) + fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate) + + # === 4️⃣ 净利润 === + net_profit = money_profit - fee + + # 保存计算结果 + t.update({ + 'point_diff': point_diff, + 'raw_profit': money_profit, + 'fee': fee, + 'net_profit': net_profit + }) + + total_points_profit += point_diff + total_money_profit += money_profit + total_fee += fee + + # if net_profit > 500 or net_profit < -500: + logger.info( + f"{t['entry_time']} {direction}({t['signal']}) " + f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} " + f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}" + ) + + # === 汇总统计 === + total_net_profit = total_money_profit - total_fee + print(f"\n一共交易笔数:{len(trades)}") + print(f"总点差:{total_points_profit:.2f}") + print(f"总原始盈利(未扣费):{total_money_profit:.2f}") + print(f"总手续费:{total_fee:.2f}") + print(f"总净利润:{total_net_profit:.2f}\n") + + print("===== 信号统计 =====") + for k, v in stats.items(): + name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit'] + win_rate = (wins / count * 100) if count > 0 else 0.0 + avg_p = (total_p / count) if count > 0 else 0.0 + print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}") diff --git a/weex/长期持有信号/读取数据库数据-30分钟版,不判断信号.py b/weex/长期持有信号/读取数据库数据-30分钟版,不判断信号.py new file mode 100644 index 0000000..c52e8c7 --- /dev/null +++ b/weex/长期持有信号/读取数据库数据-30分钟版,不判断信号.py @@ -0,0 +1,265 @@ +""" +量化交易回测系统 - 仅15分钟K线 & 反向K线即时平仓逻辑(完整版) +""" + +import datetime +from dataclasses import dataclass +from typing import List, Dict, Optional +from loguru import logger +from models.weex import Weex30 # 替换为你的15分钟K线模型 + + +# ========================= 工具函数 ========================= + +def is_bullish(c): # 阳线 + return float(c['close']) > float(c['open']) + + +def is_bearish(c): # 阴线 + return float(c['close']) < float(c['open']) + + +def check_signal(prev, curr): + """ + 包住形态信号判定: + - 前跌后涨包住 -> 做多 + - 前涨后跌包住 -> 做空 + """ + p_open, p_close = float(prev['open']), float(prev['close']) + c_open, c_close = float(curr['open']), float(curr['close']) + + if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open: + return "long", "bear_bull_engulf" + if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open: + return "short", "bull_bear_engulf" + + return None, None + + +def get_data_by_date(model, date_str: str): + """按天获取指定表的数据(15分钟K线)""" + try: + target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d') + except ValueError: + logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。") + return [] + + start_ts = int(target_date.timestamp() * 1000) + end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1 + + query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc()) + return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query] + + +# ========================= 回测逻辑 ========================= + +def backtest_15m_trend_simplified(dates: List[str]): + all_data: List[Dict] = [] + for d in dates: + all_data.extend(get_data_by_date(Weex30, d)) + if not all_data: + return [], { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + all_data.sort(key=lambda x: x['id']) + + stats = { + 'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'}, + 'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'}, + } + + trades: List[Dict] = [] + current_position: Optional[Dict] = None + idx = 1 + + while idx < len(all_data) - 1: + prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1] + direction, signal_key = check_signal(prev, curr) + + # 空仓 -> 碰到信号则开仓 + if current_position is None and direction: + entry_price = float(next_bar['open']) + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': entry_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + if current_position: + pos_dir = current_position['direction'] + pos_sig_key = current_position['signal_key'] + + # 反向信号 -> 平仓 + 反手 + if direction and direction != pos_dir: + exit_price = float(next_bar['open']) + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + + # 反手开仓 + current_position = { + 'direction': direction, + 'signal': stats[signal_key]['name'], + 'signal_key': signal_key, + 'entry_price': exit_price, + 'entry_time': next_bar['id'] + } + stats[signal_key]['count'] += 1 + idx += 1 + continue + + # === 新逻辑:遇到反向K线立即平仓 === + if pos_dir == 'long' and is_bearish(curr): + exit_price = float(curr['close']) + diff = exit_price - current_position['entry_price'] + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + current_position = None + idx += 1 + continue + + if pos_dir == 'short' and is_bullish(curr): + exit_price = float(curr['close']) + diff = current_position['entry_price'] - exit_price + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[pos_sig_key]['total_profit'] += diff + if diff > 0: + stats[pos_sig_key]['wins'] += 1 + current_position = None + idx += 1 + continue + + idx += 1 + + # 尾仓平仓 + if current_position: + last = all_data[-1] + exit_price = float(last['close']) + pos_dir = current_position['direction'] + diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else ( + current_position['entry_price'] - exit_price) + trades.append({ + 'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000), + 'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000), + 'signal': current_position['signal'], + 'direction': '做多' if pos_dir == 'long' else '做空', + 'entry': current_position['entry_price'], + 'exit': exit_price, + 'diff': diff + }) + stats[current_position['signal_key']]['total_profit'] += diff + if diff > 0: + stats[current_position['signal_key']]['wins'] += 1 + + return trades, stats + + +# ========================= 运行示例 ========================= +if __name__ == '__main__': + # dates = [f"2025-06-{i}" for i in range(1, 31)] + + dates = [] + for i in range(1, 11): + for i1 in range(1, 31): + dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{f'0{i1}' if len(str(i1)) < 2 else i1}") + + + + trades, stats = backtest_15m_trend_simplified(dates) + + logger.info("===== 每笔交易详情 =====") + + # === 参数设定 === + contract_size = 10000 # 合约规模(1手对应多少基础货币) + open_fee_fixed = 5 # 固定开仓手续费 + close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率 + + total_points_profit = 0 # 累计点差 + total_money_profit = 0 # 累计金额盈利 + total_fee = 0 # 累计手续费 + + for t in trades: + entry = t['entry'] + exit = t['exit'] + direction = t['direction'] + + # === 1️⃣ 原始价差(点差) === + point_diff = (exit - entry) if direction == '做多' else (entry - exit) + + # === 2️⃣ 金额盈利(考虑合约规模) === + money_profit = point_diff / entry * contract_size # 利润以基础货币计(例如USD) + + # === 3️⃣ 手续费计算 === + fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate) + + # === 4️⃣ 净利润 === + net_profit = money_profit - fee + + # 保存计算结果 + t.update({ + 'point_diff': point_diff, + 'raw_profit': money_profit, + 'fee': fee, + 'net_profit': net_profit + }) + + total_points_profit += point_diff + total_money_profit += money_profit + total_fee += fee + + logger.info( + f"{t['entry_time']} {direction}({t['signal']}) " + f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} " + f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}" + ) + + # === 汇总统计 === + total_net_profit = total_money_profit - total_fee + print(f"\n一共交易笔数:{len(trades)}") + print(f"总点差:{total_points_profit:.2f}") + print(f"总原始盈利(未扣费):{total_money_profit:.2f}") + print(f"总手续费:{total_fee:.2f}") + print(f"总净利润:{total_net_profit:.2f}\n") + + print("===== 信号统计 =====") + for k, v in stats.items(): + name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit'] + win_rate = (wins / count * 100) if count > 0 else 0.0 + avg_p = (total_p / count) if count > 0 else 0.0 + print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}")