pymecli 0.5.4__tar.gz → 0.5.5__tar.gz

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.
Files changed (47) hide show
  1. {pymecli-0.5.4 → pymecli-0.5.5}/PKG-INFO +1 -1
  2. {pymecli-0.5.4 → pymecli-0.5.5}/cli/bitget.py +4 -1
  3. pymecli-0.5.5/cli/gate.py +20 -0
  4. pymecli-0.5.5/cli/okx.py +22 -0
  5. {pymecli-0.5.4 → pymecli-0.5.5}/cli/tele.py +6 -6
  6. pymecli-0.5.5/crypto/okx.py +52 -0
  7. {pymecli-0.5.4 → pymecli-0.5.5}/pyproject.toml +2 -1
  8. {pymecli-0.5.4 → pymecli-0.5.5}/utils/mysql.py +10 -5
  9. pymecli-0.5.4/cli/gate.py +0 -28
  10. {pymecli-0.5.4 → pymecli-0.5.5}/.gitignore +0 -0
  11. {pymecli-0.5.4 → pymecli-0.5.5}/README.md +0 -0
  12. {pymecli-0.5.4 → pymecli-0.5.5}/api/__init__.py +0 -0
  13. {pymecli-0.5.4 → pymecli-0.5.5}/api/v1/__init__.py +0 -0
  14. {pymecli-0.5.4 → pymecli-0.5.5}/api/v1/clash.py +0 -0
  15. {pymecli-0.5.4 → pymecli-0.5.5}/api/v1/redis.py +0 -0
  16. {pymecli-0.5.4 → pymecli-0.5.5}/cli/__init__.py +0 -0
  17. {pymecli-0.5.4 → pymecli-0.5.5}/cli/dst.py +0 -0
  18. {pymecli-0.5.4 → pymecli-0.5.5}/cli/example.py +0 -0
  19. {pymecli-0.5.4 → pymecli-0.5.5}/cli/fast.py +0 -0
  20. {pymecli-0.5.4 → pymecli-0.5.5}/cli/redis_csv.py +0 -0
  21. {pymecli-0.5.4 → pymecli-0.5.5}/cli/util.py +0 -0
  22. {pymecli-0.5.4 → pymecli-0.5.5}/core/__init__.py +0 -0
  23. {pymecli-0.5.4 → pymecli-0.5.5}/core/clash.py +0 -0
  24. {pymecli-0.5.4 → pymecli-0.5.5}/core/config.py +0 -0
  25. {pymecli-0.5.4 → pymecli-0.5.5}/core/redis_client.py +0 -0
  26. {pymecli-0.5.4 → pymecli-0.5.5}/crypto/__init__.py +0 -0
  27. {pymecli-0.5.4 → pymecli-0.5.5}/crypto/bitget.py +0 -0
  28. {pymecli-0.5.4 → pymecli-0.5.5}/crypto/gate.py +0 -0
  29. {pymecli-0.5.4 → pymecli-0.5.5}/data/__init__.py +0 -0
  30. {pymecli-0.5.4 → pymecli-0.5.5}/data/dou_dict.py +0 -0
  31. {pymecli-0.5.4 → pymecli-0.5.5}/data/dou_list.py +0 -0
  32. {pymecli-0.5.4 → pymecli-0.5.5}/data/main.py +0 -0
  33. {pymecli-0.5.4 → pymecli-0.5.5}/data/template.yaml +0 -0
  34. {pymecli-0.5.4 → pymecli-0.5.5}/models/__init__.py +0 -0
  35. {pymecli-0.5.4 → pymecli-0.5.5}/models/douzero_model.py +0 -0
  36. {pymecli-0.5.4 → pymecli-0.5.5}/models/ocr_model.py +0 -0
  37. {pymecli-0.5.4 → pymecli-0.5.5}/models/response.py +0 -0
  38. {pymecli-0.5.4 → pymecli-0.5.5}/utils/__init__.py +0 -0
  39. {pymecli-0.5.4 → pymecli-0.5.5}/utils/elapsed.py +0 -0
  40. {pymecli-0.5.4 → pymecli-0.5.5}/utils/helper.py +0 -0
  41. {pymecli-0.5.4 → pymecli-0.5.5}/utils/logger.py +0 -0
  42. {pymecli-0.5.4 → pymecli-0.5.5}/utils/path.py +0 -0
  43. {pymecli-0.5.4 → pymecli-0.5.5}/utils/pd.py +0 -0
  44. {pymecli-0.5.4 → pymecli-0.5.5}/utils/pyredis.py +0 -0
  45. {pymecli-0.5.4 → pymecli-0.5.5}/utils/sleep.py +0 -0
  46. {pymecli-0.5.4 → pymecli-0.5.5}/utils/text.py +0 -0
  47. {pymecli-0.5.4 → pymecli-0.5.5}/utils/toml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pymecli
