openfund-taker 1.1.5__py3-none-any.whl → 1.2.7__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: openfund-taker
3
- Version: 1.1.5
3
+ Version: 1.2.7
4
4
  Summary: Openfund-taker
5
5
  Requires-Python: >=3.9,<4.0
6
6
  Classifier: Programming Language :: Python :: 3
@@ -9,9 +9,10 @@ Classifier: Programming Language :: Python :: 3.10
9
9
  Classifier: Programming Language :: Python :: 3.11
10
10
  Classifier: Programming Language :: Python :: 3.12
11
11
  Classifier: Programming Language :: Python :: 3.13
12
+ Requires-Dist: TA-Lib (>=0.6.3,<0.7.0)
12
13
  Requires-Dist: ccxt (>=4.4.26,<5.0.0)
13
- Requires-Dist: pydantic-settings (>=2.1.0,<3.0.0)
14
- Requires-Dist: requests (>=2.27.1,<3.0.0)
14
+ Requires-Dist: pandas (>=2.2.3,<3.0.0)
15
+ Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
15
16
  Description-Content-Type: text/markdown
16
17
 
17
18
  # buou_trail
@@ -1,4 +1,4 @@
1
- taker/MultiAssetNewTradingBot.py,sha256=O9yhgiZIggSggdtbKsQsmd4sq3tMEarXDZzds0F-tzg,37100
1
+ taker/MultiAssetNewTradingBot.py,sha256=bpgI6eewTwd7-Q5u2Au0UXd-mvFT1UM9S3H4CXPzf4g,42412
2
2
  taker/MultiAssetOldTradingBot.py,sha256=uBh_BxglvcbaHIsWHM7GI9Qa_QjzsxXaXJAAWEOMO5c,15315
3
3
  taker/ThreeLineTradingBot.py,sha256=oXIoQ8z9AzKzk0z13d0ufj2KGBOk5iHJTJNZQRDKA5U,20625
4
4
  taker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -8,8 +8,8 @@ taker/chua_ok.py,sha256=5pPAoEYbFuKxfZwqNvOO890s-2cy6n69QiI0ZA0GTCQ,12474
8
8
  taker/chua_ok_all.py,sha256=2XnZM6QdB3juSE1pqQIJyh2x1XuhlTlnBKNA3owlJ9E,15267
9
9
  taker/chua_ok_bot.py,sha256=9SW0ujhi6PfN4yR1JZ9NaA37HtnXJ2QAWUfW52NG68w,13109
10
10
  taker/config.py,sha256=YPxghO5i0vgRg9Cja8kGj9O7pgSbbtzOgf3RexqXXwY,1188
11
- taker/main.py,sha256=8cLWzEvQDeELbY5Av7JqkEyYbaNqSbAbVl1tQHXzU8s,1954
12
- openfund_taker-1.1.5.dist-info/METADATA,sha256=rTaexKjlzulJ-bihxUhNKEWJ48wfVxHTY7ZoIestcs4,7502
13
- openfund_taker-1.1.5.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
14
- openfund_taker-1.1.5.dist-info/entry_points.txt,sha256=a7mG8F7aOA5-Gk2vPWuAR4537faxaHUgM_jwIDBZoEc,50
15
- openfund_taker-1.1.5.dist-info/RECORD,,
11
+ taker/main.py,sha256=dTi-Innb_DSKp-esWPc6dVQekrGnv7dNHlv49xmVDfo,2516
12
+ openfund_taker-1.2.7.dist-info/METADATA,sha256=rlwEtnPudCYEkzK1SCkCm2AmDB94XV30TfQDkzu_UAk,7527
13
+ openfund_taker-1.2.7.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
14
+ openfund_taker-1.2.7.dist-info/entry_points.txt,sha256=a7mG8F7aOA5-Gk2vPWuAR4537faxaHUgM_jwIDBZoEc,50
15
+ openfund_taker-1.2.7.dist-info/RECORD,,
@@ -26,7 +26,7 @@ class MultiAssetNewTradingBot:
26
26
  self.current_tier = "无" # 记录当前的仓位模式
