optz
This commit is contained in:
@@ -2,9 +2,14 @@ from datetime import datetime, time
|
||||
from math import floor
|
||||
|
||||
|
||||
_MORNING_START, _MORNING_END = time(9, 30), time(11, 30)
|
||||
_AFTERNOON_START, _AFTERNOON_END = time(13), time(15)
|
||||
|
||||
|
||||
def trading_time(now: datetime) -> bool:
|
||||
if now.weekday() >= 5: return False
|
||||
return time(9, 30) <= now.time() <= time(11, 30) or time(13) <= now.time() <= time(15)
|
||||
clock = now.time()
|
||||
return _MORNING_START <= clock <= _MORNING_END or _AFTERNOON_START <= clock <= _AFTERNOON_END
|
||||
|
||||
|
||||
def calc_buy_volume(price: float, buy_value: float) -> int:
|
||||
@@ -29,4 +34,4 @@ def calculate_min_profit_rate(price: float, profit_mult: int) -> float:
|
||||
elif price >= 100:
|
||||
return 7 * profit_mult # 7%
|
||||
else:
|
||||
return 9 * profit_mult # 9%
|
||||
return 9 * profit_mult # 9%
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""简单的文件锁标记工具。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from os import PathLike
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""策略共用委托簿。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import secrets
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
@@ -69,17 +67,19 @@ class OrderBook:
|
||||
canceled = 0
|
||||
|
||||
for item in orders:
|
||||
status = str(item.order_status)
|
||||
# 不处理状态不对的
|
||||
if str(item.order_status) not in TRACKED_STATUSES:
|
||||
if status not in TRACKED_STATUSES:
|
||||
continue
|
||||
if str(item.order_status) in BUSY_STATUSES:
|
||||
if status in BUSY_STATUSES:
|
||||
busy_keys.add(self._busy_key(item.side, item.stock_code))
|
||||
# 清理过期的
|
||||
created_at = item.created_at
|
||||
if (
|
||||
item.created_at is not None
|
||||
created_at is not None
|
||||
and item.local_order_id.startswith(f"{self.order_prefix}-")
|
||||
and str(item.order_status) in CANCELABLE_STATUSES
|
||||
and current - item.created_at > self.cancel_timeout_sec
|
||||
and status in CANCELABLE_STATUSES
|
||||
and current - created_at > self.cancel_timeout_sec
|
||||
):
|
||||
try:
|
||||
client.cancel_by_id(item.order_sys_id)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
"""SQLite positions and deals, aligned with SDK models; one writer per database."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
import sqlite3
|
||||
from contextlib import closing
|
||||
from dataclasses import asdict, fields
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from itertools import chain
|
||||
|
||||
from sdk import DealItem, PositionItem
|
||||
|
||||
@@ -106,7 +105,7 @@ class OrderBook:
|
||||
raise ValueError('System order ID and positive volume are required')
|
||||
|
||||
row = asdict(deal)
|
||||
row['order_local_id'] = deal.get_local_order_id()
|
||||
row['order_local_id'] = deal.local_order_id
|
||||
if not row['order_local_id']:
|
||||
raise ValueError('Local order ID is required')
|
||||
|
||||
@@ -145,7 +144,7 @@ class OrderBook:
|
||||
raise ValueError('Execution history is append-only')
|
||||
new_deals = deals[len(self.deals):]
|
||||
positions = [{**POSITION_DEFAULTS, **item} for item in items.values()]
|
||||
for row in [*positions, *new_deals]:
|
||||
for row in chain(positions, new_deals):
|
||||
if any(isinstance(value, float) and not math.isfinite(value) for value in row.values()):
|
||||
raise ValueError('Numeric values must be finite')
|
||||
with closing(self._connect()) as db, db:
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""策略单次运行所需的公共上下文对象。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user