tf

tf代码

# momentums.py

# import sys, io, os, inspect
import numpy as np, pandas as pd; _=np
pd.set_option('display.precision', 6)
# import matplotlib.pyplot as plt

# from dqsbt.util2 import util as aid # 加载数据
# from util import ttr                # 计算指标
# import candleplotter as cplt

# from qsutil import pkl
# from texttable import Texttable
# from packages import report as rp

# from qsutil import pkl; _cn_dict = pkl.pkl_load('d:/db/amipy/data/codename_dict.pkl')
_cn_dict = {
            '399006': '创板100',
            '399300': '沪深300',
            '399905': '中证500',
}
import momentums_config as cfg
# import utility as ut
from qsutil import utility as ut
from qsutil import bbplot as bbp; _=bbp
import flower as fl; _=fl
p=dict(mfile='D:\\algolab\\study\\momentums\\momentums.py') # __file__
_pn = [n for n in dir(cfg) if not n.startswith('__')]
_pv = [getattr(cfg, n) for n in _pn]
p.update(dict(zip(_pn, _pv)))

from collections import namedtuple

Ticktime = namedtuple('Ticktime', 'oTime, bnTime, anTime, ccTime, slTime, cTime') 
tt = Ticktime('9:25', '11:30', '13:00', '14:55', '14:56', '15:00')    
NamedOrderMultiple = namedtuple('NamedOrderMultiple', 
                    'i date time operation code price percent')
NamedOrderSingle   = namedtuple('NamedOrderSingle', 
                    'i date time operation code price percent')



def pre_proc():
    ''' 
    >>> ohlc, ind = pre_proc()
    '''
    ohlc, _codes, _dnames=ut.load(subset=cfg.subset)
    ind = ut.indicator(ohlc, n1=cfg.n1, n2=cfg.n2)
    return ohlc, ind




class Order(object):
    ''' 
    多股组合下单器
    创建买单: 倒数第8行的数据, 收盘前的, 买入, 第二只个股, 目标仓位10%
    创建查单: 倒数第8行的数据, 收盘时刻, 查资产, 
    创建卖单: 倒数第2行的数据, 收盘前的, 卖出, 第二只个股, 目标仓位0%
    
    o=Order(ind)
    bo = o.create_buy_order (-8, o.codes[1], 0.1)
    print(o)

    co = o.create_check_totcap_order(-8, )
    print(o)
    co = o.create_check_totcap_order(-7, )
    print(o)
    
    co = o.create_check_totcap_order(-6, )
    print(o)

    so = o.create_sell_order(-2, o.codes[1], 0.)
    print(o) # 单个订单
    
    
    bbo = o.create_batch_buy_order(10, o.codes[:2], [.5,.3])
    bbo = o.create_batch_buy_order(100, o.codes[:2], [.5,.3])
    print(o.orders) # 订单列表(不包括查单)
    '''


    def __init__(self, ind):
        self.ind = ind
        self.codes = list(self.ind.columns.get_level_values(1).unique())
        self.init()
        
    def init(self):
        self.rowid, self.date, self.time, \
        self.operation, self.code, self.price, self.percent = \
        (None, None, None,   None, None, None, None)
        
        self.orders = []
        
    def __repr__(self):
        dt = self.date.isoformat()[:10]
        return '<Order {}>'.format(' '.join([
              f'{self.rowid:4d}', 
              dt, 
              self.time,
              f'{self.operation:2d}', 
              self.code, 
              f'{self.price:.2f}', 
              f'{self.percent:3.0%}'
        ]))
    
    def _create(self, rowid, time, operation, code, percent):
        mdf=self.ind.iloc[rowid]
        date = mdf.name
        if operation==1 or operation==-1:
            price = mdf.loc['close', code]
            print(f'code={code}, price={price}')
            self.order = NamedOrderSingle(
                rowid, date, time, operation, code, price, percent)
            self.rowid, self.date, self.time, \
            self.operation, self.code, self.price, self.percent = \
            (rowid, date, time,   \
            operation, code, price, percent)

        elif operation==0:
            _code=self.codes
            _price=mdf.loc['close'].tolist()
            _price_dict={ k:v for k,v in  zip(self.codes, _price)}
            self.order = NamedOrderSingle(
                rowid, date, time, operation, _code, _price_dict, percent)
            self.rowid, self.date, self.time, \
            self.operation, self.code, self.price, self.percent = \
            (rowid, date, time,   \
            operation, ' ',  0.0, 0.0)
                
        if operation==1 or operation==-1:
            self.orders.append(self.__repr__())
        return self.order
    
    def create_buy_order(self, rowid, code, percent):
        time, operation = tt.ccTime, 1
        self._create(rowid, time, operation, code, percent)
        return self.order

    def create_batch_buy_order(self, rowid, code, percent):
        time, operation = tt.ccTime, 1
        
        assert isinstance(code, list) and len(code)>1, 'Can not create batch order'
        orders=[]
        for _code, _pct in zip(code, percent):
            self._create(rowid, time, operation, _code, _pct)
            orders.append(self.order)
        return orders

    def create_sell_order(self, rowid, code, percent):
        time, operation = tt.ccTime, -1
        self._create(rowid, time, operation, code, percent)
        return self.order
      
    def create_check_totcap_order(self, rowid, ):
        time, operation = tt.cTime, 0
        code, percent = '', 0.0
        self._create(rowid, time, operation, code, percent)
        return self.order
        
    def porders(self):
        '''print history orders'''
        print(self.order._fields)
        for o in self.orders: print(o)        
        
        

