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)
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()
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
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))
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))
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))
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())
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))
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))
#!/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):