Esempio n. 1
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
Esempio n. 2
0
def test_signals_list():
    go = global_setting()
    go.env.is_save_original = True
    strategy = go.env.strategies['DemoStrategy']
    normal = strategy.buy(100, TICKER)
    pending = strategy.buy(100, TICKER, price=20)
    cancel_pending = strategy.cancel_pending(TICKER, 'long', 10)
    cancel_tst = strategy.cancel_tst(TICKER, 'long', True)
    assert normal in go.env.signals_normal
    assert pending in go.env.signals_pending
    assert cancel_pending in go.env.signals_cancel
    assert cancel_tst in go.env.signals_cancel

    assert normal in go.env.signals_normal_cur
    assert pending in go.env.signals_pending_cur
    assert cancel_pending in go.env.signals_cancel_cur
    assert cancel_tst in go.env.signals_cancel_cur
Esempio n. 3
0
def test_cancel_tst_order():
    go = global_setting()
    go.env.is_save_original = True
    strategy = go.env.strategies['DemoStrategy']
    broker = go.env.brokers['StockBroker']

    def func_cancel_tst(long_or_short, order_params: dict):
        broker.run()
        assert len(go.env.orders_mkt_submitted_cur) == 1
        mkt_id = go.env.orders_mkt_submitted_cur[0].mkt_id
        assert len(go.env.orders_child_of_mkt_dict[mkt_id]) == 1
        strategy.cancel_tst(TICKER, long_or_short, **order_params)
        broker.run()
        assert len(go.env.orders_child_of_mkt_dict[mkt_id]) == 0

    strategy.buy(100, TICKER, takeprofit=30)
    func_cancel_tst("long", dict(takeprofit=True))
    strategy.buy(100, TICKER, stoploss=30)
    func_cancel_tst("long", dict(stoploss=True))
    strategy.buy(100, TICKER, trailingstop=30)
    func_cancel_tst("long", dict(trailingstop=True))
    strategy.buy(100, TICKER, takeprofit_pct=0.01)
    func_cancel_tst("long", dict(takeprofit=True))
    strategy.buy(100, TICKER, stoploss_pct=0.01)
    func_cancel_tst("long", dict(stoploss=True))
    strategy.buy(100, TICKER, trailingstop_pct=0.01)
    func_cancel_tst("long", dict(trailingstop=True))

    strategy.short(100, TICKER, takeprofit=30)
    func_cancel_tst("short", dict(takeprofit=True))
    strategy.short(100, TICKER, stoploss=30)
    func_cancel_tst("short", dict(stoploss=True))
    strategy.short(100, TICKER, trailingstop=30)
    func_cancel_tst("short", dict(trailingstop=True))
    strategy.short(100, TICKER, takeprofit_pct=0.01)
    func_cancel_tst("short", dict(takeprofit=True))
    strategy.short(100, TICKER, stoploss_pct=0.01)
    func_cancel_tst("short", dict(stoploss=True))
    strategy.short(100, TICKER, trailingstop_pct=0.01)
    func_cancel_tst("short", dict(trailingstop=True))
Esempio n. 4
0
def test_cancel_pending_order():
    go = global_setting()
    go.env.is_save_original = True
    strategy = go.env.strategies['DemoStrategy']

    def func_cancel_pending(order_func, long_or_short):
        go.env.initialize_env()
        order_func(100, TICKER, price=30)
        order_func(100, TICKER, price=10)
        order_func(100, TICKER, price=2)
        broker = go.env.brokers['StockBroker']
        broker.run()
        assert len(go.env.orders_pending) == 3
        strategy.cancel_pending(TICKER, long_or_short, above_price=20)
        strategy.cancel_pending(TICKER, long_or_short, below_price=3)
        broker.run()
        assert len(go.env.orders_cancel_submitted_cur) == 2
        assert len(go.env.orders_pending) == 1

    func_cancel_pending(strategy.buy, 'long')
    func_cancel_pending(strategy.sell, 'long')
    func_cancel_pending(strategy.short, 'short')
    func_cancel_pending(strategy.cover, 'short')
Esempio n. 5
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)
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")