예제 #1
0
    def _trade_api(self, **kwargs):

        # 确保已经正确登录了融资融券账号
        self._ensure_margin_flags()

        url = 'https://trade.gf.com.cn/entry'
        resq = self.client.post(url, params=kwargs)
        if len(resq.text) == 0:
            self.client.reset()
            resq = self.client.post(url, params=kwargs)

        data = resq.json()
        logger.debug('_trade_api() return: %s' % data)

        trade_status = data.pop('success', False)
        if trade_status == False:
            logger.error(data)
            error_info = data.get('error_info', data)
            raise TraderAPIError(error_info)

        df = pd.DataFrame(data['data'])

        df.rename(columns=RENAME_DICT, inplace=True)
        if 'symbol' in df.columns:
            df['symbol'] = df['symbol'].apply(code_to_symbols)

        # 去字段的并集,提高效率
        cols = list(set(FLOAT_COLUMNS).intersection(set(df.columns)))

        for col in cols:
            df[col] = pd.to_numeric(df[col], errors='ignore')
        return df
예제 #2
0
    def _ensure_margin_flags(self):
        '''确保已经登录了融资融券账户'''
        if self.client.margin_flags == False:
            margin_login_params = {
                'classname': 'com.gf.etrade.control.RZRQUF2Control',
                'method': 'ValidataLogin'
            }

            r = self.client.post(url='https://trade.gf.com.cn/entry',
                                 params=margin_login_params)

            data = r.json()
            logger.debug('ensure_margin_flags: %s' % data)

            trade_status = data.pop('success', False)
            if trade_status == False:
                logger.error(data)
                error_info = data.get('error_info', data)
                raise TraderAPIError(error_info)

            stockholders = data.get('stockholders', [])
            self._exchange_stock_account = {}
            for holders in stockholders:
                self._exchange_stock_account[
                    holders['exchange_type']] = holders['stock_account']

            # 将session 设置为已经登录信用账户的状态
            self.client.margin_flags = True

            return
예제 #3
0
    def login(self):

        self.pre_login()

        login_params = {
            "function_id": 200,
            "login_type": "stock",
            "version": 200,
            "identity_type": "",
            "remember_me": "",
            "input_content": 1,
            "content_type": 0,
            "loginPasswordType": "B64",
            "disk_serial_id": self.disk_serial_id,
            "cpuid": self.cpuid,
            "machinecode": self.machinecode,
            "mac_addr": self.mac_address,
            "account_content": self._account,
            "password": urllib.parse.unquote(self._password),
            "validateCode": self.vcode
        }
        logger.debug('login_params is: %s' % login_params)

        r = self._session.post(
            'https://jy.yongjinbao.com.cn/winner_gj/gjzq/exchange.action',
            params=login_params)
        r.raise_for_status()

        logger.debug('Login respone: %s' % r.text)

        returnJson = r.json()['returnJson']
        data = demjson.decode(returnJson)
        error_msg = dict()
        if data['msg_no'] != '0':
            if 'msg_info' in data.keys() and data['msg_info'] != '':
                error_msg['error_info'] = data['msg_info']
            else:
                error_msg = data[data['error_grids']][1]

            if error_msg['error_info'].find('验证码') != -1:
                logger.warning('vcode error : %s' % error_msg['error_info'])
                raise VerifyCodeError(error_msg['error_info'])
            else:
                logger.error('login Failed :%s' % error_msg['error_info'])
                raise LoginFailedError(error_msg['error_info'])

        return
예제 #4
0
    def post_login(self):

        if self.margin_flags == True:
            margin_login_params = {
                'classname': 'com.gf.etrade.control.RZRQUF2Control',
                'method': 'ValidataLogin',
                'dse_sessionId': self._dse_sessionId
            }

            r = self._session.post(url='https://trade.gf.com.cn/entry',
                                   params=margin_login_params)

            data = r.json()
            logger.debug('ensure_margin_flags: %s' % data)

            trade_status = data.pop('success', False)
            if trade_status == False:
                logger.error(data)
                error_info = data.get('error_info', data)
                raise TraderAPIError(error_info)
예제 #5
0
    def _trade_api(self, **kwargs):
        url = 'https://trade.gf.com.cn/entry'
        resq = self.client.post(url, params=kwargs)
        data = resq.json()
        if data.get('success', False) == False:
            logger.error(data)
            error_info = data.get('error_info', data)
            raise TraderAPIError(error_info)

        df = pd.DataFrame(data['data'])

        df.rename(columns=RENAME_DICT, inplace=True)
        if 'symbol' in df.columns:
            df['symbol'] = df['symbol'].apply(code_to_symbols)

        # 去字段的并集,提高效率
        cols = list(set(FLOAT_COLUMNS).intersection(set(df.columns)))

        for col in cols:
            df[col] = pd.to_numeric(df[col], errors='ignore')
        return df
