import pandas as pdimport numpy as npimport mplfinance as mpffrom datetime import datetime, timedeltadef calculate_lunar_indicators(df): """ 计算农历相关技术Delta周期循环主图指标公式 """ CSR = 3 synodic_month = 29.53058782 base_date = pd.Timestamp('1899-12-30') df['RIC'] = (df.index - base_date).days + 1 df['IS'] = ((df['RIC'] + 3) / synodic_month).astype(int) fractional_part = (df['RIC'] + CSR) / synodic_month - np.floor((df['RIC'] + CSR) / synodic_month) df['YYS'] = fractional_part * synodic_month df['NLRI'] = np.where(df['YYS'] 1, np.round(df['YYS'] + synodic_month), np.floor(df['YYS'])) df['NUM'] = df['IS'] % 4 df['NLRI_prev'] = df['NLRI'].shift(1) df['ISCOLOR'] = ((df['NLRI_prev'] >= df['NLRI']) | (df['NLRI'] == 1)).astype(int) condition = (df['ISCOLOR'] == 1) & (df['NUM'] == 2) df['江恩日'] = condition[::-1].cumsum()[::-1] - condition[::-1].cumsum()[::-1].where(~condition).ffill().fillna(0) + 1 df['江恩日'] = df['江恩日'].where(condition, 0) df['基准'] = (df['RIC'] + 2) / synodic_month + 0.0016 df['ISFIRSTA'] = df['基准'].astype(int) df['SCOLORA'] = ((df['基准'].shift(1) < df['ISFIRSTA']) & (df['基准'] + 0.1 >= df['ISFIRSTA'])) | (df['基准'] == df['ISFIRSTA']) phase = (df['基准'] + 0.1).astype(int) % 4 df['A0'] = (df['ISCOLOR'] == 1) & (phase == 1) df['A1'] = (df['ISCOLOR'] == 1) & (phase == 2) df['A2'] = (df['ISCOLOR'] == 1) & (phase == 3) df['A3'] = (df['ISCOLOR'] == 1) & (phase == 0) return dfdef plot_lunar_chart(df, start_date=None, end_date=None): """ 绘制带有农历指标的K线图 """ if start_date or end_date: start = start_date or df.index[0] end = end_date or df.index[-1] plot_df = df.loc[start:end].copy() else: plot_df = df.copy() apds = [ mpf.make_addplot(plot_df['江恩日'], panel=1, color='purple', ylabel='江恩日'), ] colors = { 0: 'yellow', 1
: 'red', 2: 'green', 3: 'white' } markers = [] for num, color in colors.items(): condition = (plot_df['ISCOLOR'] == 1) & (plot_df['NUM'] == num) markers.append(mpf.make_addplot( plot_df['close'].where(condition), type='scatter', marker='o', markersize=50, color=color, alpha=0.3 )) apds.extend(markers) mpf.plot(plot_df, type='candle', addplot=apds, style='charles', title='农历周期分析', ylabel='价格', volume=False, figratio=(12, 8), show_nontrading=False)if __name__ == "__main__": dates = pd.date_range(start='2023-01-01', end='2024-01-01', freq='D') data = { 'open': np.random.uniform(100, 200, len(dates)), 'high': np.random.uniform(200, 300, len(dates)), 'low': np.random.uniform(50, 100, len(dates)), 'close': np.random.uniform(100, 200, len(dates)), 'volume': np.random.randint(10000, 50000, len(dates)) } df = pd.DataFrame(data, index=dates) df = calculate_lunar_indicators(df) end_date = df.index[-1] start_date = end_date - timedelta(days=90) plot_lunar_chart(df, start_date=start_date)