예제 #1
0
    def get_metadata(self, fact_name: str) -> dict:
        conn = Conn(self._db_name)
        # 对应的trade_type 没有找到 就去spot类型里面找。
        metadata = conn.query_one(
            "SELECT * FROM factor_metadata"
            " WHERE symbol = ? AND trade_type = ? AND contract_type = ?"
            " AND `interval` = ? AND factor_name = ? ",
            (self._symbol, self._trade_type, self._contract_type, self._interval, fact_name),
        )
        if metadata is not None:
            return metadata

        if self._contract_type != CONTRACT_TYPE_NONE:
            metadata = conn.query_one(
                "SELECT * FROM factor_metadata"
                " WHERE symbol = ? AND trade_type = ? AND contract_type = ?"
                " AND `interval` = ? AND factor_name = ? ",
                (self._symbol, self._trade_type, CONTRACT_TYPE_NONE, self._interval, fact_name),
            )
            if metadata is not None:
                return metadata

        metadata = conn.query_one(
            "SELECT * FROM factor_metadata"
            " WHERE symbol = ? AND trade_type = ? AND contract_type = ?"
            " AND `interval` = ? AND factor_name = ? ",
            (self._symbol, TRADE_TYPE_SPOT, CONTRACT_TYPE_NONE, self._interval, fact_name),
        )
        if metadata is None:
            raise RuntimeError("Can not find the meta in database. ")
        return metadata
예제 #2
0
    def __insert_asset_item(self, timestamp, datetime):
        position_total, asset_total = self.__calculate_total(timestamp)
        position_freeze, asset_freeze = self.__calculate_freeze(timestamp)
        position_sub, asset_sub = self.__calculate_sub(timestamp)

        conn = Conn(self._db_name)
        one = conn.query_one(
            """SELECT * FROM {} WHERE exchange = ? AND settle_mode = ? AND settle_currency = ? 
            AND timestamp = ? AND backtest_id = ?""".format(
                self._asset_table_name),
            (self._exchange, self._settle_mode, self._settle_currency,
             timestamp, self._backtest_id))
        if one:
            conn.execute(
                """
                UPDATE {} SET asset_total = ?, asset_sub = ?, asset_freeze = ?, 
                position_total = ?, position_sub = ?, position_freeze = ? WHERE id = ? 
                """.format(self._asset_table_name),
                (
                    asset_total,
                    asset_sub,
                    asset_freeze,
                    position_total,
                    position_sub,
                    position_freeze,
                    one["id"],
                ),
            )
        else:
            conn.insert(
                """
                INSERT INTO {} (exchange, settle_mode, settle_currency, backtest_id, 
                asset_total, asset_sub, asset_freeze, 
                position_total, position_sub, position_freeze,
                timestamp, datetime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                """.format(self._asset_table_name),
                (
                    self._exchange,
                    self._settle_mode,
                    self._settle_currency,
                    self._backtest_id,
                    asset_total,
                    asset_sub,
                    asset_freeze,
                    position_total,
                    position_sub,
                    position_freeze,
                    timestamp,
                    datetime,
                ),
            )

        one = conn.query_one(
            """SELECT * FROM {} WHERE exchange = ? AND settle_mode = ? AND settle_currency = ? 
            AND timestamp > ? AND backtest_id = ? ORDER BY timestamp LIMIT 1"""
            .format(self._asset_table_name),
            (self._exchange, self._settle_mode, self._settle_currency,
             timestamp, self._backtest_id))
        if one:
            self.__insert_asset_item(one["timestamp"], one["datetime"])
예제 #3
0
    def _get_waiting_instance_id(self) -> int:
        query_sql = """
        SELECT id FROM {trade_type}_instance_strategy WHERE symbol = ? AND exchange = ? AND strategy = ?
        AND status = ? AND wait_start_timestamp = ? ORDER BY id DESC LIMIT 1
        """
        params = (
            self["symbol"], self["exchange"], self["strategy"],
            INSTANCE_STATUS_WAITING, 0,
        )

        if self["trade_type"] == TRADE_TYPE_FUTURE:
            query_sql = """
            SELECT id FROM {trade_type}_instance_strategy WHERE symbol = ? AND exchange = ? 
            AND contract_type = ? AND strategy = ? AND status = ? AND wait_start_timestamp = ? ORDER BY id DESC LIMIT 1
            """
            params = (
                self["symbol"], self["exchange"], self["contract_type"],
                self["strategy"], INSTANCE_STATUS_WAITING, 0,
            )

        conn = Conn(self["db_name"])
        one = conn.query_one(
            query_sql.format(trade_type=self["trade_type"]),
            params,
        )
        return one["id"] if one else 0
