openfund-maker 2.0.1__py3-none-any.whl → 2.0.2__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.
@@ -0,0 +1,220 @@
1
+ # -*- coding: utf-8 -*-
2
+ import traceback
3
+ import pandas as pd
4
+
5
+ from maker.SMCStrategyMaker import SMCStrategyMaker
6
+
7
+
8
+ class BestFVGStrategyMaker(SMCStrategyMaker):
9
+ def __init__(self, config, platform_config, feishu_webhook=None,logger=None):
10
+ super().__init__(config, platform_config, feishu_webhook, logger)
11
+ self.place_order_prices = {} # 记录每个symbol的挂单价格
12
+ self.htf_last_CHoCH = {} #记录HTF的CHoCH struct
13
+
14
+ def check_price_in_fvg(self, df, side, fvg):
15
+ """
16
+ 检查最大或最小价格是否在FVG范围内
17
+ Args:
18
+ htf_last_side: str, 方向 'buy' or 'sell'
19
+ fvg_top: float, FVG上边界
20
+ fvg_bot: float, FVG下边界
21
+ Returns:
22
+ bool: 是否在FVG范围内
23
+ """
24
+ if fvg is None:
25
+ return False
26
+
27
+ fvg_top = fvg["top"]
28
+ fvg_bot = fvg["bot"]
29
+ fvg_index = fvg["index"]
30
+
31
+ # 检查价格是否在FVG范围内,bar_index 是从fvg_index+2开始
32
+ if side == 'buy':
33
+ # 多头趋势检查最低价是否进入FVG区域
34
+ min_price = min(df['low'].iloc[fvg_index+2:])
35
+ return min_price <= fvg_top
36
+ else:
37
+ # 空头趋势检查最高价是否进入FVG区域
38
+ max_price = max(df['high'].iloc[fvg_index+2:])
39
+ return fvg_bot <= max_price
40
+
41
+
42
+ def process_pair(self,symbol,pair_config):
43
+ self.logger.info("=" * 60)
44
+ """_summary_
45
+ 1. HTF 判断struct趋势
46
+ 2. HTF 获取最新的两个极值点,设置折价区和溢价区
47
+ 3. HTF 在折价区找FVG,监控价格是否进入FVG
48
+
49
+ 4. LTF 判断struct趋势是否有CHoCH
50
+ 5. LTF 寻找FVG,下单
51
+ """
52
+ try:
53
+ # 检查是否有持仓,有持仓不进行下单
54
+ if self.check_position(symbol=symbol) :
55
+ self.logger.info(f"{symbol} : 有持仓合约,不进行下单。")
56
+ if symbol in self.place_order_prices:
57
+ self.place_order_prices[symbol] = {}
58
+ return
59
+
60
+
61
+ smc_strategy = pair_config.get('smc_strategy',{})
62
+
63
+ # 获取历史K线,HTF和CTF
64
+ htf = str(smc_strategy.get('HTF','15m'))
65
+ ltf = str(smc_strategy.get('LTF', '1m'))
66
+ htf_Klines = self.get_historical_klines(symbol=symbol, bar=htf)
67
+ htf_df = self.format_klines(htf_Klines)
68
+
69
+ enable_FVG = smc_strategy.get('enable_FVG',True) # 是否启用FVG
70
+ enable_OB = smc_strategy.get('enable_OB',True) # 是否启用OB
71
+ self.logger.debug(f"{symbol} : BestFVGSMC策略 {ltf}|{htf} enable_FVG={enable_FVG} enable_OB={enable_OB} ...")
72
+
73
+ # 初始化HTF趋势相关变量
74
+ htf_last_side, htf_last_CHoCH_label = None, None
75
+
76
+ # 检查是否有上一个CHoCH结构
77
+ htf_last_CHoCH = self.htf_last_CHoCH.get(symbol,None)
78
+
79
+ # 如果存在上一个CHoCH结构,更新趋势标签和方向
80
+ if htf_last_CHoCH:
81
+ htf_last_CHoCH_label = htf_last_CHoCH["struct"]
82
+ htf_last_side = htf_last_CHoCH["side"]
83
+
84
+
85
+ # 1. HTF 判断struct趋势(CHoCH\SMS\BMS) ,HTF struct 看趋势,CTF 看FVG和OB的位置
86
+ swing_points_length = smc_strategy.get('swing_points_length',10)
87
+ htf_struct = self.detect_struct(htf_df,prd=swing_points_length,struct_key="CHoCH")
88
+ htf_struct_label = htf_struct["struct"]
89
+ htf_last_pivot_high = htf_struct["pivot_high"]
90
+ htf_last_pivot_low = htf_struct["pivot_low"]
91
+ htf_last_mid_line = self.calculate_ce(symbol,htf_last_pivot_high,htf_last_pivot_low)
92
+
93
+
94
+ # 检查是否已形成CHoCH结构
95
+ if not (htf_last_CHoCH or 'CHoCH' in htf_struct_label):
96
+ self.logger.debug(f"{symbol} : {htf} 未形成 CHoCH struct,不下单。{htf_struct}。")
97
+ return
98
+
99
+ # 更新最新的CHoCH结构信息
100
+ if 'CHoCH' in htf_struct_label and htf_struct_label != htf_last_CHoCH_label:
101
+ self.htf_last_CHoCH[symbol] = htf_struct
102
+ htf_last_CHoCH = htf_struct
103
+ htf_last_CHoCH_label = htf_struct_label
104
+ htf_last_side = htf_struct["side"]
105
+
106
+
107
+ # 2. HTF 获取最新的两个极值点,设置折价(discount)区和溢价(premium)区
108
+
109
+
110
+ # 计算溢价和折价区
111
+ premium_box = {
112
+ 'top': htf_last_pivot_high,
113
+ 'bot': htf_last_mid_line,
114
+ 'ce': self.calculate_ce(symbol,htf_last_pivot_high,htf_last_mid_line)
115
+ }
116
+ discount_box = {
117
+ 'top': htf_last_mid_line,
118
+ 'bot': htf_last_pivot_low,
119
+ 'ce': self.calculate_ce(symbol,htf_last_mid_line,htf_last_pivot_low)
120
+ }
121
+
122
+ self.logger.info(f"{symbol} : {htf} 趋势={htf_last_CHoCH_label}")
123
+ self.logger.debug(f"{symbol} : \npivot_high={htf_last_pivot_high} pivot_low={htf_last_pivot_low} mid_line={htf_last_mid_line}\n溢价区={premium_box}\n折价区={discount_box}")
124
+
125
+ # 3. find HTF FVG
126
+ pivot_index = htf_struct["pivot_low_index"] if htf_last_side == "buy" else htf_struct["pivot_high_index"]
127
+ htf_fvg_boxes = self.find_fvg_boxes(htf_df,side=htf_last_side,threshold=htf_last_mid_line,check_balanced=False,pivot_index=pivot_index)
128
+ if len(htf_fvg_boxes) == 0:
129
+ self.logger.debug(f"{symbol} : HTF={htf} 方向={htf_last_side}, 未找到 FVG")
130
+ return
131
+ self.logger.debug(f"{symbol} : HTF_fvg_box={htf_fvg_boxes[-1]}")
132
+
133
+ # 判断是否进入最近的FVG
134
+ if_tap_into_fvg = self.check_price_in_fvg(htf_df,htf_last_side,htf_fvg_boxes[-1])
135
+ if not if_tap_into_fvg:
136
+ self.logger.debug(f"{symbol} : 价格[未进入]HTF_FVG区域,不进行下单")
137
+ return
138
+ else:
139
+ self.logger.debug(f"{symbol} : 价格[进入]HTF_FVG区域,开始下单。fvgbox={htf_fvg_boxes[-1]}")
140
+
141
+ # 4. LTF 判断struct趋势是否有CHoCH
142
+
143
+
144
+ ltf_kLines = self.get_historical_klines(symbol=symbol, bar=ltf)
145
+ ltf_df = self.format_klines(ltf_kLines)
146
+
147
+ ltf_struct = self.detect_struct(ltf_df,prd=swing_points_length)
148
+ ltf_struct_label = ltf_struct["struct"]
149
+ ltf_struct_side = ltf_struct["side"]
150
+ ltf_last_pivot_high = ltf_struct["pivot_high"]
151
+ ltf_last_pivot_low = ltf_struct["pivot_low"]
152
+ ltf_last_mid_line = self.calculate_ce(symbol,ltf_last_pivot_high,ltf_last_pivot_low)
153
+
154
+ # 计算溢价和折价区
155
+ ltf_premium_box = {
156
+ 'top': ltf_last_pivot_high,
157
+ 'bot': ltf_last_mid_line,
158
+ 'ce': self.calculate_ce(symbol,ltf_last_pivot_high,ltf_last_mid_line)
159
+ }
160
+ ltf_discount_box = {
161
+ 'top': ltf_last_mid_line,
162
+ 'bot': ltf_last_pivot_low,
163
+ 'ce': self.calculate_ce(symbol,ltf_last_mid_line,ltf_last_pivot_low)
164
+ }
165
+
166
+ self.logger.info(f"{symbol} : {ltf} 趋势={ltf_struct_label} struct={ltf_struct}")
167
+ self.logger.debug(f"{symbol} : \npivot_high={ltf_last_pivot_high} pivot_low={ltf_last_pivot_low} mid_line={ltf_last_mid_line}\n溢价区={ltf_premium_box}\n折价区={ltf_discount_box}")
168
+
169
+
170
+ # 5. LTF 寻找FVG,下单
171
+ # if htf_last_CHoCH_label != ltf_struct_label :
172
+ if htf_last_side != ltf_struct_side :
173
+ self.logger.debug(f"{symbol} : {htf} {htf_last_CHoCH_label} VS {ltf} {ltf_struct_label} 趋势不一致,不进行下单")
174
+ return
175
+
176
+ threshold = 0.0
177
+ # 如果LTF结构是BMS,趋势强,FVG的范围不要求,只要能接上就行,如果结构是CHoCH或SMS,趋势弱,则取折价区或溢价区的FVG
178
+ if 'BMS' in ltf_struct_label:
179
+ threshold = ltf_last_pivot_high if ltf_struct_side == "buy" else ltf_last_pivot_low
180
+ else:
181
+ threshold = self.calculate_ce(symbol,ltf_last_pivot_high,ltf_last_pivot_low)
182
+
183
+ pivot_index = ltf_struct["pivot_low_index"] if ltf_struct_side == "buy" else ltf_struct["pivot_high_index"]
184
+
185
+ ltf_fvg_boxes = self.find_fvg_boxes(ltf_df,side=ltf_struct_side,threshold=threshold,pivot_index=pivot_index)
186
+
187
+ if len(ltf_fvg_boxes) == 0:
188
+ self.logger.debug(f"{symbol} : LTF={ltf} 趋势={ltf_struct_label}, 未找到 FVG")
189
+ return
190
+
191
+ self.logger.debug(f"{symbol} : LTF_fvg_box={ltf_fvg_boxes[-1]}")
192
+
193
+
194
+ # 4. LTF 寻找FVG,下单
195
+ order_price = ltf_fvg_boxes[-1]["top"] if ltf_struct_side == "buy" else ltf_fvg_boxes[-1]["bot"]
196
+
197
+ latest_order_price = self.place_order_prices.get(symbol,0.0)
198
+ if order_price == latest_order_price:
199
+ self.logger.debug(f"{symbol} : 下单价格 {order_price} 未变化,不进行下单。")
200
+ return
201
+
202
+
203
+ # 下单
204
+ self.cancel_all_orders(symbol=symbol)
205
+ self.place_order(symbol=symbol, price=order_price, side=ltf_struct_side, pair_config=pair_config)
206
+ self.place_order_prices[symbol] = order_price # 记录下单价格,过滤重复下单
207
+ self.logger.debug(f"{symbol} : {ltf_struct_side}, 下单价格 {order_price}")
208
+
209
+
210
+ except KeyboardInterrupt:
211
+ self.logger.info("程序收到中断信号,开始退出...")
212
+ except Exception as e:
213
+ error_message = f"程序异常退出: {str(e)}"
214
+ self.logger.error(error_message,exc_info=True)
215
+ traceback.print_exc()
216
+ self.send_feishu_notification(error_message)
217
+ finally:
218
+ self.logger.info("-" * 60)
219
+
220
+
maker/SMCStrategyMaker.py CHANGED
@@ -106,13 +106,22 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
106
106
  return OB_boxes
