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}' 
                  )
        



posted @ 2021-12-25 22:23  duanqs  阅读(42)  评论(0编辑  收藏  举报