Пример #1
0
 def cancel_entrust(self, entrust_no):
     """
     对未成交的调仓进行伪撤单
     :param entrust_no:
     :return:
     """
     xq_entrust_list = self._get_xq_history()
     is_have = False
     for xq_entrusts in xq_entrust_list:
         status = xq_entrusts["status"]  # 调仓状态
         for entrust in xq_entrusts["rebalancing_histories"]:
             if entrust["id"] == entrust_no and status == "pending":
                 is_have = True
                 buy_or_sell = ("buy" if
                                entrust["target_weight"] < entrust["weight"]
                                else "sell")
                 if (entrust["target_weight"] == 0
                         and entrust["weight"] == 0):
                     raise exceptions.TradeError(u"移除的股票操作无法撤销,建议重新买入")
                 balance = self.get_balance()[0]
                 volume = (
                     abs(entrust["target_weight"] - entrust["weight"]) *
                     balance["asset_balance"] / 100)
                 r = self._trade(
                     security=entrust["stock_symbol"],
                     volume=volume,
                     entrust_bs=buy_or_sell,
                 )
                 if len(r) > 0 and "error_info" in r[0]:
                     raise exceptions.TradeError(u"撤销失败!%s" %
                                                 ("error_info" in r[0]))
     if not is_have:
         raise exceptions.TradeError(u"撤销对象已失效")
     return True
Пример #2
0
    def handle(self, title) -> Optional[dict]:
        if title == "委托确认":
            self._submit_by_shortcut()
            return None

        if title == "提示信息":
            content = self._extract_content()
            if "超出涨跌停" in content:
                self._submit_by_shortcut()
                return None

            if "委托价格的小数价格应为" in content:
                self._submit_by_shortcut()
                return None

            if "逆回购" in content:
                self._submit_by_shortcut()
                return None

            return None

        if title == "提示":
            content = self._extract_content()
            if "成功" in content:
                entrust_no = self._extract_entrust_id(content)
                self._submit_by_click()
                return {"entrust_no": entrust_no}

            self._submit_by_click()
            time.sleep(0.05)
            raise exceptions.TradeError(content)
        # self._close() #不关闭程序 edited by leonardo
        return None
Пример #3
0
def detect_yh_client_result(image_path):
    """封装了tesseract的识别,部署在阿里云上,
    服务端源码地址为: https://github.com/shidenggui/yh_verify_code_docker"""
    api = "http://yh.ez.shidenggui.com:5000/yh_client"
    with open(image_path, "rb") as f:
        rep = requests.post(api, files={"image": f})
    if rep.status_code != 201:
        error = rep.json()["message"]
        raise exceptions.TradeError("request {} error: {}".format(api, error))
    return rep.json()["result"]
