def run_after(self):
     """
     回测之后的自定义动作
     :return:
     """
     simulation_logger.info('str_id:{}, 结束模拟盘回测:{}'.format(
         self.strategy.strategy_id, datetime.now()))
 def run_before(self):
     """
     回测之前的自定义动作
     :return:
     """
     simulation_logger.info('str_id:{}, 开始模拟盘回测:{}'.format(
         self.strategy.strategy_id, datetime.now()))
    def __run(self):
        """
        开始
        :return:
        """
        # 回测之前
        self.run_before()

        # 开始回测
        if self.__bars.size():
            __bar = self.__bars.top()

            # bar前
            for __func in __bar.befores:
                __func(__bar)

            # bar中
            simulation_logger.info('str_id:{}, bar:{}'.format(
                self.strategy.strategy_id, __bar))
            self.__process(bar=__bar)

            # bar后
            for __func in __bar.afters:
                __func(__bar)
        simulation_logger.info('str_id:{}, bar.size:{}'.format(
            self.strategy.strategy_id, self.__bars.size()))

        # 回测之后
        self.run_after()
    def run_after(self):

        self.strategy.data_update['simulation_success_flag'] = 10609
        self.strategy.data_update['simulation_message'] = '实盘成功'

        # 通知Java
        # urlPost(self.strategy.data_update)

        # 保存成功后的因子信息
        self.strategy.data_update['simulation_new_flag'] = 0
        self.strategy.data_update['simulation_cost_time'] = (
            datetime.now() - self.strategy.now).seconds
        self.strategy_data.save_strategy_data(data=self.strategy.data_update)

        simulation_logger.info('str_id:{}, run after')
        simulation_logger.info('str_id:{}, 运行后的position:{}'.format(
            self.strategy.strategy_id, self.position.positions))
        simulation_logger.info('str_id:{}, 运行后的cash:{}'.format(
            self.strategy.strategy_id, self.position.cash))
        simulation_logger.info('str_id:{}, 运行后的持仓比例:{}'.format(
            self.strategy.strategy_id, self.position.percent))
        simulation_logger.info(
            'str_id:{}, 模拟所花时间:{} s-------------------------------------------------------------------------------\n\n'
            .format(self.strategy.strategy_id,
                    self.strategy.data_update['simulation_cost_time']))
Beispiel #5
0
    def xbar(self, stock, day=None, type=0):
        stock = stock[0:6]
        df = cache.get('hq_{}'.format(stock))
        if df is None or len(df) == 0:
            df = self.Hdf.select('/df_{}'.format(stock))
            cache.add('hq_{}'.format(stock), df)

        if df is not None:
            if type == 0:
                try:
                    close, ltm = df.loc[day]
                    return [{'day': day, 'close': round(close, 2), 'ltm': ltm}]
                except Exception as e:
                    simulation_logger.info('miss:{}:{}:{}'.format(
                        e, stock, day))
                    return []
            else:
                df = df[df.index <= day]
                if not df.empty:
                    close = df['close'].values[-1]
                    ltm = df['ltm'].values[-1]
                    day = df.index[-1]
                    return [{'day': day, 'close': round(close, 2), 'ltm': ltm}]
                else:
                    return []
        else:
            return []
Beispiel #6
0
 def wrapper(*args, **kwargs):
     for __i in range(5):
         try:
             time.sleep(__i)
             func(*args, **kwargs)
             break
         except Exception as e:
             simulation_logger.info("db操作失败:{}".format(e))
 def process(self, bar):
     """
     自定义回测
     :param bar:
     :return:
     """
     simulation_logger.info('str_id:{}, 自定义回测,bar:{}。'.format(
         self.strategy.strategy_id, bar))
Beispiel #8
0
    def finances(self, befor_day=None):
        """
        选股
        :param befor_day:
        :return:
        """
        # 交集和并集需要讨论
        start = time.time()
        istocks = self.plate_select(befor_day)
        # print('istocks:{}'.format(istocks))
        pcodes = self.strategy.hqDB.find_suspendeds(befor_day)
        istocks = (istocks - set(pcodes))
        day = '/quota_' + str(befor_day).replace('-', '')
        df1 = self.strategy.hqDB.mysql_Hdf.select(day)
        if df1 is not None:
            df = df1[df1['ltm'] != 1][df1.index.isin(istocks)]
            if len(self.finance):
                for row in self.finance:
                    key, parms = row
                    # 3.6 pandas bug
                    if key == 'opcfg':
                        df[key] = df[key].astype('float64')
                    for parm in parms:
                        _p = str(parm[1]).split('&')
                        if len(_p) == 1:
                            df = df.query('{}{}{}'.format(
                                key, parm[0], parm[1]))
                        else:
                            df = df.query('{}{}{} and {}{}'.format(
                                key, parm[0], _p[0], key, _p[1]))
            if len(self.technical):
                for row in self.technical:
                    key, parms = row
                    for parm in parms:
                        df = df.query('{}{}{}'.format(key, parm[0], parm[1]))

            if len(self.orders['valuation']) > 0:
                for order in self.orders['valuation']:
                    if order[1]['period'] == '1':
                        df['{}_xrank'.format(
                            order[0])] = df[order[0]].rank(ascending=True)
                    else:
                        df['{}_xrank'.format(
                            order[0])] = df[order[0]].rank(ascending=False)

            df['xcrank'] = df[[
                col for col in df.columns if col.endswith('_xrank')
            ]].apply(lambda x: x.sum(), axis=1)
            df = df.sort_values(by=['xcrank'], ascending=False)
            codes1 = list(df.index)
            simulation_logger.info(u'选择的股票数为:{},时间:{}:花费时间:{}'.format(
                len(codes1), befor_day,
                time.time() - start))
            return codes1, df['cname'].values
        else:
            return ([], [])
    def create_new_contract(self, parameters_dic):
        """创建合约"""
        __interface = '/externalService/external/cntr/add'
        cntr_id = self.strategy_id + str(
            time.time()).split('.')[0][-3:]  # 生成合约来源ID

        if not parameters_dic.get('cntrCapAmt'):
            parameters_dic['cntrCapAmt'] = '30000000'  # 合约总资金
        parameters_dic['srcCntrId'] = cntr_id  # 合约来源编号
        self.cntr_id = cntr_id
        parameters_dic['usrId'] = self.usr_id  # 用户ID
        parameters_dic['usrNm'] = self.usr_name  # 用户名称
        parameters_dic['drCrDt'] = datetime.today().strftime(
            "%Y-%m-%d %H:%M:%S")  # 借款时间(默认当前)
        parameters_dic['repayDt'] = "2099-12-31 00:00:00"  # 还款时间
        parameters_dic['altAmt'] = "0.00"  # 预警金额
        parameters_dic['stpLosAmt'] = "0.00"  # 止损金额
        parameters_dic['drCrAmt'] = 0  # 合约借贷金额
        parameters_dic['gurtyAmt'] = parameters_dic[
            'cntrCapAmt']  # 合约保证金 cntr_cap_amt="100000",  必须和cntrCapAmt(合约金额)一致
        # parameters_dic['riskParam'] = ",,,13001:1,,,,,,,,,"    # , "riskParam": ",,,13001:1,,,,,,,,," "param": "0000000000000",
        # parameters_dic['param'] = "0000000000000"
        print('parameters_dic:', parameters_dic)
        res_data = self.con_interface.get_data(__interface, parameters_dic)
        print(
            'res_data::', res_data
        )  # {'cntrId': 41227001, 'srcCntrId': 0, 'flwId': 1545903498541358689, 'respMessage': '成功', 'respCode': '000'}
        if res_data.get('respCode') == '000':
            update_info = {
                'strategy_id': self.strategy_id,  # 策略ID
                'contract_source_id': cntr_id,  # 合约来源ID
                'contract_id': res_data['cntrId'],  # 合约编号(3.0)
                'user_id': self.usr_id,
                'type': 0,  # 暂时默认为0
            }
            # 保存新合约信息
            with MysqlManager('quant').Session as session:
                for i in range(3):
                    try:
                        session.merge(ContractInfo(**update_info))
                    except:
                        simulation_logger.info(
                            'STR_ID:{},【创建合约】数据库出现异常-{}:{}'.format(
                                self.strategy_id, i, traceback.print_exc()))
                        continue
                    break
                else:
                    with open(
                            MY_PROJECT_PATH +
                            '/error_doc/ContractInfo_error.txt', 'a') as f:
                        f.write(json.dumps(update_info) + '\n')

        res_data['srcCntrId'] = cntr_id
        return res_data