27
27
 
28
28
  self.global_symbol_stop_loss_flag = {} # 记录每个symbol是否设置全局止损
29
- self.global_symbol_take_profit_price = {} # 记录每个symbol的止盈价格
29
+ self.global_symbol_stop_loss_price = {} # 记录每个symbol的止损价格
30
30
  # 保留在止盈挂单中最高最低两个价格,计算止盈价格。
31
31
  self.max_market_price = 0.0
32
32
  self.min_market_price = float('inf') # 初始化为浮点数最大值
@@ -231,7 +231,8 @@ class MultiAssetNewTradingBot:
231
231
  def check_reverse_position(self,symbol,position,pair_config):
232
232
  side = position['side']
233
233
  try:
234
- klines = self.get_historical_klines(symbol=symbol)
234
+ klines_period = str(pair_config.get('klines_period', '1m'))
235
+ klines = self.get_historical_klines(symbol=symbol,bar=klines_period)
235
236
 
236
237
  # 计算 快线EMA & 慢线SMA
237
238
  ema_length = pair_config.get('ema', 15)
@@ -352,7 +353,7 @@ class MultiAssetNewTradingBot:
352
353
  # self.logger.debug("已重置最高总盈利和档位状态")
353
354
  # FIXME 目前只支持 单symbol
354
355
  def reset_take_profie(self):
355
- self.global_symbol_take_profit_price.clear()
356
+ self.global_symbol_stop_loss_price.clear()
356
357
  self.global_symbol_stop_loss_flag.clear()
357
358
  # 保留在止盈挂单中最高最低两个价格,计算止盈价格。
358
359
  self.max_market_price = 0.0
@@ -392,32 +393,131 @@ class MultiAssetNewTradingBot:
392
393
  # self.logger.debug(f"Order {algo_ids} cancelled:{rs}")
393
394
  except Exception as e:
394
395
  self.logger.error(f"{symbol} Error cancelling order {algo_ids}: {e}")
395
-
396
- def set_stop_loss_take_profit(self, symbol, position, stop_loss_price=None, take_profit_price=None) -> bool:
397
- self.cancel_all_algo_orders(symbol=symbol)
398
- stop_params = {}
399
-
396
+
397
+ def set_stop_loss_take_profit(self, symbol, position, stop_loss_price=None,take_profit_price=None) -> bool:
398
+ if not stop_loss_price and not take_profit_price:
399
+ self.logger.warning(f"{symbol}: No stop loss price or take profit price provided for {symbol}")
400
+ return False
400
401
  if not position:
401
402
  self.logger.warning(f"{symbol}: No position found for {symbol}")
402
- return
403
+ return False
404
+
405
+ if_stop_loss_success = False
406
+ if_take_profit_success = False
407
+
408
+ if stop_loss_price :
409
+ if_stop_loss_success = self.set_stop_loss(symbol=symbol, position=position, stop_loss_price=stop_loss_price)
410
+ if take_profit_price :
411
+ if_take_profit_success = self.set_take_profit(symbol=symbol, position=position, take_profit_price=take_profit_price)
403
412
 
413
+ return if_stop_loss_success or if_take_profit_success
414
+
415
+ def set_take_profit(self, symbol, position, take_profit_price=None) -> bool:
416
+
417
+ # 计算下单数量
404
418
  amount = abs(float(position['contracts']))
405
-
419
+
406
420
  if amount <= 0:
407
421
  self.logger.warning(f"{symbol}: amount is 0 for {symbol}")
408
422
  return
409
423
 