107
107
 
108
108
 
109
- def find_fvg_boxes(self, data, side, threshold, pivot_index=0, symbol=None, pair_config=None) -> list:
109
+ def find_fvg_boxes(self, data, side, threshold, check_balanced=True, pivot_index=0, symbol=None, pair_config=None) -> list:
110
110
  """_summary_
111
111
  寻找公允价值缺口
112
112
  Args:
113
- df (_type_): _description_
114
- side (_type_): _description_
115
- threshold (_type_): _description_
113
+ data (_type_): K线数据
114
+ side (_type_): 交易方向 'buy'|'sell'
115
+ threshold (_type_): 阈值价格,通常为溢价和折价区的CE
116
+ check_balanced (bool): 是否检查FVG是否被平衡过,默认为True
117
+ pivot_index (int): 枢轴点索引,默认为0
118
+ symbol (_type_): 交易对名称
119
+ pair_config (_type_): 交易对配置
120
+ Returns:
121
+ list: FVG盒子列表,每个盒子包含以下字段:
122
+ # index: FVG出现的K线位置索引
123
+ # top: FVG的上边界价格,对应K线的最高价或最低价
124
+ # bot: FVG的下边界价格,对应K线的最高价或最低价
116
125
  """
117
126
 
118
127
  df = data.copy().iloc[pivot_index:]