Beispiel #10
0
    def sell_all(self):
        """
        卖出所有的股票
        :return:
        """
        simulation_logger.info('str_id:{},pending order sell all'.format(self.strategy.strategy_id))
        # 如果持仓为空则直接返回
        if self.position.positions.empty:
            return True,{'message':'持仓为空,不用清仓。'}

        # 查询清仓的股票
        __before_stocks = set(self.position.shareholding)
        time1 = time.time()
        info = self.contract_operator.security_clearance(order=True,sleep_m=8)
        simulation_logger.info('str_id:{},sell all cost:{} s'.format(self.strategy.strategy_id,time.time() - time1))
        if info['respCode'] == '000':
            # 保存交易流水
            trade_time = datetime.now()
            before_assets = self.position.total_assets
            before_position = self.position.positions
            self.position.update_master(query_hold_days=False)
            simulation_logger.info('str_id:{},卖出所有股票后的更新仓位后的现金:{}'.format(self.strategy.strategy_id,self.position.cash))
            __after_stocks = set(self.position.shareholding)
            clearance_stocks = __before_stocks-__after_stocks

            # 保存交易流水的内容
            after_assets = self.position.total_assets
            after_position = self.position.positions
            # transaction_save(before_position=before_position, after_position=after_position,
            #                  before_assets=before_assets,
            #                  after_assets=after_assets, strategy_id=self.strategy.strategy_id, trade_type='sell_all',
            #                  trade_time=trade_time)
            __kwargs = {'before_position': before_position.to_dict(), 'after_position': after_position.to_dict(),
                        'before_assets': before_assets,
                        'after_assets': after_assets, 'strategy_id': self.strategy.strategy_id,
                        'trade_type': 'sell_all',
                        'trade_time': trade_time.strftime('%Y-%m-%d %H:%M:%S')}
            transaction_save.apply_async(queue='transaction', kwargs=__kwargs)

            # 删除持仓表信息
            try:
                if clearance_stocks:
                    with MysqlManager('quant').Session as session:
                        for __stock in clearance_stocks:
                            # 删除这只股票的持仓信息
                            simulation_logger.info('str_id:{},清仓一只股票:{},删除相应持仓'.format(self.strategy.strategy_id,__stock))
                            session.query(ContractPositionsInfo).filter(ContractPositionsInfo.strategy_id==str(self.strategy.polId),
                                                                        ContractPositionsInfo.contract_source_id == str(self.strategy.contract_source_id),
                                                                        ContractPositionsInfo.stock_code == str(__stock)).delete()
            except Exception as e:
                simulation_logger.info('str_id:{},清仓时删除持仓表信息出错:{}'.format(self.strategy.strategy_id,e))
            return True,info
        else:
            return False,info
 def request_cash(self):
     """
     请求cash
     :return:
     """
     result = self.contract_operator.query_assets()
     if result.get('respCode', '404') == '000':
         result = round(float(result.get('curAvalCapAmt', 0)), 2)
     else:
         result = 0
     if result:
         self.cash_flag = 1
     else:
         self.cash_flag = -1
     simulation_logger.info('str_id:{},现金:{}'.format(
         self.strategy.strategy_id, result))
     return result
 def request_total_assets(self):
     """
     请求总资产
     :return:
     """
     result = self.contract_operator.query_assets()
     if result.get('respCode', '404') == '000':
         result = round(float(result.get('tTAstAmt', 0)), 2)
     else:
         result = 0
     if result:
         # 标识查询后不为空
         self.total_assets_flag = 1
     else:
         # 标识为查询后为空
         self.total_assets_flag = -1
     simulation_logger.info('str_id:{},总资产::{}'.format(
         self.strategy.strategy_id, result))
     return result
 def update_percent(self, refresh=False):
     """
     更新仓位
     :param refresh:
     :return:
     """
     if not refresh:
         __positions = self.get_positions()
         __total_assets = self.get_total_assets()
     else:
         __total_assets = self.refresh_total_assets()
         __positions = self.refresh_positions()
     if self.total_assets_flag == 1 and self.positions_flag == 1:
         __equity = (__positions['market_value']).sum()
         self.percent = round(float(__equity / __total_assets), 6)
         simulation_logger.info('str_id:{},update percent:{}'.format(
             self.strategy.strategy_id, self.__percent))
     else:
         self.percent = 0
    def termination_contract(self,
                             parameters_dic='',
                             delete_instruction=False):
        """终止合约"""
        __interface = '/externalService/external/cntr/end'
        res_info = {
            'respCode': '400',
            'respMessage': '请求失败!请输入正确的操作指令!【delete_instruction】',
        }
        if delete_instruction is False:
            return res_info
        if not parameters_dic:
            parameters_dic = dict()
            parameters_dic['srcCntrId'] = self.cntr_id  # 合约来源ID
        res_data = self.con_interface.get_data(__interface, parameters_dic)
        # 终止合约处理合约表和合约持仓表的信息
        with MysqlManager('quant').Session as session:
            for i in range(3):
                try:
                    session.query(ContractInfo).filter(
                        ContractInfo.contract_source_id ==
                        self.cntr_id).update({'flag': 0})  # 合约表合约信息软删除
                    session.query(ContractPositionsInfo).filter(
                        ContractPositionsInfo.contract_source_id ==
                        self.cntr_id).delete()  # 合约持仓表信息删除
                except:
                    simulation_logger.info(
                        'STR_ID:{},【终止合约】数据库出现异常-{}:{}'.format(
                            self.strategy_id, i, traceback.print_exc()))
                    continue
                break
            else:
                with open(
                        MY_PROJECT_PATH +
                        '/error_doc/termination_contract_error.txt', 'a') as f:
                    save_info = {
                        'strategy_id': self.strategy_id,  # 策略ID
                        'cntr_id': self.cntr_id  # 合约来源ID
                    }
                    f.write(json.dumps(save_info) + '\n')

        return res_data
    def __status_track(self, entrust_number, sleep_m):
        """合约委托的状态追踪,超时强制撤单"""
        # 追踪状态
        flag = 0
        wait_count = 0
        res_info = {}
        while True:
            if wait_count >= 3:
                # 进行撤单操作
                # print('准备进行撤单操作...')
                revoke_entrust_res = self.revoke_entrust({
                    "entrustNo":
                    entrust_number
                })  # 撤销委托,创建委托返回的委托编号  # revoke_entrust_res =
                simulation_logger.info(
                    '撤单动作返回信息:{}'.format(revoke_entrust_res))
                # print('revoke_entrust_res:', revoke_entrust_res)
                # if revoke_entrust_res.get('respCode') == '154_6':  # 已经成功,撤销失败
                #     flag = 1
                #     res_info = self.__get_today_trans_info(entrust_number, res_info)
                # 再次判断有没有成交(当日成交)
                today_transaction_res = self.today_transaction()
                for tmp in today_transaction_res.get('list', []):
                    transId = tmp.get('delgtId', '')
                    if str(transId) == entrust_number:
                        flag = 1
                        res_info = self.__get_today_trans_info(
                            entrust_number, res_info)
                        break
                else:
                    simulation_logger.info('撤单成功!{}'.format(entrust_number))
                break
            wait_count += 1
            time.sleep(sleep_m)
            res_info = self.__get_today_trans_info(
                entrust_number, res_info)  # 在当天成交中查询 该笔委托的成交相关信息
            if res_info:
                flag = 1
                break

        return wait_count, flag, res_info