410
- adjusted_price = self.round_price_to_tick(symbol, stop_loss_price)
424
+ # 取消所有策略订单
425
+ # self.cancel_all_algo_orders(symbol=symbol)
426
+
427
+ # 止损单逻辑
428
+ adjusted_price = self.round_price_to_tick(symbol, take_profit_price)
429
+
430
+ tp_params = {
431
+
411
432
 
412
- # 设置止损单 ccxt 只支持单向(conditional)不支持双向下单(oco、conditional)
413
- if not stop_loss_price:
433
+ 'tpTriggerPx':adjusted_price,
434
+ 'tpOrdPx' : adjusted_price,
435
+ 'tpOrdKind': 'condition',
436
+ 'tpTriggerPxType':'last',
437
+
438
+ 'tdMode':position['marginMode'],
439
+ 'sz': str(amount),
440
+ # 'closeFraction': '1',
441
+ 'cxlOnClosePos': True,
442
+ 'reduceOnly':True
443
+ }
444
+
445
+ side = 'short'
446
+ if position['side'] == side: # 和持仓反向相反下单
447
+ side ='long'
448
+
449
+ orderSide = 'buy' if side == 'long' else 'sell'
450
+
451
+ max_retries = 3
452
+ retry_count = 0
453
+
454
+ while retry_count < max_retries:
455
+ try:
456
+
457
+ self.logger.debug(f"{symbol} - {orderSide}:Pre Take profit order set for {symbol} at {take_profit_price} Starting.... ")
458
+
459
+ self.exchange.create_order(
460
+ symbol=symbol,
461
+ type='optimal_limit_ioc',
462
+
463
+ price=adjusted_price,
464
+ side=orderSide,
465
+ amount=amount,
466
+ params=tp_params
467
+ )
468
+ self.logger.debug(f"{symbol} - {orderSide}: Take profit order set for {symbol} at {take_profit_price} Done.")
469
+ break
470
+
471
+
472
+ except ccxt.NetworkError as e:
473
+ # 处理网络相关错误
474
+ retry_count += 1
475
+ self.logger.warning(f"!! 设置止盈单时发生网络错误,正在进行第{retry_count}次重试: {str(e)}")
476
+ time.sleep(0.1) # 重试前等待1秒
477
+ continue
478
+ except ccxt.ExchangeError as e:
479
+ # 处理交易所API相关错误
480
+ retry_count += 1
481
+ self.logger.warning(f"!! 设置止盈单时发生交易所错误,正在进行第{retry_count}次重试: {str(e)}")
482
+ time.sleep(0.1)
483
+ continue
484
+ except Exception as e:
485
+ # 处理其他未预期的错误
486
+ retry_count += 1
487
+ self.logger.warning(f"!! 设置止盈单时发生未知错误,正在进行第{retry_count}次重试: {str(e)}")
488
+ time.sleep(0.1)
489
+ continue
490
+
491
+ if retry_count >= max_retries:
492
+ # 重试次数用完仍未成功设置止损单
493
+ self.logger.warning(f"!! {symbol} 设置止盈单时重试次数用完仍未成功设置成功。 ")
414
494
  return False
495
+ return True
496
+
497
+
498
+
499
+ def set_stop_loss(self, symbol, position, stop_loss_price=None) -> bool:
415
500
 