class JiaoGeDan(object):
    # 交割单列名字符串, 其格式与打印单笔交割单相匹配, 
    # 同时用来提取交割单列索引
    jgd_cols = 'i date time op code name price pct ' + \
               'volume amount fee cashflow ' + \
               'balance ntrade ' 
    Jgd=namedtuple('Jgd', jgd_cols) # 将具名元组类初始化为属性

    def __init__(self, *args):
        self.jgd = self.Jgd(*args)
        
    def __repr__(self):
        _dict = self.jgd._asdict()
        _dict.pop('i')
        _dict.pop('date')
        s  = '<jgd {:>4d}'.format(self.jgd[0]) 
        s += ' {}'.format(self.jgd[1].isoformat()[:10])
        s += ''' \
{time:5s} \
{op:3d} \
{code:6s} \
{name:8s} \
{price:8.2f} \
{pct:3.0%} \
{volume:5d} \
{amount:>10.2f} \
{fee:>8.2f} \
{cashflow:>10.2f} \
{balance:>10.2f} \
{ntrade:6d} \
>'''.format(**_dict)
        return s



class Account(object):
    def __init__(self, n):
        self.n=n
        f = 'i date names'.split()
        f.extend(list(map(lambda x:''.join(['psn', str(x), '_mval']), range(n))))
        f.extend('totmktcap balance totcap'.split())        
        f.extend(list(map(lambda x:''.join(['psn', str(x), '_pct']), range(n))))
        f.append('tot_pos_pct')
        self.Account = namedtuple('Account', f)
        


