openfund-maker 1.0.16__py3-none-any.whl → 1.1.0__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.
@@ -49,18 +49,6 @@ class ThreeLineOrdergBot:
49
49
  def get_precision_length(self,symbol) -> int:
50
50
  tick_size = self.get_tick_size(symbol)
51
51
  return len(f"{tick_size:.10f}".rstrip('0').split('.')[1]) if '.' in f"{tick_size:.10f}" else 0
52
-
53
- # def decimal_to_precision(self,symbol,price) -> float:
54
- # from ccxt.base.decimal_to_precision import DECIMAL_PLACES, TICK_SIZE, NO_PADDING, TRUNCATE, ROUND, ROUND_UP, ROUND_DOWN, SIGNIFICANT_DIGITS
55
- # tick_size = self.get_tick_size(symbol)
56
- # new_px = self.exchange.decimal_to_precision(
57
- # n=float(price),
58
- # precision=tick_size,
59
- # rounding_mode=ROUND,
60
- # counting_mode=TICK_SIZE
61
- # )
62
-
63
- # return new_px
64
52
 
65
53
  def get_position_mode(self):
66
54
  try:
@@ -78,7 +66,6 @@ class ThreeLineOrdergBot:
78
66
  except Exception as e:
79
67
  self.logger.error(f"无法检测持仓模式: {e}")
80
68
  return None
81
-
82
69
 
83
70
  def fetch_and_store_all_instruments(self,instType='SWAP'):
84
71
  try:
@@ -123,7 +110,6 @@ class ThreeLineOrdergBot:
123
110
  else:
124
111
  raise ValueError("Unexpected response structure or missing 'c' value")
125
112
 
126
-
127
113
  def get_mark_price(self,symbol):
128
114
  # response = market_api.get_ticker(instId)
129
115
  ticker = self.exchange.fetch_ticker(symbol)
@@ -167,29 +153,29 @@ class ThreeLineOrdergBot:
167
153
  atr = sum(trs[-period:]) / period
168
154
  return atr
169
155
 
170
- def calculate_sma_pandas(self,symbol, kLines, period) -> pd.Series:
156
+ def calculate_sma_pandas(self,symbol, klines, period) -> pd.Series:
171
157
  """
172
158
  使用 pandas 计算 SMA
173
159
  :param KLines K线
174
160
  :param period: SMA 周期
175
161
  :return: SMA 值
176
162
  """