@@ -132,13 +141,13 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
132
141
  fvg_boxes = [
133
142
  {
134
143
  'index': idx - 2, # FVG的索引
135
- 'top': float(df.loc[idx - 1, 'low']), # FVG高点为右1K线的最低点
144
+ 'top': min(float(df.loc[idx - 1, 'low']),threshold), # FVG高点为右1K线的最低点
136
145
  'bot': float(df.loc[idx - 3, 'high']) # FVG低点为左1K线的最高点
137
146
  }
138
147
  # [df.loc[idx - 1, 'low'], df.loc[idx - 3, 'high'], idx - 2]
139
148
  for idx in valid_indices
140
149
  if df.loc[idx - 3, 'high'] <= threshold and
141
- all((df.loc[idx:, 'low'] >= df.loc[idx - 3, 'high'])) # 检查FVG是否被平衡过
150
+ (not check_balanced or all((df.loc[idx:, 'low'] > df.loc[idx - 3, 'high']))) # check_balanced = true 检查FVG是否被平衡过
142
151
  ]
143
152
 
144
153
 
@@ -157,31 +166,44 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
157
166
  fvg_boxes = [
158
167
  {
159
168
  'index': idx - 2, # FVG的索引
160
- 'top': float(df.loc[idx - 1, 'high']), # FVG高点为右1K线的最高点
161
- 'bot': float(df.loc[idx - 3, 'low']) # FVG低点为左1K线的最低点
169
+ 'top': float(df.loc[idx - 3, 'low']), # FVG高点为右1K线的最高点
170
+ 'bot': max(float(df.loc[idx - 1, 'high']),threshold) # FVG低点为左1K线的最低点
162
171
  }
163
172
 
164
173
  for idx in valid_indices
165
174
  if df.loc[idx - 3, 'low'] >= threshold and
166
- all((df.loc[idx:, 'high'] >= df.loc[idx - 3, 'low'])) # 检查FVG是否被平衡过
175
+ (not check_balanced or all((df.loc[idx:, 'high'] < df.loc[idx - 3, 'low']))) # check_balanced = true 检查FVG是否被平衡过
167
176
  ]
