Пример #1
0
 def events(self, start_date, end_date, frequency):
     benchmark_symbol = self._env.config.base.benchmark
     for dt in self._env.get_calendar(benchmark_symbol, frequency, start_date, end_date):
         dt = dt.to_pydatetime()
         yield Event(EVENT.BEFORE_TRADING, calendar_dt=dt, trading_dt=dt)
         yield Event(EVENT.BAR, calendar_dt=dt, trading_dt=dt)
         yield Event(EVENT.AFTER_TRADING, calendar_dt=dt, trading_dt=dt)
         yield Event(EVENT.SETTLEMENT, calendar_dt=dt, trading_dt=dt)
Пример #2
0
 def submit_order(self, order):
     account = self._env.get_account_by_symbol(order.symbol)
     self._env.event_bus.publish_event(
         Event(EVENT.ORDER_PENDING_NEW, account=account, order=order))
     if order.is_final():
         return
     self._open_orders.append((account, order))
     order.active()
     self._env.event_bus.publish_event(
         Event(EVENT.ORDER_CREATION_PASS, account=account, order=order))
     self._match()
Пример #3
0
 def cancel_order(self, order):
     account = self._env.get_account_by_symbol(order.symbol)
     self._env.event_bus.publish_event(
         Event(EVENT.ORDER_PENDING_CANCEL, account=account, order=order))
     order.cancel("{order_id} order has been cancelled by user.").format(
         order_id=order.order_id)
     self._env.event_bus.publish_event(
         Event(EVENT.ORDER_CANCELLATION_PASS, account=account, order=order))
     try:
         self._open_orders.remove((account, order))
     except ValueError:
         pass
Пример #4
0
 def after_trading(self, event):
     for account, order in self._open_orders:
         order.reject(order.message +
                      " and {symbol} can not match. Market close.".format(
                          symbol=order.symbol))
         self._env.event_bus.publish_event(
             Event(EVENT.ORDER_UNSOLICITED_UPDATE,
                   account=account,
                   order=order))
Пример #5
0
    def _match(self, symbol=None):
        open_orders = self._open_orders
        if symbol is not None:
            open_orders = [(a, o) for (a, o) in self._open_orders
                           if o.symbol == symbol]
        self._matcher.match(open_orders)
        final_orders = [(a, o) for a, o in self._open_orders if o.is_final()]
        self._open_orders = [(a, o) for a, o in self._open_orders
                             if not o.is_final()]

        for account, order in final_orders:
            if order.status == ORDER_STATUS.REJECTED or order.status == ORDER_STATUS.CANCELLED:
                self._env.event_bus.publish_event(
                    Event(EVENT.ORDER_UNSOLICITED_UPDATE,
                          account=account,
                          order=order))
Пример #6
0
    def match(self, open_orders):
        for account, order in open_orders:
            symbol = order.symbol
            last_price = self._env.get_last_price(symbol)

            deal_price = order.price if order.type == ORDER_TYPE.LIMIT else last_price
            deal_price = self._slippage_decider.get_trade_price(
                account.type, order.side, deal_price)

            if order.type == ORDER_TYPE.LIMIT:
                if order.side == SIDE.BUY:
                    if deal_price < last_price:
                        order.message = 'Rejected [{order_price} < {last_price}]:order price too low < last price' \
                            .format(order_price=deal_price, last_price=last_price)
                        continue
                    elif account.cash < order.amount * deal_price:
                        order.message = 'Rejected [{cash} < {need_cash}] not enough cash' \
                            .format(cash=account.cash, need_cash=order.amount * deal_price)
                        continue
                if order.side == SIDE.SELL:
                    if deal_price > last_price:
                        order.message = 'Rejected [{order_price} > {last_price}]:order price too high > last price' \
                            .format(order_price=deal_price, last_price=last_price)
                        continue
                    elif account.positions[order.symbol].amount < order.amount:
                        order.message = 'Rejected [{amount} < {order_amount}]: not enough amount' \
                            .format(amount=account.positions[order.symbol].amount, order_amount=order.amount)
                        continue

            trade = Trade.create_trade(
                order_id=order.order_id,
                symbol=order.symbol,
                side=order.side,
                price=deal_price,
                frozen_price=order.price,
                amount=order.unfilled_amount,
                fee=order.fee,
            )
            order.fill(trade)
            self._env.event_bus.publish_event(
                Event(EVENT.TRADE, account=account, trade=trade, order=order))
Пример #7
0
def run(config, kwargs):
    user_funcs = {
        'init': kwargs.init,
        'handle_bar': kwargs.handle_bar,
        'before_trading': kwargs.before_trading,
        'after_trading': kwargs.after_trading,
    }
    env = Environment(config)
    mod_handler = ModHandler(env)
    mod_handler.start()
    _adjust_env(env)
    try:
        context = Context()
        env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT))
        strategy = Strategy(env.event_bus, user_funcs, context)
        strategy.init()
        Executor(env).run()

        result = mod_handler.stop(const.EXIT_CODE.EXIT_SUCCESS)
        return result
    except Exception as e:
        sys_log.error(util.error_msg())
Пример #8
0
 def before_trading(self, event):
     for account, order in self._open_orders:
         order.active()
         self._env.event_bus.publish_event(
             Event(EVENT.ORDER_CREATION_PASS, account=account, order=order))
Пример #9
0
 def init(self):
     if not self._init:
         return
     self._init(self._user_context)
     Environment.get_instance().event_bus.publish_event(
         Event(EVENT.POST_USER_INIT))
Пример #10
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author = 'wyx'
@time = 2017/5/24 11:43
@annotation = ''
"""
from quant.events import Event, EVENT

PRE_BEFORE_TRADING = Event(EVENT.PRE_BEFORE_TRADING)
POST_BEFORE_TRADING = Event(EVENT.POST_BEFORE_TRADING)
PRE_BAR = Event(EVENT.PRE_BAR)
POST_BAR = Event(EVENT.POST_BAR)
PRE_AFTER_TRADING = Event(EVENT.PRE_AFTER_TRADING)
POST_AFTER_TRADING = Event(EVENT.POST_AFTER_TRADING)
PRE_SETTLEMENT = Event(EVENT.PRE_SETTLEMENT)
POST_SETTLEMENT = Event(EVENT.POST_SETTLEMENT)


class Executor(object):
    def __init__(self, env):
        self._env = env

    KNOWN_EVENTS = {
        EVENT.BAR,
        EVENT.BEFORE_TRADING,
        EVENT.AFTER_TRADING,
        EVENT.POST_SETTLEMENT,
    }

    def run(self):