def send_order(self, strategy: MultiFactorTemplate, direction: Direction,
                   offset: Offset, price: float, volume: float, stop: bool,
                   lock: bool):
        """
        cta的下单
        """
        contract = self.main_engine.get_contract(strategy.vt_symbol)
        if not contract:
            self.write_log(f"委托失败,找不到合约:{strategy.vt_symbol}", strategy)
            return ""

        # Round order price and volume to nearest incremental value
        # 价格,首先要对价格处理,变成可下单的价格,最小变动要保持一致
        price = round_to(price, contract.pricetick)
        volume = round_to(volume, contract.min_volume)

        # 如果是停止单
        if stop:
            # 如果服务器支持,发服务器的单子,从这里可以看出,如果是支持服务器停止单的,要写在查询合约的回调函数内
            if contract.stop_supported:
                return self.send_server_stop_order(strategy, contract,
                                                   direction, offset, price,
                                                   volume, lock)
            # 如果服务器不支持,发本地的单子
            else:
                return self.send_local_stop_order(strategy, direction, offset,
                                                  price, volume, lock)
        else:
            # 如果不是停止单,就是限价单
            return self.send_limit_order(strategy, contract, direction, offset,
                                         price, volume, lock)
Beispiel #2
0
    def calculate_price(self):
        """"""
        self.clear_price()

        # Go through all legs to calculate price
        for n, leg in enumerate(self.legs.values()):
            # Filter not all leg price data has been received
            if not leg.bid_volume or not leg.ask_volume:
                self.clear_price()
                return

            # Calculate price
            price_multiplier = self.price_multipliers[leg.vt_symbol]
            if price_multiplier > 0:
                self.bid_price += leg.bid_price * price_multiplier
                self.ask_price += leg.ask_price * price_multiplier
            else:
                self.bid_price += leg.ask_price * price_multiplier
                self.ask_price += leg.bid_price * price_multiplier

            # Round price to pricetick
            if self.pricetick:
                self.bid_price = round_to(self.bid_price, self.pricetick)
                self.ask_price = round_to(self.ask_price, self.pricetick)

            # Calculate volume
            trading_multiplier = self.trading_multipliers[leg.vt_symbol]
            inverse_contract = self.inverse_contracts[leg.vt_symbol]

            if not inverse_contract:
                leg_bid_volume = leg.bid_volume
                leg_ask_volume = leg.ask_volume
            else:
                leg_bid_volume = calculate_inverse_volume(
                    leg.bid_volume, leg.bid_price, leg.size)
                leg_ask_volume = calculate_inverse_volume(
                    leg.ask_volume, leg.ask_price, leg.size)

            if trading_multiplier > 0:
                adjusted_bid_volume = floor_to(
                    leg_bid_volume / trading_multiplier, self.min_volume)
                adjusted_ask_volume = floor_to(
                    leg_ask_volume / trading_multiplier, self.min_volume)
            else:
                adjusted_bid_volume = floor_to(
                    leg_ask_volume / abs(trading_multiplier), self.min_volume)
                adjusted_ask_volume = floor_to(
                    leg_bid_volume / abs(trading_multiplier), self.min_volume)

            # For the first leg, just initialize
            if not n:
                self.bid_volume = adjusted_bid_volume
                self.ask_volume = adjusted_ask_volume
            # For following legs, use min value of each leg quoting volume
            else:
                self.bid_volume = min(self.bid_volume, adjusted_bid_volume)
                self.ask_volume = min(self.ask_volume, adjusted_ask_volume)

            # Update calculate time
            self.datetime = datetime.now(LOCAL_TZ)
Beispiel #3
0
    def hedge_passive_legs(self):
        """
        Send orders to hedge all passive legs.
        """
        # Calcualte spread volume to hedge
        active_leg = self.spread.active_leg
        active_traded = self.leg_traded[active_leg.vt_symbol]
        active_traded = round_to(active_traded, self.spread.min_volume)

        hedge_volume = self.spread.calculate_spread_volume(
            active_leg.vt_symbol,
            active_traded
        )

        # Calculate passive leg target volume and do hedge
        for leg in self.spread.passive_legs:
            passive_traded = self.leg_traded[leg.vt_symbol]
            passive_traded = round_to(passive_traded, self.spread.min_volume)

            passive_target = self.spread.calculate_leg_volume(
                leg.vt_symbol,
                hedge_volume
            )

            leg_order_volume = passive_target - passive_traded
            if leg_order_volume:
                self.send_leg_order(leg.vt_symbol, leg_order_volume)
