forked from brokermr810/QuantDinger
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmulti_indicator_composite.py
More file actions
108 lines (92 loc) · 4.03 KB
/
multi_indicator_composite.py
File metadata and controls
108 lines (92 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# ============================================================
# 多指标组合策略(文档同步版)
# Multi-Indicator Composite Strategy (Doc-Aligned Example)
# ============================================================
#
# 示例目标:
# 1. 演示如何把 `# @param`、`# @strategy` 和平台 UI 对齐
# 2. 演示如何组合均线、RSI、MACD、成交量过滤
# 3. 演示如何把原始条件整理成更稳定的边缘触发信号
#
# ============================================================
my_indicator_name = "多指标组合策略"
my_indicator_description = "均线、RSI、MACD 与成交量过滤共同参与的组合信号示例。"
# === 参数声明 ===
# @param sma_short int 10 短期均线周期
# @param sma_long int 30 长期均线周期
# @param rsi_period int 14 RSI周期
# @param rsi_oversold int 30 RSI超卖阈值
# @param rsi_overbought int 70 RSI超买阈值
# @param use_macd bool true 是否使用MACD过滤
# @param use_volume bool false 是否使用成交量过滤
# @param volume_mult float 1.5 成交量放大倍数
# === 平台默认策略配置 ===
# @strategy stopLossPct 0.025
# @strategy takeProfitPct 0.06
# @strategy entryPct 0.2
# @strategy trailingEnabled true
# @strategy trailingStopPct 0.02
# @strategy trailingActivationPct 0.04
# @strategy tradeDirection both
df = df.copy()
# === 获取参数 ===
sma_short_period = int(params.get('sma_short', 10))
sma_long_period = int(params.get('sma_long', 30))
rsi_period = int(params.get('rsi_period', 14))
rsi_oversold = int(params.get('rsi_oversold', 30))
rsi_overbought = int(params.get('rsi_overbought', 70))
use_macd = bool(params.get('use_macd', True))
use_volume = bool(params.get('use_volume', False))
volume_mult = float(params.get('volume_mult', 1.5))
# === 计算均线 ===
sma_short = df["close"].rolling(sma_short_period).mean()
sma_long = df["close"].rolling(sma_long_period).mean()
# === 计算RSI ===
delta = df["close"].diff()
gain = delta.where(delta > 0, 0).rolling(window=rsi_period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=rsi_period).mean()
rs = gain / loss.replace(0, np.nan)
rsi = 100 - (100 / (1 + rs))
# === 计算MACD ===
exp1 = df["close"].ewm(span=12, adjust=False).mean()
exp2 = df["close"].ewm(span=26, adjust=False).mean()
macd = exp1 - exp2
macd_signal = macd.ewm(span=9, adjust=False).mean()
# === 计算成交量均线 ===
volume_ma = df["volume"].rolling(20).mean()
# === 原始条件 ===
ma_golden = (sma_short > sma_long) & (sma_short.shift(1) <= sma_long.shift(1))
ma_death = (sma_short < sma_long) & (sma_short.shift(1) >= sma_long.shift(1))
rsi_buy = rsi < rsi_oversold
rsi_sell = rsi > rsi_overbought
macd_up = macd > macd_signal
macd_down = macd < macd_signal
volume_up = df["volume"] > volume_ma * volume_mult
# === 组合条件 ===
raw_buy = ma_golden | rsi_buy
raw_sell = ma_death | rsi_sell
if use_macd:
raw_buy = raw_buy & macd_up
raw_sell = raw_sell | macd_down
if use_volume:
raw_buy = raw_buy & volume_up
# === 边缘触发信号 ===
df["buy"] = (raw_buy.fillna(False) & (~raw_buy.shift(1).fillna(False))).astype(bool)
df["sell"] = (raw_sell.fillna(False) & (~raw_sell.shift(1).fillna(False))).astype(bool)
# === 买卖标记点 ===
buy_marks = [df["low"].iloc[i] * 0.995 if df["buy"].iloc[i] else None for i in range(len(df))]
sell_marks = [df["high"].iloc[i] * 1.005 if df["sell"].iloc[i] else None for i in range(len(df))]
# === 图表输出配置 ===
output = {
"name": my_indicator_name,
"plots": [
{"name": f"SMA{sma_short_period}", "data": sma_short.fillna(0).tolist(), "color": "#FF9800", "overlay": True},
{"name": f"SMA{sma_long_period}", "data": sma_long.fillna(0).tolist(), "color": "#3F51B5", "overlay": True},
{"name": "RSI", "data": rsi.fillna(50).tolist(), "color": "#722ED1", "overlay": False},
{"name": "MACD", "data": macd.fillna(0).tolist(), "color": "#13C2C2", "overlay": False}
],
"signals": [
{"type": "buy", "text": "B", "data": buy_marks, "color": "#00E676"},
{"type": "sell", "text": "S", "data": sell_marks, "color": "#FF5252"}
]
}