def init(context): # 在context中保存全局变量 context.s1 = "同花顺.AGUSDO" # 实时打印日志 logger.info("RunInfo: {}".format(context.run_info)) # 设置这个策略当中会用到的参数,在策略中可以随时调用,这个策略使用长短均线,我们在这里设定长线和短线的区间,在调试寻找最佳区间的时候只需要在这里进行数值改动 context.SHORTPERIOD = 20 context.LONGPERIOD = 120
def deposit_withdraw(self, account_type, amount): """出入金""" # 入金 现金增加,份额增加,总权益增加,单位净值不变 # 出金 现金减少,份额减少,总权益减少,单位净值不变 if account_type not in self._accounts: raise ValueError(_("invalid account type {}, choose in {}".format(account_type, list(self._accounts.keys())))) unit_net_value = self.unit_net_value self._accounts[account_type].deposit_withdraw(amount) _units = self.total_value / unit_net_value user_log.info(_("Cash add {}. units {} become to {}".format(amount, self._units ,_units))) self._units = _units
def get_stock_data_from_mongo(self, code, cyc_type): """ :param str code: WindCode :param cyc_type: Type from CycType :return: numpy.ndarray """ logger.info('Load data from MongoDB: Code = {}, CycType = {}'.format( code, cyc_type)) cursor = self.db[get_col_name(code)].find({ 'cycType': cyc_type }, { '_id': False, 'date': True, 'open': True, 'close': True, 'high': True, 'low': True, 'volume': True, 'amount': True }).sort("date", pymongo.ASCENDING) pre_close = np.round(cursor.next()['close'], CONVERTER['close'].round) data_num = cursor.count() dtype = np.dtype([(f, FIELDS[f]) for f in FIELDS.keys()]) bars = np.zeros(shape=(data_num, ), dtype=dtype) i = 0 for doc in cursor: if cyc_type == CycType.CYC_DAY: bars[i]['datetime'] = convert_date_to_int(doc['date']) bars[i]['limit_up'] = np.round( np.floor(pre_close * 11000) / 10000, CONVERTER['limit_up'].round) bars[i]['limit_down'] = np.round( np.ceil(pre_close * 9000) / 10000, CONVERTER['limit_down'].round) elif cyc_type == CycType.CYC_MINUTE: bars[i]['datetime'] = convert_dt_to_int(doc['date']) else: raise NotImplementedError bars[i]['open'] = np.round(doc['open'], CONVERTER['open'].round) bars[i]['close'] = np.round(doc['close'], CONVERTER['close'].round) bars[i]['high'] = np.round(doc['high'], CONVERTER['high'].round) bars[i]['low'] = np.round(doc['low'], CONVERTER['low'].round) bars[i]['volume'] = doc['volume'] bars[i]['total_turnover'] = doc['amount'] pre_close = doc['close'] i += 1 logger.info( 'Load data from MongoDB finished: Code = {}, CycType = {}'.format( code, cyc_type)) return bars
def _submit_by_trade(self, trade): if self._is_expired(trade): user_log.info('[实盘易] 委托已过期,忽略下单请求') return try: price_type = 0 if trade.order.type == ORDER_TYPE.LIMIT else 4 order = trade.order actual_order = self._shipane_client.execute( self._mod_config.client, action=order.side.name, symbol=order.order_book_id, type=order.type.name, priceType=price_type, price=order.price, amount=trade.last_quantity) return actual_order except Exception as e: user_log.error("[实盘易] 下单异常:" + str(e))
def handle_bar(context, bar_dict): close = FinanceDataMining_DataSource.get_bar(context.s1, bar_dict.dt, "1d")['Close'] # 因为策略需要用到均线,所以需要读取历史数据 prices = FinanceDataMining_DataSource.history_bars(context.s1, "1d", "Close", bar_dict.dt) if prices is None: return # 使用talib计算长短两根均线,均线以array的格式表达 short_avg = talib.SMA(prices, context.SHORTPERIOD) long_avg = talib.SMA(prices, context.LONGPERIOD) # 计算现在portfolio中股票的仓位 # 要有一个判断是否存在这个股票的 cur_position = 0 if context.s1 in context.portfolio.positions: cur_position = context.portfolio.positions[context.s1].quantity # 计算现在portfolio中的现金可以购买多少股票 shares = context.portfolio.cash / close # 如果短均线从上往下跌破长均线,也就是在目前的bar短线平均值低于长线平均值,而上一个bar的短线平均值高于长线平均值 if short_avg[-1] - long_avg[-1] < 0 and short_avg[-2] - long_avg[ -2] > 0 and cur_position > 0: # 进行清仓 logger.info("进行清仓") order_target_value(context.s1, 0) # 如果短均线从下往上突破长均线,为入场信号 if short_avg[-1] - long_avg[-1] > 0 and short_avg[-2] - long_avg[-2] < 0: # 满仓入股 logger.info("10分之一仓入股") import ipdb ipdb.set_trace() # XXX BREAKPOINT order_shares(context.s1, int(shares / 10), close)
def _submit_by_order(self, order): """ 对于 响应 ORDER_CREATION_PASS 事件,已经经过了事前风控,所以比如资金不足,下单手数为0等无效订单已经排除,这里不需要额外处理。 :param order: :return: """ if self._is_expired(order): user_log.info('[实盘易] 委托已过期,忽略下单请求') return try: price_type = 0 if order.type == ORDER_TYPE.LIMIT else 4 actual_order = self._shipane_client.execute( self._mod_config.client, action=order.side.name, symbol=order.order_book_id, type=order.type.name, priceType=price_type, price=order.price, amount=order.quantity) self._order_id_map[order.order_id] = actual_order['id'] return actual_order except Exception as e: user_log.error("[实盘易] 下单异常:" + str(e))
def after_trading(context): logger.info("开盘前执行after_trading函数")
def before_trading(context): logger.info("开盘前执行before_trading函数")