Choosing Order, Target-Position, and Scheduled Execution Tools
Summary
This reference compares direct order placement, cancellation, target-position control, scheduled execution, and TWAP tools for futures and stock workflows. Manual orders suit cases requiring explicit price selection, cancellation decisions, partial-fill handling, or exchange-specific behavior. TargetPosTask is intended for setting a net position and managing the orders needed to reach it; TargetPosScheduler adds time-based schedules, including TWAP and VWAP tables.
The guidance details lifecycle requirements and important constraints: order actions are transmitted on the next update call, execution helpers need continuing updates, and manual orders should not be mixed with target-position control for the same symbol. Exchange minimum opening sizes may prevent exact target completion, while direct TWAP has its own limits and does not support backtesting. The reference distinguishes live execution from scenario-based margin calculations and notes that the target-position helper is unsuitable for stocks. These are API usage rules, not evidence that any execution approach improves trading outcomes.
Key ideas
- Manual orders provide direct control over price, cancellation, and fill handling.
- Target-position tools translate a desired net position into execution orders.
- Scheduled target execution can use time tables such as TWAP or VWAP schedules.
- Exchange minimum opening sizes can prevent exact completion of a requested target.
- Direct TWAP has limitations, including lack of backtest support.
Tags
Full text
# Order Functions And Position Tools
# Order Functions And Position Tools
## Use This Reference For
- `insert_order`
- `cancel_order`
- `TargetPosTask`
- `TargetPosScheduler`
- `Twap`
- Choosing between manual order control, target-position control, and `TqScenario`
## Table Of Contents
- Manual orders
- Cancel orders
- When to use manual orders
- `TargetPosTask`
- `TargetPosTask` with exchange minimum open volume
- `TargetPosScheduler`
- Direct `Twap`
- `TqScenario` versus live execution tools
- Advanced helpers beyond the default answer
- Stock limitations
## Manual Orders: `insert_order`
`insert_order()` is the public API for direct order placement.
Key parameters:
- `symbol`
- `direction`: `BUY` or `SELL`
- `offset`: futures only, usually `OPEN`, `CLOSE`, `CLOSETODAY`
- `volume`
- `limit_price`
- `advanced`: `FAK`, `FOK`, or `None`
- `account`: required in multi-account mode
Important behavior:
- the order packet is actually sent on the next `wait_update()`
- stock trading does not use `offset`
- stock orders may omit `limit_price`; `limit_price=None` becomes `price_type="ANY"`
Basic futures example:
```python
from tqsdk import TqApi, TqAuth
api = TqApi(auth=TqAuth("快期账户", "账户密码"))
quote = api.get_quote("SHFE.au2608")
order = api.insert_order(
symbol="SHFE.au2608",
direction="BUY",
offset="OPEN",
volume=1,
limit_price=quote.ask_price1,
)
while order.status != "FINISHED":
api.wait_update()
print(order.status, order.volume_left, order.last_msg)
```
Advanced order modes:
- `advanced="FAK"`: remaining quantity is canceled immediately
- `advanced="FOK"`: all-or-kill
- `limit_price="BEST"` or `"FIVELEVEL"`: only supported on CFFEX
Do not recommend advanced combinations unless the exchange and contract class support them.
## Cancel Orders: `cancel_order`
```python
api.cancel_order(order)
api.wait_update()
```
Rules:
- `cancel_order()` accepts an order object or order id
- the cancel packet is also sent on the next `wait_update()`
- in multi-account mode, pass `account=...` if needed
## When To Use Manual Orders
Prefer manual orders when the user wants:
- explicit price control
- explicit cancellation logic
- partial-fill handling
- exchange-specific order semantics
- custom order chasing
## `TargetPosTask`
Use `TargetPosTask` when the user thinks in target net position, not individual orders.
```python
from tqsdk import TqApi, TqAuth, TargetPosTask
api = TqApi(auth=TqAuth("快期账户", "账户密码"))
target_pos = TargetPosTask(api, "DCE.m2609")
target_pos.set_target_volume(5)
while True:
api.wait_update()
```
Rules:
- create one `TargetPosTask` per account and symbol
- keep calling `wait_update()` after `set_target_volume()`
- do not mix `TargetPosTask` and manual `insert_order()` on the same symbol
- if you need a different `price`, `offset_priority`, `min_volume`, or `max_volume`, cancel the old task before creating a new one
- by default, `TargetPosTask` rejects contracts whose `quote.open_min_market_order_volume` or `quote.open_min_limit_order_volume` is greater than 1
Useful parameters:
- `price`: `"ACTIVE"`, `"PASSIVE"`, or a custom price function
- `offset_priority`
- `min_volume` and `max_volume` for split execution
- `account` in multi-account mode
- `support_open_min_volume=True` for contracts with an exchange minimum opening size, with the limitations below
Useful lifecycle APIs:
- `target_pos.cancel()`
- `target_pos.is_finished()`
## `TargetPosTask` With Exchange Minimum Open Volume
Use `support_open_min_volume=True` only when the user explicitly wants `TargetPosTask` on a contract where `quote.open_min_market_order_volume > 1` or `quote.open_min_limit_order_volume > 1`.
Important limits:
- exact target completion is not guaranteed; treat the task as complete when `abs(position.pos - target_volume) < quote.open_min_limit_order_volume`
- if split execution is enabled, both `min_volume` and `max_volume` must be at least `quote.open_min_limit_order_volume`
- when the remaining opening chase volume is below `quote.open_min_limit_order_volume`, that opening chase stops instead of sending another order
- if the task can only open positions and the calculated opening size is already below `quote.open_min_limit_order_volume`, no order is sent and the task ends
- `support_open_min_volume` is part of the singleton construction parameters; cancel the old task before recreating the same account and symbol with a different value
- `TargetPosScheduler` passes `support_open_min_volume`, `min_volume`, and `max_volume` through to `TargetPosTask`, so these same limits apply to scheduled execution
- direct `Twap` has its own `support_open_min_volume` parameter and checks `min_volume_each_order` against `quote.open_min_limit_order_volume`
Example completion check:
```python
from tqsdk import TqApi, TqAuth, TargetPosTask
api = TqApi(auth=TqAuth("快期账户", "账户密码"))
symbol = "GFEX.ps2704"
target_volume = 20
quote = api.get_quote(symbol)
position = api.get_position(symbol)
target_pos = TargetPosTask(api, symbol, support_open_min_volume=True)
target_pos.set_target_volume(target_volume)
while True:
api.wait_update()
if abs(position.pos - target_volume) < quote.open_min_limit_order_volume:
print("Target position task is complete enough for this contract rule.")
break
api.close()
```
## `TargetPosScheduler`
Use `TargetPosScheduler` when the user wants scheduled target-position execution instead of one immediate target.
It is the public helper for time-table driven execution and works with:
- a custom `time_table`
- `twap_table(...)`
- `vwap_table(...)`
Common import:
```python
from tqsdk.algorithm import twap_table, vwap_table
```
It still depends on continuous `wait_update()` calls and must not be mixed with `TargetPosTask` or manual `insert_order()` for the same workflow.
For contracts with exchange minimum opening size rules, pass `support_open_min_volume=True` to `TargetPosScheduler` as well. If split execution is enabled, `min_volume` and `max_volume` still need to satisfy the minimum opening volume rules from `TargetPosTask`.
The last scheduled item exits after the target is reached; with `support_open_min_volume=True`, it may also finish when the current target-position round ends because the remaining open volume is below the exchange minimum.
## Direct `Twap`
Prefer `TargetPosScheduler` plus `twap_table(...)` for new scheduled target-position examples.
Use direct `tqsdk.algorithm.Twap` only when the user is already using it or asks for direct TWAP order execution.
Important direct `Twap` rules:
- it does not support backtest
- it still needs continuous `wait_update()` calls
- `duration` may cross non-trading pauses but not a trading day boundary
- for open-min contracts, pass `support_open_min_volume=True`
- when `support_open_min_volume=True`, `min_volume_each_order` must be at least `quote.open_min_limit_order_volume`
- final filled volume can be smaller than the requested volume when the remaining open volume is below `quote.open_min_limit_order_volume`
Minimal pattern:
```python
from tqsdk import TqApi, TqAuth
from tqsdk.algorithm import Twap
api = TqApi(auth=TqAuth("快期账户", "账户密码"))
twap = Twap(api, "CZCE.MA609", "BUY", "OPEN", 200, 300, 5, 10, support_open_min_volume=True)
while True:
api.wait_update()
if twap.is_finished():
break
api.close()
```
## `TqScenario` Versus Live Execution Tools
Use `TqScenario` when the user wants synchronous trial calculation for futures margin or risk changes without sending live orders.
Read [scenario-and-margin.md](scenario-and-margin.md) when the request is about:
- how many lots can still be opened
- how much margin can be released by reducing positions
- what margin or risk ratio becomes after changing positions, balance, or margin rates
Do not route live execution requests to `TqScenario`.
## Advanced Helpers Beyond The Default Answer
These exist, but should not be the first answer unless the user is already using them:
- `InsertOrderTask`
- `InsertOrderUntilAllTradedTask`
Explain them as advanced or specialized execution helpers, not as the default recommendation.
## Stock Limitations
- Stock trading does not use `offset`
- `TargetPosTask` is not the right answer for stock trading
- Stock order objects are `SecurityOrder`, not `Order`
## Repository Sources
- `tqsdk/api.py`
- `doc/usage/targetpostask.rst`
- `doc/advanced/targetpostask2.rst`
- `doc/advanced/scheduler.rst`
- `tqsdk/lib/target_pos_task.py`
- `tqsdk/lib/target_pos_scheduler.py`
- `tqsdk/algorithm/time_table_generater.py`
- `tqsdk/algorithm/twap.py`Shown in full with attribution under the source's licence. Licence: Apache-2.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.