예제 #4
0
    def save(self, instance_id):
        if self._mode != MODE_BACKTEST:
            raise RuntimeError("You only can save data in backtest mode")
        # 入库前保证属性没有被篡改
        validate(instance=self, schema=indices_input)

        for name in self:
            if isinstance(self[name], int):
                sql_param = (PARAM_TYPE_INTEGER, str(self[name]), instance_id, name)
            elif isinstance(self[name], float):
                sql_param = (PARAM_TYPE_FLOAT, str(self[name]), instance_id, name)
            else:
                sql_param = (PARAM_TYPE_STRING, self[name], instance_id, name)

            conn = Conn(self._db_name)
            one = conn.query_one(
                "SELECT * FROM {} WHERE instance_id = ? AND indices_name = ?".format(self._table_name),
                (instance_id, name)
            )
            if one:
                conn.execute(
                    "UPDATE {} SET indices_type = ?, indices_value = ?"
                    " WHERE instance_id = ? AND indices_name = ?".format(self._table_name),
                    sql_param,
                )
            else:
                conn.insert(
                    "INSERT INTO {} (indices_type, indices_value, instance_id, indices_name)"
                    " VALUES (?, ?, ?, ?)".format(self._table_name),
                    sql_param,
                )
예제 #5
0
    def load(self, timestamp: int) -> dict:
        sql = """
        SELECT * FROM {} WHERE exchange = ? AND settle_mode = ? AND settle_currency = ? 
        AND timestamp <= ? ORDER BY timestamp DESC, id DESC LIMIT 1""".format(
            self._asset_table_name)
        params = (
            self._exchange,
            self._settle_mode,
            self._settle_currency,
            timestamp,
        )

        if self._mode == MODE_BACKTEST:
            sql = """
            SELECT * FROM {} WHERE exchange = ? AND settle_mode = ? AND settle_currency = ? 
            AND timestamp <= ? AND backtest_id = ? ORDER BY timestamp DESC, id DESC LIMIT 1
            """.format(self._asset_table_name)
            params = (self._exchange, self._settle_mode, self._settle_currency,
                      timestamp, self._backtest_id)

        conn = Conn(self._db_name)
        result = conn.query_one(sql, params)
        if result is None:
            raise RuntimeError("you must init_amount before load the asset. ")

        self["asset_total"] = result["asset_total"]
        self["asset_sub"] = result["asset_sub"]
        self["asset_freeze"] = result["asset_freeze"]

        self["position_total"] = result["position_total"]
        self["position_sub"] = result["position_sub"]
        self["position_freeze"] = result["position_freeze"]
        return self
예제 #6
0
    def load_from_db(self, instance_id):
        conn = Conn(self["db_name"])
        tmp_instance = conn.query_one(
            "SELECT * FROM {trade_type}_instance_{mode} WHERE id = ?".format(
                trade_type=self["trade_type"],
                mode=MODE_BACKTEST if self["mode"] == MODE_BACKTEST else MODE_STRATEGY,
            ),
            (instance_id,),
        )

        if tmp_instance is None:
            raise RuntimeError("the instance is None. ")

        self["id"] = tmp_instance["id"]
        self["status"] = tmp_instance["status"]
        self["unit_amount"] = tmp_instance.get("unit_amount") or 1

        self["asset_total"] = tmp_instance["asset_total"]
        self["asset_freeze"] = tmp_instance["asset_freeze"]

        self["param_position"] = tmp_instance["param_position"]
        self["param_max_abs_loss_ratio"] = tmp_instance["param_max_abs_loss_ratio"]

        self["wait_start_timestamp"] = tmp_instance["wait_start_timestamp"]
        self["wait_start_datetime"] = tmp_instance["wait_start_datetime"]
        self["wait_finish_timestamp"] = tmp_instance["wait_finish_timestamp"]
        self["wait_finish_datetime"] = tmp_instance["wait_finish_datetime"]

        self["open_times"] = tmp_instance["open_times"]
        self["open_start_timestamp"] = tmp_instance["open_start_timestamp"]
        self["open_start_datetime"] = tmp_instance["open_start_datetime"]
        self["open_finish_timestamp"] = tmp_instance["open_finish_timestamp"]
        self["open_finish_datetime"] = tmp_instance["open_finish_datetime"]
        self["open_expired_timestamp"] = tmp_instance["open_expired_timestamp"]
        self["open_expired_datetime"] = tmp_instance["open_expired_datetime"]

        self["liquidate_times"] = tmp_instance["liquidate_times"]
        self["liquidate_start_timestamp"] = tmp_instance["liquidate_start_timestamp"]
        self["liquidate_start_datetime"] = tmp_instance["liquidate_start_datetime"]
        self["liquidate_finish_timestamp"] = tmp_instance["liquidate_finish_timestamp"]
        self["liquidate_finish_datetime"] = tmp_instance["liquidate_finish_datetime"]

        param = Param(
            {},
            trade_type=self["trade_type"],
            db_name=self["db_name"],
            mode=self["mode"],
        )
        param.load(instance_id)
        self["param"] = param

        indices = Indices(
            {},
            trade_type=self["trade_type"],
            db_name=self["db_name"],
            mode=self["mode"],
        )
        indices.load(instance_id)
        self["indices"] = indices
