openfund-maker 2.3.2__py3-none-any.whl → 2.3.4__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.
- maker/BestTopDownStrategyMaker.py +28 -26
- maker/StrategyMaker.py +7 -8
- {openfund_maker-2.3.2.dist-info → openfund_maker-2.3.4.dist-info}/METADATA +1 -1
- {openfund_maker-2.3.2.dist-info → openfund_maker-2.3.4.dist-info}/RECORD +6 -6
- {openfund_maker-2.3.2.dist-info → openfund_maker-2.3.4.dist-info}/WHEEL +1 -1
- {openfund_maker-2.3.2.dist-info → openfund_maker-2.3.4.dist-info}/entry_points.txt +0 -0
@@ -103,7 +103,7 @@ class BestTopDownStrategyMaker(StrategyMaker):
|
|
103
103
|
step = "1.4"
|
104
104
|
# 计算支撑位和阻力位之间的利润空间百分比
|
105
105
|
htf_profit_percent = abs((htf_resistance_price - htf_support_price) / htf_support_price * 100)
|
106
|
-
min_profit_percent =
|
106
|
+
min_profit_percent = top_down_strategy.get('min_profit_percent', 4) # 默认最小利润空间为0.5%
|
107
107
|
|
108
108
|
if htf_profit_percent < min_profit_percent:
|
109
109
|
self.logger.info(f"{symbol} : {step}. HTF {htf} 支撑位={htf_support_price:.{precision}f} 与阻力位={htf_resistance_price:.{precision}f} 之间利润空间{htf_profit_percent:.2f}% < {min_profit_percent}%,等待...")
|
@@ -209,32 +209,34 @@ class BestTopDownStrategyMaker(StrategyMaker):
|
|
209
209
|
step = "2.5"
|
210
210
|
# if "CHOCH" in atf_struct[self.STRUCT_COL] or "BOS" in atf_struct[self.STRUCT_COL]:
|
211
211
|
# 2.5.1. Equal Lows & Equal Highs
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
212
|
+
if top_down_strategy.get('open_check_liquidity_areas', True):
|
213
|
+
end_idx = atf_latest_struct[self.STRUCT_HIGH_INDEX_COL] if atf_side == self.BUY_SIDE else atf_latest_struct[self.STRUCT_LOW_INDEX_COL]
|
214
|
+
last_EQ = self.find_EQH_EQL(symbol=symbol, data=atf_df, trend=atf_trend, end_idx=end_idx, pair_config=pair_config)
|
215
|
+
if last_EQ and last_EQ[self.HAS_EQ_KEY]:
|
216
|
+
price_eq = last_EQ[self.EQUAL_HIGH_COL] if atf_side == self.BUY_SIDE else last_EQ[self.EQUAL_LOW_COL]
|
217
|
+
self.logger.info(f"{symbol} : {step}.1 ATF {atf} {atf_side} find EQ {price_eq}")
|
218
|
+
# 检查是否Liquidity Sweeps
|
219
|
+
if (atf_side == self.BUY_SIDE and atf_latest_struct[self.STRUCT_HIGH_COL] > price_eq) \
|
220
|
+
or (atf_side == self.SELL_SIDE and atf_latest_struct[self.STRUCT_LOW_COL] < price_eq):
|
221
|
+
|
222
|
+
atf_side = self.SELL_SIDE if atf_side == self.BUY_SIDE else self.BUY_SIDE
|
223
|
+
self.logger.info(f"{symbol} : {step}.1 ATF {atf} Liquidity Sweeps , Reverse the ATF {atf} {atf_side} side。")
|
224
|
+
else:
|
225
|
+
self.logger.info(f"{symbol} : {step}.1 ATF {atf} is not found Liquidity Sweeps .")
|
226
|
+
else:
|
227
|
+
self.logger.info(f"{symbol} : {step}.1 ATF {atf} is not found EQ .")
|
227
228
|
|
228
229
|
# FIXME 2.5.2. Dynamic Trendlines and Channels
|
229
|
-
|
230
|
-
|
231
|
-
|
230
|
+
if top_down_strategy.get('open_check_dynamic_trendlines_and_channels', True):
|
231
|
+
atf_pre_struct = atf_struct[atf_struct[self.STRUCT_DIRECTION_COL].notna()].iloc[-2] # 看前一个结构是否为动态趋势
|
232
|
+
atf_start_index = min(atf_pre_struct[self.STRUCT_LOW_INDEX_COL] ,atf_pre_struct[self.STRUCT_HIGH_INDEX_COL])
|
233
|
+
atf_end_index = max(atf_latest_struct[self.STRUCT_LOW_INDEX_COL] ,atf_latest_struct[self.STRUCT_HIGH_INDEX_COL])
|
232
234
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
235
|
+
is_dynamic_trendlines = self.identify_dynamic_trendlines(symbol=symbol, data=atf_struct, trend=atf_trend, start_idx=atf_start_index, end_idx=atf_end_index)
|
236
|
+
if is_dynamic_trendlines :
|
237
|
+
self.logger.info(f"{symbol} : {step}.2 ATF {atf} {atf_trend} find Dynamic Trendlines .")
|
238
|
+
else:
|
239
|
+
self.logger.info(f"{symbol} : {step}.2 ATF {atf} {atf_trend} not find Dynamic Trendlines .")
|
238
240
|
|
239
241
|
|
240
242
|
# 2.6. 在HTF供需区范围,找ATF的PDArray,FVG和OB,供需区,计算监测下单区域范围。
|
@@ -388,14 +390,14 @@ class BestTopDownStrategyMaker(StrategyMaker):
|
|
388
390
|
self.logger.info(f"{symbol} : {step}. ETF {etf}, {etf_side} 价格={order_price:.{precision}}")
|
389
391
|
|
390
392
|
|
391
|
-
except KeyboardInterrupt:
|
392
|
-
self.logger.info("程序收到中断信号,开始退出...")
|
393
393
|
except Exception as e:
|
394
394
|
error_message = f"程序异常退出: {str(e)}"
|
395
395
|
# 记录错误信息和堆栈跟踪
|
396
396
|
self.logger.error(f"{error_message}\n{traceback.format_exc()}")
|
397
397
|
traceback.print_exc()
|
398
398
|
self.send_feishu_notification(symbol, error_message)
|
399
|
+
except KeyboardInterrupt:
|
400
|
+
self.logger.info("程序收到中断信号,开始退出...")
|
399
401
|
finally:
|
400
402
|
self.logger.info("=" * 60 + "\n")
|
401
403
|
|
maker/StrategyMaker.py
CHANGED
@@ -206,7 +206,7 @@ class StrategyMaker():
|
|
206
206
|
)
|
207
207
|
except Exception as e:
|
208
208
|
error_message = f"{symbol} 下单失败: {e}"
|
209
|
-
self.logger.
|
209
|
+
self.logger.error(error_message)
|
210
210
|
self.send_feishu_notification(symbol, error_message)
|
211
211
|
|
212
212
|
def cancel_all_orders(self, symbol):
|
@@ -219,7 +219,7 @@ class StrategyMaker():
|
|
219
219
|
self.exchange.cancel_all_orders(symbol=symbol)
|
220
220
|
except Exception as e:
|
221
221
|
error_message = f"{symbol} 取消所有挂单失败: {e}"
|
222
|
-
self.logger.
|
222
|
+
self.logger.error(error_message)
|
223
223
|
self.send_feishu_notification(symbol, error_message)
|
224
224
|
|
225
225
|
def get_historical_klines(self, symbol, tf='15m'):
|
@@ -237,6 +237,7 @@ class StrategyMaker():
|
|
237
237
|
def _get_cache_historical_klines_df(self, symbol, tf):
|
238
238
|
"""被缓存的获取K线数据的方法"""
|
239
239
|
return self.get_historical_klines_df(symbol, tf)
|
240
|
+
|
240
241
|
def clear_cache_historical_klines_df(self, symbol=None):
|
241
242
|
"""
|
242
243
|
清除指定交易对和时间周期的缓存
|
@@ -258,8 +259,7 @@ class StrategyMaker():
|
|
258
259
|
del self.cache_time[k]
|
259
260
|
# 由于lru_cache无法单独清除特定键,这里只能清除所有缓存
|
260
261
|
self._get_cache_historical_klines_df.cache_clear()
|
261
|
-
|
262
|
-
|
262
|
+
|
263
263
|
def get_historical_klines_df_by_cache(self, symbol, tf='15m'):
|
264
264
|
"""_summary_
|
265
265
|
获取历史K线数据
|
@@ -291,8 +291,7 @@ class StrategyMaker():
|
|
291
291
|
self.logger.debug(f"{symbol} : 重新获取新数据: {symbol} {tf}")
|
292
292
|
self.cache_time[cache_key] = current_time
|
293
293
|
return self._get_cache_historical_klines_df(symbol, tf)
|
294
|
-
|
295
|
-
|
294
|
+
|
296
295
|
def get_historical_klines_df(self, symbol, tf='15m'):
|
297
296
|
"""_summary_
|
298
297
|
获取历史K线数据
|
@@ -303,6 +302,7 @@ class StrategyMaker():
|
|
303
302
|
_type_: _description_
|
304
303
|
"""
|
305
304
|
return self.exchange.get_historical_klines_df(symbol=symbol, bar=tf)
|
305
|
+
|
306
306
|
def format_klines(self, klines) -> pd.DataFrame:
|
307
307
|
|
308
308
|
"""_summary_
|
@@ -360,8 +360,7 @@ class StrategyMaker():
|
|
360
360
|
"""
|
361
361
|
|
362
362
|
return self.smcOB.get_latest_OB(data=data, trend=trend, start_index=start_index)
|
363
|
-
|
364
|
-
|
363
|
+
|
365
364
|
def find_FVGs(self, symbol, data, side, check_balanced=True, start_index=-1, pair_config=None) -> pd.DataFrame:
|
366
365
|
"""_summary_
|
367
366
|
寻找公允价值缺口
|
@@ -1,8 +1,8 @@
|
|
1
1
|
maker/BestFVGStrategyMaker.py,sha256=a9UfClrfzkgX6jXL2FODzANtawrmGeZ_PVeO1-tweDc,12532
|
2
|
-
maker/BestTopDownStrategyMaker.py,sha256
|
2
|
+
maker/BestTopDownStrategyMaker.py,sha256=KT7x29dbJh8Kbaj1l_cHJ_CpACmdEnafNuU9viiOcMk,23981
|
3
3
|
maker/MACDStrategyMaker.py,sha256=WX8wqpF9h5W4WclN1NjZ_Bur7KFi_aMTvacfLyHzEcI,12681
|
4
4
|
maker/SMCStrategyMaker.py,sha256=hkDqymWnuyYDo1gTYY_uyO4H4yOwCw8NBTM9RcfLRPc,28780
|
5
|
-
maker/StrategyMaker.py,sha256=
|
5
|
+
maker/StrategyMaker.py,sha256=aJ_uSoGC5enYMgmRbPOKEEICk7r7yUA4XLsd04hWNfI,18820
|
6
6
|
maker/ThreeLineStrategyMaker.py,sha256=K4NZB1rH8IZMVrCFEnzwXctZQbyI9ZdyTMrYObpl-vM,32095
|
7
7
|
maker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
maker/history_code/WickReversalStrategyMaker.py,sha256=7DqPDVJot4EM0_lSAcFAHrR9rNvkIds9KLMoDOiAHEc,17486
|
@@ -11,7 +11,7 @@ maker/history_code/okxapi.py,sha256=_9G0U_o0ZC8NxaT6PqpiLgxBm9gPobC9PsFHZE1c5w0,
|
|
11
11
|
maker/history_code/zhen.py.bak,sha256=HNkrQbJts8G9umE9chEFsc0cLQApcM9KOVNMYPpkBXM,10918
|
12
12
|
maker/history_code/zhen_2.py,sha256=4IaHVtTCMSlrLGSTZrWpW2q-f7HZsUNRkW_-5QgWv24,10509
|
13
13
|
maker/main.py,sha256=PRCP2qCUiUFPQyi1YbvnmW9KqeCZcc0zGjy9OBvMWbM,3723
|
14
|
-
openfund_maker-2.3.
|
15
|
-
openfund_maker-2.3.
|
16
|
-
openfund_maker-2.3.
|
17
|
-
openfund_maker-2.3.
|
14
|
+
openfund_maker-2.3.4.dist-info/METADATA,sha256=9oxQk4iq01HIUvwM2Q1bLboESbVhFqET3p34Ga2l27c,2001
|
15
|
+
openfund_maker-2.3.4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
16
|
+
openfund_maker-2.3.4.dist-info/entry_points.txt,sha256=gKMytICEKcMRFQDFkHZLnIpID7UQFoTIM_xcpiiV6Ns,50
|
17
|
+
openfund_maker-2.3.4.dist-info/RECORD,,
|
File without changes
|