3
- Version: 0.5.4
3
+ Version: 0.5.5
4
4
  Summary: My CLI
5
5
  Project-URL: Homepage, https://pypi.org/project/pymecli
6
6
  Project-URL: Repository, https://github.com/meme2046/pymecli
@@ -20,7 +20,10 @@ app = typer.Typer()
20
20
 
21
21
  @app.command()
22
22
  def sync(
23
- env_path: str = "d:/.env",
23
+ env_path: str = typer.Argument(
24
+ ".env",
25
+ help="dotenv环境变量路径",
26
+ ),
24
27
  ):
25
28
  """同步mysql中grid数据到redis"""
26
29
  engine = get_database_engine(env_path)
@@ -0,0 +1,20 @@
1
+ import asyncio
2
+
3
+ import typer
4
+
5
+ from crypto.gate import grid_close, grid_open
6
+ from utils.mysql import get_database_engine
7
+
8
+ app = typer.Typer()
9
+
10
+ @app.command()
11
+ def rsync(
12
+ env_path: str = typer.Argument(
13
+ ".env",
14
+ help="dotenv环境变量路径",
15
+ ),
16
+ ):
17
+ """同步mysql中grid数据到redis"""
18
+ engine = get_database_engine(env_path)
19
+ asyncio.run(grid_open(engine))
20
+ asyncio.run(grid_close(engine))
@@ -0,0 +1,22 @@
1
+ import asyncio
2
+
3
+ import typer
4
+
5
+ from crypto.okx import grid_close, grid_open
6
+ from utils.mysql import get_database_engine
7
+
8
+ app = typer.Typer()
9
+
10
+
11
+ @app.command()
12
+ def sync(
13
+ env_path: str = typer.Argument(
14
+ ".env",
15
+ help="dotenv环境变量路径",
16
+ ),
17
+ ):
18
+ """同步mysql中grid数据到redis"""
19
+ engine = get_database_engine(env_path)
20
+
21
+ asyncio.run(grid_open(engine))
22
+ asyncio.run(grid_close(engine))
@@ -12,10 +12,10 @@ app = typer.Typer()
12
12
  @app.command()
13
13
  def info(
14
14
  dotenv_path: str = typer.Argument(
15
- help="dotenv file contains TELE_SEESION_STRING", default="d:/.env"
15
+ help="dotenv file contains TELE_SEESION_STRING", default=".env"
16
16
  ),
17
17
  ):
18
- load_dotenv("d:/.env")
18
+ load_dotenv(dotenv_path)
19
19
  logger.info(os.getenv("TELE_SESSION_STRING"))
20
20
 
21
21
 
@@ -23,7 +23,7 @@ def info(
23
23
  def check(
24
24
  dotenv_path: str = typer.Argument(
25
25
  help="dotenv file contains TELE_SESSION_STRING / TELE_API_ID / TELE_API_HASH",
26
- default="d:/.env",
26
+ default=".env",
27
27
  ),
28
28
  ):
29
29
  """验证 TELE_SESSION_STRING 是否有效。
@@ -87,7 +87,7 @@ def check(
87
87
  def login(
88
88
  dotenv_path: str = typer.Argument(
89
89
  help="dotenv file containing TELE_API_ID / TELE_API_HASH",
90
- default="d:/.env",
90
+ default=".env",
91
91
  ),
92
92
  ):
93
93
  """交互式登录并打印 TELE_SESSION_STRING。
@@ -141,7 +141,7 @@ def upload(
141
141
  help="要上传的图片文件路径",
142
142
  ),
143
143
  dotenv_path: str = typer.Option(
144
- help="dotenv file path", default="d:/.env"
144
+ help="dotenv file path", default=".env"
145
145
  ),
146
146
  ):
147
147
  """上传图片到指定 Telegram 频道。
@@ -289,7 +289,7 @@ def upload(
289
289
  @app.command()
290
290
  def list_channels(
291
291
  dotenv_path: str = typer.Option(
292
- help="dotenv file path", default="d:/.env"
292
+ help="dotenv file path", default=".env"
293
293
  ),
294
294
  ):
295
295
  """列出当前账号加入的所有频道及其 ID。