예제 #7
0
 def _value_by_id(self, signal_id: int, timestamp: int):
     conn = Conn(self._db_name)
     dataset = conn.query_one(
         "SELECT * FROM signal_dataset WHERE signal_id = ? AND start_timestamp <= ? AND finish_timestamp > ?"
         " ORDER BY start_timestamp DESC LIMIT 1",
         (signal_id, timestamp, timestamp),
     )
     return dataset
예제 #8
0
    def _get_waiting_instance_id(self) -> int:
        query_sql = """
        SELECT id FROM {trade_type}_instance_backtest WHERE backtest_id = ? AND symbol = ? AND exchange = ?
        AND strategy = ? AND status = ? AND wait_start_timestamp = ? 
        ORDER BY id DESC LIMIT 1
        """
        insert_sql = """
        INSERT INTO {trade_type}_instance_backtest 
        (backtest_id, symbol, exchange, strategy, status, wait_start_timestamp)
        VALUES (?, ?, ?, ?, ?, ?) 
        """
        params = (
            self["backtest_id"],
            self["symbol"],
            self["exchange"],
            self["strategy"],
            INSTANCE_STATUS_WAITING,
            0,
        )

        if self["trade_type"] == TRADE_TYPE_FUTURE:
            query_sql = """
            SELECT id FROM {trade_type}_instance_backtest WHERE backtest_id = ? AND symbol = ? AND exchange = ? 
            AND contract_type = ? AND strategy = ? AND status = ? AND wait_start_timestamp = ? 
            ORDER BY id DESC LIMIT 1
            """
            insert_sql = """
            INSERT INTO {trade_type}_instance_backtest (backtest_id, symbol, exchange, contract_type, strategy, status,
             wait_start_timestamp)
             VALUES (?, ?, ?, ?, ?, ?, ?) 
            """
            params = (
                self["backtest_id"],
                self["symbol"],
                self["exchange"],
                self["contract_type"],
                self["strategy"],
                INSTANCE_STATUS_WAITING,
                0,
            )

        conn = Conn(self["db_name"])
        one = conn.query_one(
            query_sql.format(trade_type=self["trade_type"]),
            params,
        )
        if one:
            return one["id"]

        insert_id = conn.insert(
            insert_sql.format(trade_type=self["trade_type"]),
            params,
        )
        return insert_id
예제 #9
0
    def in_signal(self, signal_name: str, timestamp: int) -> bool:
        meta = self.get_metadata(signal_name)
        signal_id = meta["signal_id"]

        conn = Conn(self._db_name)
        dataset = conn.query_one(
            "SELECT * FROM signal_dataset WHERE signal_id = ? AND start_timestamp >= ? AND finish_timestamp < ?"
            " ORDER BY start_timestamp DESC LIMIT 1",
            (signal_id, timestamp, timestamp),
        )
        return not (dataset is None)
예제 #10
0
    def _value_by_id(self, fact_id: int, timestamp: int) -> float:
        conn = Conn(self._db_name)
        fact_data = conn.query_one(
            "SELECT factor_value FROM factor_dataset"
            " WHERE factor_id = ? AND timestamp <= ? ORDER BY timestamp DESC LIMIT 1",
            (fact_id, timestamp),
        )

        if fact_data is None:
            raise RuntimeError("Can not find the factor value, there have no value in database. ")
        return fact_data["factor_value"]
