Files
Grid_Trading/tests/test_open_grid_lots.py

106 lines
2.8 KiB
Python
Raw Normal View History

2026-07-09 11:17:51 +08:00
from datetime import date, timedelta
from decimal import Decimal
from grid_trading.domain.models import Trade, TradeGroup, TradeSide
from grid_trading.domain.open_grid_lots import calculate_open_grid_lots
def make_trade(
*,
trade_id: int,
trade_date: date,
side: TradeSide,
price: str,
quantity: int,
trade_group: TradeGroup = TradeGroup.GRID,
) -> Trade:
return Trade(
id=trade_id,
account_id=1,
instrument_id=1,
trade_date=trade_date,
side=side,
price=Decimal(price),
quantity=quantity,
trade_group=trade_group,
)
def test_calculate_open_grid_lots_fifo_matches_grid_sells_against_grid_buys():
today = date(2026, 7, 9)
trades = [
make_trade(
trade_id=1,
trade_date=today - timedelta(days=3),
side=TradeSide.BUY,
price="10.00",
quantity=300,
),
make_trade(
trade_id=2,
trade_date=today - timedelta(days=2),
side=TradeSide.BUY,
price="9.50",
quantity=200,
),
make_trade(
trade_id=3,
trade_date=today - timedelta(days=1),
side=TradeSide.SELL,
price="10.30",
quantity=350,
),
make_trade(
trade_id=4,
trade_date=today,
side=TradeSide.BUY,
price="8.00",
quantity=100,
trade_group=TradeGroup.BASE,
),
]
lots = calculate_open_grid_lots(
trades,
spacing=Decimal("0.03"),
current_price=Decimal("9.80"),
as_of=today,
)
assert len(lots) == 1
[lot] = lots
assert lot.buy_trade_id == 2
assert lot.buy_date == today - timedelta(days=2)
assert lot.buy_price == Decimal("9.50")
assert lot.remaining_quantity == 150
assert lot.actual_investment == Decimal("1425.00")
assert lot.suggested_sell_price == Decimal("9.79")
assert lot.estimated_gross_profit == Decimal("43.50")
assert lot.current_price == Decimal("9.80")
assert lot.status == "可卖"
def test_calculate_open_grid_lots_reports_not_reached_and_missing_quote_statuses():
today = date(2026, 7, 9)
trades = [
make_trade(trade_id=1, trade_date=today, side=TradeSide.BUY, price="10.00", quantity=100),
]
[not_reached] = calculate_open_grid_lots(
trades,
spacing=Decimal("0.03"),
current_price=Decimal("10.20"),
as_of=today,
)
[missing_quote] = calculate_open_grid_lots(
trades,
spacing=Decimal("0.03"),
current_price=None,
as_of=today,
)
assert not_reached.suggested_sell_price == Decimal("10.30")
assert not_reached.status == "未到价"
assert missing_quote.current_price is None
assert missing_quote.status == "未刷新行情"