Пример #4
0
    def _trade(self, security, price=0, amount=0, volume=0, entrust_bs="buy"):
        """
        调仓
        :param security:
        :param price:
        :param amount:
        :param volume:
        :param entrust_bs:
        :return:
        """
        stock = self._search_stock_info(security)
        balance = self.get_balance()[0]
        if stock is None:
            raise exceptions.TradeError(u"没有查询要操作的股票信息")
        if not volume:
            volume = int(float(price) * amount)  # 可能要取整数
        if balance["current_balance"] < volume and entrust_bs == "buy":
            raise exceptions.TradeError(u"没有足够的现金进行操作")
        if stock["flag"] != 1:
            raise exceptions.TradeError(u"未上市、停牌、涨跌停、退市的股票无法操作。")
        if volume == 0:
            raise exceptions.TradeError(u"操作金额不能为零")

        # 计算调仓调仓份额
        weight = volume / balance["asset_balance"] * 100
        weight = round(weight, 2)

        # 获取原有仓位信息
        position_list = self._get_position()

        # 调整后的持仓
        is_have = False
        for position in position_list:
            if position["stock_id"] == stock["stock_id"]:
                is_have = True
                position["proactive"] = True
                old_weight = position["weight"]
                if entrust_bs == "buy":
                    position["weight"] = weight + old_weight
                else:
                    if weight > old_weight:
                        raise exceptions.TradeError(u"操作数量大于实际可卖出数量")
                    else:
                        position["weight"] = old_weight - weight
                position["weight"] = round(position["weight"], 2)
        if not is_have:
            if entrust_bs == "buy":
                position_list.append({
                    "code": stock["code"],
                    "name": stock["name"],
                    "enName": stock["enName"],
                    "hasexist": stock["hasexist"],
                    "flag": stock["flag"],
                    "type": stock["type"],
                    "current": stock["current"],
                    "chg": stock["chg"],
                    "percent": str(stock["percent"]),
                    "stock_id": stock["stock_id"],
                    "ind_id": stock["ind_id"],
                    "ind_name": stock["ind_name"],
                    "ind_color": stock["ind_color"],
                    "textname": stock["name"],
                    "segment_name": stock["ind_name"],
                    "weight": round(weight, 2),
                    "url": "/S/" + stock["code"],
                    "proactive": True,
                    "price": str(stock["current"]),
                })
            else:
                raise exceptions.TradeError(u"没有持有要卖出的股票")

        if entrust_bs == "buy":
            cash = ((balance["current_balance"] - volume) /
                    balance["asset_balance"] * 100)
        else:
            cash = ((balance["current_balance"] + volume) /
                    balance["asset_balance"] * 100)
        cash = round(cash, 2)
        logger.info("weight:%f, cash:%f", weight, cash)

        data = {
            "cash": cash,
            "holdings": str(json.dumps(position_list)),
            "cube_symbol": str(self.account_config["portfolio_code"]),
            "segment": 1,
            "comment": "",
        }

        try:
            resp = self.s.post(self.config["rebalance_url"], data=data)
        # pylint: disable=broad-except
        except Exception as e:
            logger.warning("调仓失败: %s ", e)
            return None
        else:
            logger.info("调仓 %s%s: %d", entrust_bs, stock["name"],
                        resp.status_code)
            resp_json = json.loads(resp.text)
            if "error_description" in resp_json and resp.status_code != 200:
                logger.error("调仓错误: %s", resp_json["error_description"])
                return [{
                    "error_no": resp_json["error_code"],
                    "error_info": resp_json["error_description"],
                }]
            return [{
                "entrust_no":
                resp_json["id"],
                "init_date":
                self._time_strftime(resp_json["created_at"]),
                "batch_no":
                "委托批号",
                "report_no":
                "申报号",
                "seat_no":
                "席位编号",
                "entrust_time":
                self._time_strftime(resp_json["updated_at"]),
                "entrust_price":
                price,
                "entrust_amount":
                amount,
                "stock_code":
                security,
                "entrust_bs":
                "买入",
                "entrust_type":
                "雪球虚拟委托",
                "entrust_status":
                "-",
            }]
Пример #5
0
    def adjust_weight(self, stock_code, weight):
        """
        雪球组合调仓, weight 为调整后的仓位比例
        :param stock_code: str 股票代码
        :param weight: float 调整之后的持仓百分比, 0 - 100 之间的浮点数
        """

        stock = self._search_stock_info(stock_code)
        if stock is None:
            raise exceptions.TradeError(u"没有查询要操作的股票信息")
        if stock["flag"] != 1:
            raise exceptions.TradeError(u"未上市、停牌、涨跌停、退市的股票无法操作。")

        # 仓位比例向下取两位数
        weight = round(weight, 2)
        # 获取原有仓位信息
        position_list = self._get_position()

        # 调整后的持仓
        for position in position_list:
            if position["stock_id"] == stock["stock_id"]:
                position["proactive"] = True
                position["weight"] = weight

        if weight != 0 and stock["stock_id"] not in [
                k["stock_id"] for k in position_list
        ]:
            position_list.append({
                "code": stock["code"],
                "name": stock["name"],
                "enName": stock["enName"],
                "hasexist": stock["hasexist"],
                "flag": stock["flag"],
                "type": stock["type"],
                "current": stock["current"],
                "chg": stock["chg"],
                "percent": str(stock["percent"]),
                "stock_id": stock["stock_id"],
                "ind_id": stock["ind_id"],
                "ind_name": stock["ind_name"],
                "ind_color": stock["ind_color"],
                "textname": stock["name"],
                "segment_name": stock["ind_name"],
                "weight": weight,
                "url": "/S/" + stock["code"],
                "proactive": True,
                "price": str(stock["current"]),
            })

        remain_weight = 100 - sum(i.get("weight") for i in position_list)
        cash = round(remain_weight, 2)
        logger.info("调仓比例:%f, 剩余持仓 :%f", weight, remain_weight)
        data = {
            "cash": cash,
            "holdings": str(json.dumps(position_list)),
            "cube_symbol": str(self.account_config["portfolio_code"]),
            "segment": "true",
            "comment": "",
        }

        try:
            resp = self.s.post(self.config["rebalance_url"], data=data)
        # pylint: disable=broad-except
        except Exception as e:
            logger.warning("调仓失败: %s ", e)
            return None
        logger.info("调仓 %s: 持仓比例%d", stock["name"], weight)
        resp_json = json.loads(resp.text)
        if "error_description" in resp_json and resp.status_code != 200:
            logger.error("调仓错误: %s", resp_json["error_description"])
            return [{
                "error_no": resp_json["error_code"],
                "error_info": resp_json["error_description"],
            }]
        logger.info("调仓成功 %s: 持仓比例%d", stock["name"], weight)
        return None