416
- stop_params = {
501
+
502
+ # 计算下单数量
503
+ amount = abs(float(position['contracts']))
504
+
505
+ if amount <= 0:
506
+ self.logger.warning(f"{symbol}: amount is 0 for {symbol}")
507
+ return
508
+
509
+ # 取消所有策略订单
510
+ self.cancel_all_algo_orders(symbol=symbol)
511
+
512
+
513
+ # 止损单逻辑
514
+ adjusted_price = self.round_price_to_tick(symbol, stop_loss_price)
515
+
516
+ sl_params = {
417
517
  'slTriggerPx':adjusted_price ,
418
518
  # 'slOrdPx':'-1', # 委托价格为-1时,执行市价止损
419
519
  'slOrdPx' : adjusted_price,
420
- 'slTriggerPxType':'mark',
520
+ 'slTriggerPxType':'last',
421
521
  'tdMode':position['marginMode'],
422
522
  'sz': str(amount),
423
523
  # 'closeFraction': '1',
@@ -433,21 +533,26 @@ class MultiAssetNewTradingBot:
433
533
 
434
534
  max_retries = 3
435
535
  retry_count = 0
436
-
536
+
437
537
  while retry_count < max_retries:
438
538
  try:
539
+
439
540
  self.logger.debug(f"{symbol} - {orderSide}:Pre Stop loss order set for {symbol} at {stop_loss_price} Starting.... ")
541
+
440
542
  self.exchange.create_order(
441
543
  symbol=symbol,
442
- type='conditional',
544
+ type='optimal_limit_ioc',
545
+ # type='conditional',
443
546
  # type='limit',
444
547
  price=adjusted_price,
445
548
  side=orderSide,
446
549
  amount=amount,
447
- params=stop_params
550
+ params=sl_params
448
551
  )
449
552
  self.logger.debug(f"{symbol} - {orderSide}: Stop loss order set for {symbol} at {stop_loss_price} Done.")
450
- return True
553
+ break
554
+
555
+
451
556
  except ccxt.NetworkError as e:
452
557
  # 处理网络相关错误
453
558
  retry_count += 1
@@ -466,10 +571,14 @@ class MultiAssetNewTradingBot:
466
571
  self.logger.warning(f"!! 设置止损单时发生未知错误,正在进行第{retry_count}次重试: {str(e)}")
467
572
  time.sleep(0.1)
468
573
  continue
574
+
575
+ if retry_count >= max_retries:
576
+ # 重试次数用完仍未成功设置止损单
577
+ self.logger.warning(f"!! {symbol} 设置止损单时重试次数用完仍未成功设置成功。 ")
578
+ return False
579
+
580
+ return True
469
581
 
470
- # 重试次数用完仍未成功设置止损单
471
- self.logger.warning(f"!! {symbol} 设置止损单时重试次数用完仍未成功设置成功。 ")
472
- return False
473
582
 
474
583
  def set_global_stop_loss(self, symbol, position, stop_loss_pct=None):
475
584
  """设置全局止损
@@ -482,7 +591,7 @@ class MultiAssetNewTradingBot:
482
591
  """
483
592
  # 如果已经触发过全局止损并且有止损单,则跳过
484
593
  if self.global_symbol_stop_loss_flag.get(symbol, False):
485
-
594
+
486
595
  return
487
596
  else :
488
597
  self.logger.debug(f"{symbol} - 是否设置过全局止损 {self.global_symbol_stop_loss_flag.get(symbol, False)} ")
@@ -492,55 +601,85 @@ class MultiAssetNewTradingBot:
492
601
  # 根据持仓方向计算止损价格
493
602
  side = position['side']
494
603
  if side == 'long':
495
- stop_loss_price = position['entryPrice'] * (1 - stop_loss_pct/100)
604
+ sl_price = position['entryPrice'] * (1 - stop_loss_pct/100)
605
+ tp_price = position['entryPrice'] * (1 + stop_loss_pct*2/100)
496
606
  elif side == 'short':
497
- stop_loss_price = position['entryPrice'] * (1 + stop_loss_pct/100)
607
+ sl_price = position['entryPrice'] * (1 + stop_loss_pct/100)
608
+ tp_price = position['entryPrice'] * (1 - stop_loss_pct*2/100)
498
609
 
499
- order_price = float(self.round_price_to_tick(symbol, stop_loss_price))
610
+ sl_order_price = float(self.round_price_to_tick(symbol, sl_price))
611
+ tp_order_price = float(self.round_price_to_tick(symbol, tp_price))
612
+
613
+ last_sl_price= self.global_symbol_stop_loss_price.get(symbol,None)
614
+ if last_sl_price is not None and last_sl_price == sl_order_price:
615
+ self.global_symbol_stop_loss_flag[symbol] = True
616
+ self.logger.debug(f"{symbol} - {side} 全局止损价没变化: {last_sl_price} = {sl_order_price}")
617
+ return
500
618
 
501
619
  try:
502
620
  # 设置止损单
503
621
  if_success = self.set_stop_loss_take_profit(
504
622
  symbol=symbol,
505
623
  position=position,
506
- stop_loss_price=order_price
624
+ stop_loss_price=sl_order_price,
625
+ take_profit_price=tp_order_price
507
626
  )
508
627
  if if_success:
509
628
  # 设置全局止损标志
510
- self.logger.debug(f"{symbol} - {side} 设置全局止损价: {order_price}")
629
+ self.logger.debug(f"{symbol} - {side} 设置全局止损价: {sl_order_price}")
511
630
  self.global_symbol_stop_loss_flag[symbol] = True
512
- self.global_symbol_take_profit_price[symbol] = order_price
631
+ self.global_symbol_stop_loss_price[symbol] = sl_order_price
513
632
 
514
633
  except Exception as e:
515
634
  error_msg = f"{symbol} - 设置止损时发生错误: {str(e)}"
516
635
  self.logger.error(error_msg)
517
636
  self.send_feishu_notification(error_msg)
518
637
 
519
- def calculate_take_profit_price(self, symbol, position, stop_loss_pct, offset=1) -> float:
638
+ def calculate_take_profile_price(self, symbol, position, take_profile_pct, offset=1) -> float:
639
+ tick_size = float(self.exchange.market(symbol)['precision']['price'])
640
+ # market_price = position['markPrice']
641
+ entry_price = position['entryPrice']
642
+ side = position['side']
643
+
644
+ # 计算止盈价格。
645
+
646
+ if side == 'long':
647
+
648
+ base_price = entry_price * (1-take_profile_pct)
649
+ take_profile_price = entry_price + base_price - offset * tick_size
650
+
651
+
652
+ elif side == 'short':
653
+
654
+ base_price = entry_price * (1-take_profile_pct)
655
+ take_profile_price = entry_price - base_price + offset * tick_size
656
+
657
+ return take_profile_price
658
+
659
+ def calculate_stop_loss_price(self, symbol, position, stop_loss_pct, offset=1) -> float:
520
660
  tick_size = float(self.exchange.market(symbol)['precision']['price'])
521
661
  market_price = position['markPrice']
522
662
  entry_price = position['entryPrice']
523
663
  side = position['side']
524
664
  # base_price = abs(market_price-entry_price) * (1-stop_loss_pct)
525
665
  # 计算止盈价格,用市场价格(取持仓期间历史最高)减去开仓价格的利润,再乘以不同阶段的止盈百分比。
526
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price,symbol,None)
666
+ latest_stop_loss_price = self.exchange.safe_float(self.global_symbol_stop_loss_price,symbol,None)
527
667
  if side == 'long':
528
668
  self.max_market_price = max(market_price,self.max_market_price)
529
669
  base_price = abs(self.max_market_price - entry_price) * (1-stop_loss_pct)
530
- take_profit_price = entry_price + base_price - offset * tick_size
531
- if latest_take_profit_price :
532
- take_profit_price = max(take_profit_price,latest_take_profit_price)
670
+ stop_loss_price = entry_price + base_price - offset * tick_size
671
+ if latest_stop_loss_price :
672
+ stop_loss_price = max(stop_loss_price,latest_stop_loss_price)
533
673
 
534
674
  elif side == 'short':
535
675
  self.min_market_price = min(market_price,self.min_market_price)
536
676
  base_price = abs(self.min_market_price - entry_price) * (1-stop_loss_pct)
537
- take_profit_price = entry_price - base_price + offset * tick_size
538
- if latest_take_profit_price :
539
- take_profit_price = min(take_profit_price,latest_take_profit_price)
540
- return take_profit_price
541
-
542
- # 平仓
677
+ stop_loss_price = entry_price - base_price + offset * tick_size
678
+ if latest_stop_loss_price :
679
+ stop_loss_price = min(stop_loss_price,latest_stop_loss_price)
680
+ return stop_loss_price
543
681
 
682
+ # 市价仓位平仓
544
683
  def close_all_positions(self,symbol,position):
545
684
 
546
685
  amount = abs(float(position['contracts']))
@@ -563,6 +702,7 @@ class MultiAssetNewTradingBot:
563
702
 
564
703
  'mgnMode': td_mode,
565
704
  'posSide': pos_side,
705
+ # 当市价全平时,平仓单是否需要自动撤销,默认为false. false:不自动撤单 true:自动撤单
566
706
  'autoCxl': 'true'
567
707
 
568
708
  }