예제 #11
0
 def get_metadata(self, signal_name: str) -> dict:
     conn = Conn(self._db_name)
     metadata = conn.query_one(
         "SELECT * FROM signal_metadata"
         " WHERE symbol = ? AND exchange = ? AND trade_type = ? AND contract_type = ? AND signal_name = ? ",
         (self._symbol, self._exchange, self._trade_type,
          self._contract_type, signal_name),
     )
     if metadata is None:
         raise RuntimeError("Can not find the meta in database. ")
     return metadata
예제 #12
0
    def __insert_account_flow_item(self, **kwargs):
        """
        add record in account flow table
        :param
            subject: the item of account flow
            amount: the amount of flow, the real amount * 100000000
            position: the position of the flow
            timestamp: the item of account flow

        :return: None
        """

        if self._mode != MODE_BACKTEST:
            raise RuntimeError(
                "Only backtest mode can insert data into table. ")
        validate(instance=kwargs, schema=account_flow_input)
        conn = Conn(self._db_name)
        item = conn.query_one(
            """SELECT * FROM {} WHERE symbol = ? AND exchange = ? AND settle_mode = ? AND settle_currency = ?
             AND subject = ? AND timestamp = ? AND backtest_id = ?""".format(
                self._account_flow_table_name),
            (
                self._symbol,
                self._exchange,
                self._settle_mode,
                self._settle_currency,
                kwargs.get("subject"),
                kwargs.get("timestamp"),
                self._backtest_id,
            ),
        )
        conn.insert(
            """INSERT INTO {} (symbol, exchange, settle_mode, settle_currency, backtest_id, 
            subject, amount, position, timestamp, datetime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            """.format(self._account_flow_table_name),
            (
                self._symbol,
                self._exchange,
                self._settle_mode,
                self._settle_currency,
                self._backtest_id,
                kwargs.get("subject"),
                kwargs.get("amount"),
                kwargs.get("position"),
                kwargs.get("timestamp") +
                1 if item else kwargs.get("timestamp"),
                kwargs.get("datetime"),
            ),
        )
예제 #13
0
    def __init__(self, kw):
        super().__init__(kw)
        validate(instance=kw, schema=strategy_input)
        # 初始化各个组件

        self["asset"] = Asset(
            trade_type=self.get("trade_type"),
            symbol=self.get("symbol"),
            exchange=self.get("exchange"),
            db_name=self.get("db_name_asset") or self.get("db_name"),
            mode=self.get("mode"),
            settle_mode=self.get("settle_mode") or SETTLE_MODE_BASIS,
            backtest_id=self.get("backtest_id"),
        )

        self["indices"] = Indices(
            self.get("indices") or {},
            mode=self.get("mode"),
            trade_type=self.get("trade_type"),
            db_name=self.get("db_name"),
        )
        self["param"] = Param(
            self["param"],
            db_name=self.get("db_name_param") or self.get("db_name"),
            mode=self.get("mode"),
            trade_type=self.get("trade_type"),
        )

        instance_id = kw.get("id")
        if instance_id is not None:
            conn = Conn(self["db_name"])
            instance = conn.query_one(
                "SELECT * FROM {trade_type}_instance_{mode} WHERE id = ?".format(
                    trade_type=self["trade_type"],
                    mode=MODE_BACKTEST if self["mode"] == MODE_BACKTEST else MODE_STRATEGY,
                ),
                (instance_id,),
            )

            self["strategy"] = instance["strategy"]
            self["interval"] = instance["interval"]
            self["unit_amount"] = instance["unit_amount"]
            self["param"] = self["param"].load(instance_id)
            self["indices"] = self["indices"].load(instance_id)

            if self["trade_type"] == TRADE_TYPE_FUTURE:
                self["lever"] = instance["lever"]
                self["status"] = instance["status"]
예제 #14
0
    def get_spot_value(self, factor_name: str, timestamp: int):
        symbol = self._symbol
        currencies = symbol.split("_")
        if currencies[-1] in ("usdt", "usdc", "busd"):
            symbol = currencies[0] + "_usd"

        conn = Conn(self._db_name)
        meta = conn.query_one(
            "SELECT * FROM factor_metadata"
            " WHERE symbol = ? AND trade_type = ? AND contract_type = ?"
            " AND `interval` = ? AND factor_name = ? ",
            (symbol, TRADE_TYPE_SPOT, CONTRACT_TYPE_NONE, self._interval, factor_name),
        )
        if meta is None:
            return None
        return self._value_by_id(meta["factor_id"], timestamp)
예제 #15
0
 def __calculate_sub(self, timestamp: int) -> (float, float):
     query_sql = """
         SELECT SUM(amount)/100000000 AS asset_sub, SUM(position) AS position_sub FROM {} 
         WHERE exchange = ? AND settle_mode = ? AND settle_currency = ? AND backtest_id = ?
         AND timestamp <= ? AND subject IN (?, ?, ?)
     """.format(self._account_flow_table_name)
     query_param = (
         self._exchange,
         self._settle_mode,
         self._settle_currency,
         self._backtest_id,
         timestamp,
         SUBJECT_TRANSFER_IN,
         SUBJECT_TRANSFER_OUT,
         SUBJECT_SETTLE,
     )
     conn = Conn(self._db_name)
     result = conn.query_one(query_sql, query_param)
     position_sub, asset_sub = result["position_sub"], result["asset_sub"]
     return position_sub, asset_sub
예제 #16
0
 def __calculate_total(self, timestamp: int) -> (float, float):
     query_sql = """
     SELECT SUM(position) AS position, SUM(amount)/100000000 AS amount FROM {} WHERE exchange = ?
      AND settle_mode = ? AND settle_currency = ? AND backtest_id = ? AND timestamp <= ?
      AND subject IN (?, ?, ?)""".format(self._account_flow_table_name)
     query_param = (
         self._exchange,
         self._settle_mode,
         self._settle_currency,
         self._backtest_id,
         timestamp,
         SUBJECT_INVEST,
         SUBJECT_DIVEST,
         SUBJECT_SETTLE,
     )
     conn = Conn(self._db_name)
     result = conn.query_one(query_sql, query_param)
     position_total = result.get("position") or 20
     asset_total = result.get("amount") or 0.0
     return position_total, asset_total
예제 #17
0
 def __calculate_freeze(self, timestamp: int) -> (float, float):
     query_sql = """
         SELECT SUM(amount)/100000000 AS asset_freeze, SUM(position) AS position_freeze FROM {} 
         WHERE exchange = ? AND settle_mode = ? AND settle_currency = ? AND backtest_id = ? 
         AND timestamp <= ? AND subject IN (?, ?)
     """.format(self._account_flow_table_name)
     query_param = (
         self._exchange,
         self._settle_mode,
         self._settle_currency,
         self._backtest_id,
         timestamp,
         SUBJECT_FREEZE,
         SUBJECT_UNFREEZE,
     )
     conn = Conn(self._db_name)
     result = conn.query_one(query_sql, query_param)
     position_freeze = -(result.get("position_freeze") or 0.0)
     asset_freeze = -(result.get("asset_freeze") or 0.0)
     return position_freeze, asset_freeze
예제 #18
0
    def first_invest(
        self,
        asset_total: float,
        position_total: float,
        position_sub: float,
    ) -> None:
        m = moment.get(BIRTHDAY_BTC).to(
            self.get("timezone") or "Asia/Shanghai")
        query_sql = "SELECT * FROM {} WHERE exchange = ? AND settle_mode = ? AND settle_currency = ? AND subject = ?" \
                    " AND timestamp <= ? AND backtest_id = ? LIMIT 1".format(self._account_flow_table_name)
        query_param = (
            self._exchange,
            self._settle_mode,
            self._settle_currency,
            SUBJECT_INVEST,
            m.millisecond_timestamp,
            self._backtest_id,
        )

        conn = Conn(self._db_name)
        one = conn.query_one(query_sql, query_param)
        if one:
            return

        self.__invest(
            standard_number(asset_total),
            position_total,
            m.millisecond_timestamp,
            m.format("YYYY-MM-DD HH:mm:ss"),
        )
        self.__transfer_in(
            standard_number(asset_total * position_sub / position_total),
            position_sub,
            m.millisecond_timestamp,
            m.format("YYYY-MM-DD HH:mm:ss"),
        )
        self.__insert_asset_item(
            m.millisecond_timestamp,
            m.format("YYYY-MM-DD HH:mm:ss"),
        )
예제 #19
0
    def save(self,
             check: bool = False,
             raw_order_data: str = None,
             raw_market_data: str = None):
        if check:
            # 检验参数可用性
            validate(instance=self, schema=future_order_init)
            validate(instance=self, schema=future_order_save)

        conn = Conn(self._db_name)
        one = conn.query_one(
            "SELECT id FROM {} WHERE instance_id = ? AND sequence = ?".format(
                self._table_name),
            (self["instance_id"], self["sequence"]),
        )

        if one:
            conn.execute(
                "UPDATE {} SET place_type = ?, `type` = ?, price = ?, amount = ?,"
                " avg_price = ?, deal_amount = ?, status = ?, lever = ?, fee = ?,"
                " symbol = ?, exchange = ?, contract_type = ?, unit_amount = ?, "
                " place_timestamp = ?, place_datetime = ?, deal_timestamp = ?, deal_datetime = ?,"
                " due_timestamp = ?, due_datetime = ?, swap_timestamp = ?, swap_datetime = ?,"
                " cancel_timestamp = ?, cancel_datetime = ?, raw_order_data = ?, raw_market_data = ?"
                " WHERE instance_id = ? AND sequence = ?".format(
                    self._table_name),
                (
                    self["place_type"],
                    self["type"],
                    self["price"],
                    self["amount"],
                    self["avg_price"],
                    self["deal_amount"],
                    self["status"],
                    self["lever"],
                    self["fee"],
                    self["symbol"],
                    self["exchange"],
                    self["contract_type"],
                    self["unit_amount"],
                    self["place_timestamp"],
                    self["place_datetime"],
                    self["deal_timestamp"],
                    self["deal_datetime"],
                    self["due_timestamp"],
                    self["due_datetime"],
                    self["swap_timestamp"],
                    self["swap_datetime"],
                    self["cancel_timestamp"],
                    self["cancel_datetime"],
                    raw_order_data,
                    raw_market_data,
                    self["instance_id"],
                    self["sequence"],
                ),
            )
        else:
            conn.insert(
                "INSERT INTO {} (instance_id, sequence, place_type, `type`, price,"
                " amount, avg_price, deal_amount, status, lever,"
                " fee, symbol, exchange, contract_type, unit_amount,"
                " place_timestamp, place_datetime, deal_timestamp, deal_datetime,"
                " due_timestamp, due_datetime, swap_timestamp, swap_datetime,"
                " cancel_timestamp, cancel_datetime, raw_order_data, raw_market_data) VALUES"
                " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
                .format(self._table_name, ),
                (
                    self["instance_id"],
                    self["sequence"],
                    self["place_type"],
                    self["type"],
                    self["price"],
                    self["amount"],
                    self["avg_price"],
                    self["deal_amount"],
                    self["status"],
                    self["lever"],
                    self["fee"],
                    self["symbol"],
                    self["exchange"],
                    self["contract_type"],
                    self["unit_amount"],
                    self["place_timestamp"],
                    self["place_datetime"],
                    self["deal_timestamp"],
                    self["deal_datetime"],
                    self["due_timestamp"],
                    self["due_datetime"],
                    self["swap_timestamp"],
                    self["swap_datetime"],
                    self["cancel_timestamp"],
                    self["cancel_datetime"],
                    raw_order_data,
                    raw_market_data,
                ),
            )
        self.__update_instance()
