openfund-taker 1.0.16__py3-none-any.whl → 1.0.17__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.0.16
3
+ Version: 1.0.17
4
4
  Summary: Openfund-taker
5
5
  Requires-Python: >=3.9,<4.0
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,4 +1,4 @@
1
- taker/MultiAssetNewTradingBot.py,sha256=U03nCRuzEGtV0OMIkblt5VUqYmaILZ9eJwZTSZkiSRg,35035
1
+ taker/MultiAssetNewTradingBot.py,sha256=ZHQQslFi_BeewvkqkALP4Nop9un3JvUkjQR0pWgjhvk,35055
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
@@ -9,7 +9,7 @@ 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
11
  taker/main.py,sha256=8cLWzEvQDeELbY5Av7JqkEyYbaNqSbAbVl1tQHXzU8s,1954
12
- openfund_taker-1.0.16.dist-info/METADATA,sha256=oQ0OgqkT--dIfZvsM3f3EDAw3PfMMmAfgN7R0Tna_C8,7503
13
- openfund_taker-1.0.16.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
14
- openfund_taker-1.0.16.dist-info/entry_points.txt,sha256=a7mG8F7aOA5-Gk2vPWuAR4537faxaHUgM_jwIDBZoEc,50
15
- openfund_taker-1.0.16.dist-info/RECORD,,
12
+ openfund_taker-1.0.17.dist-info/METADATA,sha256=ocHhC9D7pvCW1Ciw_q4o2D0WMwZgsIsvgJ5b3YrVH08,7503
13
+ openfund_taker-1.0.17.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
14
+ openfund_taker-1.0.17.dist-info/entry_points.txt,sha256=a7mG8F7aOA5-Gk2vPWuAR4537faxaHUgM_jwIDBZoEc,50
15
+ openfund_taker-1.0.17.dist-info/RECORD,,
@@ -117,7 +117,7 @@ class MultiAssetNewTradingBot:
117
117
  else:
118
118
  raise ValueError("Unexpected response structure or missing candlestick data")
119
119
 
120
- def judge_cross_direction(self,fastklines,slowklines) :
120
+ def judge_cross_direction(self,symbol, fastklines ,slowklines) :
121
121
  # 创建DataFrame