168
177
 
169
178
 
170
179
  return fvg_boxes
171
180
 
172
181
 
173
- def detect_struct(self, data, prd=10, s1=True, resp=7) -> dict:
182
+ def detect_struct(self, data, prd=10, struct_key=None, check_bounds=True, global_extremum=False, s1=True, resp=7) -> dict:
174
183
  """_summary_
175
- 识别智能资金结构
176
-
177
- :param data: 包含 'high' 和 'low' 列的 DataFrame
178
- :param prd: 结构周期
179
- :param s1: 结构响应布尔值
180
- :param resp: 响应周期
181
- :return: 包含结构识别结果的 DataFrame
184
+ 识别SMC结构,参考 Tradingview Smart Money Concepts Probability (Expo)@Openfund
185
+
186
+ Args:
187
+ data (df): df格式的K线数据
188
+ prd (int): 计算Swing Points的bar数量
189
+ struct_key (str): 结构类型,如 'CHoCH'|'SMS'|'BMS'
190
+ check_bounds (bool): 计算Swing Points是否检查边界,默认为True
191
+ global_extremum (bool): 是否使用全局极值点,默认为False
192
+ s1 (bool): 结构响应布尔值
193
+ resp (int): 响应周期
194
+ Returns:
195
+ dict: 包含结构识别结果的字典,包含以下字段:
196
+ "struct": 结构类型,如 'Bullish_CHoCH'|'Bullish_SMS'|'Bullish_BMS'|'Bearish_CHoCH'|'Bearish_SMS'|'Bearish_BMS'
197
+ "index": 结构出现的位置索引
198
+ "pivot_high": 枢轴高点价格
199
+ "pivot_high_index": 枢轴高点索引
200
+ "pivot_low": 枢轴低点价格
201
+ "pivot_low_index": 枢轴低点索引
202
+ "side": 交易方向,'buy'或'sell'
203
+
204
+
182
205
  """
