def on_bar_per_minute(self, time: datetime, protfolio: Portfolio): """ 市场开市后的每分钟。 """ #每天两点半的后尝试去做交易。 if time.hour == 14 and time.minute == 30: self.__history_bar100 = self.market.getHistory().getKbars( self.code, 100) assert len(self.__history_bar100) == 100 bars = self.__history_bar100 todayBar = self.market.getRealTime().getKBar(self.code) indicator = Indicator(40) indicator.update_bar(bars) dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True) if (not self.today_has_buy): # 预测金叉 todayBar.close_price = todayBar.close_price * 1.01 indicator.update_bar(todayBar) dif, dea, predict_macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True) print( f"[{self.market.getToday()}]:bar={macd_bar[-1]},predic_bar={predict_macd_bar[-1]}" ) if (predict_macd_bar[-1] > 0 and macd_bar[-1] <= 0): targetPrice = todayBar.close_price # 上一个交易日的收盘价作为买如价 print(f" gold cross!!!") if protfolio.buy(self.code, targetPrice, 100): self.today_has_buy = True elif (not self.today_has_sell): todayBar.close_price = todayBar.close_price * 0.99 indicator.update_bar(todayBar) dif, dea, predict_macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True) print( f"[{self.market.getToday()}]:bar={macd_bar[-1]},predic_bar={predict_macd_bar[-1]}" ) if (predict_macd_bar[-1] <= 0 and macd_bar[-1] > 0): targetPrice = todayBar.close_price print(f" dead cross!!!") if protfolio.sell(self.code, targetPrice, 100): self.today_has_sell = True
def getValues(self, indicator: Indicator,bar:BarData,signal:Signal) -> Map: values = {} count = 30 if indicator.count >= count: dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True); ##金叉出现 if (macd_bar[-1] >= 0 and macd_bar[-2] <= 0): if not signal.hasBuy: signal.buy = True ##死叉出现 if (macd_bar[-1] <= 0 and macd_bar[-2] >= 0): if signal.hasBuy: signal.sell = True return values
def computeAndPrint(bars: []) -> AnalysisData: data = AnalysisData() total_count = len(bars) previous_macd = -1 previouc_kdj = -1 indicator = Indicator(50) for i in range(0, total_count): bar: BarData = bars[i] indicator.update_bar(bar) k_large_than_d = False if indicator.count >= 13: k, d, j = indicator.kdj(fast_period=9, slow_period=3, array=True) k_large_than_d = k[-1] >= d[-1] ##金叉出现 if (k[-1] >= d[-1] and k[-2] <= d[-2]): previouc_kdj = i if indicator.count >= 30: dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True) ##金叉出现 if (macd_bar[-1] >= 0 and macd_bar[-2] <= 0): previous_macd = i if previouc_kdj > 0: data.count = data.count + 1 if k_large_than_d: data.k_large_than_d_count = data.k_large_than_d_count + 1 dis = previous_macd - previouc_kdj if (dis >= 0 and dis < KDJ_DIS_SIZE): data.kdj_dis[dis] = data.kdj_dis[dis] + 1 return data
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) dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=True); ##金叉出现 if (macd_bar[-1] >= 0 and macd_bar[-2] <= 0): tradePrice = bars[-1].close_price * 1.01 # 上一个交易日的收盘价作为买如价 protfolio.buy(code, tradePrice, 1) protfolio.cover(code,tradePrice,1) ##平仓做空 ##死叉出现 if (macd_bar[-1] <= 0 and macd_bar[-2] >=0): targetPrice = bars[-1].close_price * 0.99 # 上一个交易日的收盘价作为买如价 protfolio.sell(code, targetPrice, 1) protfolio.short(code, targetPrice, 1) ##开仓做空 pass
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
def generateSWTrainData(kPatterns: [], start: datetime, end: datetime) -> pd.DataFrame: sw = SWImpl() lists = sw.getSW2List() cloumns = [ "code", "name", "kPattern", "k", "d", "dif", "dea", "macd", "open", "short", "long" ] datas = [] kPatternMap = {} for kPatternValues in kPatterns: kPatternMap[kPatternValues] = True macd_list = [] for code in lists: # for code in lists: name = sw.getSw2Name(code) barList = sw.getSW2Daily(code, start, end) indicator = Indicator(34) preBar = None for bar in barList: ##先识别形态 kEncodeValue = None if indicator.inited: tmpKEncodeValue = KPattern.encode3KAgo1(indicator) if kPatternMap.__contains__(tmpKEncodeValue): kEncodeValue = tmpKEncodeValue if kEncodeValue is None: indicator.update_bar(bar) preBar = bar continue ##昨天的kdj k, d, j = indicator.kdj(array=False) dif, dea, macd = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=False) ##第二天的收益 short_pct = 100 * ((bar.high_price + bar.close_price) / 2 - preBar.close_price) / preBar.close_price long_pct = 100 * ((bar.low_price + bar.close_price) / 2 - preBar.close_price) / preBar.close_price open_pct = 100 * (bar.open_price - preBar.close_price) / preBar.close_price item = [] item.append(code) item.append(name) item.append(kEncodeValue) item.append(k) item.append(d) item.append(dif) item.append(dea) item.append(macd) #下个k线数据 item.append(open_pct) item.append(short_pct) item.append(long_pct) datas.append(item) macd_list.append(macd) indicator.update_bar(bar) preBar = bar macd_list = np.array(macd_list) print( f"total size : {len(datas)},mean ={macd_list.mean()},max={macd_list.max()},min={macd_list.min()}" ) wxl = pd.DataFrame(datas, columns=cloumns) return wxl
标准化的步骤就是: macd值处于最后一天的收盘价。 这里统计下中证500的macd标准化之后的数据统计情况 """ if __name__ == "__main__": start = datetime(2015, 10, 1) end = datetime(2020, 9, 30) souces = ZZ500DataSource(start, end) bars,code = souces.nextBars() dif_list = [] dea_list = [] while not bars is None: indicator = Indicator(40) for bar in bars: indicator.update_bar(bar) if indicator.count > 33: dif, dea, macd_bar = indicator.macd(fast_period=12, slow_period=26, signal_period=9, array=False) dif_value = dif/bar.close_price * 100 dea_value = dea / bar.close_price * 100 dif_list.append(dif_value) dea_list.append(dea_value) if abs(dif_value) > 20: print(f"dif:{dif_value},code={code},bar = {bar}") if abs(dea_value) > 20: print(f"dea:{dea_value},code={code},bar = {bar}") bars, code = souces.nextBars() dif_list = np.array(dif_list) dea_list = np.array(dea_list) def_min,def_max = [dea_list.min(),dea_list.max()] dif_min,dif_max = [dif_list.min(),dif_list.max()] print(f"dif_max:{dif_max},dif_min:{dif_min},count:{len(dif_list)}")