Exemplo n.º 1
0
class BrokerBase(OnePyEnvBase, abc.ABC):
    def __init__(self):
        self.env.brokers.update({self.__class__.__name__: self})
        self._checker = SubmitOrderChecker(self._required_cash_func)
        self._order_generator = OrderGenerator()

    def _clear_submited_order(self):
        self.env.orders_mkt_submitted_cur = []
        self.env.orders_cancel_submitted_cur = []

    def _generate_order(self):
        self._order_generator.run()

    def _check_order(self):
        self._checker.run()

    def _submit_order(self):
        # 先处理mkt, 已在checker中处理完成
        # 再处理trigger, 已在checker中处理完成
        # 再处理pending, 已在checker中处理完成
        # 再处理cancel
        self._process_cancel_order()

    def _judge_long_or_short(self, order):
        if order.action_type in [ActionType.Buy, ActionType.Sell]:
            return 'long'
        elif order.action_type in [ActionType.Short, ActionType.Cover]:
            return 'short'

    def _process_cancel_order(self):
        for cancel_order in self.env.orders_cancel_submitted_cur:
            ticker = cancel_order.ticker
            long_or_short = cancel_order.long_or_short

            if isinstance(cancel_order, CancelPendingOrder):
                for order in list(self.env.orders_pending):
                    confirm_ticker = order.ticker == ticker
                    confirm_long_short = self._judge_long_or_short(
                        order) == long_or_short

                    if confirm_ticker and confirm_long_short:
                        if cancel_order.is_target(order):
                            self.env.orders_pending.remove(order)

            elif isinstance(cancel_order, CancelTSTOrder):
                for order_list in self.env.orders_child_of_mkt_dict.values():
                    for order in list(order_list):
                        if cancel_order.is_target(order):
                            order_list.remove(order)

    @abc.abstractclassmethod
    def _required_cash_func(cls, order: MarketOrder):
        raise NotImplementedError

    def run(self):
        self._clear_submited_order()
        self._generate_order()
        self._check_order()
        self._submit_order()
Exemplo n.º 2
0
def global_setting():
    global go, strategy, order_generator
    CSVReader('./000001.csv', ticker=TICKER, fromdate=START, todate=END)
    strategy = DemoStrategy()
    StockBroker()
    StockRecorder().set_setting(initial_cash=100000,
                                comm=1,
                                comm_pct=None,
                                margin_rate=0.1)
    go = op.OnePiece()
    go._initialize_trading_system()
    go.market_maker.update_market()
    order_generator = OrderGenerator()
Exemplo n.º 3
0
class BrokerBase(OnePyEnvBase):
    def __init__(self):
        self.env.brokers.update({self.__class__.__name__: self})
        self._checker = None
        self._order_generator = OrderGenerator()

    def _clear_submited_order(self):
        self.env.orders_mkt_submitted = []

    def submit_order(self):
        pass

    def generate_order(self):
        self._order_generator.run()

    def run(self):
        self._clear_submited_order()
        self.generate_order()
        self.check_order()
        self.submit_order()

    def check_order(self):
        self._checker.run()