class Broker(object):
    ''' 
    
    
    '''
    def __init__(self, cfg, ind, 
                 nComponent=3, 
                 nAdjustPos=5,
                 dbg=True, 
        ):
        self.cfg, self.ind=cfg, ind
        # 投资组合的代码列表一定要升序排列, 保持与mdf的一致性
        # 简单地, 直接取值于ind mdf的内层列索引就好了
        # self.codes=cfg.codes
        self.codes = list(self.ind.columns.get_level_values(1).unique())
        
        self.nComponent, self.nAdjustPos, self.dbg = nComponent, nAdjustPos, dbg
        
        self.commission=cfg.commission
        self.capital =  cfg.capital
        
        self.balance, self.totmktcap, self.totcap = None, 0., 0.
        self.ntrades=0
        
        
        # mcols = 'code name volume price mktcap pospct'.split()
        self.position_mcols = pd.MultiIndex.from_product(
            [range(self.nComponent), 
             'code name price volume'.split()
            ]
        )
        self.position_mdf=pd.DataFrame({}, None, columns=self.position_mcols)
        
        self.init()
        self._init_account()
        
    def init(self):
        self.onehand=1 if self.codes[0][:2]=='39' else 100
        self.fee, self.fees=None, []
        self.positions,  self.totcaps, self.jgds=[], [], []
        
    def _init_account(self):
        # 单行账户信息构造函数
        # 使用方法: self.account = self.call_account(*args)
        self.call_account = Account(self.nComponent).Account
        self.account=None
        self.accounts=[]
    
    def _calc_afc(self, *args, ):
        '''calc amount/fee/cashflow'''
        volume, price=args
        op=self.order.operation
        if op==1:
            amount = volume * price
            fee = amount * self.commission
            cf = - (amount + fee); 
        elif op==-1:
            amount = volume * price
            fee = amount * self.commission
            cf = amount - fee
        return (amount, fee, cf)
    
    
    def _init_position(self, batch_buy_order):
        ''' 初始化头寸MultiCols df (mcdf)
        broker接收到首次批量买单之后, 进行的操作. 初始股数设置为零.
        '''
        date = batch_buy_order[0].date
        data=[]
        for o in batch_buy_order:
            cnpv=o.code, _cn_dict[o.code], o.price, 0
            data.extend(cnpv)
        self.position = pd.DataFrame([data], index=[date], columns=self.position_mcols)
    
    def _first_batch_buy(self, bbo):
        '''首次买单专用, 用来去除在买入操作(_buy方法)里的检查balance状态 '''
        assert self.balance is None, '不应该是首次买单'
        self.totcap = self.balance = self.capital 
        self._init_position(bbo)
        
        # weight=[1/self.nComponent for i in self.buy_list]
        # self.money = [self.totcap * w for w in self.weight]
        totcap = self.totcap
        
        for o in bbo:
            price = o.price
            money = totcap * o.percent
            volume = int( (money/price)//self.onehand) * self.onehand
            self._buy(o, volume)
        pass
    
    def buy_target_percent(self, order, buylist=None):
        '''
        单股买入, 包括加仓和新建仓位两种情况
        成交量由目标仓位来决定 
        buylist的用法: 
            加仓时用不着
            新建仓位时用来确定psn/头寸的席位号
        '''
        self.order = order
        target_pct = order.percent
        psn = self._get_psn()
        price = order.price
        # 加仓操作
        if psn is not None: 
            volume = self.get_position_volume()[psn]
            addon_vol = (self.totcap * target_pct - price * volume )/price
            addon_vol = int(addon_vol//self.onehand) * self.onehand
            if addon_vol >= 1:
                self._buy(order, addon_vol)
        # 想要买入新的个股
        else: 
            volume = int(
                (self.totcap * target_pct)//price
            )
            seat_dict = dict(zip( 
                buylist, 
                range(len(buylist))
            ))
            psn = seat_dict[order.code]
            if volume >= 1:
                self._buy(order, volume, flag=psn)
            pass
            
    def sell_target_percent(self, order):
        self.order = order
        target_pct = order.percent
        psn = self._get_psn()
        price = order.price; _=price
        if psn is not None: # 减仓 清仓操作
            volume = self.get_position_volume()[psn]
            if target_pct==0:
                reduce_vol = volume # 暂且为清仓
                # reduce_vol = (self.totcap * target_pct - price * volume )/price
                # reduce_vol = int(addon_vol//self.onehand) * self.onehand
                if reduce_vol >= 1:
                    self._sell(order, reduce_vol)
            else:
                print('功能还需完善!')
                raise RuntimeError('抱歉, 功能还不完善!')
        else: 
            raise RuntimeError('想要卖出不在头寸里的个股')
            pass
            
        
    
    def sort_position_seat(self, buylist= ['399300', '399905', '399006']):
        ''' 每次批操作之前应该先调用该函数, 以便使头寸进入到正确的席位上
        依照buylist订单里的席位顺序
        动能大的进首席
        '''
        pos = self.position
        # pos = utest_position(3)
        date = pos.index.values[0]
        seat_dict = dict(zip( buylist, range(len(buylist)), ))
        df = pos.loc[date].unstack(1) # 对于单行的mcdf, 这样做就消除了时间戳, 使之成为常规df
        # df = pos.loc[ [date]].unstack(1) # 对于单行的mcdf, 这样做就没有降低维度
        # df1  = pos.stack(0).loc[date]  # 非常不一样的df
        
        df['key'] = df.code.apply(lambda x: seat_dict[x])
        # 处理过程中也可以忽略重置索引和索引名称
        df=df.sort_values(by='key').drop('key', axis=1) #.reset_index(drop=True)
        # df.index.name='seat'
        flat_val = df.values.flatten()
        
        self.position = new_pos= pd.DataFrame([flat_val], [date], pos.columns)
        _=new_pos
        # p.stack().sort_values( by= (date, 'code') , axis=1)
        self.position.columns.set_levels(range(self.nComponent), level=0, inplace=True)
        # return new_pos
    
        
        
    def _get_psn(self):
        '''获取头寸坐席号psn'''
        order=self.order
        date   = order.date; _=date
        code   = order.code
        # 因为头寸df是单行的时间索引, 2层列索引(第一层是席位号,第二层是名称和持股数量)
        # 该时间戳对应最后一次操作日期, 所以用iloc方法较为通用
        # tmp    = self.position.loc[date].unstack()
        # tmp 是消灭掉时间戳的df, 方便过滤出来席位号
        #              code    name     price     volume
        #           0  399006  创板100  2151.39      4
        #           1  399300  沪深300  3982.19      2
        #           2  399905  中证500  5576.75      1
        tmp    = self.position.iloc[0].unstack()
        try:
            psn = tmp[tmp.code==code].index.values[0] # position seat number 
        except:
            psn = None # 应该是订单里要操作的个股不在头寸里面, (不属于加减仓的操作)
            print(f'Warning: {order.i} {order.code} 要操作的个股目前不在头寸里.')
        return psn
    
    def _buy(self, order, volume, flag=-1):
        '''用账户当前的资金余额买入股票, 成交量和成交价分别是volume和price.
        资金余额不足时会抛出异常.
        flag: 加仓或者开新仓标志.
            -1: 表示加仓, seat头寸坐席号psn保持不变
            >0的整数: 建新仓的psn坐席号
        '''
        self.order=order
        # self.balance = self.capital if self.balance==None else self.balance

        psn = self._get_psn() if flag==-1 else flag
        price  = order.price
        if self.balance > self.onehand*price*(1+self.commission):
            self.bprice = price * (1+self.commission)
        else:
            raise RuntimeError(f'资金余额不足! 想要买入数量={volume} @价格={price}')

        amount, fee, cf = self._calc_afc(volume, price, )
        
        self.balance += cf # 更新现金余额
        # 更新"动态头寸"里的时间戳和个股的股数, 最新买入价
        self.position.index = (order.date,)
        if flag==-1:
            self.position.loc[order.date, (psn, 'volume')] += volume 
            self.position.loc[order.date, (psn, 'price')] = price 
        elif flag>=0:
            # 新建一个临时头寸变量other, 然后并联到position里
            self.other_pos = other = self.create_tmp_pos(order, volume, psn)
            self.position = pd.concat(
                [self.position, other], axis=1, ignore_index=False
            )
        
        self._jgd = (volume, amount, fee, cf, self.balance, self.ntrades)
        self.log_jgd()

    def create_tmp_pos(self, order, volume, psn):
        '''
        注意列名清单一定要升序排列, 因为后续需要行列转换操作.
        这些操作默认情况下pandas会对索引名称自动地进行升序排列.
        '''
        data = (order.code, 
                _cn_dict[order.code], 
                order.price, 
                volume, 
        )
        other = pd.DataFrame(
            [data],
            index=[order.date,],
            columns=pd.MultiIndex.from_product([
                [100+psn],  # +100表示: 避免并联时席位号冲突
                'code name price volume'.split() # 一定要升序排列
            ])
        )
        # print(f'\n临时新建头寸other_pos \n {other}\n')
        return other


    def log_jgd(self):
        # 构造交割单: 在原始订单第6位置插入 name, 然后合并上交割字段
        # 'i date time op code name price pct \
        # volume amount fee cashflow \
        # balance \
        # ntrade '
        _ = self.order[:5] + (_cn_dict[self.order.code],) + self.order[5:7] + self._jgd 
        self.jgd = JiaoGeDan(*_)
        self.jgds.append(self.jgd.__repr__())
        '''
        if self.dbg: 
            print(jgd)
            self.printAcc1(*jgd)
        '''

    def _sell(self, order, volume):
        '''用账户当前的股票余额卖出股票, 成交量和成交价分别是volume和price.
        股票余额不足时会抛出异常.'''

        self.order = order
        psn   = self._get_psn()
        price = self.order.price
        # if not self.possize >= volume:
        #     raise RuntimeError(f'股票余额不足! 想要卖出数量={volume} @价格={price:.2f}')

        volume = int(volume//self.onehand * self.onehand)
        amount, fee, cf = self._calc_afc(volume, price)
        
        self.balance += cf # 更新可用资金
        self.ntrades += 1  # 交易次数
        # 更新"动态头寸"里的时间戳和个股的股数
        self.position.index = (order.date,)
        self.position.loc[order.date, (psn, 'volume')] -= volume 
        # 持股数量为零时, 及时清楚该席位psn
        if self.position.loc[order.date, (psn,'volume')]==0:
            self.position.drop(columns=psn, level=0, inplace=True)
        
        self._jgd = (volume, amount, fee, cf, self.balance, self.ntrades)
        self.log_jgd()
        
        
    def _check_totcap(self, order, picktime=1500):
        '''picktime:1500 表示收盘时刻的查资金操作, 会把账户信息保存到历史清单里
        别的时间的 计算总资产, 不会保存, 只是用来为目标仓位下单提必要数据.
        '''
        self.order=order
        curr = self.calc_totcap(picktime); _=curr
        
    
    def _gcp(self,order):
        ''' get close price at closing belling time of each day'''
        self.order=order
        price=order.price
        if self.possize>0:
            op=10 #'hs' #hold shares
            order = order._replace(operation=op)
            mktcap = price * self.possize; 
            totcap = mktcap + self.balance; 
            self.pos = self.pospct = mktcap/totcap #市值 总资产 仓位占比
            _=(0, 0, 0, 0, self.balance, mktcap, totcap,  self.pospct, self.possize)
            _=order + _ + (self.ntrades, )
            jgd=self.Jgd(*_)
            if self.dbg: self.printAcc1(*jgd)
            self.jgds.append(jgd)
            
            
        elif self.possize==0:
            op=0 #'hc' # hold cash
            order = order._replace(operation=op)
            mktcap = 0
            totcap = self.capital if self.balance is None else self.balance 
            self.pos=self.pospct=0
            _=(0, 0, 0, 0, self.balance, 0, totcap,  0, 0)
            _=order + _ + (self.ntrades, )
            jgd=self.Jgd(*_)
            if self.dbg: self.printAcc1(*jgd)
            self.jgds.append(jgd)

    gcp=_gcp # alias name of method
        
 
    def _get_position(self, iloc=None):
        '''  
        >>> p.get_position()
             code   mktcap   name     pospct    price     volume
        0  399006  54668.5   创业板指  0.499637  2186.74     25
        1  399905  51360.4   中证500  0.469403  5706.71      9
        
        >>> p.get_position().volume.tolist()
        Out[522]: [25, 9]
        
        >>> p.get_position(1)
        code        399905
        mktcap     51360.4
        name         中证500
        pospct    0.469403
        price      5706.71
        volume           9
        Name: 1, dtype: object
        
        >>> p.get_position(1).code
        Out[518]: '399905'
        
        >>> p.get_position(1)['volume']
        Out[519]: 9
        
        '''
        if iloc is None:
            p_df = self.position_mdf.iloc[-1].unstack() #level=-1, 表示内层索引, 把头寸信息平放到列轴里
        elif isinstance(iloc, int):
            p_df = self.position_mdf.iloc[-1].unstack().loc[iloc]
        else:
            raise RuntimeError('头寸的索引iloc越界了!')
        return p_df


    def get_position(self):
        return self.position.stack(0)
    
    def get_position_volume(self):
        return self.position.loc[:, (range(self.nComponent),'volume')].values[0]
    get_position_size = get_position_volume

    def get_position_code(self):
        return self.position.loc[:, (range(self.nComponent),'code')].values[0]

    def get_position_name(self):
        return [_cn_dict[c] for c in self.get_position_code()]
    
    def calc_totcap(self, picktime=1500):
        # np.array([2,3]) * np.array([4,5])
        '''
        account = self.position.stack(0).loc[:, ('price volume'.split())].prod(axis=1).unstack(level=1)
        account['totmktcap'] = account.sum(axis=1)
        account['balance']   = self.balance
        account['totcap']    = account['balance totmktcap'.split()].sum(axis=1)    
        '''
        code = self.get_position_code()
        names = self.get_position_name()
        volume = self.get_position_volume()
        price = [self.order.price[_code] for _code in code ]
        mktcap = volume * price 
        totmktcap = sum(mktcap)
        mkt_value = tuple(mktcap) + (totmktcap, )
        self.totcap = totmktcap + self.balance
        pospct = np.array(mkt_value) / self.totcap

        _ = (self.order.i, self.order.date, ' '.join(names)) + \
            mkt_value + \
            (self.balance, self.totcap) + \
            tuple(pospct)
            
        curr = self.call_account(*_)
        if picktime==1500:
            self.account = curr
            self.accounts.append(self.account)

    
    def _paccount(self, rdata):
        ''' print one row of account'''
        _  = ' {:4d}'.format(rdata[0]) # 序号 日期 标的名称串
        _ += ' {:10s}'.format(rdata[1].isoformat()[:10]); 
        _ += " '{}'".format(rdata[2]);    iloc_mv = 3+self.nComponent+3
        _ += ' '.join(map(lambda x: f'{x:10.2f}', rdata[3:iloc_mv])) # 市值
        _ += ' '.join(map(lambda x: f'{x:8.2%}', rdata[iloc_mv: ])) # 头寸占比
        # _ = ''.join([_1, _2, _3])
        print(f'<Acnt {_} >')
        
    def paccount(self):
        self._paccount(self.account)
        
    def paccounts(self, tail=5):
        for data in self.accounts[-tail:]:
            self._paccount(data)
        
    def check_code_to_be_killed(self, order):
        ''' 利用集合运算更简单: 先求出交集, 然后求出: 出仓股和入仓股  
        '''
        symbols = [s for s in self.get_position().code if s not in order.code]
        if bool(symbols):
            return symbols
        else: return None

    


def print_info(b):
    print('交割单:\n', b.jgd); 
    print('历史交割单'); 
    for j in b.jgds:print('', j) 
    
    print(f'现金余额:{b.balance:.2f}'); print('当前头寸:\n', b.position.stack(0)); 


def utest(nCom=2, weight=[0.7, 0.3]):
    ''' 
    >>> reset -f
    >>> ohlc, ind, o, b = utest(2, (0.7, 0.3))
    >>> ohlc, ind, o, b = utest(3, (0.3, 0.3, 0.3))
    '''
    ohlc, ind = pre_proc()
    
    
    nCom=3
    o=Order(ind)
    b=Broker(cfg, ind, nComponent=nCom)
    
    # 第100行时 下批量买单
    i=100
    bbo = o.create_batch_buy_order(i, o.codes[:nCom],  percent=(.1,.1,.1))
    print('最新订单:\n', o); print('\n历史订单:'); o.porders() # 最新订单和历史订单
    b._first_batch_buy(bbo)
    print_info(b)

    ct = o.create_check_totcap_order(i) # 查资金订单
    # totcap = b._check_totcap(ct, picktime=1400)
    b._check_totcap(ct, )
    b.paccount()

    for i in range(101, 130):    

        # 第105行时, 买单, 第1只个股,  目标仓位.4
        # 第110行时, 买单, 第2只个股,  目标仓位.3
        # 第115行时, 买单, 第3只个股,  目标仓位.2
        # 120行时, 清仓 第3只个股
        if i==105:
            ct = o.create_check_totcap_order(i) # 查资金订单
            b._check_totcap(ct, picktime=1400) # 执行查资金操作, 来刷新self.totcap 
            
            bo = o.create_buy_order(i, o.codes[0], 0.4)
            b.buy_target_percent(bo)
            
        elif i==110:
            ct = o.create_check_totcap_order(i) # 查资金订单
            b._check_totcap(ct, picktime=1400) # 执行查资金操作, 来刷新self.totcap 
            
            bo = o.create_buy_order(i, o.codes[1], 0.3)
            b.buy_target_percent(bo)
            
            
        elif i==115:
            ct = o.create_check_totcap_order(i) # 查资金订单
            b._check_totcap(ct, picktime=1400) # 执行查资金操作, 来刷新self.totcap 
            
            bo = o.create_buy_order(i, o.codes[2], 0.2)
            b.buy_target_percent(bo)
            
        elif i==120:            
            so = o.create_sell_order(i, o.codes[2], 0.)
            b.sell_target_percent(so)
            
            
            
        print(f'i={i}')
        ct = o.create_check_totcap_order(i) # 查资金订单
        b._check_totcap(ct, )




    
    # for i in range(100, 220):
    #     ct = o.create_check_totcap_order(i) # 查资金订单
    #     b._check_totcap(ct)
    #     b.paccount()
    # print()
    # b.paccounts(tail=5)
    return ohlc, ind, o, b

  


posted @ 2021-12-24 16:08  duanqs  阅读(434)  评论(0编辑  收藏  举报