Beispiel #4
0
    def send_order(self, strategy: CtaTemplate, direction: Direction,
                   offset: Offset, price: float, volume: float, stop: bool,
                   lock: bool):
        """
        """
        contract = self.main_engine.get_contract(strategy.vt_symbol)
        if not contract:
            self.write_log(f"委托失败,找不到合约:{strategy.vt_symbol}", strategy)
            return ""

        # Round order price and volume to nearest incremental value
        price = round_to(price, contract.pricetick)
        # volume = round_to(volume, contract.min_volume)
        # 判断是现货交易所,下单量的精度调整
        if strategy.exchangematerial in EXCHANGE_MATERIAL:
            # 如果在列表里,下单量就不做任何四舍五入处理(原样)
            pass
        else:
            volume = round_to(volume, contract.min_volume)

        if stop:
            if contract.stop_supported:
                return self.send_server_stop_order(strategy, contract,
                                                   direction, offset, price,
                                                   volume, lock)
            else:
                return self.send_local_stop_order(strategy, direction, offset,
                                                  price, volume, lock)
        else:
            return self.send_limit_order(strategy, contract, direction, offset,
                                         price, volume, lock)
Beispiel #5
0
    def send_order(self, strategy: CtaTemplate, direction: Direction,
                   offset: Offset, price: float, volume: float, stop: bool,
                   lock: bool):
        """
        """
        contract = self.main_engine.get_contract(strategy.vt_symbol)
        if not contract:
            self.write_log(f"委托失败,找不到合约:{strategy.vt_symbol}", strategy)
            return ""

        # Round order price and volume to nearest incremental value
        price = round_to(price, contract.pricetick)
        volume = round_to(volume, contract.min_volume)

        if stop:
            if contract.stop_supported:
                return self.send_server_stop_order(strategy, contract,
                                                   direction, offset, price,
                                                   volume, lock)
            else:
                return self.send_local_stop_order(strategy, direction, offset,
                                                  price, volume, lock)
        else:
            return self.send_limit_order(strategy, contract, direction, offset,
                                         price, volume, lock)
    def on_trade(self, trade: TradeData):
        # 同步数据到数据库
        if self.entrust == 0:
            if trade.offset == Offset.OPEN:
                msg = f'{trade.offset.value}{trade.direction.value},{trade.volume}张,成交价:{trade.price}'
                self.entrust = 1
                self.write_log(f'交易完成,{trade.orderid[-3:]},{msg}')
                if trade.direction == Direction.LONG:
                    price = self.ask_price
                    price = round_to(price, self.min_diff)
                    ref = self.sell(price, self.input_ss, False)
                    self.write_log(u'平多单{},价:{}'.format(ref[-5:-3], price))
                elif trade.direction == Direction.SHORT:
                    price = self.bid_price
                    price = round_to(price, self.min_diff)
                    ref = self.cover(price, self.input_ss, False)
                    self.write_log(u'平空单{},价:{}'.format(ref[-5:-3], price))
            else:
                if trade.direction == Direction.LONG:
                    direc = '空'
                else:
                    direc = '多'
                msg = f'{trade.offset.value}{direc},{trade.volume}张,成交价:{trade.price}'
                self.write_log(f'交易完成,{trade.orderid[-3:]},{msg}')

        self.put_event()
Beispiel #7
0
    def send_order(
        self,
        strategy: StrategyTemplate,
        vt_symbol: str,
        direction: Direction,
        offset: Offset,
        price: float,
        volume: float,
        lock: bool,
        net: bool,
    ):
        """
        Send a new order to server.
        """
        contract: ContractData = self.main_engine.get_contract(vt_symbol)
        if not contract:
            self.write_log(f"委托失败,找不到合约:{vt_symbol}", strategy)
            return ""

        # Round order price and volume to nearest incremental value
        price = round_to(price, contract.pricetick)
        volume = round_to(volume, contract.min_volume)

        # Create request and send order.
        original_req = OrderRequest(
            symbol=contract.symbol,
            exchange=contract.exchange,
            direction=direction,
            offset=offset,
            type=OrderType.LIMIT,
            price=price,
            volume=volume,
            reference=f"{APP_NAME}_{strategy.strategy_name}")

        # Convert with offset converter
        req_list = self.offset_converter.convert_order_request(
            original_req, lock, net)

        # Send Orders
        vt_orderids = []

        for req in req_list:
            req.reference = strategy.strategy_name  # Add strategy name as order reference

            vt_orderid = self.main_engine.send_order(req,
                                                     contract.gateway_name)

            # Check if sending order successful
            if not vt_orderid:
                continue

            vt_orderids.append(vt_orderid)

            self.offset_converter.update_order_request(req, vt_orderid)

            # Save relationship between orderid and strategy.
            self.orderid_strategy_map[vt_orderid] = strategy

        return vt_orderids