Beispiel #16
0
    def sell(self,sell_info):
        """
        卖出
        :param sell_info:卖出信息
        :return:
        """
        simulation_logger.info('str_id:{},pending order sell:{}'.format(self.strategy.strategy_id,sell_info))
        time1 = time.time()
        info = self.contract_operator.place_an_order(stock_info=sell_info,trade_type='sell')
        simulation_logger.info('str_id:{},sell cost:{} s'.format(self.strategy.strategy_id,time.time() - time1))
        info['used_money'] = round(float(info.get('useAmt',0)),2)
        info['trade_count'] = int(info.get('useQty',0))
        if 'useAmt' in info.keys():
            info.pop('useAmt')
        if 'transQty' in info.keys():
            info.pop('transQty')
        if info['respCode'] == '000':
            if info['trade_count']:

                # 保存交易流水
                trade_time = datetime.now()
                before_assets = self.position.total_assets
                before_position = self.position.positions
                self.position.update_master(query_hold_days=False)
                after_assets = self.position.total_assets
                after_position = self.position.positions
                # transaction_save(before_position=before_position,after_position=after_position,before_assets=before_assets,
                #                  after_assets=after_assets,strategy_id=self.strategy.strategy_id,trade_type='sell_one',
                #                  trade_time=trade_time,order_info=sell_info,result_info=info)
                __kwargs = {'before_position':before_position.to_dict(),'after_position':after_position.to_dict(),'before_assets':before_assets,
                            'after_assets':after_assets,'strategy_id':self.strategy.strategy_id,'trade_type':'sell_one',
                            'trade_time':trade_time.strftime('%Y-%m-%d %H:%M:%S'),'order_info':sell_info,'result_info':info}
                transaction_save.apply_async(queue='transaction',kwargs=__kwargs)

                # 删除持仓表信息
                try:
                    # 在持仓表中删除清仓的股票
                    if int(before_position.loc[before_position['inst'] == sell_info['stockCode'],'quantity'].values[0])==int(info['trade_count']):
                        simulation_logger.info('str_id:{},清仓一只股票成功:{},删除持仓表中数据'.format(self.strategy.strategy_id,sell_info['stockCode']))
                        with MysqlManager('quant').Session as session:
                            session.query(ContractPositionsInfo).filter(ContractPositionsInfo.strategy_id==str(self.strategy.strategy_id),
                                                                        ContractPositionsInfo.contract_source_id == str(self.strategy.contract_source_id),
                                                                        ContractPositionsInfo.stock_code == str(sell_info['stockCode'])).delete()
                except Exception as e:
                    simulation_logger.info('str_id:{},卖出单只股票时删除持仓表信息出错:{}'.format(self.strategy.strategy_id, e))
            return True,info
        else:
            return False,info
    def process(self, bar):
        """
        自定义回测函数
        :param bar: bar流
        :return:
        """
        if bar.stop:
            # 卖完所有股票
            self.sell_all()
        else:
            # 卖出一只股票
            self.sell_one()

            # 浮盈加减仓
            self.step(bar)

            # 选股
            self.select_stock(bar)

            # 买入选出的股票
            self.buy_select(bar)
        self.statistics(bar)
        simulation_logger.info('str_id:{}, end')
 def select_stock(self, bar):
     """
     选股
     :param bar:
     :return:
     """
     simulation_logger.info('str_id:{}, select stock'.format(
         self.strategy.strategy_id))
     simulation_logger.info(self.position.percent)
     # 还有仓位才进行选股
     if float(
             self.strategy.maxPosPct) - self.position.percent > 0 and float(
                 bar.weight) - self.position.percent > 0:
         self.buyStocks, self.buyNames = self.strategy.order.finances(
             bar.date)
     else:
         self.buyStocks, self.buyNames = [], []
     simulation_logger.info('str_id:{}, select stocks:{},names:{}'.format(
         self.strategy.strategy_id, self.buyStocks,
         self.buyNames).format(self.strategy.strategy_id))
 def sell_all(self):
     """
     清仓
     :return:
     """
     simulation_logger.info(
         '\nstr_id:{}, sell all------------------------------------------------------------------------------.'
         .format(self.strategy.strategy_id))
     flag, message = self.pending_order.sell_all()
     if flag:
         simulation_logger.info('str_id:{}, 清仓成功,info:{}'.format(
             self.strategy.strategy_id, message))
         self.position.update_master(query_hold_days=False)
         simulation_logger.info('str_id:{}, 成功更新后的cash:{}'.format(
             self.strategy.strategy_id, self.position.cash))
     else:
         simulation_logger.info('str_id:{}, 清仓失败,info:{}'.format(
             self.strategy.strategy_id, message))
         self.position.update_master(query_hold_days=False)
         simulation_logger.info('str_id:{}, 失败更新后的cash:{}'.format(
             self.strategy.strategy_id, self.position.cash))
     # 更新可用现金
     if not self.strategy.maxBuyStockCash:
         self.strategy.available_cash_day = self.position.cash
     simulation_logger.info(
         'str_id:{}, end sell all------------------------------------------------------------------------------.\n'
         .format(self.strategy.strategy_id))
 def statistics(self, bar):
     simulation_logger.info('str_id:{}, statistics'.format(
         self.strategy.strategy_id))
    def place_an_order(self, stock_info, sleep_m=5, trade_type='buy'):
        """
            新策略下单
            trade_type: 默认为1(买), 2为卖
        """
        # 返回数据(模板)
        res_info = {
            'respCode': '000',
            'respMessage': '成功',
        }
        stock_code = str(stock_info.get('stockCode'))
        if trade_type == 'buy':  # 买
            stock_info['tradeType'] = "10801"

        elif trade_type == 'sell':  # 卖
            stock_info['tradeType'] = "10802"

        # 【买/卖】
        business_res = self.business_instructions(stock_info)  # 委托
        # print('business_res:', business_res)
        if business_res.get(
                'status_code') or business_res.get('respCode') != '000':
            res_info['respCode'] = '404'
            res_info['respMessage'] = '请求异常,请重新尝试!详情:{}'.format(business_res)
            return res_info

        entrust_number = business_res.get('entrustNo')  # 委托编号
        print('entrust_number:', entrust_number)

        # 状态追踪
        wait_count, flag, new_res_info = self.__status_track(entrust_number,
                                                             sleep_m=sleep_m)
        simulation_logger.info(
            'STR_ID:{}【追踪结果】wait_count:{},flag:{},stockCode:{}'.format(
                self.strategy_id, str(wait_count), str(flag), stock_code))

        if flag == 0:  # 下单失败
            res_info['respCode'] = '404'
            res_info['respMessage'] = '下单失败!'
            return res_info

        if trade_type == 'buy':  # 买
            # 保存合约信息到python合约持仓表
            update_info = {
                'strategy_id': str(self.strategy_id),  # 策略ID
                'contract_source_id': str(self.cntr_id),  # 合约来源ID
                # 'contract_id': self.cntr_id,  # 传过来的合约编号(3.0)
                'stock_code': stock_code,  # 股票号码
                'user_id': self.usr_id,
                'type': 0,  # 暂时默认为0
                'flag': flag
            }
            # print('update_info:', update_info)
            simulation_logger.info('STR_ID:{},【持仓信息存储】:{},stockCode:{}'.format(
                self.strategy_id, update_info, stock_info.get('stockCode')))

            # 下单成功后保存持仓信息
            with MysqlManager('quant').Session as session:
                for i in range(3):
                    try:
                        session.merge(ContractPositionsInfo(**update_info))
                    except:
                        simulation_logger.info(
                            'STR_ID:{},【下单】数据库异常-{}:{}'.format(
                                self.strategy_id, i, traceback.print_exc()))
                        continue
                    break
                else:
                    with open(
                            MY_PROJECT_PATH +
                            '/error_doc/ContractPositionsInfo_error.txt',
                            'a') as f:
                        f.write(json.dumps(update_info) + '\n')

        res_info['useQty'] = new_res_info.get('useQty')  # 成交数量
        res_info['useAmt'] = new_res_info.get('useAmt')  # 成交金额
        return res_info
    def sell_one(self):
        """
        清仓一只股票
        :return:
        """
        simulation_logger.info(
            'str_id:{}, \nsell one--------------------------------------------------------------------------------.'
            .format(self.strategy.strategy_id))
        for _, row in self.position.positions.iterrows():
            # 不是T+1日不能卖出
            if row.hold_days <= 1:
                simulation_logger.info('str_id:{}, 不是T+1日不能卖出,row:{}'.format(
                    self.strategy.strategy_id, row.hold_days))
                simulation_logger.info(
                    'str_id:{}, -----------------------------------------------------------------------------------------------------\n'
                    .format(self.strategy.strategy_id))
                continue
            # 判断个股是否达到离场条件
            status, msg = self.strategy.order.leave(row)
            # 如果达到离场条件则卖出这只股票
            if status:
                simulation_logger.info(
                    'str_id:{}, 达到单只股票离场条件,stock:{},info:{}'.format(
                        self.strategy.strategy_id, row.inst, msg))
                # 判断是否跌停和停牌退市
                # 跌停不能卖出
                limit_move_status, _ = self.strategy.hqDB.get_limit_move(
                    stock=row.inst)
                if limit_move_status == -1 or limit_move_status == 2:
                    simulation_logger.info(
                        'str_id:{}, 跌停不能卖出,stock:{},limit_move_status:{}'.
                        format(self.strategy.strategy_id, row.inst,
                               limit_move_status))
                    simulation_logger.info(
                        'str_id:{}, -----------------------------------------------------------------------------------------------------\n'
                        .format(self.strategy.strategy_id))
                    continue

                # 获取当前股票是否停牌和最新价,停牌不能卖出
                status, price = self.strategy.hqDB.get_status_price(
                    stock=row.inst)
                if not status:
                    simulation_logger.info(
                        'str_id:{}, 停牌不能卖出,stock:{},status:{}'.format(
                            self.strategy.strategy_id, row.inst, status))
                    simulation_logger.info(
                        'str_id:{}, -----------------------------------------------------------------------------------------------------\n'
                        .format(self.strategy.strategy_id))
                    continue

                # 构造下单的信息,10801:买入,10802:卖出
                sell_info = {
                    "stockCode": "{}".format(f14(row.inst)),
                    "stockName": row['name'],
                    "entrustPrice": "{}".format(price),
                    "entrustCount":
                    str(int(int(row['quantity_sell']) / 100) * 100)
                }
                __flag, __info = self.pending_order.sell(sell_info)
                if __flag:
                    simulation_logger.info('str_id:{}, 下单卖出成功,info:{}'.format(
                        self.strategy.strategy_id, __info))
                    # self.position.update_master(query_hold_days=False)
                    simulation_logger.info('str_id:{}, 成功更新后的cash:{}'.format(
                        self.strategy.strategy_id, self.position.cash))
                else:
                    self.position.update_master(query_hold_days=False)
                    simulation_logger.info('str_id:{}, 失败更新后的cash:{}'.format(
                        self.strategy.strategy_id, self.position.cash))
                    simulation_logger.info('str_id:{}, 下单卖出失败,info:{}'.format(
                        self.strategy.strategy_id, __info))
            else:
                simulation_logger.info('str_id:{}, 没有达到离场条件:{}'.format(
                    self.strategy.strategy_id, msg))
            simulation_logger.info(
                'str_id:{}, -----------------------------------------------------------------------------------------------------\n'
                .format(self.strategy.strategy_id))
        # 更新可用现金
        if not self.strategy.maxBuyStockCash:
            self.strategy.available_cash_day = self.position.cash
        simulation_logger.info(
            'str_id:{}, end sell one--------------------------------------------------------------------------------.\n\n'
            .format(self.strategy.strategy_id))
    def buy_select(self, bar):
        """
        得到委托数量和委托价格
        :param bar:
        :return:
        """
        simulation_logger.info(
            'str_id:{}, buy select--------------------------------------------------------------------------------'
            .format(self.strategy.strategy_id))
        if self.strategy.maxPositionStockNum:
            self.strategy.maxPositionStockNum = int(
                self.strategy.maxPositionStockNum)
        if self.strategy.maxBuyStockNum:
            self.strategy.maxBuyStockNum = int(self.strategy.maxBuyStockNum)
        bar.weight = round(float(bar.weight), 4)
        self.strategy.maxPosPct = round(float(self.strategy.maxPosPct), 6)
        self.strategy.sglMaxPosPct = round(float(self.strategy.sglMaxPosPct),
                                           6)

        # 最大持仓股票数量,如果用户输入大于20,则取20
        # maxPositionStockNum:最大持股数量
        # 根据最大持仓 / 单票进场仓位得出一个可以持股的数量,两者取其小
        # max_buy:根据最大持仓和单只股票进场仓位得到的持有股票数限制
        max_buy_stocks = self.strategy.max_buy
        if self.strategy.maxPositionStockNum:
            max_buy_stocks = min(max_buy_stocks,
                                 self.strategy.maxPositionStockNum)

        # 将stocks进行和名字的对应组合成列表
        stocks = list(zip(self.buyStocks, self.buyNames))

        # 如果股票优先级是随机买入则随机取股票
        if self.strategy.randomSort:
            random.shuffle(stocks)

        # 如果用户设置了单日最大买入股票数量,则先将股票数量限制在这个数量
        if self.strategy.maxBuyStockNum:
            stocks = stocks[0:self.strategy.maxBuyStockNum]

        for stock, name in stocks:

            # 可用金额过小则不买入
            __available_cash_tmp = min(self.position.cash,
                                       self.strategy.available_cash_day)
            if __available_cash_tmp < 1000:
                return

            # 超过最大买入数,不得再买
            # print('len:{},max buy stocks:{}'.format(self.strategy.strategy_id,len(self.position.positions),max_buy_stocks))
            if len(self.position.positions) >= max_buy_stocks:
                simulation_logger.info(
                    'str_id:{}, 超过最大买入数,不得再买,len of positions:{},max_buy_stocks:{}'
                    .format(self.strategy.strategy_id,
                            len(self.position.positions), max_buy_stocks))
                return

            # 如果当前持仓大于等于基准择时持仓则不买入,只有现有仓位小于用户设置的牛熊市最大持仓才会进行买入操作
            if self.position.percent >= bar.weight:
                simulation_logger.info(
                    'str_id:{}, 当前持仓大于等于基准择时持仓则不买入,position.percent:{},bar.weight:{}'
                    .format(self.strategy.strategy_id, self.position.percent,
                            bar.weight))
                return

            # 如果当前持仓大于等于最大持仓则不买入
            if self.position.percent >= self.strategy.maxPosPct:
                simulation_logger.info(
                    'str_id:{}, 当前持仓大于等于最大持仓则不买入,position.percent:{},maxPosPct:{}'
                    .format(self.strategy.strategy_id, self.position.percent,
                            self.strategy.maxPosPct))
                return

            # 如果不能重复买入 并且仓位有这只股票,则不买入,rmRepetitionSort:去重买入
            if self.strategy.rmRepetitionSort and stock in self.position.shareholding:
                simulation_logger.info(
                    'str_id:{}, 不能重复买入 并且仓位有这只股票,则不买入,position.shareholding:{},stock:{}'
                    .format(self.strategy.strategy_id,
                            self.position.shareholding, stock))
                continue

            # 单只股票进场仓位
            single_entry_position = self.strategy.sglPosPct

            # 得到单只股票限制后的进场仓位
            __single_status, single_position, __message = self.__get_single_restrict_position(
                single_entry_position=single_entry_position, stock=stock)
            if not __single_status:
                simulation_logger.info('str_id:{}, 单只股票限制后的进场仓位为空:{}'.format(
                    self.strategy.strategy_id, __message))
                continue

            # 根据单只股票进场仓位,执行买入操作,包括更新
            __status, __info = self.__buy_by_position(
                stock=stock,
                name=name,
                single_position=single_position,
                bar=bar)
            if not __status:
                simulation_logger.info('str_id:{}, 买入失败:{}'.format(
                    self.strategy.strategy_id, __info))
                continue
        simulation_logger.info(
            'str_id:{}, end buy select--------------------------------------------------------------------------------\n\n'
            .format(self.strategy.strategy_id))
    def step(self, bar):
        """
        浮盈加减仓
        :param bar:
        :return:
        """
        simulation_logger.info(
            'str_id:{}, step--------------------------------------------------------------------------------------------'
        )
        for _, row in self.position.positions.iterrows():
            status, init2, msg = self.strategy.order.step(row)

            # 没有达到条件则跳过
            if not status:
                simulation_logger.info(
                    'str_id:{}, 没有达到条件则跳过,,message:{}\n'.format(
                        self.strategy.strategy_id, msg))
                continue

            # 获取当前股票是否停牌和最新价,停牌不能卖出
            status, price = self.strategy.hqDB.get_status_price(stock=row.inst)
            if not status:
                simulation_logger.info('str_id:{}, 停牌退市不能卖出,stock:{}'.format(
                    self.strategy.strategy_id, row.inst))
                continue

            # 加仓的情况
            init2 = round(float(init2), 4)
            if init2 > 0:
                simulation_logger.info(
                    'str_id:{}, 加仓--------------------------------------------------------------------------------------------'
                    .format(self.strategy.strategy_id))
                simulation_logger.info(
                    'str_id:{}, 浮盈加减仓,加仓,stock:{},name:{},init2:{},msg:{}'.
                    format(self.strategy.strategy_id, row.inst, row['name'],
                           init2, msg))
                # 如果没有持则不操作
                if not row.get('percent'):
                    continue

                # 得到单只股票最大仓位限制后的剩余仓位
                __single_remain = self.strategy.sglMaxPosPct - float(
                    row['percent'])

                # 得到本来的进场仓位
                __origin_position = init2 * float(row['percent'])

                # 得到以上限制后的进场仓位,还要比单只股票持仓上限要小
                single_position = round(
                    min(__single_remain, __origin_position), 6)

                # 如果持仓小于等于0则跳过
                if single_position <= 0:
                    simulation_logger.info(
                        'str_id:{}, 持仓小于等于0则跳过,stock:{},single_position:{}'.
                        format(self.strategy.strategy_id, row.inst,
                               single_position))
                    simulation_logger.info(
                        'str_id:{}, 结束加仓--------------------------------------------------------------------------------------------\n'
                        .format(self.strategy.strategy_id))
                    continue

                # 根据单只股票进场仓位,执行买入操作,包括更新
                __status, __info = self.__buy_by_position(
                    stock=row.inst,
                    name=row['name'],
                    single_position=single_position,
                    bar=bar)
                if not __status:
                    simulation_logger.info('str_id:{}, 买入失败:{},持仓已更新'.format(
                        self.strategy.strategy_id, __info))
                else:
                    simulation_logger.info('str_id:{}, 买入成功:{},持仓已更新'.format(
                        self.strategy.strategy_id, __info))
                simulation_logger.info(
                    'str_id:{}, 结束加仓--------------------------------------------------------------------------------------------\n'
                    .format(self.strategy.strategy_id))
                continue

            # 减仓的情况
            elif init2 < 0:
                simulation_logger.info(
                    'str_id:{}, 减仓--------------------------------------------------------------------------------------------'
                    .format(self.strategy.strategy_id))
                simulation_logger.info(
                    'str_id:{}, 浮盈加减仓,减仓,stock:{},name:{},init2:{},msg:{}'.
                    format(self.strategy.strategy_id, row.inst, row['name'],
                           init2, msg))
                # 不是T+1日不能卖出
                if row.hold_days <= 1:
                    simulation_logger.info(
                        'str_id:{}, 不是T+1日不能卖出,stock:{},row.hold_days:{}'.
                        format(self.strategy.strategy_id, row.inst,
                               row.hold_days))
                    simulation_logger.info(
                        'str_id:{}, 结束减仓--------------------------------------------------------------------------------------------\n'
                        .format(self.strategy.strategy_id))
                    continue

                # 判断是否跌停和停牌退市
                # 跌停不能卖出
                limit_move_status, _ = self.strategy.hqDB.get_limit_move(
                    stock=row.inst)
                if limit_move_status == -1 or limit_move_status == 2:
                    simulation_logger.info(
                        'str_id:{}, 跌停不能卖出,stock:{},limit_move_status:{}'.
                        format(self.strategy.strategy_id, row.inst,
                               limit_move_status))
                    simulation_logger.info(
                        'str_id:{}, 结束减仓--------------------------------------------------------------------------------------------\n'
                        .format(self.strategy.strategy_id))
                    continue

                # 获取当前股票是否停牌和最新价,停牌不能卖出
                status, price = self.strategy.hqDB.get_status_price(
                    stock=row.inst)
                if not status:
                    simulation_logger.info(
                        'str_id:{}, 跌停不能卖出,stock:{},status:{}'.format(
                            self.strategy.strategy_id, row.inst, status))
                    simulation_logger.info(
                        'str_id:{}, 结束减仓--------------------------------------------------------------------------------------------\n'
                        .format(self.strategy.strategy_id))
                    continue

                # 得到可卖出的数量
                __sell_count = min(int(row['quantity_sell']),
                                   int(row['quantity'] * abs(init2)))
                __sell_count = str(int(__sell_count / 100) * 100)

                # 构造下单的信息,10801:买入,10802:卖出
                sell_info = {
                    "stockCode": "{}".format(f14(row.inst)),
                    "stockName": row['name'],
                    "entrustPrice": "{}".format(price),
                    "entrustCount": __sell_count
                }
                __flag, __info = self.pending_order.sell(sell_info)
                if __flag:
                    simulation_logger.info('str_id:{}, 下单卖出成功,info:{}'.format(
                        self.strategy.strategy_id, __info))
                    self.position.update_master(query_hold_days=False)
                    simulation_logger.info('str_id:{}, 成功更新后的cash:{}'.format(
                        self.strategy.strategy_id, self.position.cash))
                else:
                    self.position.update_master(query_hold_days=False)
                    simulation_logger.info('str_id:{}, 失败更新后的cash:{}'.format(
                        self.strategy.strategy_id, self.position.cash))
                    simulation_logger.info('str_id:{}, 下单卖出失败,info:{}'.format(
                        self.strategy.strategy_id, __info))
                # 更新可用现金
                if not self.strategy.maxBuyStockCash:
                    self.strategy.available_cash_day = self.position.cash
                simulation_logger.info(
                    'str_id:{}, 结束减仓--------------------------------------------------------------------------------------------\n'
                    .format(self.strategy.strategy_id))
            else:
                continue
        simulation_logger.info(
            'str_id:{}, end step-------------------------------------------------------------------------------------------------\n'
            .format(self.strategy.strategy_id))
