Files
mt5_python_ea_suite/core/data/dryrun.py
T
silencesdg 430376eb61 feat: 一票制并发锁 + MT5硬止损兜底
- 一票制: _pending_long/_pending_short 计数器防同一周期内多信号穿透
- 硬止损: MT5下单时附带sl/tp,倍率1.5x(止损)/1.3x(止盈),比EA软止损更宽
- config.py: 新增 hard_sl_multiplier/hard_tp_multiplier
- 全部 send_order 链路(abc/remote/live/server/dryrun/backtest) 支持 sl/tp 参数
- 对冲模块: 彻底移除
- 日志: 去重+30轮摘要
2026-05-14 14:07:13 +08:00

63 lines
2.3 KiB
Python

import pandas as pd
from logger import logger
from core.data.abc import DataProvider
from core.data.live import LiveDataProvider
from config import SIMULATION_CONFIG
class DryRunDataProvider(DataProvider):
"""纸上交易数据提供者 — 使用实时价格但不发送真实订单"""
def __init__(self, initial_equity=10000, leverage=100):
self.simulated_ticket_counter = 0
self.equity = initial_equity
self.leverage = leverage
self._live_data_source = LiveDataProvider()
self.spread = SIMULATION_CONFIG.get("spread", 16)
def initialize(self):
logger.info("纸上交易模式初始化...")
return self._live_data_source.initialize()
def shutdown(self):
logger.info("纸上交易模式关闭.")
self._live_data_source.shutdown()
def get_current_price(self, symbol):
price_data = self._live_data_source.get_current_price(symbol)
if price_data:
spread_half = self.spread * 0.01 / 2
mid_price = price_data['last']
return {
'bid': mid_price - spread_half,
'ask': mid_price + spread_half,
'last': mid_price,
'time': price_data['time']
}
return None
def get_historical_data(self, symbol, timeframe, count, **kwargs):
return self._live_data_source.get_historical_data(symbol, timeframe, count, **kwargs)
def get_symbol_info(self, symbol):
return self._live_data_source.get_symbol_info(symbol)
def get_account_info(self):
return {'equity': self.equity}
def get_positions(self, symbol):
return []
def send_order(self, symbol, order_type, volume, sl=None, tp=None):
self.simulated_ticket_counter += 1
price_data = self.get_current_price(symbol)
price = price_data['last'] if price_data else "N/A"
logger.info(f"[纸上交易] 模拟下单: {order_type} {volume:.2f}{symbol} @ {price}")
return {'order': self.simulated_ticket_counter}
def close_position(self, ticket, symbol, volume):
price_data = self.get_current_price(symbol)
price = price_data['last'] if price_data else "N/A"
logger.info(f"[纸上交易] 模拟平仓: Ticket {ticket} @ {price}")
return True