@@ -582,39 +722,39 @@ class MultiAssetNewTradingBot:
582
722
  self.logger.error(f"{symbol} Error closing position for {symbol}: {e}")
583
723
  self.send_feishu_notification(f"{symbol} Error closing position for {symbol}: {e}")
584
724
 
585
- def check_take_profit_trigger(self, symbol: str, position: dict) -> bool:
725
+ def check_stop_loss_trigger(self, symbol: str, position: dict) -> bool:
586
726
  """
587
- 检查是否触发止盈条件
727
+ 检查是否触发止损条件
588
728
  Args:
589
729
  symbol: 交易对
590
730
  position: 持仓信息
591
731
  Returns:
592
732
  bool: 是否需要平仓
593
733
  """
594
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price, symbol, 0.0)
595
- if latest_take_profit_price == 0.0:
596
- self.logger.warning(f"{symbol} 未设置止盈价格,执行平仓")
734
+ latest_stop_loss_price = self.exchange.safe_float(self.global_symbol_stop_loss_price, symbol, 0.0)
735
+ if latest_stop_loss_price == 0.0:
736
+ self.logger.warning(f"{symbol} 未设置止损价格,执行平仓")
597
737
  return True
598
738
 
599
739
  mark_price = position['markPrice']
600
740
  side = position['side']