Beispiel #25
0
                                                                        ContractPositionsInfo.stock_code == str(sell_info['stockCode'])).delete()
                except Exception as e:
                    simulation_logger.info('str_id:{},卖出单只股票时删除持仓表信息出错:{}'.format(self.strategy.strategy_id, e))
            return True,info
        else:
            return False,info


if __name__ == '__main__':
    data = {'polId':100000000000021,'currentuserid':2000000000000000}
    # 初始化实例信息
    strategy = Strategy()
    with MysqlManager('quant').Session as session:
        query_res = session.query(ContractInfo.contract_source_id).filter(ContractInfo.strategy_id==data['polId']).all()
    if not query_res:  # 没有查询到对应的合约来源ID
        simulation_logger.info('该策略没有创建合约,需重先创建新合约')
        module_func = ModuleFunc(strategy_id=data['polId'], usr_id=data['currentuserid'], usr_name='--')  # 用户来源ID
        __info = module_func.create_new_contract({'cntrCapAmt': '30000000'})  # 创建新的合约
        if __info['respCode'] != '000':
            simulation_logger.info('合约创建失败:{}'.format(__info))
            exit(0)
        else:
            # 将合约id保存到strategy中
            strategy.contract_source_id = __info['srcCntrId']
            strategy.contract_id = __info['cntrId']
    else:
        simulation_logger.info('该策略已有合约,直接初始化')
        contract_source_id = query_res[0][0]
        # 得到合约的持仓实例
        strategy.contract_id = query_res[0][1]
        strategy.contract_source_id = query_res[0][0]
    def __buy_by_position(self, stock, name, single_position: float, bar):
        """
        根据单只股票进场仓位,执行总仓位限制后的买入操作,包括得到最终下单信息、下单、更新仓位和相关指标
        :param stock: 股票
        :param name: 股票名
        :param single_position: 单只股票买入仓位
        :return:
        """
        if single_position <= 0:
            return False, '单只股票买入仓位小于等于0,买入失败,stock:{},single_position:{}'.format(
                stock, single_position)
        # 得到总仓位限制后的进场仓位
        # 最大持仓的剩余仓位
        __max_remain = self.strategy.maxPosPct - self.position.percent

        # 得到牛熊市最大持仓限制之后的仓位
        __weight_remain = bar.weight - self.position.percent

        # 得到以上限制后的进场仓位,还要比单只股票持仓上限要小
        single_position = min(single_position, __max_remain, __weight_remain,
                              self.strategy.sglMaxPosPct)

        # 如果持仓小于等于0则跳过
        if single_position <= 0:
            return False, '持仓小于等于0则跳过,买入失败,stock:{},single_position:{}'.format(
                stock, single_position)

        # 得到买入的金额
        simulation_logger.info(
            'str_id:{}, total_assets:{},single_position:{}'.format(
                self.strategy.strategy_id, self.position.total_assets,
                single_position))
        buy_money = round(self.position.total_assets * single_position, 2)

        # 买入金额不能大于现金,也不能大于最大单日买入金额
        simulation_logger.info(
            'str_id:{}, buy_money:{},cash:{},available_cash:{}'.format(
                self.strategy.strategy_id, buy_money, self.position.cash,
                self.strategy.available_cash_day))
        # 得到能用的现金
        available_cash_tmp = min(self.position.cash,
                                 self.strategy.available_cash_day)

        # 得到买入金额,买入金额和手续费要小于等于可用余额
        if buy_money * 1.0005 >= available_cash_tmp:
            buy_money = int(available_cash_tmp / 1.0005)

        # 金额过小则不买入
        if buy_money < 1000:
            return False, '金额过小则不买入,买入失败,stock:{},buy_money:{}'.format(
                stock, buy_money)

        # 涨停不能买入
        limit_move_status, _ = self.strategy.hqDB.get_limit_move(stock=stock)
        if limit_move_status == 1 or limit_move_status == 2:
            return False, '涨停不能买入,买入失败,stock:{},limit_move_status:{}'.format(
                stock, limit_move_status)

        # 获取当前股票是否停牌和最新价
        status, price = self.strategy.hqDB.get_status_price(stock=stock)

        # 构造下单的信息,10801:买入,10802:卖出
        buy_info = {
            "stockCode": "{}".format(f14(stock)),
            "stockName": "{}".format(name),
            "entrustPrice": "{}".format(price)
        }

        # 停牌不买入
        if not status:
            return False, '停牌不买入,买入失败,stock:{},status:{}'.format(stock, status)

        # 得到买入数量
        buy_count = int(buy_money / (price * 100)) * 100

        # 买入数量不足一手不交易
        if buy_count < 100:
            return False, '买入数量不足一手不交易,买入失败,stock:{},buy_count:{}'.format(
                stock, buy_count)

        # 加入到买入信息中
        buy_info['entrustCount'] = "{}".format(buy_count)

        # 下单
        flag, info = self.pending_order.buy(buy_info=buy_info)
        # simulation_logger.info('str_id:{}, flag:{}'.format(self.strategy.strategy_id,flag))
        # 成交则更新持仓
        if not flag:
            self.position.update_master(query_hold_days=False)
            simulation_logger.info('str_id:{}, 失败更新后的cash:{}'.format(
                self.strategy.strategy_id, self.position.cash))
            # simulation_logger.info('str_id:{}, ------------------------------------------------------------------------------------------------------------\n\n')
            return False, '下单买入失败:{}'.format(info)
        else:
            self.strategy.available_cash_day = self.strategy.available_cash_day - round(
                float(info['used_money']) * 1.0005, 2)
            simulation_logger.info('str_id:{}, available money:{}'.format(
                self.strategy.strategy_id, self.strategy.available_cash_day))
            self.position.update_master(query_hold_days=False)
            simulation_logger.info('str_id:{}, 成功更新后的cash:{}'.format(
                self.strategy.strategy_id, self.position.cash))
        simulation_logger.info(
            'str_id:{}, ------------------------------------------------------------------------------------------------------------\n\n'
            .format(self.strategy.strategy_id))
        return True, info
    def run_before(self):
        """
        开始回测之前
        :return:
        """
        simulation_logger.info('str_id:{},hq:{}'.format(
            self.strategy.strategy_id, self.strategy.hq))
        simulation_logger.info('str_id:{}, 保存的因子信息:{}'.format(
            self.strategy.strategy_id, self.strategy.data_update))
        # 更新保存策略信息
        self.strategy_data.save_strategy_data(data=self.strategy.data_update)

        # 判断今天是否是交易日,如果不是则不买卖
        clear_flag = False
        __trade_flag = self.__judge_trade_date()
        if not __trade_flag:
            clear_flag = True

        # 设置只保存,也不买卖
        if not self.strategy.data_update.get('save_or_simulation', 0):
            clear_flag = True

        if clear_flag:
            self.clear_bar()

        # 得到当日最大可用资金
        simulation_logger.info('str_id:{}, run before')
        if self.strategy.maxBuyStockCash:
            self.strategy.available_cash_day = round(
                float(self.strategy.maxBuyStockCash) *
                self.position.total_assets, 2)
        else:
            self.strategy.available_cash_day = self.position.cash

        simulation_logger.info('str_id:{}, 运行前的持仓:{}'.format(
            self.strategy.strategy_id, self.position.positions))
        simulation_logger.info('str_id:{}, 运行前的总资产:{}'.format(
            self.strategy.strategy_id, self.position.total_assets))
        simulation_logger.info('str_id:{}, 运行前的当日可用现金:{}'.format(
            self.strategy.strategy_id, self.strategy.available_cash_day))
        simulation_logger.info('str_id:{}, 运行前的现金:{}'.format(
            self.strategy.strategy_id, self.position.cash))