122
122
  df = pd.DataFrame({
123
123
  'fast': fastklines,
@@ -131,7 +131,9 @@ class MultiAssetNewTradingBot:
131
131
  # 从后往前找最近的交叉点
132
132
  last_golden = df['golden_cross'].iloc[::-1].idxmax() if df['golden_cross'].any() else None
133
133
  last_death = df['death_cross'].iloc[::-1].idxmax() if df['death_cross'].any() else None
134
+ # self.logger.debug(f"golden_cross = {last_golden}, death_cross = {last_death}")
134
135
 
136
+ # self.logger.debug(f"df= \n{df[['fast','slow','golden_cross','death_cross']].tail()}")
135
137
  # 判断最近的交叉类型
136
138
  if last_golden is None and last_death is None:
137
139
  return {
@@ -152,29 +154,34 @@ class MultiAssetNewTradingBot:
152
154
  'index': last_death
153
155
  }
154
156
 
157
+ def judge_ma_apex(self,symbol,pair_config, fastklines,slowklines) -> bool:
158
+ period = int(pair_config.get('ema_range_period', 3))
159
+ precision= self.get_precision_length(symbol)
155
160
 
156
- def judge_ma_apex(self,symbol, fastklines,slowklines) -> bool:
157
161
  df = pd.DataFrame({
158
162
  'ema': fastklines,
159
163
  'sma': slowklines
160
164
  })
161
-
162
165
  # 快线和慢线的差值
163
- df['diff'] = df['ema']-df['sma']
166
+ # emasma转换为tick_size精度
167
+ # 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)))
168
+ df['diff'] = df['ema'].round(precision)-df['sma'].round(precision)
169
+ df['ema_diff'] = df['ema'] - df['ema'].shift(1)
170
+ df['sma_diff'] = df['sma'] - df['sma'].shift(1)
164
171
  # 计算斜率,【正】表示两线距离扩张,【负】表示两线距离收缩
165
172
  df['slope'] = df['diff'].abs().diff().round(4)
166
- df['flag'] = df['slope'] <= 0.0
167
173
 
168
- self.logger.debug(f"{symbol}: slopes = \n{df[['ema','sma','diff','slope','flag']].iloc[-6:-1]} ")
169
- # 检查最后两个斜率是否都为负
170
- # 取slopes最新的第2个和第3个值进行判断
171
- # 20250213 因为有持仓,因此判定条件更严谨,只有收缩才平仓
172
- return all(slope < 0.0 for slope in df['slope'].iloc[-3:-1])
174
+ self.logger.debug(f"{symbol}: slopes = \n{df[['ema','ema_diff','sma','sma_diff','diff','slope']].iloc[-6:-1]} ")
175
+
176
+ # 两条线的距离是扩张状态还是收缩状态 true 是收缩 flase 是扩张
177
+ is_expanding_or_contracting = all(df['slope'].tail(period) <= 0 ) and any(df['slope'].tail(period) < 0)
178
+
179
+ return is_expanding_or_contracting
173
180
 
174
181
  # 定义根据均线斜率判断 K 线方向的函数: 0 空 1 多 -1 平
175
182
 
176
183
  # 定义根据均线斜率判断 K 线方向的函数: 0 空 1 多 -1 平
177
- def judge_k_line_direction(self,symbol, pair_config, ema:pd.Series) -> int:
184
+ def judge_k_line_direction(self, symbol, pair_config, ema: pd.Series, klines) -> int:
178
185
  """
179
186
  判断K线方向
180
187
  Args:
@@ -184,36 +191,22 @@ class MultiAssetNewTradingBot:
184
191
  Returns:
185
192
  int: -1:平, 0:空, 1:多
186
193
  """
187
- def check_ema_range(ema_data: pd.Series, period: int, limit: float, tick_size: float) -> bool:
188
- """检查EMA是否在指定范围内震荡"""
189
- ema_window = ema_data[-period:]
190
- price_range = ema_window.max() - ema_window.min()
191
- return abs(price_range) <= limit * tick_size
192
-
193
- def get_trend_direction(slope: float) -> int:
194
- """根据斜率判断趋势方向"""
195
- if slope > 0:
196
- return 1 # 上升趋势
197
- elif slope < 0:
198
- return 0 # 下降趋势
199
- return -1 # 震荡趋势
200
-
201
194
  # 获取配置参数
202
- tick_size = self.get_tick_size(symbol)
203
- ema_range_period = int(pair_config.get('ema_range_period', 3))
204
- ema_range_limit = float(pair_config.get('ema_range_limit', 1))
195
+ period = int(pair_config.get('ema_range_period', 3))
205
196
 
206
- # 判断是否在震荡区间
207
- if check_ema_range(ema, ema_range_period, ema_range_limit, tick_size):
208
- direction = -1
197
+ ema_4_diff = ema.diff().tail(period)
198
+
199
+ direction = None
200
+ if all(ema_4_diff <= 0) :
201
+ # 下降趋势
202
+ direction = 0
203
+ elif all(ema_4_diff >= 0) :
204
+ # 上升趋势
205
+ direction = 1
209
206
  else:
210
- # 计算最新斜率并判断方向
211
- latest_slope = ema.diff().iloc[-1]
212
- direction = get_trend_direction(latest_slope)
213
-
214
- self.logger.debug(f"{symbol}: 极差={abs(ema[-ema_range_period:].max() - ema[-ema_range_period:].min()):.9f} "
215
- f"斜率={ema.diff().iloc[-1]:.9f}, K线方向 {direction}")
216
-
207
+ # 震荡趋势
208
+ direction = -1
209
+ self.logger.debug(f"{symbol}: K线极差={ema_4_diff.map('{:.9f}'.format).values} ,K线方向={direction}")
217
210
  return direction
218
211
 
219
212
  def check_reverse_position(self,symbol,position,pair_config):
@@ -229,7 +222,8 @@ class MultiAssetNewTradingBot:
229
222
  fastk = self.calculate_ema_pandas(symbol, klines, period=ema_length)
230
223
  slowk = self.calculate_sma_pandas(symbol, klines, period=sma_length)
231
224
 
232
- cross_direction = self.judge_cross_direction(fastklines=fastk,slowklines=slowk)
225
+ cross_direction = self.judge_cross_direction(symbol=symbol,fastklines=fastk,slowklines=slowk)
226
+
233
227
  # 更新交叉状态
234
228
  if cross_direction['cross'] != -1 : #本次不一定有交叉
235
229
  self.cross_directions[symbol] = cross_direction
@@ -238,16 +232,18 @@ class MultiAssetNewTradingBot:
238
232
  last_cross_direction = self.exchange.safe_dict(self.cross_directions,symbol,None)
239
233
  # 计算 快线EMA & 慢线SMA
240
234
  # 结合金叉死叉判断是否是周期顶部和底部
241
- is_apex = self.judge_ma_apex(symbol=symbol,fastklines=fastk,slowklines=slowk)
235
+ is_apex = self.judge_ma_apex(symbol=symbol,pair_config=pair_config, fastklines=fastk,slowklines=slowk)
236
+
237
+ kline_direction = self.judge_k_line_direction(symbol=symbol, pair_config=pair_config, ema=fastk, klines=klines)
242
238
 
243
239
  self.logger.debug(f"{symbol} cross={last_cross_direction},见顶={is_apex},持仓方向={side}")
244
- # 金叉逻辑
245
- if last_cross_direction and last_cross_direction['cross'] == 1 and is_apex and side == 'long': # 金叉
240
+ # 金叉逻辑 ,如果是金叉,且是周期顶部,且K线方向是空头,就清仓多单
241
+ if last_cross_direction and last_cross_direction['cross'] == 1 and is_apex and side == 'long' and kline_direction == 0:
246
242
  self.logger.debug(f"{symbol} 金叉:{last_cross_direction['cross']},见顶={is_apex},持仓方向={side},开始清理多单!!")
247
243
  self.close_all_positions(symbol=symbol, position=position)
248
244
 
249
- # 死叉逻辑
250
- elif last_cross_direction and last_cross_direction['cross'] == 0 and is_apex and side == 'short':
245
+ # 死叉逻辑 ,如果是死叉,且是周期底部,且K线方向是多头,就清仓空单
246
+ elif last_cross_direction and last_cross_direction['cross'] == 0 and is_apex and side == 'short' and kline_direction == 1:
251
247
  self.logger.debug(f"{symbol} 死叉:{last_cross_direction['cross']},见顶={is_apex},持仓方向={side},开始清理空单!!")
252
248
  self.close_all_positions(symbol=symbol, position=position)
253
249
 
@@ -266,9 +262,9 @@ class MultiAssetNewTradingBot:
266
262
  :param period: SMA 周期
267
263
  :return: SMA 值
268
264
  """
269
- precision= self.get_precision_length(symbol)
265
+
270
266
  df = pd.DataFrame(kLines, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
271
- sma = df['close'].rolling(window=period).mean().round(precision)
267
+ sma = df['close'].rolling(window=period).mean()
272
268
  return sma
273
269
 
274
270
  def calculate_ema_pandas(self,symbol,kLines, period):
@@ -278,10 +274,10 @@ class MultiAssetNewTradingBot:
278
274
  :param period: EMA 周期
279
275
  :return: EMA 值
280
276
  """
281
- precision= self.get_precision_length(symbol)
277
+
282
278
  df = pd.DataFrame(kLines, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
283
279
  # 计算EMA
284
- ema = df['close'].ewm(span=period, adjust=False).mean().round(precision)
280
+ ema = df['close'].ewm(span=period, adjust=False).mean()
285
281
  return ema
286
282
 
287
283
  # 计算平均利润