openfund-core 1.0.8__py3-none-any.whl → 1.0.9__py3-none-any.whl
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.
- core/smc/SMCLiquidity.py +5 -7
- core/smc/SMCPDArray.py +28 -11
- {openfund_core-1.0.8.dist-info → openfund_core-1.0.9.dist-info}/METADATA +1 -1
- {openfund_core-1.0.8.dist-info → openfund_core-1.0.9.dist-info}/RECORD +6 -6
- {openfund_core-1.0.8.dist-info → openfund_core-1.0.9.dist-info}/WHEEL +1 -1
- {openfund_core-1.0.8.dist-info → openfund_core-1.0.9.dist-info}/entry_points.txt +0 -0
core/smc/SMCLiquidity.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
from decimal import Decimal
|
2
3
|
from core.smc.SMCStruct import SMCStruct
|
3
4
|
|
4
5
|
|
@@ -27,20 +28,17 @@ class SMCLiquidity(SMCStruct):
|
|
27
28
|
df = data.copy()
|
28
29
|
|
29
30
|
# 识别高点
|
30
|
-
df[self.LIQU_HIGH_COL] = 0
|
31
|
+
df[self.LIQU_HIGH_COL] = Decimal(0.0)
|
31
32
|
for i in range(pivot_length, len(df) - pivot_length):
|
32
33
|
if df[self.HIGH_COL].iloc[i] == max(df[self.HIGH_COL].iloc[i-pivot_length:i+pivot_length+1]):
|
33
|
-
df.loc[df.index[i], self.LIQU_HIGH_COL] = df[self.HIGH_COL].iloc[i]
|
34
|
-
|
34
|
+
df.loc[df.index[i], self.LIQU_HIGH_COL] = df[self.HIGH_COL].iloc[i]
|
35
35
|
# 识别低点
|
36
|
-
df[self.LIQU_LOW_COL] = 0
|
36
|
+
df[self.LIQU_LOW_COL] = Decimal(0.0)
|
37
37
|
for i in range(pivot_length, len(df) - pivot_length):
|
38
38
|
|
39
39
|
if df[self.LOW_COL].iloc[i] == min(df[self.LOW_COL].iloc[i-pivot_length:i+pivot_length+1]):
|
40
40
|
df.loc[df.index[i], self.LIQU_LOW_COL] = df[self.LOW_COL].iloc[i]
|
41
41
|
|
42
|
-
|
43
|
-
|
44
42
|
return df
|
45
43
|
|
46
44
|
def find_EQH_EQL(self, data, trend, end_idx=-1, atr_offset=0.1) -> dict:
|
@@ -63,7 +61,7 @@ class SMCLiquidity(SMCStruct):
|
|
63
61
|
try:
|
64
62
|
self.check_columns(df, check_columns)
|
65
63
|
except ValueError as e:
|
66
|
-
self.logger.warning(f"DataFrame must contain columns {check_columns} : {str(e)}")
|
64
|
+
# self.logger.warning(f"DataFrame must contain columns {check_columns} : {str(e)}")
|
67
65
|
df = self._identify_liquidity_pivots(df)
|
68
66
|
|
69
67
|
df = df[(df[self.LIQU_HIGH_COL] > 0) | (df[self.LIQU_LOW_COL] > 0)]
|
core/smc/SMCPDArray.py
CHANGED
@@ -9,13 +9,14 @@ class SMCPDArray(SMCFVG,SMCOrderBlock):
|
|
9
9
|
PD_LOW_COL = "pd_low"
|
10
10
|
PD_MID_COL = "pd_mid"
|
11
11
|
PD_TYPE_COL = "pd_type"
|
12
|
+
PD_WAS_BALANCED_COL = "pd_was_balanced"
|
12
13
|
|
13
14
|
def __init__(self):
|
14
15
|
super().__init__()
|
15
16
|
self.logger = logging.getLogger(__name__)
|
16
17
|
|
17
18
|
def find_PDArrays(
|
18
|
-
self, struct: pd.DataFrame, side, start_index=-1,
|
19
|
+
self, struct: pd.DataFrame, side, start_index=-1, balanced=False,
|
19
20
|
) -> pd.DataFrame:
|
20
21
|
"""_summary_
|
21
22
|
寻找PDArrays,包括Fair Value Gap (FVG)|Order Block (OB)|Breaker Block(BB)|Mitigation Block(BB)
|
@@ -23,7 +24,7 @@ class SMCPDArray(SMCFVG,SMCOrderBlock):
|
|
23
24
|
data (pd.DataFrame): K线数据
|
24
25
|
side (_type_): 交易方向 'buy'|'sell'
|
25
26
|
start_index (int): 开始查找索引的起点,默认为-1
|
26
|
-
|
27
|
+
balanced (bool): PD是否有效,默认为False。PD被crossed过,则是无效PD
|
27
28
|
|
28
29
|
Returns:
|
29
30
|
pd.DataFrame: _description_
|
@@ -36,11 +37,14 @@ class SMCPDArray(SMCFVG,SMCOrderBlock):
|
|
36
37
|
else struct.copy().iloc[max(0, start_index - 1) :]
|
37
38
|
)
|
38
39
|
|
39
|
-
df_FVGs = self.find_FVGs(df, side,
|
40
|
-
# self.logger.info(f"fvgs:\n{df_FVGs[['timestamp', self.FVG_SIDE, self.FVG_TOP, self.FVG_BOT, self.FVG_WAS_BALANCED]]}")
|
40
|
+
df_FVGs = self.find_FVGs(df, side, start_index)
|
41
41
|
|
42
|
+
if not balanced:
|
43
|
+
df_FVGs = df_FVGs[~df_FVGs[self.FVG_WAS_BALANCED]]
|
44
|
+
# self.logger.info(f"fvgs:\n{df_FVGs[['timestamp', self.FVG_SIDE, self.FVG_TOP, self.FVG_BOT, self.FVG_WAS_BALANCED]]}")
|
42
45
|
|
43
|
-
|
46
|
+
is_valid = not balanced
|
47
|
+
df_OBs = self.find_OBs(struct=df, side=side, start_index=start_index, is_valid=is_valid)
|
44
48
|
# self.logger.info("find_OBs:\n %s", df_OBs)
|
45
49
|
|
46
50
|
# 使用更简洁的方式重命名和合并时间戳列
|
@@ -59,6 +63,10 @@ class SMCPDArray(SMCFVG,SMCOrderBlock):
|
|
59
63
|
df_PDArrays[self.TIMESTAMP_COL] = df_PDArrays[timestamp_mapping[self.TIMESTAMP_COL][0]].fillna(
|
60
64
|
df_PDArrays[timestamp_mapping[self.TIMESTAMP_COL][1]]
|
61
65
|
)
|
66
|
+
|
67
|
+
df_PDArrays[self.PD_WAS_BALANCED_COL] = df_PDArrays[[self.OB_WAS_CROSSED, self.FVG_WAS_BALANCED]].apply(
|
68
|
+
lambda x: x.iloc[0] if pd.notna(x.iloc[0]) else x.iloc[1], axis=1)
|
69
|
+
|
62
70
|
df_PDArrays[self.PD_TYPE_COL] = df_PDArrays[[self.FVG_SIDE, self.OB_DIRECTION_COL]].apply(
|
63
71
|
lambda x: 'FVG-OB' if pd.notna(x.iloc[0]) and pd.notna(x.iloc[1]) else 'FVG' if pd.notna(x.iloc[0]) else 'OB', axis=1
|
64
72
|
)
|
@@ -68,10 +76,12 @@ class SMCPDArray(SMCFVG,SMCOrderBlock):
|
|
68
76
|
df_PDArrays.loc[:, self.PD_MID_COL] = (df_PDArrays[self.PD_HIGH_COL] + df_PDArrays[self.PD_LOW_COL]) / 2
|
69
77
|
|
70
78
|
|
71
|
-
|
79
|
+
# 根据balanced参数过滤PDArrays,返回符合条件的数据
|
80
|
+
|
81
|
+
return df_PDArrays[df_PDArrays[self.PD_WAS_BALANCED_COL] == balanced]
|
72
82
|
|
73
83
|
|
74
|
-
def get_latest_PDArray(self, df_PDArrays: pd.DataFrame, side, start_index=-1,
|
84
|
+
def get_latest_PDArray(self, df_PDArrays: pd.DataFrame, side, start_index=-1, balanced=False, mask=None) -> dict:
|
75
85
|
"""_summary_
|
76
86
|
过滤PDArrays,只保留指定方向的PDArrays
|
77
87
|
Args:
|
@@ -89,16 +99,22 @@ class SMCPDArray(SMCFVG,SMCOrderBlock):
|
|
89
99
|
self.check_columns(df, check_columns)
|
90
100
|
except ValueError as e:
|
91
101
|
df = self.build_struct(df)
|
92
|
-
|
93
|
-
df = self.find_PDArrays(df, side, start_index, check_balanced)
|
94
102
|
|
95
|
-
|
96
|
-
|
103
|
+
|
104
|
+
check_columns = [self.PD_TYPE_COL]
|
105
|
+
try:
|
106
|
+
self.check_columns(df, check_columns)
|
107
|
+
except ValueError as e:
|
108
|
+
df = self.find_PDArrays(df, side, start_index, balanced)
|
109
|
+
|
110
|
+
if mask is not None:
|
111
|
+
df = df[mask]
|
97
112
|
|
98
113
|
if len(df) == 0:
|
99
114
|
self.logger.info("未找到PDArray.")
|
100
115
|
return None
|
101
116
|
else:
|
117
|
+
self.logger.debug(f"PDArray:\n{df[[self.TIMESTAMP_COL, self.PD_TYPE_COL, self.PD_HIGH_COL, self.PD_LOW_COL, self.PD_MID_COL,self.PD_WAS_BALANCED_COL,self.OB_WAS_CROSSED,self.FVG_WAS_BALANCED]]}")
|
102
118
|
last_pd = df.iloc[-1]
|
103
119
|
return {
|
104
120
|
self.TIMESTAMP_COL: last_pd[self.TIMESTAMP_COL],
|
@@ -106,4 +122,5 @@ class SMCPDArray(SMCFVG,SMCOrderBlock):
|
|
106
122
|
self.PD_HIGH_COL: last_pd[self.PD_HIGH_COL],
|
107
123
|
self.PD_LOW_COL: last_pd[self.PD_LOW_COL],
|
108
124
|
self.PD_MID_COL: last_pd[self.PD_MID_COL],
|
125
|
+
self.PD_WAS_BALANCED_COL: last_pd[self.PD_WAS_BALANCED_COL],
|
109
126
|
}
|
@@ -3,13 +3,13 @@ core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
core/main.py,sha256=E-VZzem7-0_J6EmOo9blLPokc5MRcgjqCbqAvbkPnWI,630
|
4
4
|
core/smc/SMCBase.py,sha256=epRC5bWDymx7ZMIhn_bVJRjvBHItt6BCnYASO2fhSDg,4302
|
5
5
|
core/smc/SMCFVG.py,sha256=KDyqR8dQiKYpJ25HpXeVPdxVgAxbtwc9LJ-OVrGIlZk,3009
|
6
|
-
core/smc/SMCLiquidity.py,sha256
|
6
|
+
core/smc/SMCLiquidity.py,sha256=-OvMZQCcy7qRSomU58sUmhRJt-gUGt1oPJAiW01_i7I,8009
|
7
7
|
core/smc/SMCOrderBlock.py,sha256=lh868FUjb6RHQ0DwUeBfYymf9j-Lcv6YWJvYlJF3iUo,9918
|
8
|
-
core/smc/SMCPDArray.py,sha256=
|
8
|
+
core/smc/SMCPDArray.py,sha256=IjBdpQuAQd3t_nTovEzeiml-EQ-KeLNCmitFxadYxMM,5030
|
9
9
|
core/smc/SMCStruct.py,sha256=dW3iLKNV78pDbcpyL7SjLVUyAsc1DrO8gSCJkGbrKO4,12339
|
10
10
|
core/smc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
core/utils/OPTools.py,sha256=tJ1Jq_Caab6OWaX12xn4_g9ryf98Rm5I1zsJEEU8NIQ,1002
|
12
|
-
openfund_core-1.0.
|
13
|
-
openfund_core-1.0.
|
14
|
-
openfund_core-1.0.
|
15
|
-
openfund_core-1.0.
|
12
|
+
openfund_core-1.0.9.dist-info/METADATA,sha256=900HtTV6y1pBx_WFKy3Gg30UpGsMkfT-bm0UdTw9x08,1953
|
13
|
+
openfund_core-1.0.9.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
14
|
+
openfund_core-1.0.9.dist-info/entry_points.txt,sha256=g8GUw3cyKFtcG5VWs8geU5VBLqiWr59GElqERuH8zD0,48
|
15
|
+
openfund_core-1.0.9.dist-info/RECORD,,
|
File without changes
|