Exemplo n.º 4
0
def test_signals_orders():
    go = global_setting()
    strategy = go.env.strategies['DemoStrategy']
    go.market_maker.update_market()
    order_generator = OrderGenerator()
    go.env.execute_on_close_or_next_open = 'open'
    go.env.is_save_original = True

    CLOSE = go.env.feeds[TICKER].current_ohlc['close'] = 11
    HIGH = go.env.feeds[TICKER].current_ohlc['high'] = 20
    LOW = go.env.feeds[TICKER].current_ohlc['low'] = 5
    NEXT_OPEN = go.env.feeds[TICKER].next_ohlc['open'] = 10

    def test_buy(param_dict: dict, pct: bool):

        go.env.initialize_env()
        signal = strategy.buy(100, TICKER, **param_dict)

        assert signal in go.env.signals_normal
        assert signal in go.env.signals_normal_cur
        assert signal.action_type == ActionType.Buy

        order_generator.run()
        mkt_order = go.env.orders_mkt_normal_cur[0]
        assert mkt_order.signal is signal
        assert mkt_order.is_pure() is False
        assert mkt_order.first_cur_price == mkt_order.execute_price == NEXT_OPEN
        assert isinstance(mkt_order.signal, Signal)
        pending_orders = go.env.orders_child_of_mkt_dict[mkt_order.mkt_id]

        for order in pending_orders:
            assert order.action_type == ActionType.Sell

            if isinstance(order, geno.StopSellOrder):
                stop_sell = order
            elif isinstance(order, geno.LimitSellOrder):
                limit_sell = order
            elif isinstance(order, geno.TrailingStopSellOrder):
                trailingstop_sell = order
            else:
                raise Exception("This can't be raised")

        assert stop_sell.signal == limit_sell.signal == trailingstop_sell.signal
        assert stop_sell.mkt_id == limit_sell.mkt_id == trailingstop_sell.mkt_id

        if pct:
            assert stop_sell.trigger_key == 'stoploss_pct'
            assert limit_sell.trigger_key == 'takeprofit_pct'
            assert trailingstop_sell.trigger_key == 'trailingstop_pct'
            assert stop_sell.target_price == round(NEXT_OPEN * 0.9, 3)
            assert limit_sell.target_price == round(NEXT_OPEN * 1.1, 3)
            assert trailingstop_sell.initialize_latest_target_price() == round(
                NEXT_OPEN * 0.9, 3)
            assert NEXT_OPEN * 0.9 <= trailingstop_sell.target_price <= HIGH - NEXT_OPEN * 0.1
        else:
            assert stop_sell.trigger_key == 'stoploss'
            assert limit_sell.trigger_key == 'takeprofit'
            assert trailingstop_sell.trigger_key == 'trailingstop'
            assert stop_sell.target_price == NEXT_OPEN - 10 / 100
            assert limit_sell.target_price == NEXT_OPEN + 10 / 100
            assert trailingstop_sell.initialize_latest_target_price(
            ) == NEXT_OPEN - 10 / 100
            assert NEXT_OPEN - 10 / 100 <= trailingstop_sell.target_price <= HIGH - 10 / 100

    def test_short(param_dict: dict, pct: bool):

        go.env.initialize_env()
        signal = strategy.short(100, TICKER, **param_dict)

        assert signal in go.env.signals_normal
        assert signal in go.env.signals_normal_cur
        assert signal.action_type == ActionType.Short

        order_generator.run()
        mkt_order = go.env.orders_mkt_normal_cur[0]
        assert mkt_order.signal is signal
        assert mkt_order.is_pure() is False
        assert mkt_order.first_cur_price == mkt_order.execute_price == NEXT_OPEN
        assert isinstance(mkt_order.signal, Signal)
        pending_orders = go.env.orders_child_of_mkt_dict[mkt_order.mkt_id]

        for order in pending_orders:
            assert order.action_type == ActionType.Cover

            if isinstance(order, geno.StopCoverOrder):
                stop_cover_short = order
            elif isinstance(order, geno.LimitCoverOrder):
                limit_cover_short = order
            elif isinstance(order, geno.TrailingStopCoverOrder):
                trailingstop_cover_short = order
            else:
                raise Exception("This can't be raised")

        assert stop_cover_short.signal == limit_cover_short.signal == trailingstop_cover_short.signal
        assert stop_cover_short.mkt_id == limit_cover_short.mkt_id == trailingstop_cover_short.mkt_id

        if pct:
            assert stop_cover_short.trigger_key == 'stoploss_pct'
            assert limit_cover_short.trigger_key == 'takeprofit_pct'
            assert trailingstop_cover_short.trigger_key == 'trailingstop_pct'
            assert stop_cover_short.target_price == round(NEXT_OPEN * 1.1, 3)
            assert limit_cover_short.target_price == round(NEXT_OPEN * 0.9, 3)
            assert trailingstop_cover_short.initialize_latest_target_price(
            ) == round(NEXT_OPEN * 1.1, 3)

            if go.env.instrument == 'A_shares':  # A股要做跳高跳空成交处理
                OPEN = go.env.feeds[TICKER].current_ohlc['open'] = 15
                assert trailingstop_cover_short.target_price == OPEN
            else:
                assert LOW + NEXT_OPEN * 0.1 <= trailingstop_cover_short.target_price <= NEXT_OPEN * 1.1
        else:

            assert stop_cover_short.trigger_key == 'stoploss'
            assert limit_cover_short.trigger_key == 'takeprofit'
            assert trailingstop_cover_short.trigger_key == 'trailingstop'
            assert stop_cover_short.target_price == NEXT_OPEN + 10 / 100
            assert limit_cover_short.target_price == NEXT_OPEN - 10 / 100
            assert trailingstop_cover_short.initialize_latest_target_price() == NEXT_OPEN + \
                10/100

            if go.env.instrument == 'A_shares':  # A股要做跳高跳空成交处理
                OPEN = go.env.feeds[TICKER].current_ohlc['open'] = 15
                assert trailingstop_cover_short.target_price == OPEN
            else:
                assert LOW + 10 / 100 <= trailingstop_cover_short.target_price <= NEXT_OPEN + 10 / 100

    test_buy(
        dict(
            takeprofit=10,
            stoploss=10,  # 测试 Buy
            trailingstop=10),
        pct=False)

    test_buy(
        dict(
            takeprofit_pct=0.1,
            stoploss_pct=0.1,  # 测试 Buy  指令,带pct
            trailingstop_pct=0.1),
        pct=True)

    test_short(
        dict(
            takeprofit=10,
            stoploss=10,  # 测试 Short
            trailingstop=10),
        pct=False)

    test_short(
        dict(
            takeprofit_pct=0.1,
            stoploss_pct=0.1,  # 测试 Short 指令,带pct
            trailingstop_pct=0.1),
        pct=True)

    # 测试Sell
    go.env.initialize_env()
    signal = strategy.sell(100, TICKER)
    order_generator.run()
    mkt_order = go.env.orders_mkt_normal_cur[0]
    assert mkt_order.execute_price == NEXT_OPEN

    # 测试 Cover
    go.env.initialize_env()
    signal = strategy.cover(100, TICKER)
    order_generator.run()
    mkt_order = go.env.orders_mkt_normal_cur[0]
    assert mkt_order.execute_price == NEXT_OPEN

    def func_test_pending_order(order_func, order_class, param_dict,
                                target_price):
        go.env.initialize_env()
        signal = order_func(100, TICKER, **param_dict)
        assert signal.price == target_price
        order_generator.run()
        pending_order = go.env.orders_pending[0]
        assert isinstance(pending_order, order_class) is True
        assert pending_order.target_price == round(signal.price, 3)

    # 测试挂单 Buy
    func_test_pending_order(strategy.buy, geno.StopBuyOrder,
                            dict(price_pct=0.01), CLOSE * 1.01)
    func_test_pending_order(strategy.buy, geno.LimitBuyOrder,
                            dict(price_pct=-0.01), CLOSE * 0.99)
    func_test_pending_order(strategy.buy, geno.StopBuyOrder,
                            dict(price=CLOSE + 1), CLOSE + 1)
    func_test_pending_order(strategy.buy, geno.LimitBuyOrder,
                            dict(price=CLOSE - 1), CLOSE - 1)

    # 测试挂单Sell
    func_test_pending_order(strategy.sell, geno.LimitSellOrder,
                            dict(price_pct=0.01), CLOSE * 1.01)
    func_test_pending_order(strategy.sell, geno.StopSellOrder,
                            dict(price_pct=-0.01), CLOSE * 0.99)
    func_test_pending_order(strategy.sell, geno.LimitSellOrder,
                            dict(price=CLOSE + 1), CLOSE + 1)
    func_test_pending_order(strategy.sell, geno.StopSellOrder,
                            dict(price=CLOSE - 1), CLOSE - 1)

    # 测试挂单 Short
    func_test_pending_order(strategy.short, geno.LimitShortOrder,
                            dict(price_pct=0.01), CLOSE * 1.01)
    func_test_pending_order(strategy.short, geno.StopShortOrder,
                            dict(price_pct=-0.01), CLOSE * 0.99)
    func_test_pending_order(strategy.short, geno.LimitShortOrder,
                            dict(price=CLOSE + 1), CLOSE + 1)
    func_test_pending_order(strategy.short, geno.StopShortOrder,
                            dict(price=CLOSE - 1), CLOSE - 1)

    # 测试挂单 Cover
    func_test_pending_order(strategy.cover, geno.StopCoverOrder,
                            dict(price_pct=0.01), CLOSE * 1.01)
    func_test_pending_order(strategy.cover, geno.LimitCoverOrder,
                            dict(price_pct=-0.01), CLOSE * 0.99)
    func_test_pending_order(strategy.cover, geno.StopCoverOrder,
                            dict(price=CLOSE + 1), CLOSE + 1)
    func_test_pending_order(strategy.cover, geno.LimitCoverOrder,
                            dict(price=CLOSE - 1), CLOSE - 1)