601
741
 
602
- if side == 'long' and mark_price < latest_take_profit_price:
603
- self.logger.warning(f"!![非正常关闭]: {symbol} 方向 {side} - 市场价格 {mark_price} 低于止盈 {latest_take_profit_price},触发全局止盈")
742
+ if side == 'long' and mark_price < latest_stop_loss_price:
743
+ self.logger.warning(f"!![非正常关闭]: {symbol} 方向 {side} - 市场价格 {mark_price} 低于止盈 {latest_stop_loss_price},触发全局止盈")
604
744
  return True
605
- elif side == 'short' and mark_price > latest_take_profit_price:
606
- self.logger.warning(f"!![非正常关闭]: {symbol} 方向 {side} - 市场价格 {mark_price} 高于止盈价 {latest_take_profit_price},触发全局止盈")
745
+ elif side == 'short' and mark_price > latest_stop_loss_price:
746
+ self.logger.warning(f"!![非正常关闭]: {symbol} 方向 {side} - 市场价格 {mark_price} 高于止盈价 {latest_stop_loss_price},触发全局止盈")
607
747
  return True
608
748
 
609
749
  return False
610
750
 
611
751
  def check_position(self, symbol, position):
612
752
  # 清理趋势相反的仓位
613
- pair_config = self.trading_pairs_config.get(symbol, {})
614
- self.check_reverse_position(symbol=symbol, position=position, pair_config=pair_config)
753
+ # pair_config = self.trading_pairs_config.get(symbol, {})
754
+ # self.check_reverse_position(symbol=symbol, position=position, pair_config=pair_config)
615
755
 
616
- # 检查是否触发止盈
617
- if self.check_take_profit_trigger(symbol, position):
756
+ # 检查止损是否触发止盈
757
+ if self.check_stop_loss_trigger(symbol, position):
618
758
  self.close_all_positions(symbol=symbol, position=position)
619
759
  return
620
760
 
@@ -655,57 +795,58 @@ class MultiAssetNewTradingBot:
655
795
  self.logger.info(f"{symbol} 低档回撤止盈阈值: {self.low_trail_stop_loss_pct:.2f}%")
656
796
  if total_profit >= self.low_trail_stop_loss_pct:
657
797
 
658
- take_profit_price = self.calculate_take_profit_price(symbol=symbol, position=position,stop_loss_pct=self.low_trail_stop_loss_pct )
798
+ sl_price = self.calculate_stop_loss_price(symbol=symbol, position=position,stop_loss_pct=self.low_trail_stop_loss_pct )
799
+ # tp_price = self.calculate_take_profile_price(symbol=symbol, position=position,stop_loss_pct=self.low_trail_stop_loss_pct)
659
800
  # 判断止盈价格是否变化,无变化不需要设置
