import pandas as pd
import numpy as np
import talib
import mplfinance as mpf
from matplotlib import pyplot as plt
from datetime import datetime
date_rng = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
df = pd.DataFrame({
'Open': np.random.uniform(100, 200, len(date_rng)),
'High': np.random.uniform(200, 300, len(date_rng)),
'Low': np.random.uniform(50, 100, len(date_rng)),
'Close': np.random.uniform(100, 200, len(date_rng)),
'Volume': np.random.randint(10000, 100000, len(date_rng))
}, index=date_rng)
# 技术指标计算函数
def calculate_technical_indicators(df):
# 1. 成交量预测 (AA) - 使用模拟数据
df['预测'] = df['Volume'] * np.random.uniform(0.8, 1.2, len(df)) / 10000
# 2. 主动买卖计算
bb = df['Volume'] / ((df['High'] - df['Low']) * 2 - abs(df['Close'] - df['Open']))
# 主动买计算
condition1 = (df['Close'] > df['Open'])
condition2 = (df['Close'] < df['Open'])
df['主动买'] = np.where(
condition1,
bb * (df['High'] - df['Low']),
np.where(
condition2,
bb * ((df['High'] - df['Open']) + (df['Close'] - df['Low'])),
df['Volume'] / 2
)
)
# 主动卖计算
df['主动卖'] = np.where(
condition1,
-bb * ((df['High'] - df['Close']) + (df['Open'] - df['Low']),
np.where(
condition2,
-bb * (df['High'] - df['Low']),
-df['Volume'] / 2
)
)
# 3. 主买/主卖标准化
df['主买'] = df['主动买'] / 10000
df['主卖'] = -df['主动卖'] / 10000
df['总额'] = df['主买'] + df['主卖']
df['主买占比%'] = df['主买'] / df['总额'] * 100
# 4. 买卖平衡计算
df['V总'] = df['主动买'] - df['主动卖']
df['买卖比'] = df['主动买'] / (-df['主动卖'])
df['VE'] = df['V总'] / df['V总'].shift(1)
df['倍量'] = (df['VE'] > 2).astype(int)
df['倍缩'] = (df['VE'] <= 0.5).astype(int)
# 5. 移动平均线
df['MA5'] = talib.MA(df['Volume'], timeperiod=5)
df['MA10'] = talib.MA(df['Volume'], timeperiod=10)
df['MA120'] = talib.MA(df['Volume'], timeperiod=60)
# 6. SAR指标计算
df['SAR'] = talib.SAR(df['High'], df['Low'], acceleration=0.02, maximum=0.2)
df['持币'] = np.where(df['SAR'] >= df['High'], df['SAR'], np.nan)
df['持股'] = np.where(df['SAR'] <= df['Low'], df['SAR'], np.nan)
# 7. KDJ指标计算
df['VAR3'] = (df['Close'] - talib.MA(df['Close'], 6)) / talib.MA(df['Close'], 6) * 100
df['VAR4'] = (df['Close'] - talib.MA(df['Close'], 24)) / talib.MA(df['Close'], 24) * 100
df['VAR5'] = (df['Close'] - talib.MA(df['Close'], 32)) / talib.MA(df['Close'], 32) * 100
df['VAR6'] = (df['VAR3'] + df['VAR4'] + df['VAR5']) / 3
df['VAR7'] = talib.EMA(df['VAR6'], timeperiod=5)
df['K'] = talib.EMA(df['VAR7'], timeperiod=5) * 2
df['D'] = talib.EMA(df['K'], timeperiod=5)
df['J'] = df['K'] * 3 - df['D'] * 2
return df
# 计算所有指标
df = calculate_technical_indicators(df)
# 可视化设置
def visualize_data(df):
# 创建子图布局
fig = plt.figure(figsize=(16, 12))
gs = fig.add_gridspec(6, 1)
ax1 = fig.add_subplot(gs[:3, 0])
ax2 = fig.add_subplot(gs[3, 0], sharex=ax1)
ax3 = fig.add_subplot(gs[4, 0], sharex=ax1)
ax4 = fig.add_subplot(gs[5, 0], sharex=ax1)
# K线图
mpf.plot(df, type='candle', ax=ax1, volume=False)
# 成交量分析
ax2.bar(df.index, df['主买'], color='magenta', label='主买')
ax2.bar(df.index, df['主卖'], color='green', label='主卖')
ax2.plot(df.index, df['MA5'], 'white', label='MA5')
ax2.plot(df.index, df['MA120'], 'yellow', label='MA120')
# 标记倍量/倍缩
ax2.scatter(df[df['倍量'] == 1].index,
df.loc[df['倍量'] == 1, '预测'] * 1.2,
color='red', marker='^', s=100)
ax2.scatter(df[df['倍缩'] == 1].index,
df.loc[df['倍缩'] == 1, '预测'] * 0.8,
color='green', marker='v', s=100)
# KDJ指标
ax3.plot(df.index, df['K'], 'm-', label='K')
ax3.plot(df.index, df['D'], 'w-', label='D')
ax3.plot(df.index, df['J'], 'y-', label='J')
# 买卖信号
buy_signals = df[df['持股'].notna()]
sell_signals = df[df['持币'].notna()]
ax4.plot(df.index, df['买卖比'], 'b-', label='买卖比')
ax4.scatter(buy_signals.index, buy_signals['买卖比'],
color='red', marker='^', s=100, label=
'买入信号')
ax4.scatter(sell_signals.index, sell_signals['买卖比'],
color='green', marker='v', s=100, label='卖出信号')
# 添加图例和标签
ax1.set_title('价格走势')
ax2.set_title('成交量分析')
ax3.set_title('KDJ指标')
ax4.set_title('买卖信号')
ax1.legend()
ax2.legend()
ax3.legend()
ax4.legend()
# 策略说明
fig.text(0.1, 0.01,
'【粉+黄做多】【粉+蓝做空】【粉色做多】【蓝色做空】【黄色做多】【红色倍量】【绿色缩量】',
color='cyan', fontsize=12)
plt.tight_layout()
plt.show()
# 执行可视化
visualize_data(df[-100:]) # 展示最近100天的数据