Beispiel #28
0
def simulation_entrance(data, save_or_simulation=0):
    """
    模拟盘函数入口,用户新对接模拟盘会在下一个交易日买卖,9:35之前的会在今天买卖
    :param data:
    :param save_or_simulation: 进行保存还是保存并模拟,0:只保存,1:保存并模拟
    :return:
    """
    # 如果data为空则不模拟
    if not data or 'list' not in data.keys():
        return

    # 初始化数据
    # 10607实盘中,10608实盘出错,10609实盘成功
    data['simulation_success_flag'] = 10607
    if 'back_success_flag' in data.keys() and int(
            data['back_success_flag']) != 10605:
        data['simulation_success_flag'] = 10608
    data['simulation_time'] = datetime.now().strftime('%Y-%m-%d')
    data['simulation_flag'] = 1
    data['simulation_message'] = '实盘中'
    data['strategy_message'] = '实盘模拟'
    data['save_or_simulation'] = int(save_or_simulation)

    # 用于java
    data['bkstResponMessage'] = u'实盘中'
    data['bkstResponCode'] = 10607
    data['trade_type'] = 'simulation'

    # 通知JAVA
    # if data.get('simulation_new_flag',0) > 0:
    #     urlPost(data)

    # 如果回测失败则直接退出模拟
    # if data['back_success_flag'] == 10606:
    #     return

    # 解析语法
    data_calculate = parse(data)

    # 整理策略
    strategy = Strategy()
    strategy.hqDB = DataCollection()
    strategy.init_data(data_calculate)
    simulation_logger.info(
        '\n\n-----------------------------------------------------------------------------------------------------------------------'
    )
    simulation_logger.info('str_id:{},strategy:{}'.format(
        strategy.strategy_id, strategy))

    # 初始化实例信息
    with MysqlManager('quant').Session as session:
        query_res = session.query(
            ContractInfo.contract_source_id,
            ContractInfo.contract_id).filter_by(
                strategy_id=data_calculate['strategy_id'], flag=1).all()
    if not query_res:  # 没有查询到对应的合约来源ID
        simulation_logger.info('str_id:{},该策略没有创建合约,需重先创建新合约'.format(
            strategy.strategy_id))
        module_func = ModuleFunc(strategy_id=data_calculate['strategy_id'],
                                 usr_id=data_calculate['user_id'],
                                 usr_name='--')  # 用户来源ID
        __info = module_func.create_new_contract({'cntrCapAmt':
                                                  '30000000'})  # 创建新的合约
        if __info['respCode'] != '000':
            simulation_logger.info('str_id:{},合约创建失败:{}'.format(
                strategy.strategy_id, __info))
            exit(0)
        else:
            # 将合约id保存到strategy中
            strategy.contract_id = __info['cntrId']
            strategy.contract_source_id = __info['srcCntrId']
            data['contract_id'] = int(__info['cntrId'])
            data['contract_source_id'] = int(__info['srcCntrId'])
    else:
        simulation_logger.info('str_id:{},该策略已有合约,直接初始化'.format(
            strategy.strategy_id))
        cntr_id = query_res[0][0]
        data['contract_id'] = int(query_res[0][1])
        data['contract_source_id'] = int(query_res[0][0])
        module_func = ModuleFunc(strategy_id=data_calculate['strategy_id'],
                                 cntr_id=cntr_id,
                                 usr_id=data_calculate['user_id'],
                                 usr_name='--')  # 用户来源ID
        # 将合约id保存到strategy中
        strategy.contract_id = query_res[0][1]
        strategy.contract_source_id = query_res[0][0]

    # 保存更新策略因子信息
    # print('得到的数据:{}'.format(data))
    strategy.data_update = data

    # 得到合约的持仓实例
    position = Position(contract_operator=module_func, strategy=strategy)

    # 得到合约的挂单实例
    pending_order = PendingOrder(contract_operator=module_func,
                                 position=position,
                                 strategy=strategy)

    # 得到策略数据操作类型
    strategy_data = StrategyData()

    # 装在模拟盘回测框架
    simulation_trader = prototype.clone('simulation_trader',
                                        strategy=strategy,
                                        position=position,
                                        pending_order=pending_order,
                                        strategy_data=strategy_data)

    # 正式开始回测交易
    simulation_trader.start()

    # 关闭数据库连接
    strategy.hqDB.close()
