128 lines
4.8 KiB
Python
128 lines
4.8 KiB
Python
|
||
from logger_config import get_logger
|
||
|
||
class SimulationTrader:
|
||
def __init__(self, logger=None):
|
||
self.logger = logger or get_logger('simulation_trader')
|
||
# 添加模拟持仓字典,用于追踪模拟交易的持仓
|
||
self.sim_positions = {}
|
||
# 模拟资金账户信息
|
||
self.sim_balance = {"cash": 1000000.00, "frozen": 0.00, "total": 1000000.00}
|
||
|
||
def is_logged_in(self):
|
||
"""检查交易系统是否已经登录
|
||
|
||
Returns:
|
||
bool: True表示已登录,模拟交易系统总是返回已登录状态
|
||
"""
|
||
return True
|
||
|
||
def login(self):
|
||
self.logger.info("模拟交易:登录成功")
|
||
return True
|
||
|
||
def logout(self):
|
||
self.logger.info("模拟交易:登出成功")
|
||
return True
|
||
|
||
def buy(self, code, price, amount):
|
||
message = f"模拟买入 - 代码: {code}, 价格: {price}, 数量: {amount}"
|
||
self.logger.info(message)
|
||
|
||
# 更新模拟持仓
|
||
if code not in self.sim_positions:
|
||
self.sim_positions[code] = {
|
||
"stock_code": code,
|
||
"volume": 0,
|
||
"can_use_volume": 0,
|
||
"frozen_volume": 0,
|
||
"avg_price": 0.0,
|
||
"market_value": 0.0
|
||
}
|
||
|
||
# 计算新的平均成本
|
||
current_cost = self.sim_positions[code]["avg_price"] * self.sim_positions[code]["volume"]
|
||
new_cost = price * amount
|
||
total_volume = self.sim_positions[code]["volume"] + amount
|
||
|
||
# 更新持仓信息
|
||
self.sim_positions[code]["volume"] += amount
|
||
self.sim_positions[code]["can_use_volume"] += amount
|
||
self.sim_positions[code]["avg_price"] = (current_cost + new_cost) / total_volume if total_volume > 0 else 0
|
||
self.sim_positions[code]["market_value"] = self.sim_positions[code]["volume"] * price
|
||
|
||
# 更新资金
|
||
self.sim_balance["cash"] -= price * amount
|
||
self.sim_balance["total"] = self.sim_balance["cash"] + sum(pos["market_value"] for pos in self.sim_positions.values())
|
||
|
||
return {"order_id": "simulation", "message": message}
|
||
|
||
def sell(self, code, price, amount):
|
||
message = f"模拟卖出 - 代码: {code}, 价格: {price}, 数量: {amount}"
|
||
self.logger.info(message)
|
||
|
||
# 更新模拟持仓
|
||
if code in self.sim_positions:
|
||
# 确保可用数量足够
|
||
if self.sim_positions[code]["can_use_volume"] >= amount:
|
||
# 更新持仓信息
|
||
self.sim_positions[code]["volume"] -= amount
|
||
self.sim_positions[code]["can_use_volume"] -= amount
|
||
self.sim_positions[code]["market_value"] = self.sim_positions[code]["volume"] * price
|
||
|
||
# 如果持仓为0,删除该股票
|
||
if self.sim_positions[code]["volume"] <= 0:
|
||
del self.sim_positions[code]
|
||
|
||
# 更新资金
|
||
self.sim_balance["cash"] += price * amount
|
||
self.sim_balance["total"] = self.sim_balance["cash"] + sum(pos["market_value"] for pos in self.sim_positions.values())
|
||
else:
|
||
message = f"模拟卖出失败 - 代码: {code}, 可用数量不足"
|
||
self.logger.warning(message)
|
||
else:
|
||
message = f"模拟卖出失败 - 代码: {code}, 无持仓"
|
||
self.logger.warning(message)
|
||
|
||
return {"order_id": "simulation", "message": message}
|
||
|
||
def cancel(self, entrust_no):
|
||
message = f"模拟撤单 - 委托号: {entrust_no}"
|
||
self.logger.info(message)
|
||
return {"order_id": "simulation", "message": message}
|
||
|
||
def get_balance(self):
|
||
message = "模拟交易:查询余额"
|
||
self.logger.info(message)
|
||
return self.sim_balance
|
||
|
||
def get_positions(self):
|
||
message = "模拟交易:查询持仓"
|
||
self.logger.info(message)
|
||
# 返回与XtTrader格式一致的持仓数据
|
||
return [
|
||
{
|
||
"account_id": "simulation",
|
||
"stock_code": code,
|
||
"volume": pos["volume"],
|
||
"can_use_volume": pos["can_use_volume"],
|
||
"open_price": pos["avg_price"],
|
||
"avg_price": pos["avg_price"],
|
||
"market_value": pos["market_value"],
|
||
"frozen_volume": pos["frozen_volume"],
|
||
"on_road_volume": 0
|
||
} for code, pos in self.sim_positions.items()
|
||
]
|
||
|
||
def get_today_trades(self):
|
||
message = "模拟交易:查询今日成交"
|
||
self.logger.info(message)
|
||
return []
|
||
|
||
def get_today_entrust(self):
|
||
message = "模拟交易:查询今日委托"
|
||
self.logger.info(message)
|
||
return []
|
||
|
||
def is_trading_time(self):
|
||
return True |