Beispiel #8
0
    def calculate_traded(self):
        """"""
        # Calculate traded volume
        self.traded = 0

        for n, leg in enumerate(self.spread.legs.values()):
            leg_traded = self.leg_traded[leg.vt_symbol]
            trading_multiplier = self.spread.trading_multipliers[leg.vt_symbol]

            adjusted_leg_traded = leg_traded / trading_multiplier
            adjusted_leg_traded = round_to(adjusted_leg_traded,
                                           self.spread.min_volume)

            if adjusted_leg_traded > 0:
                adjusted_leg_traded = floor_to(adjusted_leg_traded,
                                               self.spread.min_volume)
            else:
                adjusted_leg_traded = ceil_to(adjusted_leg_traded,
                                              self.spread.min_volume)

            if not n:
                self.traded = adjusted_leg_traded
            else:
                if adjusted_leg_traded > 0:
                    self.traded = min(self.traded, adjusted_leg_traded)
                elif adjusted_leg_traded < 0:
                    self.traded = max(self.traded, adjusted_leg_traded)
                else:
                    self.traded = 0

        self.traded_volume = abs(self.traded)

        if self.target > 0 and self.traded >= self.target:
            self.status = Status.ALLTRADED
        elif self.target < 0 and self.traded <= self.target:
            self.status = Status.ALLTRADED
        elif not self.traded:
            self.status = Status.NOTTRADED
        else:
            self.status = Status.PARTTRADED

        # Calculate traded price
        self.traded_price = 0

        for n, leg in enumerate(self.spread.legs.values()):
            # If any leg is not traded yet, set spread trade price to 0
            leg_traded = self.leg_traded[leg.vt_symbol]
            if not leg_traded:
                self.traded_price = 0
                break

            leg_cost = self.leg_cost[leg.vt_symbol]
            leg_price = leg_cost / leg_traded

            price_multiplier = self.spread.price_multipliers[leg.vt_symbol]
            self.traded_price += leg_price * price_multiplier

        self.traded_price = round_to(self.traded_price, self.spread.pricetick)
Beispiel #9
0
 def send_order(self, strategy: CtaTemplate, direction: Direction,
                offset: Offset, price: float, volume: float, stop: bool,
                lock: bool):
     """"""
     if callable(self.pricetick):
         price = round_to(price, self.pricetick(price))
     else:
         price = round_to(price, self.pricetick)
     if stop:
         vt_orderid = self.send_stop_order(direction, offset, price, volume)
     else:
         vt_orderid = self.send_limit_order(direction, offset, price,
                                            volume)
     return [vt_orderid]
Beispiel #10
0
    def on_order(self, order: OrderData):
        """
        Callback of new order data update.
        """
        msg = f'\t报单更新,{order.orderid},{order.symbol},{order.offset.value},价:{order.price},委托:{order.volume},{order.status.value}'
        self.write_log(msg)

        if order.volume == order.traded or order.status == Status.ALLTRADED:
            # 开仓,平仓委托单全部成交
            # 计算收益
            if order.direction == Direction.LONG:
                self.buy_times = self.buy_times + 1
                self.roi = self.roi - order.price * order.traded * self.rate
            else:
                self.sell_times = self.sell_times + 1
                self.roi = self.roi + (order.price - self.base_line -
                                       order.price * self.rate) * order.traded

            self.base_line = order.price
            self.new_up = self.base_line * (1 + self.grid_height / 100)
            self.new_down = self.base_line / (1 + self.grid_height / 100)
            self.new_down = round_to(self.new_down, self.min_diff)
            self.entrust = 0
            if self.get_engine_type() == EngineType.LIVE:
                base_pos = self.cta_engine.main_engine.get_account('.'.join(
                    [order.exchange.value, self.base]))
                volumn = round_to(base_pos.balance, self.min_volumn)
            else:
                volumn = 10

            sub = order.symbol + ' ' + order.offset.value + u',{}'.format(
                order.price)
            self.roi = round(self.roi, 4)
            msg2 = u'{},\n低吸次数:{},高抛次数:{},套利:{}{}, 持仓{}'.format(
                msg, self.buy_times, self.sell_times, self.roi, self.quote,
                volumn)

            if self.get_engine_type() == EngineType.LIVE:
                self.send_email(msg2)
                sendWxMsg(sub, msg2)

        elif order.status in [Status.CANCELLED, Status.REJECTED]:
            self.write_log("取消多余的单")
            self.cancel_all()

            sleep(10)  # 10s
            self.entrust = 0

        self.put_event()