Exemplo n.º 5
0
 def __init__(self):
     self.env.brokers.update({self.__class__.__name__: self})
     self._checker = SubmitOrderChecker(self._required_cash_func)
     self._order_generator = OrderGenerator()
Exemplo n.º 6
0
def test_pending_order_checker():
    go = global_setting()
    strategy = go.env.strategies['DemoStrategy']
    go.market_maker.update_market()
    order_generator = OrderGenerator()
    pending_order_checker = PendingOrderChecker()

    go.env.execute_on_close_or_next_open = 'open'

    CLOSE = go.env.feeds[TICKER].current_ohlc['close'] = 11
    HIGH = go.env.feeds[TICKER].current_ohlc['high'] = 20
    LOW = go.env.feeds[TICKER].current_ohlc['low'] = 5
    NEXT_OPEN = go.env.feeds[TICKER].next_ohlc['open'] = 10

    # 挂单带pending
    go.env.initialize_env()
    strategy.buy(100, TICKER, price=12, takeprofit_pct=0.01)

    order_generator.run()  # 提交订单到挂单
    assert len(go.env.orders_pending) == 1

    pending_order_checker.run()  # 触发mkt挂单生成信号
    assert len(go.env.orders_pending) == 0
    assert len(go.env.signals_trigger_cur) == 1
    assert len(go.env.orders_child_of_mkt_dict) == 0

    order_generator.run()  # mkt挂单信号生成为order
    assert len(go.env.orders_mkt_absolute_cur) == 1
    assert len(go.env.signals_trigger_cur) == 0
    assert len(go.env.orders_child_of_mkt_dict) == 1  # 伴随takeprofit挂单

    pending_order_checker.run()  # takeprofit触发生成信号
    assert len(go.env.signals_trigger_cur) == 1

    order_generator.run()  # takeprofit 信号生成为order
    assert len(go.env.orders_mkt_absolute_cur) == 2
    assert len(go.env.signals_trigger_cur) == 0
    assert go.env.orders_mkt_absolute_cur[0].execute_price == 12
    assert go.env.orders_mkt_absolute_cur[1].execute_price == round(
        12 * 1.01, 3)

    # 市价单带pending
    go.env.initialize_env()
    strategy.buy(100, TICKER, takeprofit_pct=0.01)

    order_generator.run()  # 生成市价单
    assert len(go.env.signals_trigger_cur) == 0
    assert go.env.orders_child_of_mkt_dict != {}
    assert len(go.env.orders_mkt_normal_cur) == 1

    pending_order_checker.run()  # 生成挂单触发信号
    assert go.env.orders_child_of_mkt_dict == {}
    assert len(go.env.signals_trigger_cur) == 1

    order_generator.run()  # 挂单信号成交并转化为order
    assert len(go.env.orders_mkt_absolute_cur) == 1
    assert go.env.orders_mkt_absolute_cur[-1].execute_price == round(
        NEXT_OPEN * 1.01, 3)
    assert len(go.env.signals_trigger_cur) == 0
    assert len(go.env.orders_mkt_absolute_cur) == 1
