import pandas as pd
import numpy as np
import mplfinance as mpf
from datetime import datetime, timedelta
def 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 df
def 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)