Beispiel #11
0
    def calculate_traded_price(self):
        """"""
        self.traded_price = 0
        spread = self.spread

        # Basic spread
        if not isinstance(spread, AdvancedSpreadData):
            for leg in spread.legs.values():
                # If any leg is not traded yet, set spread trade price to 0
                leg_traded = self.leg_traded[leg.vt_symbol]
                if not leg_traded:
                    self.traded_price = 0
                    break

                leg_cost = self.leg_cost[leg.vt_symbol]
                leg_price = leg_cost / leg_traded

                price_multiplier = spread.price_multipliers[leg.vt_symbol]
                self.traded_price += leg_price * price_multiplier

            self.traded_price = round_to(self.traded_price, spread.pricetick)
        # Advanced spread
        else:
            data = {}

            for variable, vt_symbol in spread.variable_symbols.items():
                leg = spread.legs[vt_symbol]
                trading_multiplier = spread.trading_multipliers[leg.vt_symbol]

                # Use last price for non-trading leg (trading multiplier is 0)
                if not trading_multiplier:
                    data[variable] = leg.tick.last_price
                else:
                    # If any leg is not traded yet, clear data dict to set traded price to 0
                    leg_traded = self.leg_traded[leg.vt_symbol]
                    if not leg_traded:
                        data.clear()
                        break

                    leg_cost = self.leg_cost[leg.vt_symbol]
                    data[variable] = leg_cost / leg_traded

            if data:
                self.traded_price = spread.parse_formula(
                    spread.price_code, data)
                self.traded_price = round_to(self.traded_price,
                                             spread.pricetick)
            else:
                self.traded_price = 0
Beispiel #12
0
    def send_order(
        self,
        vt_symbol: str,
        price: float,
        volume: float,
        direction: Direction,
    ):
        """"""
        # For inverse contract:
        # calculate contract trading volume from coin trading volume
        if self.spread.is_inverse(vt_symbol):
            size = self.spread.get_leg_size(vt_symbol)

            if self.offset == Offset.CLOSE:
                leg = self.spread.legs[vt_symbol]
                volume = volume * leg.net_pos_price / size
            else:
                volume = volume * price / size

        # Round order volume to min_volume of contract
        leg = self.spread.legs[vt_symbol]
        volume = round_to(volume, leg.min_volume)

        # If new order volume is 0, then check if algo finished
        if not volume:
            finished = self.check_algo_finished()

            if finished:
                self.status = Status.ALLTRADED
                self.put_event()

                msg = "各腿剩余数量均不足最小下单量,算法执行结束"
                self.write_log(msg)

            return

        # Round order price to pricetick of contract
        price = round_to(price, leg.pricetick)

        # Otherwise send order
        vt_orderids = self.algo_engine.send_order(self, vt_symbol, price,
                                                  volume, direction, self.lock)

        self.leg_orders[vt_symbol].extend(vt_orderids)

        msg = "发出委托[{}],{},{},{}@{}".format("|".join(vt_orderids), vt_symbol,
                                            direction.value, volume, price)
        self.write_log(msg)
Beispiel #13
0
    def send_order(
        self,
        algo: AlgoTemplate,
        vt_symbol: str,
        direction: Direction,
        price: float,
        volume: float,
        order_type: OrderType,
        offset: Offset
    ):
        """"""
        contract = self.main_engine.get_contract(vt_symbol)
        if not contract:
            self.write_log(f'委托下单失败,找不到合约:{vt_symbol}', algo)
            return

        volume = round_to(volume, contract.min_volume)
        if not volume:
            return ""

        req = OrderRequest(
            symbol=contract.symbol,
            exchange=contract.exchange,
            direction=direction,
            type=order_type,
            volume=volume,
            price=price,
            offset=offset,
            reference=f"{APP_NAME}_{algo.algo_name}"
        )
        vt_orderid = self.main_engine.send_order(req, contract.gateway_name)

        self.orderid_algo_map[vt_orderid] = algo
        return vt_orderid
Beispiel #14
0
 def send_order(self, strategy: CtaTemplate, direction: Direction,
                offset: Offset, price: float, volume: float, stop: bool,
                lock: bool):
     """"""
     price = round_to(price, self.pricetick)
     vt_orderid = self.send_limit_order(direction, offset, price, volume)
     return [vt_orderid]
Beispiel #15
0
    def send_order(self, strategy: StrategyTemplate, vt_symbol: str,
                   direction: Direction, offset: Offset, price: float,
                   volume: float, lock: bool) -> List[str]:
        """"""
        price = round_to(price, self.priceticks[vt_symbol])
        symbol, exchange = extract_vt_symbol(vt_symbol)

        self.limit_order_count += 1

        order = OrderData(
            symbol=symbol,
            exchange=exchange,
            orderid=str(self.limit_order_count),
            direction=direction,
            offset=offset,
            price=price,
            volume=volume,
            status=Status.SUBMITTING,
            datetime=self.datetime,
            gateway_name=self.gateway_name,
        )

        self.active_limit_orders[order.vt_orderid] = order
        self.limit_orders[order.vt_orderid] = order

        return [order.vt_orderid]
