def test_czsc_trader(): bars = read_1min() kg = KlineGenerator(max_count=3000, freqs=['1分钟', '5分钟', '15分钟', '30分钟', '60分钟', '日线']) for row in tqdm(bars[:-10000], desc='init kg'): kg.update(row) events = [ Event(name="开多", operate=Operate.LO, factors=[ Factor(name="5分钟三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), ]), Event(name="平多", operate=Operate.LE, factors=[ Factor(name="1分钟一卖", signals_all=[Signal("1分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="5分钟一卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="5分钟二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="5分钟三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]) ]), ] ct = CzscTrader(op_freq=Freq.F5, kg=kg, get_signals=get_default_signals, events=events) assert len(ct.s) == 215 for row in bars[-10000:]: op = ct.check_operate(row) print(" : op : ", op) print(" : cache : ", dict(ct.cache), "\n") assert len(ct.s) == 215
def get_event(): event = Event(name="选股测试", operate=Operate.LO, factors=[ Factor(name="月线KDJ金叉_日线MACD强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_MACD状态_任意_DIFF大于0_DEA大于0_柱子增大_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), Factor(name="月线KDJ金叉_日线潜在三买", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_倒0笔_潜在三买_构成中枢_近3K在中枢上沿附近_近7K突破中枢GG_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), ]) return event
def is_third_buy(symbol): """判断一个股票现在是否有日线三买""" bars = get_kline(symbol, freq="D", end_date=datetime.now(), count=1000) c = CZSC(bars, get_signals=get_default_signals) factor_ = Factor( name="类三买选股因子", signals_any=[ Signal("日线_倒1笔_基础形态_类三买_任意_任意_0"), Signal("日线_倒1笔_类买卖点_类三买_任意_任意_0"), ], signals_all=[ Signal("日线_倒1笔_拟合优度_小于0.2_任意_任意_0") ] ) if factor_.is_match(c.signals): return True else: return False
def stocks_dwm_selector_rt(context): if context.now.isoweekday() >= 6: return event = Event( name="选股", operate=Operate.LO, factors=[ Factor(name="月线KDJ金叉_日线MACD强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_MACD状态_任意_DIFF大于0_DEA大于0_柱子增大_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), Factor(name="月线KDJ金叉_日线潜在三买", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_倒0笔_潜在三买_构成中枢_近3K在中枢上沿附近_近7K突破中枢GG_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), Factor(name="月线KDJ金叉_周线三笔强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ], signals_any=[ Signal('周线_倒1笔_三笔形态_向下不重合_任意_任意_0'), Signal('周线_倒1笔_三笔形态_向下奔走型_任意_任意_0'), Signal('周线_倒1笔_三笔形态_向下盘背_任意_任意_0'), ]), Factor(name="月线KDJ金叉_周线MACD强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('周线_MACD状态_任意_DIFF大于0_DEA大于0_柱子增大_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), ]) stocks_dwm_selector(event, signals.get_selector_signals, end_date=context.now, wx_key=context.wx_key)
def evaluate_trade(): """设定 long_open_event, long_exit_event 执行快速回测,查看回测结果""" long_open_event = Event( name='开多', operate=Operate.LO, factors=[ Factor(name="15分钟一买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="15分钟二买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="15分钟三买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), ]) long_exit_event = Event( name="一卖", operate=Operate.LE, factors=[ Factor(name="15分钟一卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="15分钟二卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="15分钟三卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]) ]) pairs, pf = long_trade_simulator(signals, long_open_event, long_exit_event)
def get_events(): events = [ Event(name="开多", operate=Operate.LO, factors=[ Factor(name="5分钟三买", signals_all=[ Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0"), Signal("15分钟_倒0笔_方向_向上_任意_任意_0"), Signal("60分钟_倒1K_DIF多空_多头_任意_任意_0"), Signal("60分钟_倒1K_DIF方向_向上_任意_任意_0"), ]), Factor(name="15分钟三买", signals_all=[ Signal("15分钟_倒1笔_类买卖点_类三买_任意_任意_0"), Signal("60分钟_倒1K_DIF多空_多头_任意_任意_0"), Signal("60分钟_倒1K_DIF方向_向上_任意_任意_0"), ]), Factor(name="30分钟三买", signals_all=[ Signal("30分钟_倒1笔_类买卖点_类三买_任意_任意_0"), Signal("15分钟_倒0笔_方向_向上_任意_任意_0"), Signal("60分钟_倒1K_DIF多空_多头_任意_任意_0"), Signal("60分钟_倒1K_DIF方向_向上_任意_任意_0"), ]), ]), Event(name="平多", operate=Operate.LE, factors=[ Factor(name="5分钟一卖", signals_all=[ Signal("5分钟_倒1笔_类买卖点_类一卖_任意_任意_0"), Signal("5分钟_倒1K_结束_是_任意_任意_0"), ]), Factor(name="15分钟一卖", signals_all=[ Signal("15分钟_倒1笔_类买卖点_类一卖_任意_任意_0"), Signal("15分钟_倒1K_结束_是_任意_任意_0"), ]), Factor(name="30分钟一卖", signals_all=[ Signal("30分钟_倒1笔_类买卖点_类一卖_任意_任意_0"), Signal("30分钟_倒1K_结束_是_任意_任意_0"), ]), Factor(name="5分钟二卖", signals_all=[ Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0"), Signal("5分钟_倒1K_结束_是_任意_任意_0"), ]), Factor(name="60分钟DIF空头", signals_all=[ Signal("60分钟_倒1K_DIF多空_空头_任意_任意_0"), Signal("60分钟_倒1K_结束_是_任意_任意_0"), ]), ]), ] return events
def evaluate_event(): """对单个事件进行表现评估""" event = Event(name="单事件", operate=Operate.LO, factors=[ Factor(name="60分钟DIF多头向上", signals_all=[ Signal("60分钟_DIF_状态_多头_向上_任意_0"), ]), ]) pairs1, pf1 = one_event_estimator(signals, event) event = Event(name="单事件", operate=Operate.LO, factors=[ Factor(name="60分钟DIF空头向下", signals_all=[ Signal("60分钟_DIF_状态_空头_向下_任意_0"), ]), ]) pairs2, pf2 = one_event_estimator(signals, event)
def get_factors(): double_signal_factors = [ Factor(name="日线MACD多头&日线DIF多头", signals_all=[ Signal(k1='日线', k2='倒1K', k3='MACD多空', v1='多头'), Signal(k1='日线', k2='倒1K', k3='DIF多空', v1='多头'), ]), Factor(name="日线SMA20多头向上", signals_all=[ Signal(k1='日线', k2='倒1K', k3='SMA20多空', v1='多头'), Signal(k1='日线', k2='倒1K', k3='SMA20方向', v1='向上'), ]), Factor(name="日线SMA60多头向上", signals_all=[ Signal(k1='日线', k2='倒1K', k3='SMA60多空', v1='多头'), Signal(k1='日线', k2='倒1K', k3='SMA60方向', v1='向上'), ]), ] triple_signal_factors = [ Factor(name="日线MACD长多", signals_all=[ Signal(k1='日线', k2='倒1K', k3='DIF多空', v1='多头'), Signal(k1='日线', k2='倒1K', k3='SMA60多空', v1='多头'), Signal(k1='日线', k2='倒1K', k3='SMA60方向', v1='向上'), ]), Factor(name="日线MACD短多", signals_all=[ Signal(k1='日线', k2='倒1K', k3='MACD多空', v1='多头'), Signal(k1='日线', k2='倒1K', k3='SMA20多空', v1='多头'), Signal(k1='日线', k2='倒1K', k3='SMA20方向', v1='向上'), ]), ] factors = double_signal_factors + triple_signal_factors return factors
def test_cobra_backtest(): bars = read_1min() signals = bt.generate_signals(bars, len(bars) - 10000, bt.get_default_signals) long_open_event = Event( name="开多", operate=Operate.LO, factors=[ Factor(name="5分钟三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), ]) long_exit_event = Event( name="平多", operate=Operate.LE, factors=[ Factor(name="1分钟一卖", signals_all=[Signal("1分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="5分钟一卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="5分钟二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="5分钟三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]) ]) pairs, pf = bt.long_trade_simulator(signals, long_open_event, long_exit_event, T0=True, verbose=True) assert len(pairs) == 65 assert pf['累计收益(%)'] > pf['基准收益(%)'] event = Event(name="多头过滤", operate=Operate.LO, factors=[ Factor(name="多头过滤", signals_all=[ Signal("30分钟_倒1K_DIF多空_多头_任意_任意_0"), ]), ]) pairs, pf = bt.one_event_estimator(signals, event) assert len(pairs) == 8 assert pf['累计收益(%)'] > pf['基准收益(%)']
def stocks_dwm_selector( end_date: [str, datetime] = datetime.now(), data_path=None): """大级别选股(日线&月线&周线)""" if isinstance(end_date, str): end_date = pd.to_datetime(end_date) if not data_path: home_path = os.path.expanduser('~') data_path = os.path.join(home_path, '.czsc_selector') print(f"selector results path: {data_path}") df = ts.pro.stock_basic( exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date') records = df.to_dict('records') file_results = os.path.join( data_path, f"selector_results_{end_date.strftime('%Y%m%d')}.xlsx") event = Event( name="选股", operate=Operate.LO, factors=[ Factor(name="月线KDJ金叉_日线MACD强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_MACD状态_任意_DIFF大于0_DEA大于0_柱子增大_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), Factor(name="月线KDJ金叉_日线潜在三买", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_倒0笔_潜在三买_构成中枢_近3K在中枢上沿附近_近7K突破中枢GG_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), Factor(name="月线KDJ金叉_周线三笔强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ], signals_any=[ Signal('周线_倒1笔_三笔形态_向下不重合_任意_任意_0'), Signal('周线_倒1笔_三笔形态_向下奔走型_任意_任意_0'), Signal('周线_倒1笔_三笔形态_向下盘背_任意_任意_0'), ]), Factor(name="月线KDJ金叉_周线MACD强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('周线_MACD状态_任意_DIFF大于0_DEA大于0_柱子增大_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), ]) results = [] signals_res = [] for row in tqdm(records, desc=f"{end_date.strftime('%Y%m%d')} selector"): symbol = row['ts_code'] try: k0 = ts.get_kline(symbol, asset='E', freq=Freq.D, start_date="20200101", end_date=end_date) k1 = ts.get_kline(symbol, asset='E', freq=Freq.W, start_date="20100101", end_date=end_date) k2 = ts.get_kline(symbol, asset='E', freq=Freq.M, start_date="20000101", end_date=end_date) c0 = CZSC(k0, get_signals=signals.get_selector_signals) c1 = CZSC(k1, get_signals=signals.get_selector_signals) c2 = CZSC(k2, get_signals=signals.get_selector_signals) s = OrderedDict(row) s.update(c0.signals) s.update(c1.signals) s.update(c2.signals) signals_res.append(s) m, f = event.is_match(s) if m: dt_fmt = "%Y%m%d" res = { 'symbol': symbol, 'name': s['name'], 'reason': f, 'end_dt': k0[-1].dt.strftime(dt_fmt), 'F10': f"http://basic.10jqka.com.cn/{symbol.split('.')[0]}", 'Kline': f"https://finance.sina.com.cn/realstock/company/{symbol[-2:].lower()}{symbol[:6]}/nc.shtml" } results.append(res) print(res) except: print("fail on {}".format(symbol)) traceback.print_exc() df_r = pd.DataFrame(results) df_r.to_excel(file_results, index=False) print(f"selector results saved into {file_results}") return df_r
def test_factor(): freq = Freq.F15 s = OrderedDict() default_signals = [ Signal(k1=str(freq.value), k2="倒0笔", k3="方向", v1="向上", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="长度", v1="大于5", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="三K形态", v1="顶分型", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒1笔", k3="表里关系", v1="其他", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒1笔", k3="RSQ状态", v1="小于0.2", v2='其他', v3='其他'), ] for signal in default_signals: s[signal.key] = signal.value factor = Factor(name="单测", signals_all=[ Signal(k1=str(freq.value), k2="倒0笔", k3="方向", v1="向上", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="长度", v1="大于5", v2='其他', v3='其他') ]) assert factor.is_match(s) factor = Factor(name="单测", signals_all=[ Signal(k1=str(freq.value), k2="倒0笔", k3="方向", v1="向上", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="长度", v1="大于5", v2='其他', v3='其他') ], signals_any=[ Signal(k1=str(freq.value), k2="倒1笔", k3="RSQ状态", v1="小于0.2", v2='其他', v3='其他') ]) assert factor.is_match(s) factor = Factor(name="单测", signals_all=[ Signal(k1=str(freq.value), k2="倒0笔", k3="方向", v1="向上", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="长度", v1="大于5", v2='其他', v3='其他') ], signals_any=[ Signal(k1=str(freq.value), k2="倒1笔", k3="RSQ状态", v1="小于0.8", v2='其他', v3='其他') ]) assert not factor.is_match(s)
def test_event(): freq = Freq.F15 s = OrderedDict() default_signals = [ Signal(k1=str(freq.value), k2="倒0笔", k3="方向", v1="向上", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="长度", v1="大于5", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="三K形态", v1="顶分型", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒1笔", k3="表里关系", v1="其他", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒1笔", k3="RSQ状态", v1="小于0.2", v2='其他', v3='其他'), ] for signal in default_signals: s[signal.key] = signal.value event = Event(name="单测", operate=Operate.LO, factors=[ Factor(name="测试", signals_all=[ Signal(k1=str(freq.value), k2="倒0笔", k3="方向", v1="向上", v2='其他', v3='其他'), Signal(k1=str(freq.value), k2="倒0笔", k3="长度", v1="大于5", v2='其他', v3='其他') ]) ]) m, f = event.is_match(s) assert m and f event = Event(name="单测", operate=Operate.LO, factors=[ Factor(name="测试", signals_all=[ Signal('15分钟_倒0笔_方向_向上_其他_其他_0'), Signal('15分钟_倒0笔_长度_任意_其他_其他_0') ]) ]) m, f = event.is_match(s) assert m and f event = Event(name="单测", operate=Operate.LO, factors=[ Factor(name="测试", signals_all=[ Signal('15分钟_倒0笔_方向_向上_其他_其他_20'), Signal('15分钟_倒0笔_长度_任意_其他_其他_0') ]) ]) m, f = event.is_match(s) assert not m and not f event = Event(name="单测", operate=Operate.LO, factors=[ Factor(name="测试", signals_all=[ Signal('15分钟_倒0笔_方向_向下_其他_其他_0'), Signal('15分钟_倒0笔_长度_任意_其他_其他_0') ]) ]) m, f = event.is_match(s) assert not m and not f
def stocks_monitor(symbols, wx_key): """对实盘股票池进行定时监控""" events = [ # 开多 Event(name="一买", operate=Operate.LO, factors=[ Factor(name="5分钟类一买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="5分钟形一买", signals_all=[Signal("5分钟_倒1笔_基础形态_类一买_任意_任意_0")]), Factor(name="15分钟类一买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="15分钟形一买", signals_all=[Signal("15分钟_倒1笔_基础形态_类一买_任意_任意_0")]), Factor(name="30分钟类一买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="30分钟形一买", signals_all=[Signal("30分钟_倒1笔_基础形态_类一买_任意_任意_0")]), ]), Event(name="二买", operate=Operate.LO, factors=[ Factor(name="5分钟类二买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="5分钟形二买", signals_all=[Signal("5分钟_倒1笔_基础形态_类二买_任意_任意_0")]), Factor(name="15分钟类二买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="15分钟形二买", signals_all=[Signal("15分钟_倒1笔_基础形态_类二买_任意_任意_0")]), Factor(name="30分钟类二买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="30分钟形二买", signals_all=[Signal("30分钟_倒1笔_基础形态_类二买_任意_任意_0")]), ]), Event(name="三买", operate=Operate.LO, factors=[ Factor(name="5分钟类三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="5分钟形三买", signals_all=[Signal("5分钟_倒1笔_基础形态_类三买_任意_任意_0")]), Factor(name="15分钟类三买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="15分钟形三买", signals_all=[Signal("15分钟_倒1笔_基础形态_类三买_任意_任意_0")]), Factor(name="30分钟类三买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="30分钟形三买", signals_all=[Signal("30分钟_倒1笔_基础形态_类三买_任意_任意_0")]), ]), # 平多 Event(name="一卖", operate=Operate.LE, factors=[ Factor(name="5分钟类一卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="5分钟形一卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类一卖_任意_任意_0")]), Factor(name="15分钟类一卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="15分钟形一卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类一卖_任意_任意_0")]), Factor(name="30分钟类一卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="30分钟形一卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类一卖_任意_任意_0")]), ]), Event(name="二卖", operate=Operate.LE, factors=[ Factor(name="5分钟类二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="5分钟形二卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类二卖_任意_任意_0")]), Factor(name="15分钟类二卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="15分钟形二卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类二卖_任意_任意_0")]), Factor(name="30分钟类二卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="30分钟形二卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类二卖_任意_任意_0")]), ]), Event(name="三卖", operate=Operate.LE, factors=[ Factor(name="5分钟类三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]), Factor(name="5分钟形三卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类三卖_任意_任意_0")]), Factor(name="15分钟类三卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]), Factor(name="15分钟形三卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类三卖_任意_任意_0")]), Factor(name="30分钟类三卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]), Factor(name="30分钟形三卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类三卖_任意_任意_0")]), ]), ] shares = get_shares() data_path = './data/monitor' os.makedirs(data_path, exist_ok=True) push_text("实盘池监控启动 @ {}".format(datetime.now().strftime("%Y-%m-%d %H:%M")), wx_key) for symbol in symbols: try: file_ct = os.path.join(data_path, "{}.ct".format(symbol)) if os.path.exists(file_ct): ct: GmCzscTrader = read_pkl(file_ct) ct.update_factors() else: ct = GmCzscTrader(symbol, max_count=2000, get_signals=get_monitor_signals) save_pkl(ct, file_ct) print(f"run monitor on {symbol} at {ct.end_dt}") msg = f"标的代码:{symbol}\n标的名称:{shares.get(symbol, '')}\n" \ f"同花顺F10:http://basic.10jqka.com.cn/{symbol.split('.')[1]}\n" msg += f"新浪行情:https://finance.sina.com.cn/realstock/company/{symbol[:2].lower()}{symbol[-6:]}/nc.shtml\n" for event in events: m, f = event.is_match(ct.s) if m: msg += "监控提醒:{}@{}\n".format(event.name, f) if "监控提醒" in msg: push_text(msg.strip("\n"), key=wx_key) except Exception as e: traceback.print_exc() print("{} 执行失败 - {}".format(symbol, e)) push_text("实盘池监控结束 @ {}".format(datetime.now().strftime("%Y-%m-%d %H:%M")), wx_key)
]), ]) stocks_dwm_selector(event, signals.get_selector_signals, end_date=context.now, wx_key=context.wx_key) if __name__ == '__main__': event = Event( name="选股", operate=Operate.LO, factors=[ Factor(name="月线KDJ金叉_日线MACD强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_MACD状态_任意_DIFF大于0_DEA大于0_柱子增大_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), Factor(name="月线KDJ金叉_日线潜在三买", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_倒0笔_潜在三买_构成中枢_近3K在中枢上沿附近_近7K突破中枢GG_0'), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ]), Factor(name="月线KDJ金叉_周线三笔强势", signals_all=[ Signal("月线_KDJ状态_任意_金叉_任意_任意_0"), Signal('日线_MA5状态_任意_收盘价在MA5上方_任意_任意_0'), ], signals_any=[ Signal('周线_倒1笔_三笔形态_向下不重合_任意_任意_0'),
def test_advanced_trader_with_t0(): bars = read_1min() kg = KlineGenerator(max_count=3000, freqs=['1分钟', '5分钟', '15分钟', '30分钟', '60分钟', '日线']) for row in tqdm(bars[:150000], desc='init kg'): kg.update(row) events = [ Event(name="开多", operate=Operate.LO, factors=[ Factor(name="5分钟一买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="1分钟一买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), ]), Event(name="加多1", operate=Operate.LA1, factors=[ Factor(name="5分钟二买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="1分钟二买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), ]), Event(name="加多2", operate=Operate.LA1, factors=[ Factor(name="5分钟三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="1分钟三买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), ]), Event(name="平多", operate=Operate.LE, factors=[ Factor(name="5分钟二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="5分钟三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]) ]), ] long_pos = PositionLong(symbol='000001.SH', hold_long_a=0.5, hold_long_b=0.8, hold_long_c=1, T0=True) ct = CzscAdvancedTrader(kg=kg, get_signals=get_default_signals, long_events=events, long_pos=long_pos) assert len(ct.s) == 16 for row in tqdm(bars[150000:], desc="trade"): ct.update(row) if long_pos.pos_changed: print(" : op : ", long_pos.operates[-1]) if ct.long_pos.pos > 0: assert ct.long_pos.long_high > 0 assert ct.long_pos.long_cost > 0 assert ct.long_pos.long_bid > 0 print(pd.DataFrame(ct.long_pos.evaluate_operates())['盈亏比例'].sum())
def monitor(use_cache=True): push_text( "自选股CZSC笔因子监控启动 @ {}".format( datetime.now().strftime("%Y-%m-%d %H:%M")), qywx_key) moni_path = os.path.join(ct_path, "monitor") # 首先清空历史快照 if os.path.exists(moni_path): shutil.rmtree(moni_path) os.makedirs(moni_path, exist_ok=True) events_monitor = [ # 开多 Event(name="一买", operate=Operate.LO, factors=[ Factor(name="5分钟类一买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="5分钟形一买", signals_all=[Signal("5分钟_倒1笔_基础形态_类一买_任意_任意_0")]), Factor(name="15分钟类一买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="15分钟形一买", signals_all=[Signal("15分钟_倒1笔_基础形态_类一买_任意_任意_0")]), Factor(name="30分钟类一买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="30分钟形一买", signals_all=[Signal("30分钟_倒1笔_基础形态_类一买_任意_任意_0")]), ]), Event(name="二买", operate=Operate.LO, factors=[ Factor(name="5分钟类二买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="5分钟形二买", signals_all=[Signal("5分钟_倒1笔_基础形态_类二买_任意_任意_0")]), Factor(name="15分钟类二买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="15分钟形二买", signals_all=[Signal("15分钟_倒1笔_基础形态_类二买_任意_任意_0")]), Factor(name="30分钟类二买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="30分钟形二买", signals_all=[Signal("30分钟_倒1笔_基础形态_类二买_任意_任意_0")]), ]), Event(name="三买", operate=Operate.LO, factors=[ Factor(name="5分钟类三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="5分钟形三买", signals_all=[Signal("5分钟_倒1笔_基础形态_类三买_任意_任意_0")]), Factor(name="15分钟类三买", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="15分钟形三买", signals_all=[Signal("15分钟_倒1笔_基础形态_类三买_任意_任意_0")]), Factor(name="30分钟类三买", signals_all=[Signal("30分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="30分钟形三买", signals_all=[Signal("30分钟_倒1笔_基础形态_类三买_任意_任意_0")]), ]), # 平多 Event(name="一卖", operate=Operate.LE, factors=[ Factor(name="5分钟类一卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="5分钟形一卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类一卖_任意_任意_0")]), Factor(name="15分钟类一卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="15分钟形一卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类一卖_任意_任意_0")]), Factor(name="30分钟类一卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类一卖_任意_任意_0")]), Factor(name="30分钟形一卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类一卖_任意_任意_0")]), ]), Event(name="二卖", operate=Operate.LE, factors=[ Factor(name="5分钟类二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="5分钟形二卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类二卖_任意_任意_0")]), Factor(name="15分钟类二卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="15分钟形二卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类二卖_任意_任意_0")]), Factor(name="30分钟类二卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="30分钟形二卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类二卖_任意_任意_0")]), ]), Event(name="三卖", operate=Operate.LE, factors=[ Factor(name="5分钟类三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]), Factor(name="5分钟形三卖", signals_all=[Signal("5分钟_倒1笔_基础形态_类三卖_任意_任意_0")]), Factor(name="15分钟类三卖", signals_all=[Signal("15分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]), Factor(name="15分钟形三卖", signals_all=[Signal("15分钟_倒1笔_基础形态_类三卖_任意_任意_0")]), Factor(name="30分钟类三卖", signals_all=[Signal("30分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]), Factor(name="30分钟形三卖", signals_all=[Signal("30分钟_倒1笔_基础形态_类三卖_任意_任意_0")]), ]), ] for s in symbols: print(s) try: file_ct = os.path.join(ct_path, "{}.ct".format(s)) if os.path.exists(file_ct) and use_cache: ct: CzscTrader = read_pkl(file_ct) ct.update_factors() else: ct = CzscTrader(s, max_count=1000) save_pkl(ct, file_ct) # 每次执行,会在moni_path下面保存一份快照 file_html = os.path.join( moni_path, f"{ct.symbol}_{ct.end_dt.strftime('%Y%m%d%H%M')}.html") ct.take_snapshot(file_html, width="1400px", height="580px") msg = f"标的代码:{s}\n同花顺F10:http://basic.10jqka.com.cn/{s.split('.')[0]}\n" for event in events_monitor: m, f = event.is_match(ct.s) if m: msg += "监控提醒:{}@{}\n".format(event.name, f) if "监控提醒" in msg: push_text(msg.strip("\n"), key=qywx_key) except Exception as e: traceback.print_exc() print("{} 执行失败 - {}".format(s, e)) push_text( "自选股CZSC笔因子监控结束 @ {}".format( datetime.now().strftime("%Y-%m-%d %H:%M")), qywx_key)
def run_advanced_trader(T0=True): bars = read_1min() kg = BarGenerator(base_freq='1分钟', freqs=['5分钟', '15分钟', '30分钟', '60分钟', '日线'], max_count=3000) for row in tqdm(bars[:150000], desc='init kg'): kg.update(row) long_events = [ Event(name="开多", operate=Operate.LO, factors=[ Factor(name="5分钟一买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="1分钟一买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), ]), Event(name="加多1", operate=Operate.LA1, factors=[ Factor(name="5分钟二买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="1分钟二买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), ]), Event(name="加多2", operate=Operate.LA1, factors=[ Factor(name="5分钟三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="1分钟三买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), ]), Event(name="平多", operate=Operate.LE, factors=[ Factor(name="5分钟二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="5分钟三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]) ]), ] long_pos = PositionLong(symbol='000001.SH', hold_long_a=0.5, hold_long_b=0.8, hold_long_c=1, T0=T0) short_events = [ Event(name="开空", operate=Operate.SO, factors=[ Factor(name="5分钟一买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), Factor(name="1分钟一买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类一买_任意_任意_0")]), ]), Event(name="加空1", operate=Operate.SA1, factors=[ Factor(name="5分钟二买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), Factor(name="1分钟二买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类二买_任意_任意_0")]), ]), Event(name="加空2", operate=Operate.SA1, factors=[ Factor(name="5分钟三买", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), Factor(name="1分钟三买", signals_all=[Signal("1分钟_倒1笔_类买卖点_类三买_任意_任意_0")]), ]), Event(name="平空", operate=Operate.SE, factors=[ Factor(name="5分钟二卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类二卖_任意_任意_0")]), Factor(name="5分钟三卖", signals_all=[Signal("5分钟_倒1笔_类买卖点_类三卖_任意_任意_0")]) ]), ] short_pos = PositionShort(symbol='000001.SH', hold_short_a=0.5, hold_short_b=0.8, hold_short_c=1, T0=T0) ct = CzscAdvancedTrader( bg=kg, get_signals=get_default_signals, long_events=long_events, long_pos=long_pos, short_events=short_events, short_pos=short_pos, ) assert len(ct.s) == 28 for row in tqdm(bars[150000:], desc="trade"): ct.update(row) # if long_pos.pos_changed: # print(" : long op : ", long_pos.operates[-1]) # if short_pos.pos_changed: # print(" : short op : ", short_pos.operates[-1]) if ct.long_pos.pos > 0: assert ct.long_pos.long_high > 0 assert ct.long_pos.long_cost > 0 assert ct.long_pos.long_bid > 0 if ct.short_pos.pos > 0: assert ct.short_pos.short_low > 0 assert ct.short_pos.short_cost > 0 assert ct.short_pos.short_bid > 0 long_yk = pd.DataFrame(ct.long_pos.pairs)['盈亏比例'].sum() short_yk = pd.DataFrame(ct.short_pos.pairs)['盈亏比例'].sum() assert abs(long_yk) == abs(short_yk) print(f"\nT0={T0}: 多头累计盈亏比例:{long_yk};空头累计盈亏比例:{short_yk}") if not T0: assert ct.s['多头_最大_盈利'] == '超过800BP_任意_任意_0' assert ct.s['多头_累计_盈亏'] == '盈利_超过800BP_任意_0' assert ct.s['空头_最大_回撤'] == '超过800BP_任意_任意_0' assert ct.s['空头_累计_盈亏'] == '亏损_超过800BP_任意_0'