def on_market_prepare_open(self, protfolio: Portfolio, today: datetime): """ 市场准备开始(比如:竞价). """ indicator = Indicator(40) for code in self.codes: bars = self.market.getHistory().getKbars(code, 100) indicator.update_bar(bars) count = 20 aroon_down, aroon_up = indicator.aroon(count) need_hold = aroon_up > 50 and aroon_up > aroon_down position = protfolio.getLongPosition(code) if need_hold: if position.pos_total < 1: targetPrice = bars[-1].close_price * 1.05 # 上一个交易日的收盘价作为买如价 ok = protfolio.buyAtPercentage(code, targetPrice, 1) print(f"buy: price = {targetPrice} , {ok}") else: if position.pos_total > 0: targetPrice = bars[-1].close_price * 0.92 # 上一个交易日的收盘价作为买如价 ok = protfolio.sellAll(code, targetPrice) print(f"sell: price = {targetPrice} , {ok}") pass
def getValues(self, indicator: Indicator,bar:BarData,signal:Signal) -> Map: values = {} count = 15 if indicator.count >= count: aroon_down,aroon_up = indicator.aroon(count,True) values["arron_up_25"] = aroon_up[-1] values["arron_down_25"] = aroon_down[-1] need_hold = aroon_up[-1] > 50 and aroon_up[-1] > aroon_down[-1] if need_hold: if not signal.hasBuy: signal.buy = True # print(f"{bar.datetime}: 买: price:{bar.close_price * 1.01}") else: if( signal.hasBuy): signal.sell = True #print(f"{bar.datetime}: 卖: price:{bar.close_price * 0.99}") else: values["arron_up_25"] = 50 values["arron_down_25"] = 50 return values
def getValues(self, indicator: Indicator, bar: BarData, signal: Signal) -> Map: values = {} if indicator.count >= 25: aroon_down, aroon_up = indicator.aroon(25, True) values["arron_up_25"] = aroon_up[-1] values["arron_down_25"] = aroon_down[-1] need_hold = aroon_up[-1] > 50 and aroon_up[-1] > aroon_down[-1] if need_hold: if self.has_bug == False: signal.buy = True self.has_bug = True else: if (self.has_bug == True): signal.sell = True self.has_bug = False else: values["arron_up_25"] = 50 values["arron_down_25"] = 50 return values
class KDJMovementEngineModel(CoreEngineModel): def __init__(self): self.lasted15Bar = np.array([ None, None, None, None, None, None, None, None, None, None, None, None, None, None, None ]) self.lasted3BarKdj = np.array([None, None, None]) self.lasted3BarMacd = np.array([None, None, None]) self.lasted3BarArron = np.array([None, None]) self.kdjEncoder = FloatEncoder([15, 30, 45, 60, 75, 90]) self.mDateOccurCountMap = {} ##统计产生收集个数的次数 self.sw = SWImpl() def onCollectStart(self, code: str) -> bool: from earnmi.chart.Indicator import Indicator self.indicator = Indicator(34) self.code = code return True def onCollectTrace(self, bar: BarData) -> CollectData: self.indicator.update_bar(bar) self.lasted15Bar[:-1] = self.lasted15Bar[1:] self.lasted3BarKdj[:-1] = self.lasted3BarKdj[1:] self.lasted3BarMacd[:-1] = self.lasted3BarMacd[1:] self.lasted3BarArron[:-1] = self.lasted3BarArron[1:] k, d, j = self.indicator.kdj(fast_period=9, slow_period=3) dif, dea, mBar = self.indicator.macd(fast_period=12, slow_period=26, signal_period=9) aroon_down, aroon_up = self.indicator.aroon(n=14) self.lasted15Bar[-1] = bar self.lasted3BarKdj[-1] = [k, d, j] self.lasted3BarMacd[-1] = [dif, dea, mBar] self.lasted3BarArron[-1] = [aroon_down, aroon_up] if self.indicator.count <= 15: return None #最近15天之内不含停牌数据 if not BarUtils.isAllOpen(self.lasted15Bar): return None #交易日天数间隔超过5天的数据 if BarUtils.getMaxIntervalDay(self.lasted15Bar) >= 5: return None timeKey = utils.to_start_date(bar.datetime) if self.mDateOccurCountMap.get(timeKey) is None: self.mDateOccurCountMap[timeKey] = 0 if self.indicator.count >= 30: k0, d0, j0 = self.lasted3BarKdj[-2] k1, d1, j1 = self.lasted3BarKdj[-1] #金叉产生 goldCross = k0 < d0 and k1 >= d1 if not goldCross: return None kPatternValue = KPattern.encode3KAgo1(self.indicator) if not kPatternValue is None: self.mDateOccurCountMap[timeKey] += 1 dimen = Dimension(type=TYPE_2KAGO1, value=kPatternValue) collectData = CollectData(dimen=dimen) collectData.occurBars = list(self.lasted15Bar[-3:]) collectData.occurKdj = list(self.lasted3BarKdj) collectData.occurExtra['lasted3BarMacd'] = self.lasted3BarMacd collectData.occurExtra[ 'lasted3BarArron'] = self.lasted3BarArron return collectData return None def onCollect(self, data: CollectData, newBar: BarData): #不含停牌数据 if not BarUtils.isOpen(newBar): data.setValid(False) return data.predictBars.append(newBar) size = len(data.predictBars) if size >= 5: data.setFinished() def getYLabelPct(self, cData: CollectData) -> [float, float]: if len(cData.predictBars) < 5: #不能作为y标签。 return None, None bars: ['BarData'] = cData.predictBars basePrice = self.getYBasePrice(cData) highIndex = 0 lowIndex = 0 highBar = cData.predictBars[0] lowBar = cData.predictBars[0] sell_pct = 100 * ((highBar.high_price + highBar.close_price) / 2 - basePrice) / basePrice buy_pct = 100 * ((lowBar.low_price + lowBar.close_price) / 2 - basePrice) / basePrice for i in range(1, len(cData.predictBars)): bar: BarData = cData.predictBars[i] _s_pct = 100 * ( (bar.high_price + bar.close_price) / 2 - basePrice) / basePrice _b_pct = 100 * ( (bar.low_price + bar.close_price) / 2 - basePrice) / basePrice if _s_pct > sell_pct: sell_pct = _s_pct highIndex = i if _b_pct < buy_pct: buy_pct = _b_pct lowIndex = i return sell_pct, buy_pct def getYBasePrice(self, cData: CollectData) -> float: ##以金叉发生的当前收盘价作为基准值。 return cData.occurBars[-2].close_price def generateXFeature(self, cData: CollectData) -> []: #保证len小于三,要不然就不能作为生成特征值。 if (len(cData.occurBars) < 3): return None basePrcie = self.getYBasePrice(cData) ##使用随机森林,所以不需要标准化和归一化 goldCrossBar = cData.occurBars[-2] god_cross_dif, god_cross_dea, god_cross_macd = cData.occurExtra.get( 'lasted3BarMacd')[-2] god_cross_dif = 100 * god_cross_dif / basePrcie god_cross_dea = 100 * god_cross_dea / basePrcie k, d, j = cData.occurKdj[-2] def getSellBuyPct(bar: BarData): s_pct = 100 * ( (bar.high_price + bar.close_price) / 2 - basePrcie) / basePrcie b_pct = 100 * ( (bar.low_price + bar.close_price) / 2 - basePrcie) / basePrcie return s_pct, b_pct s_pct_1, b_pct_1 = getSellBuyPct(cData.occurBars[-3]) s_pct_2, b_pct_2 = getSellBuyPct(cData.occurBars[-2]) s_pct_3, b_pct_3 = getSellBuyPct(cData.occurBars[-1]) data = [] data.append(god_cross_dif) data.append(god_cross_dea) data.append(k) data.append(d) data.append(s_pct_1) data.append(b_pct_1) data.append(s_pct_2) data.append(b_pct_2) data.append(s_pct_3) data.append(b_pct_3) return data
class TheEngineModel(CoreEngineModel): def __init__(self): self.lasted3Bar = np.array([None, None, None]) self.lasted3BarKdj = np.array([None, None, None]) self.kdjEncoder = FloatEncoder([15, 30, 45, 60, 75, 90]) self.mDateOccurCountMap = {} ##统计产生收集个数的次数 self.sw = SWImpl() def onCollectStart(self, code: str) -> bool: from earnmi.chart.Indicator import Indicator self.indicator = Indicator(34) self.code = code return True def onCollectTrace(self, bar: BarData) -> CollectData: self.indicator.update_bar(bar) self.lasted3Bar[:-1] = self.lasted3Bar[1:] self.lasted3BarKdj[:-1] = self.lasted3BarKdj[1:] k, d, j = self.indicator.kdj(fast_period=9, slow_period=3) self.lasted3Bar[-1] = bar self.lasted3BarKdj[-1] = [k, d, j] timeKey = utils.to_start_date(bar.datetime) if self.mDateOccurCountMap.get(timeKey) is None: self.mDateOccurCountMap[timeKey] = 0 if self.indicator.count >= 30: aroon_down, aroon_up = self.indicator.aroon(n=14, array=False) from earnmi.chart.KPattern import KPattern if aroon_up < aroon_down or aroon_up < 50: return None kPatternValue = KPattern.encode2KAgo1(self.indicator) if not kPatternValue is None: self.mDateOccurCountMap[timeKey] += 1 _kdj_mask = self.kdjEncoder.mask() kPatternValue = kPatternValue * _kdj_mask * _kdj_mask + self.kdjEncoder.encode( k) * _kdj_mask + self.kdjEncoder.encode(d) dimen = Dimension(type=TYPE_2KAGO1, value=kPatternValue) collectData = CollectData(dimen=dimen) collectData.occurBars.append(self.lasted3Bar[-2]) collectData.occurBars.append(self.lasted3Bar[-1]) collectData.occurKdj.append(self.lasted3BarKdj[-2]) collectData.occurKdj.append(self.lasted3BarKdj[-1]) return collectData return None def onCollect(self, data: CollectData, newBar: BarData) -> bool: if len(data.occurBars) < 3: data.occurBars.append(self.lasted3Bar[-1]) data.occurKdj.append(self.lasted3BarKdj[-1]) else: data.predictBars.append(newBar) size = len(data.predictBars) return size >= 2 @abstractmethod def getYLabelPrice(self, cData: CollectData) -> [float, float, float]: bars: ['BarData'] = cData.predictBars if len(bars) > 0: sell_price = -9999999999 buy_price = -sell_price for bar in bars: sell_price = max((bar.high_price + bar.close_price) / 2, sell_price) buy_price = min((bar.low_price + bar.close_price) / 2, buy_price) return sell_price, buy_price return None, None def getYBasePrice(self, cData: CollectData) -> float: return cData.occurBars[-2].close_price def generateXFeature(self, cData: CollectData) -> []: #保证len小于三,要不然就不能作为生成特征值。 if (len(cData.occurBars) < 3): return None occurBar = cData.occurBars[-2] skipBar = cData.occurBars[-1] kdj = cData.occurKdj[-1] sell_pct = 100 * ((skipBar.high_price + skipBar.close_price) / 2 - occurBar.close_price) / occurBar.close_price buy_pct = 100 * ((skipBar.low_price + skipBar.close_price) / 2 - occurBar.close_price) / occurBar.close_price def set_0_between_100(x): if x > 100: return 100 if x < 0: return 0 return x def percent_to_one(x): return int(x * 100) / 1000.0 data = [] data.append(percent_to_one(buy_pct)) data.append(percent_to_one(sell_pct)) data.append(set_0_between_100(kdj[0]) / 100) data.append(set_0_between_100(kdj[2]) / 100) return data