660
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price,symbol,0.0)
661
- if take_profit_price == latest_take_profit_price:
801
+ latest_sl_price = self.exchange.safe_float(self.global_symbol_stop_loss_price,symbol,0.0)
802
+ if sl_price == latest_sl_price:
662
803
  self.logger.debug(f"{symbol} 止盈价格未变化,不设置")
663
804
  return
664
- if_success = self.set_stop_loss_take_profit(symbol, position, stop_loss_price=take_profit_price)
805
+ if_success = self.set_stop_loss_take_profit(symbol, position, stop_loss_price=sl_price )
665
806
  if if_success:
666
- self.logger.info(f"{symbol} 总盈利触发低档保护止盈,当前回撤到: {total_profit:.2f}%,市场价格:{position['markPrice']},设置止盈位: {take_profit_price:.9f}")
667
- self.global_symbol_take_profit_price[symbol] = take_profit_price
807
+ self.logger.info(f"{symbol} 总盈利触发低档保护止盈,当前回撤到: {total_profit:.2f}%,市场价格:{position['markPrice']},设置止盈位: {sl_price:.9f}")
808
+ self.global_symbol_stop_loss_price[symbol] = sl_price
668
809
  self.reset_highest_profit_and_tier()
669
- self.send_feishu_notification(f"{symbol} 总盈利触发低档保护止盈,当前回撤到: {total_profit:.2f}%,市场价格:{position['markPrice']},设置止盈位: {take_profit_price:.9f}")
810
+ self.send_feishu_notification(f"{symbol} 总盈利触发低档保护止盈,当前回撤到: {total_profit:.2f}%,市场价格:{position['markPrice']},设置止盈位: {sl_price:.9f}")
670
811
  return
671
812
  elif self.current_tier == "第一档移动止盈":
672
813
  trail_stop_loss = self.highest_total_profit * (1 - self.trail_stop_loss_pct)
673
814
  self.logger.info(f"{symbol} 第一档回撤止盈阈值: {trail_stop_loss:.2f}%")
674
815
  if total_profit >= trail_stop_loss:
675
- take_profit_price = self.calculate_take_profit_price(symbol=symbol, position=position,stop_loss_pct=self.trail_stop_loss_pct )
816
+ sl_price = self.calculate_stop_loss_price(symbol=symbol, position=position,stop_loss_pct=self.trail_stop_loss_pct )
676
817
  # 判断止盈价格是否变化,无变化不需要设置
677
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price,symbol,0.0)
678
- if take_profit_price == latest_take_profit_price :
818
+ latest_sl_price = self.exchange.safe_float(self.global_symbol_stop_loss_price,symbol,0.0)
819
+ if sl_price == latest_sl_price :
679
820
  self.logger.debug(f"{symbol} 止盈价格未变化,不设置")
680
821
  return
681
- if_success = self.set_stop_loss_take_profit(symbol, position, stop_loss_price=take_profit_price)
822
+ if_success = self.set_stop_loss_take_profit(symbol, position, stop_loss_price=sl_price)
682
823
  if if_success:
683
824
  self.logger.info(
684
- f"{symbol} 总盈利达到第一档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']},设置止盈位: {take_profit_price:.9f}")
825
+ f"{symbol} 总盈利达到第一档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']},设置止盈位: {sl_price:.9f}")
685
826
  # 记录一下止盈价格
686
- self.global_symbol_take_profit_price[symbol] = float(take_profit_price)
827
+ self.global_symbol_stop_loss_price[symbol] = float(sl_price)
687
828
  self.reset_highest_profit_and_tier()
688
829
  self.send_feishu_notification(
689
- f"{symbol} 总盈利达到第一档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']}, 设置止盈位: {take_profit_price:.9f}")
830
+ f"{symbol} 总盈利达到第一档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']}, 设置止盈位: {sl_price:.9f}")
690
831
  return
691
832
 
692
833
  elif self.current_tier == "第二档移动止盈":
693
834
  trail_stop_loss = self.highest_total_profit * (1 - self.higher_trail_stop_loss_pct)
