real_trader/src/simulation/simulation_trader.py
2025-05-12 10:20:07 +08:00

190 lines
7.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.

from logger_config import get_logger
from trade_constants import (
TRADE_TYPE_SIMULATION,
ORDER_DIRECTION_BUY,
ORDER_DIRECTION_SELL,
ORDER_STATUS_COMPLETED,
ORDER_STATUS_CANCELLED,
)
from position_manager import PositionManager
from base_trader import BaseTrader
import random
from typing import Dict
from local_position import LocalPosition
class SimulationTrader(BaseTrader):
def __init__(self, logger=None):
super().__init__(logger)
self.logger = logger or get_logger("simulation_trader")
# 模拟资金账户信息
self.sim_balance = {"account_id": "simulation", "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, strategy_name="default_strategy"):
message = f"模拟买入 - 代码: {code}, 价格: {price}, 数量: {amount}, 策略: {strategy_name}"
self.logger.info(message)
# 计算交易成本
cost = price * amount
# 检查余额是否足够
if self.sim_balance["cash"] < cost:
message = f"模拟买入失败 - 代码: {code}, 资金不足"
self.logger.warning(message)
return {"order_id": None, "message": message, "success": False}
# 更新资金
self.sim_balance["cash"] -= cost
# 更新持仓管理器
position_manager = self.get_position_manager(strategy_name)
position_manager.update_position(
code, ORDER_DIRECTION_BUY, amount
)
order_id = random.randint(1, 999999) # 使用随机函数生成小于1000000的随机整数
position_manager.add_pending_order(
order_id, code, price, amount, ORDER_DIRECTION_BUY
)
# 假设立刻全部成交
position_manager.update_order_status(order_id, amount, ORDER_STATUS_COMPLETED)
# 更新总资产
self._update_total_assets()
return {"order_id": order_id, "message": message, "success": True}
def sell(self, code, price, amount, strategy_name="default_strategy"):
message = f"模拟卖出 - 代码: {code}, 价格: {price}, 数量: {amount}, 策略: {strategy_name}"
self.logger.info(message)
# 获取策略持仓
position_manager = self.get_position_manager(strategy_name)
strategy_positions = position_manager.get_positions()
# 检查持仓是否足够
if (
code not in strategy_positions
or strategy_positions[code].closeable_amount < amount
):
message = f"模拟卖出失败 - 代码: {code}, 可用数量不足"
self.logger.warning(message)
return {"order_id": None, "message": message, "success": False}
# 更新资金
proceeds = price * amount
self.sim_balance["cash"] += proceeds
# 更新持仓管理器
position_manager.update_position(
code, ORDER_DIRECTION_SELL, amount
)
order_id = random.randint(1, 999999) # 使用随机函数生成小于1000000的随机整数
position_manager.add_pending_order(
order_id, code, price, amount, ORDER_DIRECTION_SELL
)
# 假设立刻全部成交
position_manager.update_order_status(order_id, amount, ORDER_STATUS_COMPLETED)
# 更新总资产
self._update_total_assets()
return {"order_id": order_id, "message": message, "success": True}
def _update_total_assets(self):
"""更新总资产"""
# 此处简化处理,在实际情况中应该计算所有持仓的市值
self.sim_balance["total"] = self.sim_balance["cash"]
def cancel(self, order_id):
message = f"模拟撤单 - 委托号: {order_id}"
self.logger.info(message)
position_managers = self.get_all_position_managers()
for position_manager in position_managers.values():
if order_id in position_manager.pending_orders:
position_manager.update_order_status(order_id, 0, ORDER_STATUS_CANCELLED)
return {"order_id": "order_id", "message": message, "success": True}
else:
return {"order_id": None, "message": "订单不存在", "success": False}
def get_balance(self):
message = "模拟交易:查询余额"
self.logger.info(message)
return self.sim_balance
def get_positions(self):
message = "模拟交易:查询持仓"
self.logger.info(message)
position_managers = self.get_all_position_managers()
positions: Dict[str, LocalPosition] = {}
for position_manager in position_managers.values():
positions.update(position_manager.get_positions())
# convert to json list
return [{"account_id": "simulation", "code": position.code, "total_amount": position.total_amount, "closeable_amount": position.closeable_amount} for position in positions.values()]
def get_today_trades(self):
message = "模拟交易:查询今日成交"
self.logger.info(message)
return {"message": "模拟交易:查询今日成交未实现", "success": True}
def get_today_orders(self):
message = "模拟交易:查询今日委托"
self.logger.info(message)
return {"message": "模拟交易:查询今日委托未实现", "success": True}
def get_position(self, stock_code, strategy_name="default_strategy"):
"""查询指定股票代码的持仓信息
Args:
stock_code: 股票代码,例如 "600000.SH"
strategy_name: 策略名称,默认为"default_strategy"
Returns:
dict: 持仓详情如果未持有则返回None
"""
position_manager = self.get_position_manager(strategy_name)
positions = position_manager.get_positions()
if stock_code in positions:
position_info = positions[stock_code]
return {
"account_id": "simulation",
"code": stock_code,
"strategy_name": strategy_name,
"total_amount": position_info.total_amount,
"closeable_amount": position_info.closeable_amount,
}
return None
def get_order(self, order_id):
position_managers = self.get_all_position_managers()
for position_manager in position_managers.values():
if order_id in position_manager.pending_orders:
order_info = position_manager.pending_orders[order_id]
return {
"order_id": order_id,
"stock_code": order_info.stock_code,
"price": order_info.price,
"amount": order_info.amount,
"direction": order_info.direction,
"status": order_info.status,
"strategy_name": order_info.strategy_name,
}
return None