Beispiel #16
0
    def on_order(self, packet: dict) -> None:
        """委托更新推送"""
        data = packet["data"]
        for d in data:
            order: OrderData = parse_order_data(d, self.gateway_name)
            self.gateway.on_order(order)

            # 检查是否有成交
            if d["fillSz"] == "0":
                return

            # 将成交数量四舍五入到正确精度
            trade_volume: float = float(d["fillSz"])
            contract: ContractData = symbol_contract_map.get(
                order.symbol, None)
            if contract:
                trade_volume = round_to(trade_volume, contract.min_volume)

            trade: TradeData = TradeData(
                symbol=order.symbol,
                exchange=order.exchange,
                orderid=order.orderid,
                tradeid=d["tradeId"],
                direction=order.direction,
                offset=order.offset,
                price=float(d["fillPx"]),
                volume=trade_volume,
                datetime=parse_timestamp(d["uTime"]),
                gateway_name=self.gateway_name,
            )
            self.gateway.on_trade(trade)
Beispiel #17
0
    def on_order(self, data: dict) -> None:
        """"""
        orderid = data["clientOrderId"]
        order = self.gateway.get_order(orderid)
        if not order:
            return

        traded_volume = float(data.get("tradeVolume", 0))

        contract = symbol_contract_map.get(order.symbol, None)
        if contract:
            traded_volume = round_to(traded_volume, contract.min_volume)

        # Push order event
        order.traded += traded_volume
        order.status = STATUS_HUOBI2VT.get(data["orderStatus"], None)
        self.gateway.on_order(order)

        # Push trade event
        if not traded_volume:
            return

        trade = TradeData(
            symbol=order.symbol,
            exchange=Exchange.HUOBI,
            orderid=order.orderid,
            tradeid=str(data["tradeId"]),
            direction=order.direction,
            price=float(data["tradePrice"]),
            volume=traded_volume,
            datetime=datetime.now(CHINA_TZ),
            gateway_name=self.gateway_name,
        )
        self.gateway.on_trade(trade)
Beispiel #18
0
    def __init__(self, algo_engine: BaseEngine, algo_name: str, setting: dict):
        """"""
        super().__init__(algo_engine, algo_name, setting)

        # Parameters
        self.vt_symbol = setting["vt_symbol"]
        self.direction = Direction(setting["direction"])
        self.price = setting["price"]
        self.volume = setting["volume"]
        self.time = setting["time"]
        self.interval = setting["interval"]
        self.offset = Offset(setting["offset"])

        # Variables
        self.order_volume = self.volume / (self.time / self.interval)
        contract = self.get_contract(self.vt_symbol)
        if contract:
            self.order_volume = round_to(self.order_volume,
                                         contract.min_volume)

        self.timer_count = 0
        self.total_count = 0
        self.traded = 0

        self.last_tick = None

        self.subscribe(self.vt_symbol)
        self.put_parameters_event()
        self.put_variables_event()
Beispiel #19
0
def load_bar_data(
    spread: SpreadData,
    interval: Interval,
    start: datetime,
    end: datetime,
    pricetick: float = 0
):
    """"""
    # Load bar data of each spread leg
    leg_bars: Dict[str, Dict] = {}

    for vt_symbol in spread.legs.keys():
        symbol, exchange = extract_vt_symbol(vt_symbol)

        bar_data: List[BarData] = database_manager.load_bar_data(
            symbol, exchange, interval, start, end
        )

        bars: Dict[datetime, BarData] = {bar.datetime: bar for bar in bar_data}
        leg_bars[vt_symbol] = bars

    # Calculate spread bar data
    spread_bars: List[BarData] = []

    for dt in bars.keys():
        spread_price = 0
        spread_value = 0
        spread_available = True

        for leg in spread.legs.values():
            leg_bar = leg_bars[leg.vt_symbol].get(dt, None)

            if leg_bar:
                price_multiplier = spread.price_multipliers[leg.vt_symbol]
                spread_price += price_multiplier * leg_bar.close_price
                spread_value += abs(price_multiplier) * leg_bar.close_price
            else:
                spread_available = False

        if spread_available:
            if pricetick:
                spread_price = round_to(spread_price, pricetick)

            spread_bar = BarData(
                symbol=spread.name,
                exchange=exchange.LOCAL,
                datetime=dt,
                interval=interval,
                open_price=spread_price,
                high_price=spread_price,
                low_price=spread_price,
                close_price=spread_price,
                gateway_name="SPREAD",
            )
            spread_bar.value = spread_value
            spread_bars.append(spread_bar)

    return spread_bars
