openfund-taker 1.2.2__py3-none-any.whl → 1.2.8__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.2.2
3
+ Version: 1.2.8
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=TJGkAvuEgQv8AnaC3wmhAE9G9R6gJgXc1o4vtLplusQ,37564
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.2.2.dist-info/METADATA,sha256=5L9h4JzuVYsPGByxHS0Cufwgn6tikgrBDKO28egKMW8,7502
13
- openfund_taker-1.2.2.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
14
- openfund_taker-1.2.2.dist-info/entry_points.txt,sha256=a7mG8F7aOA5-Gk2vPWuAR4537faxaHUgM_jwIDBZoEc,50
15
- openfund_taker-1.2.2.dist-info/RECORD,,
11
+ taker/main.py,sha256=dTi-Innb_DSKp-esWPc6dVQekrGnv7dNHlv49xmVDfo,2516
12
+ openfund_taker-1.2.8.dist-info/METADATA,sha256=I5TSrQi-mzrYZmAuE6qUft3sUgepFD2lI2V99XpY_Eo,7527
13
+ openfund_taker-1.2.8.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
14
+ openfund_taker-1.2.8.dist-info/entry_points.txt,sha256=a7mG8F7aOA5-Gk2vPWuAR4537faxaHUgM_jwIDBZoEc,50
15
+ openfund_taker-1.2.8.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') # 初始化为浮点数最大值
@@ -353,7 +353,7 @@ class MultiAssetNewTradingBot:
353
353
  # self.logger.debug("已重置最高总盈利和档位状态")
354
354
  # FIXME 目前只支持 单symbol
355
355
  def reset_take_profie(self):
356
- self.global_symbol_take_profit_price.clear()
356
+ self.global_symbol_stop_loss_price.clear()
357
357
  self.global_symbol_stop_loss_flag.clear()
358
358
  # 保留在止盈挂单中最高最低两个价格,计算止盈价格。
359
359
  self.max_market_price = 0.0
@@ -393,28 +393,127 @@ class MultiAssetNewTradingBot:
393
393
  # self.logger.debug(f"Order {algo_ids} cancelled:{rs}")
394
394
  except Exception as e:
395
395
  self.logger.error(f"{symbol} Error cancelling order {algo_ids}: {e}")
396
-
397
- def set_stop_loss_take_profit(self, symbol, position, stop_loss_price=None, take_profit_price=None) -> bool:
398
- self.cancel_all_algo_orders(symbol=symbol)
399
- stop_params = {}
400
-
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
401
401
  if not position:
402
402
  self.logger.warning(f"{symbol}: No position found for {symbol}")
403
- 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)
404
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
+ # 计算下单数量
405
418
  amount = abs(float(position['contracts']))
406
-
419
+
407
420
  if amount <= 0:
408
421
  self.logger.warning(f"{symbol}: amount is 0 for {symbol}")
409
422
  return
410
423
 
411
- 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
+
432
+
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
412
490
 
413
- # 设置止损单 ccxt 只支持单向(conditional)不支持双向下单(oco、conditional)
414
- if not stop_loss_price:
491
+ if retry_count >= max_retries:
492
+ # 重试次数用完仍未成功设置止损单
493
+ self.logger.warning(f"!! {symbol} 设置止盈单时重试次数用完仍未成功设置成功。 ")
415
494
  return False
495
+ return True
496
+
497
+
498
+
499
+ def set_stop_loss(self, symbol, position, stop_loss_price=None) -> bool:
416
500
 