694
835
  self.logger.info(f"{symbol} 第二档回撤止盈阈值: {trail_stop_loss:.2f}%")
695
836
  if total_profit >= trail_stop_loss:
696
- take_profit_price = self.calculate_take_profit_price(symbol=symbol, position=position,stop_loss_pct=self.higher_trail_stop_loss_pct)
837
+ sl_price = self.calculate_stop_loss_price(symbol=symbol, position=position,stop_loss_pct=self.higher_trail_stop_loss_pct)
697
838
  # 判断止盈价格是否变化,无变化不需要设置
698
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price,symbol,0.0)
699
- if take_profit_price == latest_take_profit_price:
839
+ latest_sl_price = self.exchange.safe_float(self.global_symbol_stop_loss_price,symbol,0.0)
840
+ if sl_price == latest_sl_price:
700
841
  self.logger.debug(f"{symbol} 止盈价格未变化,不设置")
701
842
  return
702
- if_success = self.set_stop_loss_take_profit(symbol, position, stop_loss_price=take_profit_price)
843
+ if_success = self.set_stop_loss_take_profit(symbol, position, stop_loss_price=sl_price)
703
844
  if if_success:
704
- self.logger.info(f"{symbol} 总盈利达到第二档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']},设置止盈位: {take_profit_price:.9f}")
845
+ self.logger.info(f"{symbol} 总盈利达到第二档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']},设置止盈位: {sl_price:.9f}")
705
846
  # 记录一下止盈价格
706
- self.global_symbol_take_profit_price[symbol] = take_profit_price
847
+ self.global_symbol_stop_loss_price[symbol] = sl_price
707
848
  self.reset_highest_profit_and_tier()
708
- self.send_feishu_notification(f"{symbol} 总盈利达到第二档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']},设置止盈位: {take_profit_price:.9f}")
849
+ self.send_feishu_notification(f"{symbol} 总盈利达到第二档回撤阈值,最高总盈利: {self.highest_total_profit:.2f}%,当前回撤到: {total_profit:.2f}%,市场价格: {position['markPrice']},设置止盈位: {sl_price:.9f}")
709
850
  return
710
851
  else :
711
852
  self.logger.info(f"{symbol} 全局止损阈值: {self.stop_loss_pct:.2f}%")
taker/main.py CHANGED
@@ -1,6 +1,5 @@
1
- import os
2
- import json
3
1
  import logging
2
+ import yaml
4
3
  from logging.handlers import TimedRotatingFileHandler
5
4
 
6
5
  from taker.MultiAssetNewTradingBot import MultiAssetNewTradingBot
@@ -24,17 +23,31 @@ def build_logger(log_config) -> logging.Logger:
24
23
  logger.addHandler(console_handler)
25
24
 
26
25
  return logger
27
-
26
+
27
+ def read_config_file(file_path):
28
+ try:
29
+ # 打开 YAML 文件
30
+ with open(file_path, 'r', encoding='utf-8') as file:
31
+ # 使用 yaml.safe_load 方法解析 YAML 文件内容
32
+ data = yaml.safe_load(file)
33
+ return data
34
+ except FileNotFoundError:
35
+ raise Exception(f"文件 {file_path} 未找到。")
36
+ except yaml.YAMLError as e:
37
+ raise Exception(f"解析 {file_path} 文件时出错: {e}")
28
38
 
29
39
 
30
40
  def main():
31
41
  import importlib.metadata
32
42
  version = importlib.metadata.version("openfund-taker")
33
43
 
34
- openfund_config_path = 'config.json'
44
+ # openfund_config_path = 'config.json'
45
+ openfund_config_path = 'taker_config.yaml'
46
+ config_data = read_config_file(openfund_config_path)
47
+
35
48
 
36
- with open(openfund_config_path, 'r') as f:
37
- config_data = json.load(f)
49
+ # with open(openfund_config_path, 'r') as f:
50
+ # config_data = json.load(f)
38
51
 
39
52
  platform_config = config_data['okx']
40
53
  feishu_webhook_url = config_data['feishu_webhook']