import inspect
from datetime import datetime
def validate_backtest_settings():
"""检查回测设置中的潜在问题,避免自身代码导致的误告警"""
try:
# 获取当前运行的策略代码(模块级代码)
frame = inspect.currentframe()
module_frame = None
while frame:
if frame.f_code.co_name == '< module>':
module_frame = frame
break
frame = frame.f_back
if not module_frame:
strategy_code = '' # 如果无法获取源码,使用空字符串
else:
# 获取模块完整源码
module_lines, _ = inspect.findsource(module_frame)
full_code = ''.join(module_lines)
# 获取当前函数(validate_backtest_settings)的源码,用于过滤
current_func_lines, func_start_line = inspect.findsource(validate_backtest_settings)
func_end_line = func_start_line + len(current_func_lines)
# 过滤掉当前函数的代码,只保留真正的策略代码
# 行号从1开始,需要转换为索引(减1)
strategy_lines = []
for i, line in enumerate(module_lines):
# 只保留不在当前函数代码范围内的行
if not (func_start_line < = i + 1 < func_end_line):
strategy_lines.append(line)
strategy_code = ''.join(strategy_lines)
except Exception as e:
print(f"警告:无法获取完整策略代码 ({str(e)})")
strategy_code = ''
issues_found = []
# 检查第一骗:未来数据
if "avoid_future_data" not in strategy_code:
issues_found.append("⚠️ 警告:未设置 avoid_future_data=True,可能使用了未来数据")
# 检查第二骗:滑点设置
if "FixedSlippage" in strategy_code:
issues_found.append("⚠️ 警告:使用了固定的滑点金额,这可能不符合实际情况, 建议使用千分之二滑点 set_slippage(PriceRelatedSlippage(0.002))")
if "set_slippage" not in strategy_code:
issues_found.append("⚠️ 警告:未设置滑点,建议使用千分之二滑点 set_slippage(PriceRelatedSlippage(0.002))")
# 检查第三骗:成交量限制
if "order_volume_ratio" not in strategy_code:
issues_found.append("⚠️ 警告:未设置order_volume_ratio,建议设置为0.02")
if "match_with_order_book" not in strategy_code:
issues_found.append("⚠️ 警告:未开启盘口撮合,可能导致模拟盘环境下虚假成交")
# 打印检查结果
print("\n===== 回测设置检查结果 =====")
if issues_found:
for issue in issues_found:
print(f"{get_current_time()} - INFO - {issue}")
print("\n建议修正以上问题以获得更准确的回测结果")
else:
print(f"{get_current_time()} - INFO - ✅ 初步回测作弊检查通过,暂未发现常见问题")
print("===============================\n")
def get_current_time():
"""返回当前时间字符串"""
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 在策略末尾调用此函数
validate_backtest_settings()
2025-08-11