177
- precision= self.get_precision_length(symbol)
178
- df = pd.DataFrame(kLines, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
179
- sma = df['close'].rolling(window=period).mean().round(precision)
163
+
164
+ df = pd.DataFrame(klines, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
165
+ sma = df['close'].rolling(window=period).mean()
180
166
  return sma
181
167
 
182
- def calculate_ema_pandas(self,symbol, kLines, period) -> pd.Series:
168
+ def calculate_ema_pandas(self,symbol, klines, period) -> pd.Series:
183
169
  """
184
170
  使用 pandas 计算 EMA
185
171
  :param KLines K线
186
172
  :param period: EMA 周期
187
173
  :return: EMA 值
188
174
  """
189
- precision= self.get_precision_length(symbol)
190
- df = pd.DataFrame(kLines, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
175
+
176
+ df = pd.DataFrame(klines, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
191
177
  # 计算EMA
192
- ema = df['close'].ewm(span=period, adjust=False).mean().round(precision)
178
+ ema = df['close'].ewm(span=period, adjust=False).mean()
193
179
  return ema
194
180
 
195
181
  def calculate_average_amplitude(self,klines, period=60):
@@ -202,23 +188,187 @@ class ThreeLineOrdergBot:
202
188
  amplitudes.append(amplitude)
203
189
  average_amplitude = sum(amplitudes) / len(amplitudes)
204
190
  return average_amplitude
191
+
192
+ def calculate_range_diff(self,prices:pd.Series) -> float:
193
+ """
194
+ 计算价格列表中最后一个价格与第一个价格的差值。
195
+ Args:
196
+ prices: 价格列表。
197
+ Returns:
198
+ diff: 计算最高价列的最大值与最小值的差值
199
+
200
+ """
201
+ if prices.empty:
202
+ return None
203
+ # 将价格列表转换为pandas Series格式
204
+
205
+ diff = prices.max() - prices.min()
206
+
207
+ return diff
205
208
 
206
- def cancel_all_orders(self,symbol):
207
- try:
208
- # 获取所有未完成订单
209
- params = {
210
- # 'instId': instId
209
+ def calculate_place_order_price(self, symbol,side,base_price, amplitude_limit, offset=1) -> float:
210
+ """
211
+ 计算开仓价格
212
+ Args:
213
+ symbol: 交易对
214
+ side: 开仓方向
215
+ base_price: 开盘价格
216
+ amplitude_limit: 振幅限制
217
+ offset: 偏移量
218
+ Returns:
219
+ place_order_price: 开仓价格
220
+ """
221
+ tick_size = self.get_tick_size(symbol)
222
+ place_order_price = None
223
+ # 计算止盈价格,用市场价格(取持仓期间历史最高)减去开仓价格的利润,再乘以不同阶段的止盈百分比。
224
+
225
+ if side == 'buy':
226
+ place_order_price = base_price * (1- amplitude_limit/100) - offset * tick_size
227
+ else:
228
+ place_order_price = base_price * (1 + amplitude_limit/100) + offset * tick_size
229
+ self.logger.debug(f"++++ {symbol} 下单价格: {place_order_price:.9f} 方向 {side} 基准价格{base_price} 振幅限制 {amplitude_limit} ")
230
+ return float(self.round_price_to_tick(place_order_price,tick_size))
231
+
232
+ # 定义根据均线斜率判断 K 线方向的函数: 0 空 1 多 -1 平
233
+ def judge_k_line_direction(self, symbol, pair_config, ema: pd.Series, klines) -> int:
234
+ """
235
+ 判断K线方向
236
+ Args:
237
+ symbol: 交易对
238
+ pair_config: 配置参数
239
+ ema: EMA数据
240
+ Returns:
241
+ int: -1:平, 0:空, 1:多
242
+ """
243
+ # 获取配置参数
244
+ period = int(pair_config.get('ema_range_period', 3))
245
+
246
+ # precision= self.get_precision_length(symbol)
247
+
248
+ ema_4_diff = ema.diff().tail(period)
249
+
250
+ direction = None
251
+ if all(ema_4_diff <= 0) :
252
+ # 下降趋势
253
+ direction = 0
254
+ elif all(ema_4_diff >= 0) :
255
+ # 上升趋势
256
+ direction = 1
257
+ else:
258
+ # 震荡趋势
259
+ direction = -1
260
+ self.logger.debug(f"{symbol}: K线极差={ema_4_diff.map('{:.9f}'.format).values} ,K线方向={direction}")
261
+ return direction
262
+
263
+ def judge_ema_direction(self, symbol, pair_config, ema: pd.Series) -> int:
264
+ """
265
+ 判断EMA方向
266
+ Args:
267
+ symbol: 交易对
268
+ pair_config: 配置参数
269
+ ema: EMA数据
270
+ Returns:
271
+ int: -1:平, 0:空, 1:多
272
+ """
273
+ # 获取配置参数
274
+ period = int(pair_config.get('ema_range_period', 3))
275
+
276
+ precision= self.get_precision_length(symbol)
277
+
278
+ ema_4_diff = ema.round(precision).diff().tail(period)
279
+
280
+ direction = None
281
+ if all(ema_4_diff <= 0) and any(ema_4_diff < 0) :
282
+ # 下降趋势
283
+ direction = 0
284
+ elif all(ema_4_diff >= 0) and any(ema_4_diff > 0) :
285
+ # 上升趋势
286
+ direction = 1
287
+ # 都是 (0 0 0) 或 (+ 0 -) 这两种情况认为都是震荡
288
+ else:
289
+ # 震荡趋势
290
+ direction = -1
291
+ self.logger.debug(f"{symbol}: EMA极差={ema_4_diff.map('{:.4f}'.format).values} ,EMA方向={direction}")
292
+ return direction
293
+
294
+ def judge_cross_direction(self,fastklines,slowklines) :
295
+ # 创建DataFrame
296
+ df = pd.DataFrame({
297
+ 'fast': fastklines,
298
+ 'slow': slowklines
299
+ })
300
+
301
+ # 判断金叉和死叉
302
+ df['golden_cross'] = (df['fast'] > df['slow']) & (df['fast'].shift(1) < df['slow'].shift(1))
303
+ df['death_cross'] = (df['fast'] < df['slow']) & (df['fast'].shift(1) > df['slow'].shift(1))
304
+
305
+ # 从后往前找最近的交叉点
306
+ last_golden = df['golden_cross'].iloc[::-1].idxmax() if df['golden_cross'].any() else None
307
+ last_death = df['death_cross'].iloc[::-1].idxmax() if df['death_cross'].any() else None
308
+
309
+ # 判断最近的交叉类型
310
+ if last_golden is None and last_death is None:
311
+ return {
312
+ 'cross': -1, # 无交叉
313
+ 'index': None
211
314
  }
212
- open_orders = self.exchange.fetch_open_orders(symbol=symbol,params=params)
213
-
214
- # 取消每个订单
215
- for order in open_orders:
216
- self.exchange.cancel_order(order['id'], symbol,params=params)
217
-
218
- self.logger.info(f"{symbol} 挂单取消成功.")
219
- except Exception as e:
220
- self.logger.error(f"{symbol} 取消订单失败: {str(e)}")
315
+
316
+ # 如果金叉更近或只有金叉
317
+ if last_golden is not None and (last_death is None or last_golden > last_death):
318
+ return {
319
+ 'cross': 1, # 金叉
320
+ 'index': last_golden
321
+ }
322
+ # 如果死叉更近或只有死叉
323
+ else:
324
+ return {
325
+ 'cross': 0, # 死叉
326
+ 'index': last_death
327
+ }
328
+
329
+ def judge_ma_apex(self,symbol,pair_config, fastklines,slowklines) -> bool:
330
+ period = int(pair_config.get('ema_range_period', 3))
331
+ precision= self.get_precision_length(symbol)
332
+
333
+ df = pd.DataFrame({
334
+ 'ema': fastklines,
335
+ 'sma': slowklines
336
+ })
337
+ # 快线和慢线的差值
338
+ # 将ema和sma转换为tick_size精度
339
+ # df['diff'] = df['ema'].apply(lambda x: float(self.round_price_to_tick(x, tick_size))) - df['sma'].apply(lambda x: float(self.round_price_to_tick(x, tick_size)))
340
+ df['diff'] = df['ema'].round(precision)-df['sma'].round(precision)
341
+ df['ema_diff'] = df['ema'] - df['ema'].shift(1)
342
+ df['sma_diff'] = df['sma'] - df['sma'].shift(1)
343
+ # 计算斜率,【正】表示两线距离扩张,【负】表示两线距离收缩
344
+ df['slope'] = df['diff'].abs().diff().round(4)
345
+
346
+ self.logger.debug(f"{symbol}: slopes = \n{df[['ema','ema_diff','sma','sma_diff','diff','slope']].iloc[-6:-1]} ")
347
+
348
+ # 两条线的距离是扩张状态还是收缩状态 true 是收缩 flase 是扩张
349
+ is_expanding_or_contracting = all(df['slope'].tail(period) <= 0 ) and any(df['slope'].tail(period) < 0)
221
350
 
351
+ return is_expanding_or_contracting
352
+
353
+ def judge_range_diff(self,symbol,pair_config,prices:pd.Series) -> bool:
354
+ """
355
+ 计算价格列表中最后一个价格与第一个价格的差值。
356
+ Args:
357
+ prices: 价格列表。
358
+ Returns:
359
+ diff: 计算最高价列的最大值与最小值的差值
360
+
361
+ """
362
+ limit = int(pair_config.get('ema_range_limit', 1))
363
+ period = int(pair_config.get('ema_range_period', 3))
364
+ tick_size = self.get_tick_size(symbol)
365
+ if prices.empty:
366
+ return None
367
+
368
+ diff = prices.tail(period).max() - prices.tail(period).min()
369
+ self.logger.debug(f"{symbol}: 最高价列的最大值与最小值的差值 = {diff:.9f}")
370
+ return abs(diff) <= tick_size * limit
371
+
222
372
  def set_leverage(self,symbol, leverage, mgnMode='isolated',posSide=None):
223
373
  try:
224
374
  # 设置杠杆
@@ -255,7 +405,6 @@ class ThreeLineOrdergBot:
255
405
  self.logger.error(f"{symbol} 检查持仓失败: {str(e)}")
256
406
  return False
257
407
 
258
-
259
408
  def place_order(self,symbol, price, amount_usdt, side):
260
409
 
261
410
 
@@ -312,147 +461,24 @@ class ThreeLineOrdergBot:
312
461
  # self.logger.debug(f"{symbol} ++ Order placed rs : {order_result}")
313
462
  except Exception as e:
314
463
  self.logger.error(f"{symbol} Failed to place order: {e}")
315
- self.logger.info(f"--------- ++ {symbol} Order placed done! --------")
316
-
317
- # 定义根据均线斜率判断 K 线方向的函数: 0 空 1 多 -1 平
318
- def judge_k_line_direction(self,symbol, pair_config, ema:pd.Series) -> int:
319
- """
320
- 判断K线方向
321
- Args:
322
- symbol: 交易对
323
- pair_config: 配置参数
324
- ema: EMA数据
325
- Returns:
326
- int: -1:平, 0:空, 1:多
327
- """
328
- def check_ema_range(ema_data: pd.Series, period: int, limit: float, tick_size: float) -> bool:
329
- """检查EMA是否在指定范围内震荡"""
330
- ema_window = ema_data[-period:]
331
- price_range = ema_window.max() - ema_window.min()
332
- return abs(price_range) <= limit * tick_size
333
-
334
- def get_trend_direction(slope: float) -> int:
335
- """根据斜率判断趋势方向"""
336
- if slope > 0:
337
- return 1 # 上升趋势
338
- elif slope < 0:
339
- return 0 # 下降趋势
340
- return -1 # 震荡趋势
341
-
342
- # 获取配置参数
343
- tick_size = self.get_tick_size(symbol)
344
- ema_range_period = int(pair_config.get('ema_range_period', 3))
345
- ema_range_limit = float(pair_config.get('ema_range_limit', 1))
346
-
347
- # 判断是否在震荡区间
348
- if check_ema_range(ema, ema_range_period, ema_range_limit, tick_size):
349
- direction = -1
350
- else:
351
- # 计算最新斜率并判断方向
352
- latest_slope = ema.diff().iloc[-1]
353
- direction = get_trend_direction(latest_slope)
354
-
355
- self.logger.debug(f"{symbol}: 极差={abs(ema[-ema_range_period:].max() - ema[-ema_range_period:].min()):.9f} "
356
- f"斜率={ema.diff().iloc[-1]:.9f}, K线方向 {direction}")
357
-
358
- return direction
464
+ self.logger.info(f"--------- ++ {symbol} Order placed done! --------")
359
465
 
360
- def judge_cross_direction(self,fastklines,slowklines) :
361
- # 创建DataFrame
362
- df = pd.DataFrame({
363
- 'fast': fastklines,
364
- 'slow': slowklines
365
- })
366
-
367
- # 判断金叉和死叉
368
- df['golden_cross'] = (df['fast'] > df['slow']) & (df['fast'].shift(1) < df['slow'].shift(1))
369
- df['death_cross'] = (df['fast'] < df['slow']) & (df['fast'].shift(1) > df['slow'].shift(1))
370
-
371
- # 从后往前找最近的交叉点
372
- last_golden = df['golden_cross'].iloc[::-1].idxmax() if df['golden_cross'].any() else None
373
- last_death = df['death_cross'].iloc[::-1].idxmax() if df['death_cross'].any() else None
374
-
375
- # 判断最近的交叉类型
376
- if last_golden is None and last_death is None:
377
- return {
378
- 'cross': -1, # 无交叉
379
- 'index': None
380
- }
381
-
382
- # 如果金叉更近或只有金叉
383
- if last_golden is not None and (last_death is None or last_golden > last_death):
384
- return {
385
- 'cross': 1, # 金叉
386
- 'index': last_golden
387
- }
388
- # 如果死叉更近或只有死叉
389
- else:
390
- return {
391
- 'cross': 0, # 死叉
392
- 'index': last_death
466
+ def cancel_all_orders(self,symbol):
467
+ try:
468
+ # 获取所有未完成订单
469
+ params = {
470
+ # 'instId': instId
393
471
  }
472
+ open_orders = self.exchange.fetch_open_orders(symbol=symbol,params=params)
473
+
474
+ # 取消每个订单
475
+ for order in open_orders:
476
+ self.exchange.cancel_order(order['id'], symbol,params=params)
477
+
478
+ self.logger.info(f"{symbol} 挂单取消成功.")
479
+ except Exception as e:
480
+ self.logger.error(f"{symbol} 取消订单失败: {str(e)}")
394
481
 
395
- def judge_ma_apex(self,symbol, fastklines,slowklines) -> bool:
396
-
397
- df = pd.DataFrame({
398
- 'ema': fastklines,
399
- 'sma': slowklines
400
- })
401
- # 快线和慢线的差值
402
- # 将ema和sma转换为tick_size精度
403
- # df['diff'] = df['ema'].apply(lambda x: float(self.round_price_to_tick(x, tick_size))) - df['sma'].apply(lambda x: float(self.round_price_to_tick(x, tick_size)))
404
- df['diff'] = df['ema']-df['sma']
405
- # 计算斜率,【正】表示两线距离扩张,【负】表示两线距离收缩
406
- df['slope'] = df['diff'].abs().diff().round(4)
407
- df['flag'] = df['slope'] <= 0.0
408
-
409
- self.logger.debug(f"{symbol}: slopes = \n{df[['ema','sma','diff','slope','flag']].iloc[-6:-1]} ")
410
- # 检查最后两个斜率是否都为负
411
- # 取slopes最新的第2个和第3个值进行判断
412
-
413
- return all(slope <= 0.0 for slope in df['slope'].iloc[-3:-1])
414
-
415
-
416
- def calculate_range_diff(self,prices:pd.Series) -> float:
417
- """
418
- 计算价格列表中最后一个价格与第一个价格的差值。
419
- Args:
420
- prices: 价格列表。
421
- Returns:
422
- diff: 计算最高价列的最大值与最小值的差值
423
-
424
- """
425
- if prices.empty:
426
- return None
427
- # 将价格列表转换为pandas Series格式
428
-
429
- diff = prices.max() - prices.min()
430
-
431
- return diff
432
-
433
- def calculate_place_order_price(self, symbol,side,base_price, amplitude_limit, offset=1) -> float:
434
- """
435
- 计算开仓价格
436
- Args:
437
- symbol: 交易对
438
- side: 开仓方向
439
- base_price: 开盘价格
440
- amplitude_limit: 振幅限制
441
- offset: 偏移量
442
- Returns:
443
- place_order_price: 开仓价格
444
- """
445
- tick_size = float(self.exchange.market(symbol)['precision']['price'])
446
- place_order_price = None
447
- # 计算止盈价格,用市场价格(取持仓期间历史最高)减去开仓价格的利润,再乘以不同阶段的止盈百分比。
448
-
449
- if side == 'buy':
450
- place_order_price = base_price * (1- amplitude_limit/100) - offset * tick_size
451
- else:
452
- place_order_price = base_price * (1 + amplitude_limit/100) + offset * tick_size
453
- self.logger.debug(f"++++ {symbol} 下单价格: {place_order_price:.9f} 方向 {side} 基准价格{base_price} 振幅限制 {amplitude_limit} ")
454
- return float(self.round_price_to_tick(place_order_price,tick_size))
455
-
456
482
  def process_pair(self,symbol,pair_config):
457
483
  # 检查是否有持仓,有持仓不进行下单
458
484
  if self.check_position(symbol=symbol) :
@@ -474,8 +500,8 @@ class ThreeLineOrdergBot:
474
500
  sma_length = pair_config.get('sma', 50)
475
501
 
476
502
  # 增加 金叉死叉 方向确认的 20250209
477
- fastk = self.calculate_ema_pandas(symbol, klines, period=ema_length)
478
- slowk = self.calculate_sma_pandas(symbol, klines, period=sma_length)
503
+ fastk = self.calculate_ema_pandas(symbol=symbol, klines=klines, period=ema_length)
504
+ slowk = self.calculate_sma_pandas(symbol=symbol, klines=klines, period=sma_length)
479
505
 
480
506
  cross_direction = self.judge_cross_direction(fastklines=fastk,slowklines=slowk)
481
507
  # 更新交叉状态
@@ -487,27 +513,37 @@ class ThreeLineOrdergBot:
487
513
 
488
514
 
489
515
  # 判断趋势:多头趋势或空头趋势
490
- direction = self.judge_k_line_direction(symbol=symbol, pair_config=pair_config,ema=fastk)
516
+ direction = self.judge_k_line_direction(symbol=symbol, pair_config=pair_config,ema=fastk,klines=klines)
491
517
  if direction == 1:
492
518
  is_bullish_trend = True
493
519
  elif direction == 0:
494
520
  is_bearish_trend = True
495
521
 
496
522
  # 结合金叉死叉判断是否是周期顶部和底部
497
- is_apex = self.judge_ma_apex(symbol=symbol,fastklines=fastk,slowklines=slowk)
523
+ is_apex = self.judge_ma_apex(symbol=symbol,pair_config=pair_config, fastklines=fastk,slowklines=slowk)
524
+ ema_direction = self.judge_ema_direction(symbol=symbol, pair_config=pair_config,ema=fastk)
525
+ if_inner_range = self.judge_range_diff(symbol=symbol, pair_config=pair_config, prices=fastk)
498
526
  # 金叉死叉逻辑
499
527
  if last_cross_direction and last_cross_direction['cross'] == 1 : # 金叉
500
528
  self.logger.debug(f"{symbol} 金叉:{last_cross_direction},清理空单,挂多单!!")
501
529
  is_bearish_trend = False
502
- if is_apex :
503
- self.logger.debug(f"{symbol} 金叉:{last_cross_direction},周期见顶 {is_apex},不开单!!")
530
+ # 强校验下单条件
531
+ if is_apex or ema_direction == -1 or if_inner_range:
532
+ self.logger.debug(f"{symbol} 强校验 - 死叉:{last_cross_direction},两线收缩={is_apex} ,ema_平={ema_direction},均线振幅={if_inner_range} ,不开单!!")
533
+ # 弱校验下单条件
534
+ # if is_apex or ema_direction == -1:
535
+ # self.logger.debug(f"{symbol} 金叉:{last_cross_direction},两线收缩={is_apex} ,ema_平={ema_direction},不开单!!")
504
536
  is_bullish_trend = False
505
537
 
506
538
  elif last_cross_direction and last_cross_direction['cross'] == 0 : # 死叉
507
539
  self.logger.debug(f"{symbol} 死叉:{last_cross_direction},清理多单,挂空单!!")
508
540
  is_bullish_trend = False
509
- if is_apex :
510
- self.logger.debug(f"{symbol} 死叉:{last_cross_direction},周期见顶 {is_apex},不开单!!")
541
+ # 强校验下单条件
542
+ if is_apex or ema_direction == -1 or if_inner_range :
543
+ self.logger.debug(f"{symbol} 强校验 - 死叉:{last_cross_direction},两线收缩={is_apex} ,ema_平={ema_direction},均线振幅={if_inner_range} ,不开单!!")
544
+ # 弱校验下单条件
545
+ # if is_apex or ema_direction == -1:
546
+ # self.logger.debug(f"{symbol} 死叉:{last_cross_direction},两线收缩={is_apex} ,ema_平={ema_direction},不开单!!")
511
547
  is_bearish_trend = False
512
548
 
513
549
  else:
@@ -535,9 +571,7 @@ class ThreeLineOrdergBot:
535
571
 
536
572
  amplitude_limit = pair_config.get('amplitude_limit', 0.32)
537
573
 
538
- self.logger.debug(f"{symbol} 当前K线的前三根K线 最高价: {max_high}, 最低价: {min_low}")
539
-
540
-
574
+ self.logger.debug(f"{symbol} 当前K线的前三根K线 最高价: {max_high}, 最低价: {min_low}")
541
575
 
542
576
  long_amount_usdt = pair_config.get('long_amount_usdt', 5)
543
577
  short_amount_usdt = pair_config.get('short_amount_usdt', 5)
@@ -550,6 +584,7 @@ class ThreeLineOrdergBot:
550
584
  close_price = klines[-1][4]
551
585
  self.logger.debug(f"-- {symbol} 最新K线 {klines[-1]}")
552
586
 
587
+ # FIXME calculate_range_diff 去掉
553
588
  if is_bullish_trend:
554
589
  diff = self.calculate_range_diff(prices=low_prices)
555
590
  cur_amplitude_limit = diff / close_price * 100
@@ -579,8 +614,6 @@ class ThreeLineOrdergBot:
579
614
  self.logger.error(error_message,exc_info=True)
580
615
  traceback.print_exc()
581
616
  self.send_feishu_notification(error_message)
582
-
583
-
584
617
 
585
618
  def monitor_klines(self):
586
619
  symbols = list(self.trading_pairs_config.keys()) # 获取所有币对的ID
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: openfund-maker
3
- Version: 1.0.16
3
+ Version: 1.1.0
4
4
  Summary: Openfund-maker.
5
5
  Requires-Python: >=3.9,<4.0
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,4 +1,4 @@
1
- maker/ThreeLineOrderBot.py,sha256=e-KVx6a4cW2Afe0kNOKcA8isDObnzM_7wEmIlfw9tcI,25741
1
+ maker/ThreeLineOrderBot.py,sha256=UBWtLMJtL6mAS4CLYThja5Z_XE7UCD4bBhik0T0Xp0s,27521
2
2
  maker/WickReversalOrderBot.py,sha256=Oc6wChdWu39lfWh3NRHM8BqvaRIYDNZiDR6PDnE9XUM,17374
3
3
  maker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  maker/config.py,sha256=YPxghO5i0vgRg9Cja8kGj9O7pgSbbtzOgf3RexqXXwY,1188
@@ -7,7 +7,7 @@ maker/main_m.py,sha256=0PzDTnuBrxfpy5WDfsIHKAzZ_7pkuvuqqeWik0vpWio,15522
7
7
  maker/okxapi.py,sha256=_9G0U_o0ZC8NxaT6PqpiLgxBm9gPobC9PsFHZE1c5w0,553
8
8
  maker/zhen.py.bak,sha256=HNkrQbJts8G9umE9chEFsc0cLQApcM9KOVNMYPpkBXM,10918
9
9
  maker/zhen_2.py,sha256=4IaHVtTCMSlrLGSTZrWpW2q-f7HZsUNRkW_-5QgWv24,10509
10
- openfund_maker-1.0.16.dist-info/METADATA,sha256=CkBN5XbxLll1H5OvDev47s8mYi4cS80yqIg50Q-fVJw,1966
11
- openfund_maker-1.0.16.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
12
- openfund_maker-1.0.16.dist-info/entry_points.txt,sha256=gKMytICEKcMRFQDFkHZLnIpID7UQFoTIM_xcpiiV6Ns,50
13
- openfund_maker-1.0.16.dist-info/RECORD,,
10
+ openfund_maker-1.1.0.dist-info/METADATA,sha256=y6UyUbgh-IJwrJiklJxR4mBCK-SQg56J2EpDI8cIIVc,1965
11
+ openfund_maker-1.1.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
12
+ openfund_maker-1.1.0.dist-info/entry_points.txt,sha256=gKMytICEKcMRFQDFkHZLnIpID7UQFoTIM_xcpiiV6Ns,50
13
+ openfund_maker-1.1.0.dist-info/RECORD,,