Beispiel #20
0
    def generate_rand_volume(self):
        """"""
        rand_volume = uniform(self.min_volume, self.max_volume)
        rand_volume = round_to(rand_volume, self.volume_change)

        if self.volume_change == 1:
            rand_volume = int(rand_volume)

        return rand_volume
Beispiel #21
0
    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.new_up = self.base_line * (1 + self.grid_height / 100)
        self.new_down = self.base_line / (1 + self.grid_height / 100)
        self.new_down = round_to(self.new_down, self.min_diff)

        self.write_log("策略启动")
Beispiel #22
0
    def onMarketData(self, mk_type: int, symbol: str, data: dict) -> None:
        """"""
        timestamp = f"{self.date}{str(data['nTime'])}"
        dt = datetime.strptime(timestamp, "%Y%m%d%H%M%S%f")
        dt = CHINA_TZ.localize(dt)

        tick = TickData(symbol=symbol,
                        exchange=MK_GTJA2VT[mk_type],
                        datetime=dt,
                        volume=data["iVolume"],
                        last_price=data["uMatch"] / 10000,
                        limit_up=data["uHighLimited"] / 10000,
                        limit_down=data["uLowLimited"] / 10000,
                        open_price=data["uOpen"] / 10000,
                        high_price=data["uHigh"] / 10000,
                        low_price=data["uLow"] / 10000,
                        pre_close=data["uPreClose"] / 10000,
                        gateway_name=self.gateway_name)

        tick.bid_price_1, tick.bid_price_2, tick.bid_price_3, tick.bid_price_4, tick.bid_price_5 = data[
            "bid"][0:5]
        tick.ask_price_1, tick.ask_price_2, tick.ask_price_3, tick.ask_price_4, tick.ask_price_5 = data[
            "ask"][0:5]
        tick.bid_volume_1, tick.bid_volume_2, tick.bid_volume_3, tick.bid_volume_4, tick.bid_volume_5 = data[
            "bid_qty"][0:5]
        tick.ask_volume_1, tick.ask_volume_2, tick.ask_volume_3, tick.ask_volume_4, tick.ask_volume_5 = data[
            "ask_qty"][0:5]

        pricetick = symbol_pricetick_map.get(tick.vt_symbol, 0)
        if pricetick:
            tick.bid_price_1 = round_to(tick.bid_price_1 / 10000, pricetick)
            tick.bid_price_2 = round_to(tick.bid_price_2 / 10000, pricetick)
            tick.bid_price_3 = round_to(tick.bid_price_3 / 10000, pricetick)
            tick.bid_price_4 = round_to(tick.bid_price_4 / 10000, pricetick)
            tick.bid_price_5 = round_to(tick.bid_price_5 / 10000, pricetick)
            tick.ask_price_1 = round_to(tick.ask_price_1 / 10000, pricetick)
            tick.ask_price_2 = round_to(tick.ask_price_2 / 10000, pricetick)
            tick.ask_price_3 = round_to(tick.ask_price_3 / 10000, pricetick)
            tick.ask_price_4 = round_to(tick.ask_price_4 / 10000, pricetick)
            tick.ask_price_5 = round_to(tick.ask_price_5 / 10000, pricetick)

        tick.name = symbol_name_map.get(tick.vt_symbol, tick.symbol)
        self.gateway.on_tick(tick)
Beispiel #23
0
 def cal_annual_returns(trades: {}, end_date, end_cash):
     """计算年化收益,需要交易日、金额, 截止日:金额"""
     # cash1 * (1 + x / 100)^[(end_date - self.start_date)/365] + cash2 * (1 + x / 100)^[(end_date - self.start_date)/365] = end_val
     # trades, key: date, value: cash
     expression = ''
     for date, cash in trades.items():
         td = round_to((end_date - date).days / 365, 0.001)
         expression = expression + str(cash) + '*(1 + x) **' + str(td) + '+'
     expression = expression[:-1] + '-' + str(end_cash)
     return expression