@@ -0,0 +1,52 @@
1
+ from sqlalchemy import Engine
2
+
3
+ from utils import logger
4
+ from utils.mysql import mysql_to_redis
5
+
6
+
7
+ async def grid_open(engine: Engine):
8
+ query = "select * from okx_spot where ((cost is not null or benefit is not null) and profit is null) and up_status = 0 and order_id is not null and deleted_at is null;"
9
+ key_prefix = "okx_grid"
10
+ table = "okx_spot"
11
+
12
+ row_count = await mysql_to_redis(
13
+ engine,
14
+ key_prefix,
15
+ table,
16
+ query,
17
+ update_status=1,
18
+ d_column_names=["order_id", "client_order_id"],
19
+ pd_dtype={
20
+ "order_id": str,
21
+ "fx_order_id": str,
22
+ "created_at": "datetime64[ns]",
23
+ "open_at": "datetime64[ns]",
24
+ "close_at": "datetime64[ns]",
25
+ },
26
+ )
27
+
28
+ logger.info(f"🧮 okx grid open count:({row_count})")
29
+
30
+
31
+ async def grid_close(engine: Engine):
32
+ query = "select * from okx_spot where profit is not null and up_status in (0,1) and deleted_at is null;"
33
+ key_prefix = "okx_grid"
34
+ table = "okx_spot"
35
+
36
+ row_count = await mysql_to_redis(
37
+ engine,
38
+ key_prefix,
39
+ table,
40
+ query,
41
+ update_status=2,
42
+ d_column_names=["order_id", "client_order_id"],
43
+ pd_dtype={
44
+ "order_id": str,
45
+ "fx_order_id": str,
46
+ "created_at": "datetime64[ns]",
47
+ "open_at": "datetime64[ns]",
48
+ "close_at": "datetime64[ns]",
49
+ },
50
+ )
51
+
52
+ logger.info(f"🧮 okx grid close count:({row_count})")
@@ -36,7 +36,7 @@
36
36
  name = "pymecli"
37
37
  readme = "README.md"
38
38
  requires-python = ">=3.10"
39
- version = "0.5.4"
39
+ version = "0.5.5"
40
40
 
41
41
  [project.urls]
42
42
  Homepage = "https://pypi.org/project/pymecli"
@@ -49,6 +49,7 @@
49
49
  example = "cli.example:app"
50
50
  fast = "cli.fast:typer_app"
51
51
  gate = "cli.gate:app"
52
+ okx = "cli.okx:app"
52
53
  util = "cli.util:app"
53
54
  # 临时命令
54
55
  rd = "cli.redis_csv:app"
@@ -1,5 +1,4 @@
1
1
  import os
2
- import time
3
2
 
4
3
  import pandas as pd
5
4
  from dotenv import load_dotenv
@@ -10,7 +9,7 @@ from utils.pd import deduplicated, dt_to_timestamp
10
9
  from utils.pyredis import get_redis_client
11
10
 
12
11
 
13
- def get_database_engine(env_path: str) -> Engine:
12
+ def get_database_engine(env_path: str = ".env") -> Engine:
14
13
  """创建数据库引擎"""
15
14
  load_dotenv(env_path)
16
15
  host = os.getenv("MYSQL_HOST")
@@ -129,8 +128,11 @@ async def mysql_to_redis_and_csv(
129
128
 
130
129
  # 1. 写入完整数据到 Hash(自动覆盖)
131
130
  pipe.hset(key, mapping=row_dict)
132
- # 2. 写入 ZSet 索引:score = Unix 时间戳
133
- pipe.zadd(f"by_time:{key_prefix}", {id: time.time()})
131
+ # 2. 写入 ZSet 索引:score = 开仓时间戳(空值用 0 兜底)
132
+ score = row["open_at"]
133
+ if score is None or pd.isna(score):
134
+ score = 0
135
+ pipe.zadd(f"by_time:{key_prefix}", {id: score})
134
136
  count += 1
135
137
 
136
138
  await pipe.execute()
@@ -221,7 +223,10 @@ async def mysql_to_redis(
221
223
  row_dict = row.where(pd.notna(row), "").to_dict()
222
224
 
223
225
  pipe.hset(key, mapping=row_dict)
224
- pipe.zadd(f"by_time:{key_prefix}", {id: time.time()})
226
+ score = row["open_at"]
227
+ if score is None or pd.isna(score):
228
+ score = 0
229
+ pipe.zadd(f"by_time:{key_prefix}", {id: score})
225
230
  count += 1
226
231
 
227
232
  await pipe.execute()
pymecli-0.5.4/cli/gate.py DELETED
@@ -1,28 +0,0 @@
1
- import asyncio
2
-
3
- import typer
4
-
5
- from crypto.gate import grid_close, grid_open
6
- from utils.mysql import get_database_engine
7
-
8
- app = typer.Typer()
9
-
10
-
11
- # @app.command()
12
- # def sync(
13
- # env_path: str = "d:/.env", csv_path: str = "d:/github/meme2046/data/gate_0.csv"
14
- # ):
15
- # """同步mysql中grid数据到csv文件"""
16
- # engine = get_database_engine(env_path)
17
- # gate_open(engine, csv_path)
18
- # gate_close(engine, csv_path)
19
-
20
-
21
- @app.command()
22
- def rsync(
23
- env_path: str = "d:/.env",
24
- ):
25
- """同步mysql中grid数据到redis"""
26
- engine = get_database_engine(env_path)
27
- asyncio.run(grid_open(engine))
28
- asyncio.run(grid_close(engine))
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes