pc2c o2c pc2o pc2o_kt
pc2c o2c pc2o pc2o_kt
class Broker(object):
def __init__(self, cfg, **kwargs,):
self.code = cfg.code
self.onehand = 1 if self.code[:2]=='39' else 100
self.capital=cfg.capital
self.comm=cfg.commission
self.possize=0
for k,v in kwargs.items(): setattr(self, k, v)
self.bal = None # 买股资金初始化值None:指示首次买股时用capitlal的值, 后续的买股资金都用bal的值了
self._fund = 0
self.ntrades = 0 # 累计卖出(包括减仓操作)次数
self.account=[] #交割单列表
self.cols = ' i date time op price pct volume amount '+\
' fee cashflow balence mktcap totcap '+\
' p_size p_ratio ntrades'
# 交割单列名字符串, 其格式与打印单笔交割单相匹配,
# 同时用来提取交割单列索引
def calc_prejgd(self, price, operation, percent, _fund):
# 1. 依据订单参数, 计算成交量volume 2. 更新possize
if operation==1:
volume = int(self.bal/price/self.onehand);
volume = volume*self.onehand;
self.possize += volume
elif operation==-1:
volume= int(self.possize * percent /self.onehand)*self.onehand;
self.possize -= volume
self.ntrades +=1
amount = volume * price;
fee = amount * self.comm;
cf = (amount + operation * fee)* np.sign(-operation)
self.bal += cf + _fund #现金余额: 首次买股之后的资金余额应该包括备用金
mktcap = price * self.possize;
totcap = mktcap + self.bal;
posratio = mktcap/totcap #市值 总资产 仓位占比
prejgd = (volume, amount, fee, cf,
mktcap, totcap, posratio)
return prejgd
def buy(self, i, dt, time, price, operation, percent, debug=False):
''' 开仓
# buy 开仓 & 清算 dkai djia djian
# 0. 依据订单参数, 设置投入资金额度, 然后计算留存的备用金
# 初始资金的percent, (1-percent)
# 1. 计算成交量volume 2. 更新possize
# 3. 计算成交额/手续费/现金流
# 4. 更新现金余额 计算市值 总资产 头寸占比
'''
# leverage = 1; self.capital *= 1+leverage;
self.bal = self.capital if self.bal == None else self.bal
self.bal, _fund = self.bal * percent, self.bal * (1 - percent)
# 现金余额依据订单的买股比例, 分配买股金, 备用金
if self.bal> self.onehand*price:
(volume, amount, fee, cf,
mktcap, totcap, posratio) = \
self.calc_prejgd(price, operation, percent, _fund)
self.set_jgd(i, dt, time, operation, price, percent,
volume, amount, fee, cf,
mktcap, totcap, posratio,
debug=debug)
else:
# print(f' {dt} {time} 多余的买入指令, 账户里的资金余额已经不足买股!')
pass
def sell(self, i, dt, time, price, operation, percent, debug=True):
''' 清仓或者减仓 '''
# sell 减仓 at close at volume=percent * possize
# 首先判断 是否持有仓位: possize
if self.possize>0.0:
(volume, amount, fee, cf,
mktcap, totcap, posratio) = \
self.calc_prejgd(price, operation, percent, 0)
self.set_jgd(i, dt, time, operation, price, percent,
volume, amount, fee, cf,
mktcap, totcap, posratio,
debug=debug)
else:
# print(f'"Warning": {dt} {time} 多余的卖出指令(连续的卖出或者买入之前的卖出指令), do nothing')
pass
def cc(self, i, dt, time, price, operation, percent, debug=False):
''' check total capital'''
volume = 0 # int
amount = fee = cf = 0.0 # float
if not self.bal==None:
self.bal += 0 #现金余额
mktcap = price * self.possize;
totcap = mktcap + self.bal;
posratio = mktcap/totcap #市值 总资产 仓位占比
self.set_jgd(i, dt, time, operation, price, percent,
volume, amount, fee, cf,
mktcap, totcap, posratio, debug=debug)
else:
print(f'"Warning": {dt} {time} 账户还没有进行过交易.')
# 或者无效的单子(比如卖出指令首单)')
mktcap, totcap, posratio = 0.0, self.capital, 0.0
self.set_jgd(i, dt, time, operation, price, percent,
volume, amount, fee, cf,
mktcap, totcap, posratio, debug=debug)
pass
def set_jgd(self, *args, debug=False):
(i, dt, time, operation, price, percent,
volume, amount, fee, cf,
mktcap, totcap,
posratio,) = args
jgd = (i, dt, time, operation, price, percent,
volume, amount, fee, cf,
self.bal,
mktcap, totcap,
self.possize,
posratio,
self.ntrades) # 设置单笔交割单(又添加3个项目)
self.account.append(jgd) # 追加到交割单列表
if debug: self.printAcc1(*jgd)
def printAcc1(self,
i, dt, time, operation, price, percent,
volume, amount, fee, cf,
bal, mktcap, totcap,
possize, posratio, ntrades,
):
if i<100 or i>self.orders_len-20 :
bal = 0 if bal is None else bal
print(f'{i:5d}', dt,
f'{time:>5s} {operation:2d}',
f'{price:7.2f}',
f'{str(percent):>4s}',
f'{volume:5d} {amount:12.2f} {fee:8.2f} {cf:12.2f}',
f'{bal:12.2f} {mktcap:12.2f} {totcap:12.2f}',
f'{possize:5d} {posratio:.2f} {ntrades:3d}'
)
duanqs