Beispiel #24
0
    def onDepthMarketData(self, data: dict) -> None:
        """"""
        timestamp = str(data["data_time"])
        dt = datetime.strptime(timestamp, "%Y%m%d%H%M%S%f")
        dt = dt.replace(tzinfo=CHINA_TZ)

        tick = TickData(symbol=data["ticker"],
                        exchange=EXCHANGE_XTP2VT[data["exchange_id"]],
                        datetime=dt,
                        volume=data["qty"],
                        last_price=data["last_price"],
                        limit_up=data["upper_limit_price"],
                        limit_down=data["lower_limit_price"],
                        open_price=data["open_price"],
                        high_price=data["high_price"],
                        low_price=data["low_price"],
                        pre_close=data["pre_close_price"],
                        gateway_name=self.gateway_name)

        tick.bid_price_1, tick.bid_price_2, tick.bid_price_3, tick.bid_price_4, tick.bid_price_5 = data[
            "bid"][0:5]
        tick.ask_price_1, tick.ask_price_2, tick.ask_price_3, tick.ask_price_4, tick.ask_price_5 = data[
            "ask"][0:5]
        tick.bid_volume_1, tick.bid_volume_2, tick.bid_volume_3, tick.bid_volume_4, tick.bid_volume_5 = data[
            "bid_qty"][0:5]
        tick.ask_volume_1, tick.ask_volume_2, tick.ask_volume_3, tick.ask_volume_4, tick.ask_volume_5 = data[
            "ask_qty"][0:5]

        pricetick = symbol_pricetick_map.get(tick.vt_symbol, 0)
        if pricetick:
            tick.bid_price_1 = round_to(tick.bid_price_1, pricetick)
            tick.bid_price_2 = round_to(tick.bid_price_2, pricetick)
            tick.bid_price_3 = round_to(tick.bid_price_3, pricetick)
            tick.bid_price_4 = round_to(tick.bid_price_4, pricetick)
            tick.bid_price_5 = round_to(tick.bid_price_5, pricetick)
            tick.ask_price_1 = round_to(tick.ask_price_1, pricetick)
            tick.ask_price_2 = round_to(tick.ask_price_2, pricetick)
            tick.ask_price_3 = round_to(tick.ask_price_3, pricetick)
            tick.ask_price_4 = round_to(tick.ask_price_4, pricetick)
            tick.ask_price_5 = round_to(tick.ask_price_5, pricetick)

        tick.name = symbol_name_map.get(tick.vt_symbol, tick.symbol)
        self.gateway.on_tick(tick)
Beispiel #25
0
    def calculate_price(self) -> None:
        """"""
        option = self.option

        # Get ref price
        self.pricing_impv = option.pricing_impv
        ref_price = option.calculate_ref_price()
        self.ref_price = round_to(ref_price, self.pricetick)

        # Calculate spread
        algo_spread = max(self.price_spread,
                          self.volatility_spread * option.cash_vega)
        half_spread = algo_spread / 2

        # Calculate bid/ask
        self.algo_bid_price = round_to(ref_price - half_spread, self.pricetick)
        self.algo_ask_price = round_to(ref_price + half_spread, self.pricetick)
        self.algo_spread = round_to(algo_spread, self.pricetick)

        self.put_pricing_event()
Beispiel #26
0
    def update_trade(self, trade: TradeData):
        """"""
        # For inverse contract:
        # record coin trading volume as leg trading volume,
        # not contract volume!
        if self.spread.is_inverse(trade.vt_symbol):
            size = self.spread.get_leg_size(trade.vt_symbol)

            trade_volume = calculate_inverse_volume(
                trade.volume,
                trade.price,
                size
            )
        else:
            trade_volume = trade.volume

        if trade.direction == Direction.LONG:
            self.leg_traded[trade.vt_symbol] += trade_volume
            self.leg_cost[trade.vt_symbol] += trade_volume * trade.price
        else:
            self.leg_traded[trade.vt_symbol] -= trade_volume
            self.leg_cost[trade.vt_symbol] -= trade_volume * trade.price

        self.calculate_traded_volume()
        self.calculate_traded_price()

        # Sum up total traded volume of each order,
        self.order_trade_volume[trade.vt_orderid] += trade.volume

        # Remove order from active list if all volume traded
        order = self.orders[trade.vt_orderid]
        contract = self.get_contract(trade.vt_symbol)

        trade_volume = round_to(
            self.order_trade_volume[order.vt_orderid],
            contract.min_volume
        )

        if trade_volume == order.volume:
            vt_orderids = self.leg_orders[order.vt_symbol]
            if order.vt_orderid in vt_orderids:
                vt_orderids.remove(order.vt_orderid)

        msg = "委托成交[{}],{},{},{}@{}".format(
            trade.vt_orderid,
            trade.vt_symbol,
            trade.direction.value,
            trade.volume,
            trade.price
        )
        self.write_log(msg)

        self.put_event()
        self.on_trade(trade)