Beispiel #29
0
    def buy(self,buy_info):
        """
        买入
        :param buy_info:
        :return:
        """
        # simulation_logger.info('\n---------------------------------------------------------------------------------------------------------------------')
        simulation_logger.info('str_id:{},pending order buy:{}'.format(self.strategy.strategy_id,buy_info))
        time1 = time.time()
        info = self.contract_operator.place_an_order(stock_info=buy_info,  trade_type='buy')
        simulation_logger.info('str_id:{},buy cost:{} s'.format(self.strategy.strategy_id,time.time()-time1))
        simulation_logger.info('str_id:{},买入结果:{}'.format(self.strategy.strategy_id,info))
        info['used_money'] = round(float(info.get('useAmt',0)),2)
        info['trade_count'] = int(info.get('useQty',0))
        if 'useAmt' in info.keys():
            info.pop('useAmt')
        if 'transQty' in info.keys():
            info.pop('transQty')
        if info['respCode'] == '000':
            # 保存交易流水
            simulation_logger.info('str_id:{},trade count:{}'.format(self.strategy.strategy_id,info['trade_count']))
            if info['trade_count']:
                # 保存交易流水
                trade_time = datetime.now()
                before_assets = self.position.total_assets
                before_position = self.position.positions
                self.position.update_master(query_hold_days=False)
                after_assets = self.position.total_assets
                after_position = self.position.positions
                # transaction_save(before_position=before_position,after_position=after_position,before_assets=before_assets,
                #                  after_assets=after_assets,strategy_id=self.strategy.strategy_id,trade_type='buy_one',
                #                  trade_time=trade_time,order_info=buy_info,result_info=info)
                __kwargs = {'before_position':before_position.to_dict(),'after_position':after_position.to_dict(),'before_assets':before_assets,
                            'after_assets':after_assets,'strategy_id':self.strategy.strategy_id,'trade_type':'buy_one',
                            'trade_time':trade_time.strftime('%Y-%m-%d %H:%M:%S'),'order_info':buy_info,'result_info':info,
                            'user_id':self.strategy.user_id,'contract_source_id':self.strategy.contract_source_id}
                transaction_save.apply_async(queue='transaction',kwargs=__kwargs)

            # 保存到持仓表中
            try:
                if buy_info['stockCode'] in list(before_position.inst):
                    __sql = "INSERT INTO contract_positions_info (date,create_time,update_time,strategy_id, contract_source_id, stock_code,user_id,type,flag,positions_days) \
                            VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE type=0,flag=1"
                else:
                    __sql = "INSERT INTO contract_positions_info (date,create_time,update_time,strategy_id, contract_source_id, stock_code,user_id,type,flag,positions_days) \
                            VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE type=0,flag=1,positions_days=1"
                __values = [datetime.now(),datetime.now(),datetime.now(),str(self.strategy.strategy_id), str(self.strategy.contract_source_id), str(buy_info['stockCode']),str(self.strategy.user_id),0,1,1]
                # 申请资源
                mysql = Mysql()
                ids = mysql.update(sql=__sql, param=__values)
                simulation_logger.info('str_id:{},买入添加持仓表信息成功 sql:{},id:{}'.format(self.strategy.strategy_id,__sql,ids))
                # 释放资源
                mysql.dispose()
            except Exception as e:
                simulation_logger.info('str_id:{},买入添加持仓信息出错:{}'.format(self.strategy.strategy_id,e))
            return True,info
        else:
            return False,info