183
-
184
-
206
+
185
207
  # data = data.copy()
186
208
  data['Up'] = None
187
209
  data['Dn'] = None
@@ -204,8 +226,8 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
204
226
  data.at[index, 'iDn'] = data.at[max(0,index - 1), 'iDn'] if data.at[max(0,index - 1), 'iDn'] is not None else index
205
227
 
206
228
  # 寻找枢轴高点和低点
207
- pvtHi = self.is_pivot_high(data, index, prd)
208
- pvtLo = self.is_pivot_low(data, index, prd)
229
+ pvtHi = self.is_pivot_high(data, index, prd, check_bounds)
230
+ pvtLo = self.is_pivot_low(data, index, prd, check_bounds)
209
231
 
210
232
  if pvtHi:
211
233
  data.at[index, 'Up'] = data.at[index, 'high']
@@ -215,7 +237,8 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
215
237
  data.at[index, 'iDn'] = index
216
238
  # 寻找Bullish结构
217
239
  if data.at[index, 'Up'] > data.at[index - 1, 'Up']:
218
-
240
+
241
+ data.at[index, 'iUp'] = index
219
242
  if data.at[index - 1, 'pos'] <= 0:
220
243
  # data.at[index, 'pattern'] = 'CHoCH (Bullish)'
221
244
  data.at[index, 'pattern'] = 'Bullish_CHoCH'
@@ -230,12 +253,12 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
230
253
  data.at[index, 'pattern'] = 'Bullish_BMS'
231
254
  data.at[index, 'pos'] = data.at[index - 1, 'pos'] + 1
232
255
 
233
- elif data.at[index, 'Up'] < data.at[index - 1, 'Up']:
256
+ elif global_extremum and data.at[index, 'Up'] < data.at[index - 1, 'Up']:
234
257
  data.at[index, 'iUp'] = data.at[index - 1, 'iUp']
235
258
 
236
259
  # # 寻找Bearish结构
237
260
  if data.at[index, 'Dn'] < data.at[index - 1, 'Dn']:
238
-
261
+ data.at[index, 'iDn'] = index
239
262
  if data.at[index - 1, 'pos'] >= 0:
240
263
 
241
264
  data.at[index, 'pattern'] = 'Bearish_CHoCH'
