openfund-core 1.0.10__tar.gz → 1.0.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openfund_core-1.0.10 → openfund_core-1.0.12}/PKG-INFO +1 -1
- {openfund_core-1.0.10 → openfund_core-1.0.12}/pyproject.toml +1 -1
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/smc/SMCStruct.py +52 -39
- {openfund_core-1.0.10 → openfund_core-1.0.12}/README.md +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/Exchange.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/__init__.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/main.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/smc/SMCBase.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/smc/SMCFVG.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/smc/SMCLiquidity.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/smc/SMCOrderBlock.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/smc/SMCPDArray.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/smc/__init__.py +0 -0
- {openfund_core-1.0.10 → openfund_core-1.0.12}/src/core/utils/OPTools.py +0 -0
@@ -15,6 +15,7 @@ class SMCStruct(SMCBase):
|
|
15
15
|
STRUCT_DIRECTION_COL = "struct_direction"
|
16
16
|
HIGH_START_COL = "high_start"
|
17
17
|
LOW_START_COL = "low_start"
|
18
|
+
DIRECTION_COL = "direction"
|
18
19
|
|
19
20
|
def __init__(self):
|
20
21
|
super().__init__()
|
@@ -62,7 +63,7 @@ class SMCStruct(SMCBase):
|
|
62
63
|
self.LOW_COL: df[self.LOW_COL].iloc[0],
|
63
64
|
self.HIGH_START_COL: -1,
|
64
65
|
self.LOW_START_COL: -1,
|
65
|
-
|
66
|
+
self.DIRECTION_COL: 0
|
66
67
|
}
|
67
68
|
|
68
69
|
# 确定突破判断列
|
@@ -71,8 +72,8 @@ class SMCStruct(SMCBase):
|
|
71
72
|
|
72
73
|
for i in range(1, len(df)):
|
73
74
|
curr_prices = {
|
74
|
-
self.HIGH_COL: df[break_price_col].iloc[i],
|
75
|
-
self.LOW_COL: df[break_price_col_low].iloc[i]
|
75
|
+
self.HIGH_COL: self.toDecimal(df[break_price_col].iloc[i]),
|
76
|
+
self.LOW_COL: self.toDecimal(df[break_price_col_low].iloc[i])
|
76
77
|
}
|
77
78
|
|
78
79
|
# 获取前3根K线价格
|
@@ -88,8 +89,9 @@ class SMCStruct(SMCBase):
|
|
88
89
|
prev_prices=prev_prices[self.HIGH_COL],
|
89
90
|
struct_start=structure[self.HIGH_START_COL],
|
90
91
|
i=i,
|
91
|
-
direction=structure[
|
92
|
-
target_direction=1
|
92
|
+
direction=structure[self.DIRECTION_COL],
|
93
|
+
target_direction=1,
|
94
|
+
mode=self.HIGH_COL
|
93
95
|
)
|
94
96
|
|
95
97
|
is_low_broken = self._check_structure_break(
|
@@ -98,26 +100,44 @@ class SMCStruct(SMCBase):
|
|
98
100
|
prev_prices=prev_prices[self.LOW_COL],
|
99
101
|
struct_start=structure[self.LOW_START_COL],
|
100
102
|
i=i,
|
101
|
-
direction=structure[
|
103
|
+
direction=structure[self.DIRECTION_COL],
|
102
104
|
target_direction=2,
|
103
105
|
mode=self.LOW_COL
|
104
106
|
)
|
105
|
-
|
106
|
-
if is_low_broken:
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
107
|
+
|
108
|
+
if is_low_broken:
|
109
|
+
|
110
|
+
# 获取新的极值点
|
111
|
+
extreme_idx = self._get_structure_extreme_bar(
|
112
|
+
df, i, struct_index=structure[self.LOW_START_COL],
|
113
|
+
mode=self.HIGH_COL
|
112
114
|
)
|
115
|
+
# 如果没有找到swing point,结构突破不成立
|
116
|
+
if extreme_idx != 0 :
|
117
|
+
# 处理低点突破
|
118
|
+
structure = self._handle_structure_break(
|
119
|
+
df, i, structure,
|
120
|
+
break_type=self.LOW_COL,
|
121
|
+
struct_type='BOS' if structure[self.DIRECTION_COL] == 1 else 'CHOCH',
|
122
|
+
extreme_idx=extreme_idx
|
123
|
+
)
|
113
124
|
|
114
125
|
elif is_high_broken:
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
126
|
+
|
127
|
+
# 获取新的极值点
|
128
|
+
extreme_idx = self._get_structure_extreme_bar(
|
129
|
+
df, i, struct_index=structure[self.HIGH_START_COL],
|
130
|
+
mode=self.LOW_COL
|
120
131
|
)
|
132
|
+
# 如果没有找到swing point,结构突破不成立
|
133
|
+
if extreme_idx != 0 :
|
134
|
+
# 处理高点突破
|
135
|
+
structure = self._handle_structure_break(
|
136
|
+
df, i, structure,
|
137
|
+
break_type=self.HIGH_COL,
|
138
|
+
struct_type='BOS' if structure[self.DIRECTION_COL] == 2 else 'CHOCH',
|
139
|
+
extreme_idx=extreme_idx
|
140
|
+
)
|
121
141
|
|
122
142
|
else:
|
123
143
|
# 更新当前结构
|
@@ -136,8 +156,8 @@ class SMCStruct(SMCBase):
|
|
136
156
|
获取结构最高点或最低点
|
137
157
|
:param df: DataFrame数据
|
138
158
|
:param bar_index: 当前K线索引
|
139
|
-
:param
|
140
|
-
:param mode:
|
159
|
+
:param struct_index: 结构开始索引
|
160
|
+
:param mode: high 寻找最高点,low 寻找最低点
|
141
161
|
:return: 结构极值点的索引
|
142
162
|
"""
|
143
163
|
df = df.copy()
|
@@ -148,11 +168,13 @@ class SMCStruct(SMCBase):
|
|
148
168
|
|
149
169
|
# 获取窗口内的极值点索引
|
150
170
|
if mode == self.HIGH_COL:
|
151
|
-
extremeBar = window[self.HIGH_COL].argmax()
|
171
|
+
# extremeBar = window[self.HIGH_COL].argmax()
|
172
|
+
extremeBar = window[self.HIGH_COL].idxmax()
|
152
173
|
price_col = self.HIGH_COL
|
153
174
|
comp_func = lambda x, y: x > y
|
154
175
|
else:
|
155
|
-
extremeBar = window[self.LOW_COL].argmin()
|
176
|
+
# extremeBar = window[self.LOW_COL].argmin()
|
177
|
+
extremeBar = window[self.LOW_COL].idxmin()
|
156
178
|
price_col = self.LOW_COL
|
157
179
|
comp_func = lambda x, y: x < y
|
158
180
|
|
@@ -160,7 +182,7 @@ class SMCStruct(SMCBase):
|
|
160
182
|
pivot = 0
|
161
183
|
# 从后向前遍历寻找结构极值点
|
162
184
|
# for i in range(lookback - 1, -1, -1):
|
163
|
-
for idx in range(bar_index - 1, struct_index
|
185
|
+
for idx in range(bar_index - 1, struct_index, -1):
|
164
186
|
# 计算当前位置的索引
|
165
187
|
# idx = bar_index - i
|
166
188
|
if idx - 2 < 0 or idx + 1 >= len(df):
|
@@ -182,10 +204,8 @@ class SMCStruct(SMCBase):
|
|
182
204
|
# 比较当前点位与之前记录的极值点的价格,因为在区间内有多个极致点,需要比较
|
183
205
|
if comp_func(df[price_col].iloc[idx-1], df[price_col].iloc[pivot]):
|
184
206
|
pivot = idx - 1
|
185
|
-
if pivot != 0:
|
186
|
-
extremeBar = pivot
|
187
207
|
|
188
|
-
return
|
208
|
+
return pivot
|
189
209
|
|
190
210
|
def _check_structure_break(self, curr_price, struct_price, prev_prices, struct_start, i, direction, target_direction, mode='high'):
|
191
211
|
"""检查结构是否突破"""
|
@@ -202,21 +222,14 @@ class SMCStruct(SMCBase):
|
|
202
222
|
|
203
223
|
return basic_break or direction_break
|
204
224
|
|
205
|
-
def _handle_structure_break(self, df, i, structure, break_type, struct_type):
|
225
|
+
def _handle_structure_break(self, df, i, structure, break_type, struct_type, extreme_idx ):
|
206
226
|
"""处理结构突破"""
|
207
227
|
is_high_break = break_type == self.HIGH_COL
|
208
|
-
|
209
|
-
struct_start = structure[self.HIGH_START_COL] if is_high_break else structure[self.LOW_START_COL]
|
210
|
-
|
211
|
-
# 获取新的极值点
|
212
|
-
extreme_idx = self._get_structure_extreme_bar(
|
213
|
-
df, i, struct_start,
|
214
|
-
mode=self.LOW_COL if is_high_break else self.HIGH_COL
|
215
|
-
)
|
228
|
+
|
216
229
|
|
217
230
|
# 更新结构信息
|
218
231
|
new_structure = structure.copy()
|
219
|
-
new_structure[
|
232
|
+
new_structure[self.DIRECTION_COL] = 2 if is_high_break else 1
|
220
233
|
|
221
234
|
if is_high_break:
|
222
235
|
new_structure.update({
|
@@ -234,7 +247,7 @@ class SMCStruct(SMCBase):
|
|
234
247
|
})
|
235
248
|
|
236
249
|
# 更新DataFrame结构信息
|
237
|
-
# df.at[i, self.STRUCT_DIRECTION_COL] = new_structure[
|
250
|
+
# df.at[i, self.STRUCT_DIRECTION_COL] = new_structure[self.DIRECTION_COL]
|
238
251
|
df.at[i, self.STRUCT_DIRECTION_COL] = self.BULLISH_TREND if is_high_break else self.BEARISH_TREND
|
239
252
|
df.at[i, self.STRUCT_COL] = f"{self.BULLISH_TREND if is_high_break else self.BEARISH_TREND}_{struct_type}"
|
240
253
|
|
@@ -245,13 +258,13 @@ class SMCStruct(SMCBase):
|
|
245
258
|
new_structure = structure.copy()
|
246
259
|
|
247
260
|
# 检查是否需要更新高点
|
248
|
-
if (structure[
|
261
|
+
if (structure[self.DIRECTION_COL] in (2,0)) and df.at[i,self.HIGH_COL] > structure[self.HIGH_COL]:
|
249
262
|
if not (is_struct_body_break and all(i-j > structure[self.HIGH_START_COL] for j in range(1,4))):
|
250
263
|
new_structure[self.HIGH_COL] = df.at[i,self.HIGH_COL]
|
251
264
|
new_structure[self.HIGH_START_COL] = i
|
252
265
|
|
253
266
|
# 检查是否需要更新低点
|
254
|
-
elif (structure[
|
267
|
+
elif (structure[self.DIRECTION_COL] in (1,0)) and df.at[i,self.LOW_COL] < structure[self.LOW_COL]:
|
255
268
|
if not (is_struct_body_break and all(i-j > structure[self.LOW_START_COL] for j in range(1,4))):
|
256
269
|
new_structure[self.LOW_COL] = df.at[i,self.LOW_COL]
|
257
270
|
new_structure[self.LOW_START_COL] = i
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|