Exemplo n.º 7
0
 def __init__(self):
     self.env.brokers.update({self.__class__.__name__: self})
     self._checker = None
     self._order_generator = OrderGenerator()
def test_submit_order_checker():
    go = global_setting()
    strategy = go.env.strategies['DemoStrategy']
    go.market_maker.update_market()
    order_generator = OrderGenerator()
    order_checker = SubmitOrderChecker(StockBroker._required_cash_func)

    NEXT_OPEN = 10

    def settle_next_open():
        go.env.initialize_env()
        go.market_maker.initialize()
        go.market_maker.update_market()
        go.env.execute_on_close_or_next_open = 'open'
        go.env.feeds[TICKER].next_ohlc['open'] = NEXT_OPEN

    # 测试 缺少position
    settle_next_open()
    strategy.sell(100, TICKER)
    strategy.cover(100, TICKER)
    order_generator.run()
    order_checker.run()
    assert go.env.orders_mkt_submitted_cur == []

    # 测试 缺少cash
    settle_next_open()
    assert TICKER in go.env.tickers
    strategy.buy(100, TICKER)
    strategy.buy(100, TICKER)
    go.env.recorder.cash[-1]['value'] = NEXT_OPEN * 100
    order_generator.run()
    order_checker.run()
    assert len(go.env.orders_mkt_submitted_cur) == 1

    settle_next_open()
    strategy.buy(100, TICKER)
    strategy.buy(100, TICKER)
    go.env.recorder.cash[-1]['value'] = NEXT_OPEN * 100 - 1
    order_generator.run()
    order_checker.run()
    assert go.env.orders_mkt_submitted_cur == []

    settle_next_open()
    strategy.buy(100, TICKER)
    strategy.buy(100, TICKER)
    go.env.recorder.cash[-1]['value'] = NEXT_OPEN * 100 + 1
    order_generator.run()
    order_checker.run()
    assert len(go.env.orders_mkt_submitted_cur) == 1

    # 测试 partial 成交
    settle_next_open()
    strategy.sell(100, TICKER)
    strategy.cover(100, TICKER)
    long_po = go.env.recorder.position.data[f'{TICKER}_long'][-1]['value'] = 30
    short_po = go.env.recorder.position.data[f'{TICKER}_short'][-1][
        'value'] = 40
    order_generator.run()
    order_checker.run()
    assert len(go.env.orders_mkt_submitted_cur) == 2

    for order in go.env.orders_mkt_submitted_cur:
        if order.action_type == ActionType.Sell:
            assert order.size == long_po
        elif order.action_type == ActionType.Cover:
            assert order.size == short_po
        else:
            raise Exception("This can't be raised")