@@ -249,7 +272,7 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
249
272
  data.at[index, 'pattern'] = 'Bearish_BMS'
250
273
  data.at[index, 'pos'] = data.at[index - 1, 'pos'] - 1
251
274
 
252
- elif data.at[index, 'Dn'] > data.at[index - 1, 'Dn']:
275
+ elif global_extremum and data.at[index, 'Dn'] > data.at[index - 1, 'Dn']:
253
276
  data.at[index, 'iDn'] = data.at[index - 1, 'iDn']
254
277
 
255
278
  # 获取最后一个结构和位置
@@ -267,6 +290,8 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
267
290
 
268
291
  for i in range(len(data)-1, -1, -1):
269
292
  if data.at[i, 'pattern'] is not None:
293
+ if struct_key is not None and struct_key not in data.at[i, 'pattern']:
294
+ continue
270
295
  last_struct["struct"] = data.at[i, 'pattern']
271
296
  last_struct["index"] = i
272
297
 
@@ -298,7 +323,7 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
298
323
 
299
324
 
300
325
 
301
- def is_pivot_high(self,data, index, period, check_bounds=False):
326
+ def is_pivot_high(self, data, index, period, check_bounds=False):
302
327
  """
303
328
  判断当前索引处是否为枢轴高点
304
329
  :param data: 包含 'high' 列的 DataFrame
@@ -314,7 +339,7 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
314
339
  return all(current_high >= prev_highs) and all(current_high >= next_highs)
315
340
 
316
341
 
317
- def is_pivot_low(self,data, index, period, check_bounds=False):
342
+ def is_pivot_low(self, data, index, period, check_bounds=False):
318
343
  """
319
344
  判断当前索引处是否为枢轴低点
320
345
  :param data: 包含 'low' 列的 DataFrame
@@ -369,7 +394,7 @@ class SMCStrategyMaker(ThreeLineStrategyMaker):
369
394
 
370
395
  enable_FVG = smc_strategy.get('enable_FVG',True) # 是否启用FVG
371
396
  enable_OB = smc_strategy.get('enable_OB',True) # 是否启用OB
372
- self.logger.debug(f"{symbol} : SMC策略 {ctf}\{htf} enable_FVG={enable_FVG} enable_OB={enable_OB} ...")
397
+ self.logger.debug(f"{symbol} : SMC策略 {ctf}|{htf} enable_FVG={enable_FVG} enable_OB={enable_OB} ...")
373
398
 
374
399
  side = 'none'
375
400
  # 1. HTF 判断struct趋势(CHoCH\SMS\BMS) ,HTF struct 看趋势,CTF 看FVG和OB的位置
maker/main.py CHANGED
@@ -9,6 +9,7 @@ from maker.WickReversalStrategyMaker import WickReversalStrategyMaker
9
9
  from maker.ThreeLineStrategyMaker import ThreeLineStrategyMaker
10
10
  from maker.MACDStrategyMaker import MACDStrategyMaker
11
11
  from maker.SMCStrategyMaker import SMCStrategyMaker
12
+ from maker.BestFVGStrategyMaker import BestFVGStrategyMaker
12
13
 
13
14
  def build_logger(log_config) -> logging.Logger:
14
15
  # 配置日志
@@ -59,9 +60,16 @@ def main():
59
60
  feishu_webhook_url = config_data['feishu_webhook']
60
61
  logger = build_logger(config_data["Logger"])
61
62
  package_name = __package__ or "maker"
62
- logger.info(f" ++ {package_name}:{version} is doing...")
63
- logger.info("开始执行交易任务...")
64
- bot = SMCStrategyMaker(config_data, platform_config, feishu_webhook=feishu_webhook_url, logger=logger)
63
+
64
+
65
+ maker = config_data.get('actived_maker', 'MACDStrategyMaker')
66
+
67
+
68
+ # 根据配置动态创建策略实例
69
+ strategy_class = globals()[maker]
70
+ bot = strategy_class(config_data, platform_config, feishu_webhook=feishu_webhook_url, logger=logger)
71
+
72
+ logger.info(f" ++ {package_name}.{maker}:{version} is doing...")
65
73
 