예제 #20
0
    def save(self,
             check: bool = False,
             raw_order_data: str = None,
             raw_market_data: str = None):
        if check:
            # 检验参数可用性
            validate(instance=self, schema=order_input)

        conn = Conn(self._db_name)
        one = conn.query_one(
            "SELECT id FROM {} WHERE instance_id = ? AND sequence = ?".format(
                self._table_name),
            (self["instance_id"], self["sequence"]),
        )

        if one:
            conn.execute(
                "UPDATE {} SET place_type = ?, `type` = ?, price = ?, amount = ?,"
                " avg_price = ?, deal_amount = ?, status = ?, lever = ?, fee = ?,"
                " symbol = ?, exchange = ?, unit_amount = ?, place_timestamp = ?, place_datetime = ?,"
                " deal_timestamp = ?, deal_datetime = ?, swap_timestamp = ?, swap_datetime = ?,"
                " cancel_timestamp = ?, cancel_datetime = ?, raw_order_data = ?, raw_market_data = ?"
                " WHERE instance_id = ? AND sequence = ?".format(
                    self._table_name),
                (
                    self["place_type"],
                    self["type"],
                    self["price"],
                    self["amount"],
                    self["avg_price"],
                    self["deal_amount"],
                    self["status"],
                    self["lever"],
                    self["fee"],
                    self["symbol"],
                    self["exchange"],
                    self["unit_amount"],
                    self["place_timestamp"],
                    self["place_datetime"],
                    self["deal_timestamp"],
                    self["deal_datetime"],
                    self["swap_timestamp"],
                    self["swap_datetime"],
                    self["cancel_timestamp"],
                    self["cancel_datetime"],
                    raw_order_data,
                    raw_market_data,
                    self["instance_id"],
                    self["sequence"],
                ),
            )
        else:
            conn.insert(
                "INSERT INTO {} (instance_id, sequence, place_type, `type`, price,"
                " amount, avg_price, deal_amount, status, lever,"
                " fee, symbol, exchange, unit_amount, place_timestamp, place_datetime, deal_timestamp, deal_datetime,"
                " cancel_timestamp, cancel_datetime, raw_order_data, raw_market_data) VALUES"
                " (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
                .format(self._table_name, ),
                (
                    self["instance_id"],
                    self["sequence"],
                    self["place_type"],
                    self["type"],
                    self["price"],
                    self["amount"],
                    self["avg_price"],
                    self["deal_amount"],
                    self["status"],
                    self["lever"],
                    self["fee"],
                    self["symbol"],
                    self["exchange"],
                    self["unit_amount"],
                    self["place_timestamp"],
                    self["place_datetime"],
                    self["deal_timestamp"],
                    self["deal_datetime"],
                    self["cancel_timestamp"],
                    self["cancel_datetime"],
                    raw_order_data,
                    raw_market_data,
                ),
            )

        orders = conn.query(
            "SELECT * FROM {} WHERE instance_id = ? ORDER BY sequence".format(
                self._table_name),
            (self["instance_id"], ),
        )

        open_amount, open_fee = 0, 0.0
        open_start_timestamp, open_finish_timestamp = 0, 0
        open_start_datetime, open_finish_datetime = "", ""
        open_type, open_place_type = ORDER_TYPE_OPEN_LONG, ""

        liquidate_amount, liquidate_fee = 0, 0.0
        liquidate_start_timestamp, liquidate_finish_timestamp = 0, 0
        liquidate_start_datetime, liquidate_finish_datetime = "", ""
        liquidate_type, liquidate_place_type = ORDER_TYPE_LIQUIDATE_LONG, ""

        for order in orders:
            place_timestamp = order["place_timestamp"]
            place_datetime = moment.get(order["place_timestamp"]).to(
                self.get("timezone")
                or "Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss")

            if order["type"] in (ORDER_TYPE_OPEN_LONG, ORDER_TYPE_OPEN_SHORT):
                open_amount += order["deal_amount"]
                open_fee += order["fee"]
                open_type = order["type"]
                open_place_type = order["place_type"]

                if order["sequence"] == 0:
                    open_start_timestamp = place_timestamp
                    open_start_datetime = place_datetime
                open_finish_timestamp = place_timestamp
                open_finish_datetime = place_datetime

            if order["type"] in (ORDER_TYPE_LIQUIDATE_LONG,
                                 ORDER_TYPE_LIQUIDATE_SHORT):
                liquidate_amount += order["deal_amount"]
                liquidate_fee += order["fee"]
                liquidate_type = order["type"]
                liquidate_place_type = order["place_type"]

                if liquidate_start_timestamp == 0:
                    liquidate_start_timestamp = place_timestamp
                    liquidate_start_datetime = place_datetime
                liquidate_finish_timestamp = place_timestamp
                liquidate_finish_datetime = place_datetime

        if open_amount != liquidate_amount:
            return

        conn.execute(
            "UPDATE {trade_type}_instance_{mode} SET open_fee = ?, open_type = ?, open_place_type = ?,"
            " open_start_timestamp = ?, open_start_datetime = ?, open_finish_timestamp = ?, open_finish_datetime = ?, "
            " liquidate_fee = ?, liquidate_type = ?, liquidate_place_type = ?,"
            " liquidate_start_timestamp = ?, liquidate_start_datetime = ?,"
            " liquidate_finish_timestamp = ?, liquidate_finish_datetime = ? WHERE id = ?"
            .format(
                trade_type=self._trade_type,
                mode=MODE_STRATEGY
                if self._mode != MODE_BACKTEST else MODE_BACKTEST,
            ),
            (
                open_fee,
                open_type,
                open_place_type,
                open_start_timestamp,
                open_start_datetime,
                open_finish_timestamp,
                open_finish_datetime,
                liquidate_fee,
                liquidate_type,
                liquidate_place_type,
                liquidate_start_timestamp,
                liquidate_start_datetime,
                liquidate_finish_timestamp,
                liquidate_finish_datetime,
                self["instance_id"],
            ),
        )