417
- 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 = {
418
517
  'slTriggerPx':adjusted_price ,
419
518
  # 'slOrdPx':'-1', # 委托价格为-1时,执行市价止损
420
519
  'slOrdPx' : adjusted_price,
@@ -434,21 +533,26 @@ class MultiAssetNewTradingBot:
434
533
 
435
534
  max_retries = 3
436
535
  retry_count = 0
437
-
536
+
438
537
  while retry_count < max_retries:
439
538
  try:
539
+
440
540
  self.logger.debug(f"{symbol} - {orderSide}:Pre Stop loss order set for {symbol} at {stop_loss_price} Starting.... ")
541
+
441
542
  self.exchange.create_order(
442
543
  symbol=symbol,
443
- type='conditional',
544
+ type='optimal_limit_ioc',
545
+ # type='conditional',
444
546
  # type='limit',
445
547
  price=adjusted_price,
446
548
  side=orderSide,
447
549
  amount=amount,
448
- params=stop_params
550
+ params=sl_params
449
551
  )
450
552
  self.logger.debug(f"{symbol} - {orderSide}: Stop loss order set for {symbol} at {stop_loss_price} Done.")
451
- return True
553
+ break
554
+
555
+
452
556
  except ccxt.NetworkError as e:
453
557
  # 处理网络相关错误
454
558
  retry_count += 1
@@ -467,10 +571,14 @@ class MultiAssetNewTradingBot:
467
571
  self.logger.warning(f"!! 设置止损单时发生未知错误,正在进行第{retry_count}次重试: {str(e)}")
468
572
  time.sleep(0.1)
469
573
  continue
574
+
575
+ if retry_count >= max_retries:
576
+ # 重试次数用完仍未成功设置止损单
577
+ self.logger.warning(f"!! {symbol} 设置止损单时重试次数用完仍未成功设置成功。 ")
578
+ return False
579
+
580
+ return True
470
581
 
471
- # 重试次数用完仍未成功设置止损单
472
- self.logger.warning(f"!! {symbol} 设置止损单时重试次数用完仍未成功设置成功。 ")
473
- return False
474
582
 
475
583
  def set_global_stop_loss(self, symbol, position, stop_loss_pct=None):
476
584
  """设置全局止损
@@ -493,16 +601,19 @@ class MultiAssetNewTradingBot:
493
601
  # 根据持仓方向计算止损价格
494
602
  side = position['side']
495
603
  if side == 'long':
496
- 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)
497
606
  elif side == 'short':
498
- 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)
499
609
 
500
- 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))
501
612
 
502
- last_take_profit_price= self.global_symbol_take_profit_price.get(symbol,None)
503
- if last_take_profit_price is not None and last_take_profit_price == order_price:
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:
504
615
  self.global_symbol_stop_loss_flag[symbol] = True
505
- self.logger.debug(f"{symbol} - {side} 全局止损价没变化: {last_take_profit_price} = {order_price}")
616
+ self.logger.debug(f"{symbol} - {side} 全局止损价没变化: {last_sl_price} = {sl_order_price}")
506
617
  return
507
618
 
508
619
  try:
@@ -510,44 +621,65 @@ class MultiAssetNewTradingBot:
510
621
  if_success = self.set_stop_loss_take_profit(
511
622
  symbol=symbol,
512
623
  position=position,
513
- stop_loss_price=order_price
624
+ stop_loss_price=sl_order_price,
625
+ take_profit_price=tp_order_price
514
626
  )
515
627
  if if_success:
516
628
  # 设置全局止损标志
517
- self.logger.debug(f"{symbol} - {side} 设置全局止损价: {order_price}")
629
+ self.logger.debug(f"{symbol} - {side} 设置全局止损价: {sl_order_price}")
518
630
  self.global_symbol_stop_loss_flag[symbol] = True
519
- self.global_symbol_take_profit_price[symbol] = order_price
631
+ self.global_symbol_stop_loss_price[symbol] = sl_order_price
520
632
 
521
633
  except Exception as e:
522
634
  error_msg = f"{symbol} - 设置止损时发生错误: {str(e)}"
523
635
  self.logger.error(error_msg)
524
636
  self.send_feishu_notification(error_msg)
525
637
 
526
- 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:
527
660
  tick_size = float(self.exchange.market(symbol)['precision']['price'])
528
661
  market_price = position['markPrice']
529
662
  entry_price = position['entryPrice']
530
663
  side = position['side']
531
664
  # base_price = abs(market_price-entry_price) * (1-stop_loss_pct)
532
665
  # 计算止盈价格,用市场价格(取持仓期间历史最高)减去开仓价格的利润,再乘以不同阶段的止盈百分比。
533
- 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)
534
667
  if side == 'long':
535
668
  self.max_market_price = max(market_price,self.max_market_price)
536
669
  base_price = abs(self.max_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 = 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)
540
673
 
541
674
  elif side == 'short':
542
675
  self.min_market_price = min(market_price,self.min_market_price)
543
676
  base_price = abs(self.min_market_price - entry_price) * (1-stop_loss_pct)
544
- take_profit_price = entry_price - base_price + offset * tick_size
545
- if latest_take_profit_price :
546
- take_profit_price = min(take_profit_price,latest_take_profit_price)
547
- return take_profit_price
548
-
549
- # 平仓
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
550
681
 
682
+ # 市价仓位平仓
551
683
  def close_all_positions(self,symbol,position):
552
684
 
553
685
  amount = abs(float(position['contracts']))
@@ -570,6 +702,7 @@ class MultiAssetNewTradingBot:
570
702
 
571
703
  'mgnMode': td_mode,
572
704
  'posSide': pos_side,
705
+ # 当市价全平时,平仓单是否需要自动撤销,默认为false. false:不自动撤单 true:自动撤单
573
706
  'autoCxl': 'true'
574
707
 
575
708
  }
@@ -589,39 +722,39 @@ class MultiAssetNewTradingBot:
589
722
  self.logger.error(f"{symbol} Error closing position for {symbol}: {e}")
590
723
  self.send_feishu_notification(f"{symbol} Error closing position for {symbol}: {e}")
591
724
 
592
- def check_take_profit_trigger(self, symbol: str, position: dict) -> bool:
725
+ def check_stop_loss_trigger(self, symbol: str, position: dict) -> bool:
593
726
  """
594
- 检查是否触发止盈条件
727
+ 检查是否触发止损条件
595
728
  Args:
596
729
  symbol: 交易对
597
730
  position: 持仓信息
598
731
  Returns:
599
732
  bool: 是否需要平仓
600
733
  """
601
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price, symbol, 0.0)
602
- if latest_take_profit_price == 0.0:
603
- 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} 未设置止损价格,执行平仓")
604
737
  return True
605
738
 
606
739
  mark_price = position['markPrice']
607
740
  side = position['side']
608
741
 
609
- if side == 'long' and mark_price < latest_take_profit_price:
610
- 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},触发全局止盈")
611
744
  return True
612
- elif side == 'short' and mark_price > latest_take_profit_price:
613
- 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},触发全局止盈")
614
747
  return True
615
748
 
616
749
  return False
617
750
 
618
751
  def check_position(self, symbol, position):
619
752
  # 清理趋势相反的仓位
620
- pair_config = self.trading_pairs_config.get(symbol, {})
621
- 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)
622
755
 
623
- # 检查是否触发止盈
624
- if self.check_take_profit_trigger(symbol, position):
756
+ # 检查止损是否触发止盈
757
+ if self.check_stop_loss_trigger(symbol, position):
625
758
  self.close_all_positions(symbol=symbol, position=position)
626
759
  return
627
760
 
@@ -662,57 +795,58 @@ class MultiAssetNewTradingBot:
662
795
  self.logger.info(f"{symbol} 低档回撤止盈阈值: {self.low_trail_stop_loss_pct:.2f}%")
663
796
  if total_profit >= self.low_trail_stop_loss_pct:
664
797
 
665
- 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)
666
800
  # 判断止盈价格是否变化,无变化不需要设置
667
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price,symbol,0.0)
668
- 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:
669
803
  self.logger.debug(f"{symbol} 止盈价格未变化,不设置")
670
804
  return
671
- 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 )
672
806
  if if_success:
673
- self.logger.info(f"{symbol} 总盈利触发低档保护止盈,当前回撤到: {total_profit:.2f}%,市场价格:{position['markPrice']},设置止盈位: {take_profit_price:.9f}")
674
- 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
675
809
  self.reset_highest_profit_and_tier()
676
- 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}")
677
811
  return
678
812
  elif self.current_tier == "第一档移动止盈":
679
813
  trail_stop_loss = self.highest_total_profit * (1 - self.trail_stop_loss_pct)
680
814
  self.logger.info(f"{symbol} 第一档回撤止盈阈值: {trail_stop_loss:.2f}%")
681
815
  if total_profit >= trail_stop_loss:
682
- 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 )
683
817
  # 判断止盈价格是否变化,无变化不需要设置
684
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price,symbol,0.0)
685
- 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 :
686
820
  self.logger.debug(f"{symbol} 止盈价格未变化,不设置")
687
821
  return
688
- 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)
689
823
  if if_success:
690
824
  self.logger.info(
691
- 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}")
692
826
  # 记录一下止盈价格
693
- self.global_symbol_take_profit_price[symbol] = float(take_profit_price)
827
+ self.global_symbol_stop_loss_price[symbol] = float(sl_price)
694
828
  self.reset_highest_profit_and_tier()
695
829
  self.send_feishu_notification(
696
- 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}")
697
831
  return
698
832
 
699
833
  elif self.current_tier == "第二档移动止盈":
700
834
  trail_stop_loss = self.highest_total_profit * (1 - self.higher_trail_stop_loss_pct)
701
835
  self.logger.info(f"{symbol} 第二档回撤止盈阈值: {trail_stop_loss:.2f}%")
702
836
  if total_profit >= trail_stop_loss:
703
- 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)
704
838
  # 判断止盈价格是否变化,无变化不需要设置
705
- latest_take_profit_price = self.exchange.safe_float(self.global_symbol_take_profit_price,symbol,0.0)
706
- 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:
707
841
  self.logger.debug(f"{symbol} 止盈价格未变化,不设置")
708
842
  return
709
- 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)
710
844
  if if_success:
711
- 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}")
712
846
  # 记录一下止盈价格
713
- self.global_symbol_take_profit_price[symbol] = take_profit_price
847
+ self.global_symbol_stop_loss_price[symbol] = sl_price
714
848
  self.reset_highest_profit_and_tier()
715
- 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}")
716
850
  return
717
851
  else :
718
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']