예제 #6
0
    def _trade_api(self, **kwargs):
        '''
        底层交易接口
        '''

        logger.debug('call params: %s' % kwargs)
        r = self.client.get(
            url=
            'https://jy.yongjinbao.com.cn/winner_gj/gjzq/stock/exchange.action',
            params=kwargs)
        logger.debug('return: %s' % r.text)

        # 解析返回的结果数据
        returnJson = r.json()['returnJson']
        if returnJson is None:
            return None

        data = demjson.decode(returnJson)
        if data['msg_no'] != '0':
            error_msg = data[data['error_grids']][1]
            logger.error('error no: %s,error info: %s' % (error_msg.get(
                'error_no', ''), error_msg.get('error_info', '')))
            raise TraderAPIError(error_msg.get('error_info', ''))

        data = data['Func%s' % data['function_id']]
        df = pd.DataFrame(data[1:])

        # 替换表头的命名
        df.rename(columns=RENAME_DICT, inplace=True)
        # 生成symbol
        if 'symbol' in df.columns:
            df['symbol'] = df['symbol'].apply(code_to_symbols)
        # FLOAT_COLUMNS和 df.columns取交集,以减少调用时间
        cols = list(set(FLOAT_COLUMNS).intersection(set(df.columns)))

        for col in cols:
            df[col] = pd.to_numeric(df[col], errors='ignore')

        return df
예제 #7
0
    def order(self, symbol, amount=0, volume=0, wait=10):
        '''
        按数量下单
        :return: order_no, left
        '''
        logger.debug(
            'order_amount: symbol: %s, amount: %s, volume: %s, wait: %s' %
            (symbol, amount, volume, wait))

        if (amount == 0 and volume == 0):
            raise AttributeError('order_amount amount and volume can not be 0')

        # 下单
        try:
            hq = self.hq(symbol)
            logger.debug('hq: %s' % hq.loc[symbol])
            price = hq.loc[symbol, 'lasttrade']
            amount = amount if amount else round(volume,
                                                 2) // price // 100 * 100
            if amount == 0:
                return 0, 0

            if amount > 0 or volume > 0:
                price = hq.loc[symbol, 'ask']
                order_no = self.buy(symbol, price, amount=amount)
                logger.info('buy order send,order_no: %s' % order_no)
            elif amount < 0 or volume < 0:
                price = hq.loc[symbol, 'bid']
                order_no = self.sell(symbol, price, amount=-amount)
                logger.info('sell order send,order_no: %s' % order_no)

        except TraderError as err:
            logger.debug('Order Error: %s' % err)
            raise err

        # 每隔2秒检查一下成交状态.
        # 如果是已成交,则返回order_no, 0
        # 如果是已报、部成, 则再等2秒钟。
        # 如果是其他状态,就报警
        time.sleep(5)
        for i in range(int((wait + 1) / 2)):
            logger.info('Check Order Status %s times.' % i)
            orderlist = self.orderlist
            if order_no in orderlist.index:
                status = orderlist.loc[order_no, 'order_status']
            else:
                # 如果记录的订单号不在orderlist里面,则认为已经成交了。
                status = '已成'

            if status in ('已成'):
                logger.info('Order Success. %s' % orderlist.loc[order_no])
                return order_no, 0

            elif status in ('已报', '部成', '正常'):
                logger.info('Order not Complete. %s' % orderlist.loc[order_no])
                time.sleep(5)

            elif status in ('未报'):
                logger.info('Not Allow to Send Order. %s' %
                            orderlist.loc[order_no])
                self.cancel(order_no)
                return order_no, amount
            else:
                logger.error('Order Status Invaild. %s' %
                             orderlist.loc[order_no])
                raise TraderAPIError('Order Status Invaild. %s' %
                                     orderlist.loc[order_no])

        # 等待了足够时间,仍未全部成交,则撤单
        try:
            logger.warning('Cancel order: %s' % order_no)
            self.cancel(order_no)
            time.sleep(0.3)
            orderlist = self.orderlist
            status = orderlist.loc[order_no, 'order_status']
            if status in ('已撤', '部撤'):
                orderlist['left'] = orderlist['order_amount'] - orderlist[
                    'business_amount']
                left = orderlist.loc[order_no, 'left']
                if amount < 0:
                    left = -left
                return order_no, left
            else:
                raise TraderAPIError('Order Status Invaild. %s' %
                                     orderlist.loc[order_no])

        except TraderError as err:
            logger.warning(err)
            logger.warning('Order Status Invaild. %s' %
                           orderlist.loc[order_no])