예제 #21
0
    def save(self, slippage=0.01, fee=-0.0005) -> None:
        self.check_instance(self)
        conn = Conn(self["db_name"])
        one = conn.query_one(
            "SELECT id FROM {trade_type}_instance_{mode} WHERE id = ?".format(
                **self),
            (self["id"], ),
        )

        if one is None:
            raise RuntimeError("I think can not insert in this place. ")

        if self["trade_type"] == TRADE_TYPE_FUTURE:
            conn.execute(
                "UPDATE {trade_type}_instance_{mode} SET symbol = ?, exchange = ?, contract_type = ?,"
                " strategy = ?, unit_amount = ?, lever = ?, status = ?, `interval` = ?,"
                " wait_start_timestamp = ?, wait_start_datetime = ?,"
                " wait_finish_timestamp = ?, wait_finish_datetime = ?,"
                " open_times = ?, open_start_timestamp = ?, open_start_datetime = ?,"
                " open_finish_timestamp = ?, open_finish_datetime = ?,"
                " open_expired_timestamp = ?, open_expired_datetime = ?,"
                " liquidate_times = ?, liquidate_start_timestamp = ?, liquidate_start_datetime = ?,"
                " liquidate_finish_timestamp = ?, liquidate_finish_datetime = ?,"
                " asset_total = ?, asset_freeze = ?, param_position = ?, param_max_abs_loss_ratio = ?"
                " WHERE id = ?".format(trade_type=self["trade_type"],
                                       mode=self["mode"]),
                (
                    self["symbol"],
                    self["exchange"],
                    self["contract_type"],
                    self["strategy"],
                    self["unit_amount"],
                    self["lever"],
                    self["status"],
                    self["interval"],
                    self["wait_start_timestamp"],
                    self["wait_start_datetime"],
                    self["wait_finish_timestamp"],
                    self["wait_finish_datetime"],
                    self["open_times"],
                    self["open_start_timestamp"],
                    self["open_start_datetime"],
                    self["open_finish_timestamp"],
                    self["open_finish_datetime"],
                    self["open_expired_timestamp"],
                    self["open_expired_datetime"],
                    self["liquidate_times"],
                    self["liquidate_start_timestamp"],
                    self["liquidate_start_datetime"],
                    self["liquidate_finish_timestamp"],
                    self["liquidate_finish_datetime"],
                    self["asset_total"],
                    self["asset_freeze"],
                    self["param_position"],
                    self["param_max_abs_loss_ratio"],
                    self["id"],
                ),
            )
            order: FutureOrder = self["order"]
        else:
            conn.execute(
                "UPDATE {trade_type}_instance_{mode} SET symbol = ?, exchange = ?,"
                " strategy = ?, unit_amount = ?, status = ?, lever = ?,"
                " wait_start_timestamp = ?, wait_start_datetime = ?,"
                " wait_finish_timestamp = ?, wait_finish_datetime = ?,"
                " open_times = ?, open_start_timestamp = ?, open_start_datetime = ?,"
                " open_finish_timestamp = ?, open_finish_datetime = ?,"
                " open_expired_timestamp = ?, open_expired_datetime = ?,"
                " liquidate_times = ?, liquidate_start_timestamp = ?, liquidate_start_datetime = ?,"
                " liquidate_finish_timestamp = ?, liquidate_finish_datetime = ?,"
                " asset_total = ?, asset_freeze = ?, param_position = ?, param_max_abs_loss_ratio = ?"
                " WHERE id = ?".format(trade_type=self["trade_type"],
                                       mode=self["mode"]),
                (
                    self["symbol"],
                    self["exchange"],
                    self["strategy"],
                    self["unit_amount"],
                    self["status"],
                    self["lever"],
                    self["wait_start_timestamp"],
                    self["wait_start_datetime"],
                    self["wait_finish_timestamp"],
                    self["wait_finish_datetime"],
                    self["open_times"],
                    self["open_start_timestamp"],
                    self["open_start_datetime"],
                    self["open_finish_timestamp"],
                    self["open_finish_datetime"],
                    self["open_expired_timestamp"],
                    self["open_expired_datetime"],
                    self["liquidate_times"],
                    self["liquidate_start_timestamp"],
                    self["liquidate_start_datetime"],
                    self["liquidate_finish_timestamp"],
                    self["liquidate_finish_datetime"],
                    self["asset_total"],
                    self["asset_freeze"],
                    self["param_position"],
                    self["param_max_abs_loss_ratio"],
                    self["id"],
                ),
            )
            order: CommonOrder = self["order"]

        order.deal(slippage=slippage, fee=fee)
        order.save(check=True, raw_order_data=json.dumps(self))

        param: Param = self["param"]
        param.save(self["id"])

        indices: Indices = self["indices"]
        indices.save(self["id"])