Beispiel #27
0
    def onRtnOptionData(self, head: dict, data: dict) -> None:
        """"""
        timestamp = f"{head['tradeDate']} {head['updateTime']}"

        tick = TickData(symbol=data["SecurityID"],
                        exchange=EXCHANGE_OES2VT[head["exchId"]],
                        datetime=datetime.strptime(timestamp,
                                                   "%Y%m%d %H%M%S%f"),
                        volume=data["TotalVolumeTraded"],
                        pre_close=data["PrevClosePx"],
                        last_price=data["TradePx"] / 10000,
                        open_price=data["OpenPx"] / 10000,
                        high_price=data["HighPx"] / 10000,
                        low_price=data["LowPx"] / 10000,
                        gateway_name=self.gateway_name)
        tick.bid_price_1, tick.bid_price_2, tick.bid_price_3, tick.bid_price_4, tick.bid_price_5 = data[
            "bid"][0:5]
        tick.ask_price_1, tick.ask_price_2, tick.ask_price_3, tick.ask_price_4, tick.ask_price_5 = data[
            "ask"][0:5]
        tick.bid_volume_1, tick.bid_volume_2, tick.bid_volume_3, tick.bid_volume_4, tick.bid_volume_5 = data[
            "bid_qty"][0:5]
        tick.ask_volume_1, tick.ask_volume_2, tick.ask_volume_3, tick.ask_volume_4, tick.ask_volume_5 = data[
            "ask_qty"][0:5]

        pricetick = SYMBOL_PRICETICK_MAP.get(tick.vt_symbol, 0)
        if pricetick:
            tick.bid_price_1 = round_to(tick.bid_price_1 / 10000, pricetick)
            tick.bid_price_2 = round_to(tick.bid_price_2 / 10000, pricetick)
            tick.bid_price_3 = round_to(tick.bid_price_3 / 10000, pricetick)
            tick.bid_price_4 = round_to(tick.bid_price_4 / 10000, pricetick)
            tick.bid_price_5 = round_to(tick.bid_price_5 / 10000, pricetick)
            tick.ask_price_1 = round_to(tick.ask_price_1 / 10000, pricetick)
            tick.ask_price_2 = round_to(tick.ask_price_2 / 10000, pricetick)
            tick.ask_price_3 = round_to(tick.ask_price_3 / 10000, pricetick)
            tick.ask_price_4 = round_to(tick.ask_price_4 / 10000, pricetick)
            tick.ask_price_5 = round_to(tick.ask_price_5 / 10000, pricetick)

        tick.name = SYMBOL_NAME_MAP.get(tick.vt_symbol, "")
        self.gateway.on_tick(tick)
Beispiel #28
0
    def process_trade_event(self, event: Event):
        """"""
        trade = event.data

        # Filter duplicate trade push
        if trade.vt_tradeid in self.vt_tradeids:
            return
        self.vt_tradeids.add(trade.vt_tradeid)

        self.offset_converter.update_trade(trade)

        strategy = self.orderid_strategy_map.get(trade.vt_orderid, None)
        if not strategy:
            return

        contract = self.main_engine.get_contract(strategy.vt_symbol)
        if not contract:
            volume = trade.volume
        else:
            # Round order price and volume to nearest incremental value
            volume = round_to(trade.volume, contract.min_volume)

        # Update strategy pos before calling on_trade method
        if trade.direction == Direction.LONG:
            strategy.pos += volume
        else:
            strategy.pos -= volume

        if contract:
            strategy.pos = round_to(strategy.pos, contract.min_volume)

        self.call_strategy_func(strategy, strategy.on_trade, trade)

        # Sync strategy variables to data file
        self.sync_strategy_data(strategy)

        # Update GUI
        self.put_strategy_event(strategy)
Beispiel #29
0
    def send_order(self, strategy: CtaTemplate, direction: Direction,
                   offset: Offset, price: float, volume: float, lock: bool,
                   order_type: OrderType, extra: dict):
        """"""
        price = round_to(price, self.pricetick)
        if order_type == order_type.STOP:
            vt_orderid = self.send_stop_order(direction, offset, price, volume)
        elif order_type == order_type.MARKET:
            vt_orderid = self.send_market_order(direction, offset, price,
                                                volume, extra)
        else:
            vt_orderid = self.send_limit_order(direction, offset, price,
                                               volume, extra)

        return [vt_orderid]
    def on_trade(self, trade: TradeData):
        # 同步数据到数据库
        self.posPrice = trade.price
        self.sync_data()
        if self.entrust == 0:
            msg = u'{}{},{}张,成交价:{}'.format(trade.offset.value,
                                            trade.direction.value,
                                            trade.volume, trade.price)
            self.write_log(u'交易完成,{},{},pos:{}'.format(trade.orderid, msg,
                                                       self.poss))

            if trade.offset == Offset.OPEN:
                if trade.direction == Direction.LONG:
                    price = trade.price - self.step
                    price = round_to(price, self.min_diff)
                    ref = self.sell(price, self.input_ss, True)
                    self.write_log(u'开多停止单{},价:{}'.format(ref, price))
                elif trade.direction == Direction.SHORT:
                    price = trade.price + self.step
                    price = round_to(price, self.min_diff)
                    ref = self.cover(price, self.input_ss, True)
                    self.write_log(u'开空停止单{},价:{}'.format(ref, price))

        self.put_event()