66
74
  # 获取计划配置
67
75
  schedule_config = config_data.get('schedule', {})
@@ -93,7 +101,7 @@ def main():
93
101
  )
94
102
 
95
103
  try:
96
- logger.info(f"启动定时任务调度器,从 {next_run} 开始每5分钟执行一次...")
104
+ logger.info(f"启动定时任务调度器,从 {next_run} 开始每{monitor_interval}分钟执行一次...")
97
105
  scheduler.start()
98
106
  except (KeyboardInterrupt, SystemExit):
99
107
  logger.info("程序收到中断信号,正在退出...")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: openfund-maker
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: Openfund-maker.
5
5
  Requires-Python: >=3.9,<4.0
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,15 +1,16 @@
1
+ maker/BestFVGStrategyMaker.py,sha256=IEE8jEIYcpS0jD5jbBx0Tqhy5vFRdcZJ3WUnsUCIH88,10384
1
2
  maker/MACDStrategyMaker.py,sha256=iS5HO04piKHFJxUI2e5QmicxzGeK-V1aphJSr2n_4Ac,12651
2
- maker/SMCStrategyMaker.py,sha256=PWy3eQsX8XFb3gJoNamZFKZf1O09zEQClm7R-YjY06I,25099
3
+ maker/SMCStrategyMaker.py,sha256=LUm9HFX5S_OKesynPyf4SBsfGnK0awPeChpHWOfD8VM,26957
3
4
  maker/ThreeLineStrategyMaker.py,sha256=ArjnHlGECiD3cCFXxO0Ex5scR2agwoxZY-4mKukyKc4,30402
4
5
  maker/WickReversalStrategyMaker.py,sha256=7DqPDVJot4EM0_lSAcFAHrR9rNvkIds9KLMoDOiAHEc,17486
5
6
  maker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
7
  maker/config.py,sha256=YPxghO5i0vgRg9Cja8kGj9O7pgSbbtzOgf3RexqXXwY,1188
7
- maker/main.py,sha256=WhrfrZecbV9ihDL14J1-oTuLJq8Zt1mg9lN4pvnlaN0,4201
8
+ maker/main.py,sha256=XpZ2N55bi5Fi_r2FKuqBu8e71mTxgHgrtzJUjBe1fUc,4405
8
9
  maker/main_m.py,sha256=0PzDTnuBrxfpy5WDfsIHKAzZ_7pkuvuqqeWik0vpWio,15522
9
10
  maker/okxapi.py,sha256=_9G0U_o0ZC8NxaT6PqpiLgxBm9gPobC9PsFHZE1c5w0,553
10
11
  maker/zhen.py.bak,sha256=HNkrQbJts8G9umE9chEFsc0cLQApcM9KOVNMYPpkBXM,10918
11
12
  maker/zhen_2.py,sha256=4IaHVtTCMSlrLGSTZrWpW2q-f7HZsUNRkW_-5QgWv24,10509
12
- openfund_maker-2.0.1.dist-info/METADATA,sha256=0rnk8ay_ii8XOu-UbbqF_U3raNfusEnzjWYdvqCF-4Y,1953
13
- openfund_maker-2.0.1.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
14
- openfund_maker-2.0.1.dist-info/entry_points.txt,sha256=gKMytICEKcMRFQDFkHZLnIpID7UQFoTIM_xcpiiV6Ns,50
15
- openfund_maker-2.0.1.dist-info/RECORD,,
13
+ openfund_maker-2.0.2.dist-info/METADATA,sha256=6_GxwAKR7yNlXakwFH7Q7I0UiOrPTkuqLVJWZCjN8_M,1953
14
+ openfund_maker-2.0.2.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
15
+ openfund_maker-2.0.2.dist-info/entry_points.txt,sha256=gKMytICEKcMRFQDFkHZLnIpID7UQFoTIM_xcpiiV6Ns,50
16
+ openfund_maker-2.0.2.dist-info/RECORD,,