190 lines
7.2 KiB
Python
190 lines
7.2 KiB
Python
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
|
||
|
||
|