Reservations and Transfers
- Reservations and transfers are pre-order preparation operations, not orders themselves.
- Buying a disposition stock requires a cash reservation; selling a disposition stock or a full-cash-settlement stock requires a share reservation.
- These operations have no cancellation mechanism and are irreversible after submission. Confirm the details before submitting.
- Status changes are not pushed proactively. For cash and share reservations, query after submission; for a transfer, rely on the application response as described below.
What these features do
The Neo API provides three pre-order preparation operations:
| Operation | Methods | Purpose |
|---|---|---|
| Cash reservation | reserve_cash, query_reserves | Reserve funds in an account for a subsequent buy order |
| Share reservation | reserve_stock, query_reserved_stocks | Reserve inventory for a specified instrument in an account for a subsequent sell order |
| Transfer | query_transfer_inventory, transfer_stock, query_transfers | Move inventory from the current account to another specified account |
Cash and share reservations both secure the required resource before an order can be submitted. Exchanges require advance collection of funds or shares for certain instruments. An order submitted before the applicable reservation is completed will be rejected.
When it is needed
| Scenario | Required operation | Description |
|---|---|---|
| Buy a disposition stock | Cash reservation | Buying during the disposition period requires advance collection of funds. Reserve sufficient cash before submitting the buy order. |
| Sell a disposition stock or full-cash-settlement stock | Share reservation | Advance collection of shares applies. Reserve the instrument inventory before submitting the sell order. |
| Move inventory between different accounts of the same investor | Transfer | For example, moving inventory between a primary account and a sub-account. |
Orders for ordinary instruments do not require these operations and can be submitted directly.
Whether an instrument is designated as a disposition stock or full-cash-settlement stock changes over time. Confirm its status on the trading day before placing an order.
Before you start
Before calling these features, complete the following preparations for the account:
- Use fubon-neo SDK version 2.2.9 or later.
- Sign the required electronic depository agreement. The backend rejects the operation if the agreement has not been completed.
- Use an API key with account-service permission. Both application and query methods in this feature group require that permission.
Operational characteristics
Irreversible after submission
These operations do not provide a cancellation or release interface. Once an application is submitted, it cannot be withdrawn through the API. Confirm the amount, instrument, and quantity before submitting. If the program times out, do not resubmit immediately. For cash and share reservations, query the account-wide total or reserved-share balance first to determine whether the prior application was accepted. A transfer currently cannot be confirmed by query: the record query does not immediately reflect the application and its sequence number cannot be matched to the application's sequence number. Reconcile with your broker or branch before deciding whether to resubmit, or inventory may be moved more than once.
Application service hours
Cash reservation, share reservation, and transfer applications are accepted on trading days from 08:00 to 14:30. The backend rejects requests outside this window; query methods are not subject to this restriction.
Status is not reported proactively
These operations do not use the order-report channel, so no status-change notifications are pushed proactively. For cash and share reservations, wait several seconds before querying, use reasonable polling intervals and a maximum number of attempts, and use the query result—not the immediate application response—as the basis for a subsequent order.
The examples below assume that login has completed and the securities account account has been obtained.
Cash reservation
Apply for a cash reservation
Prepay TWD settlement funds for a subsequent buy order.
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.reserve_cash(account, 10000)
print(result)
Result {
is_success: True,
message: None,
data : ReserveCashRecord {
date: "2026/07/28",
time: "10:53:23.000",
seq_no: "118036",
branch_no: "20207",
account: "9801163",
currency: "TWD",
amount: 10000,
status: 10
}}
const result = sdk.stock.reserveCash(account, 10000)
console.log(result)
{
isSuccess: true,
data: {
date: "2026/07/28",
time: "10:53:23.000",
seqNo: "118036",
branchNo: "20207",
account: "9801163",
currency: "TWD",
amount: 10000,
status: 10
}
}
var result = sdk.Stock.ReserveCash(account, 10000);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = ReserveCashRecord{
date = 2026/07/28,
time = 10:53:23.000,
seqNo = 118036,
branchNo = 20207,
account = 9801163,
currency = TWD,
amount = 10000,
status = 10
}
}
auto result = sdk->stock->reserve_cash(account, 10000);
result, err := sdk.Stock.ReserveCash(account, 10000)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
Query cash reservations
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_reserves(account)
print(result)
Result {
is_success: True,
message: None,
data : ReserveCashSummary {
branch_no: "20207",
account: "9801163",
currency: "TWD",
reserved_amount: 9960200,
returned_amount: 0,
ordered_amount: 0,
}}
const result = sdk.stock.queryReserves(account)
console.log(result)
{
isSuccess: true,
data: {
branchNo: "20207",
account: "9801163",
currency: "TWD",
reservedAmount: 9960200,
returnedAmount: 0,
orderedAmount: 0
}
}
var result = sdk.Stock.QueryReserves(account);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = ReserveCashSummary{
branchNo = 20207,
account = 9801163,
currency = TWD,
reservedAmount = 9960200,
returnedAmount = 0,
orderedAmount = 0
}
}
auto result = sdk->stock->query_reserves(account);
result, err := sdk.Stock.QueryReserves(account)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
Share reservation
Apply for a share reservation
Reserve the shares that will be sold. quantity is measured in shares (1 lot = 1,000 shares).
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.reserve_stock(account, "2330", 1000)
print(result)
Result {
is_success: True,
message: None,
data : ReserveStockRecord {
seq_no: "118036",
stock_no: "2330",
reserved_share: 1000,
}}
const result = sdk.stock.reserveStock(account, "2330", 1000)
console.log(result)
{
isSuccess: true,
data: {
seqNo: "118036",
stockNo: "2330",
reservedShare: 1000
}
}
var result = sdk.Stock.ReserveStock(account, "2330", 1000);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = ReserveStockRecord{
seqNo = 118036,
stockNo = 2330,
reservedShare = 1000
}
}
auto result = sdk->stock->reserve_stock(account, "2330", 1000);
result, err := sdk.Stock.ReserveStock(account, "2330", 1000)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
Query share reservations
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_reserved_stocks(account)
print(result)
Result {
is_success: True,
message: None,
data : [
ReserveStockItem { stock_no: "2330", market: Taiex, reserved_share: 5599 },
ReserveStockItem { stock_no: "1260", market: Taiemg, reserved_share: 3000 },
]
}
const result = sdk.stock.queryReservedStocks(account)
console.log(result)
{
isSuccess: true,
data: [
{ stockNo: "2330", market: Taiex, reservedShare: 5599 },
{ stockNo: "1260", market: Taiemg, reservedShare: 3000 }
]
}
var result = sdk.Stock.QueryReservedStocks(account);
foreach (var record in result.data)
{
Console.WriteLine(record);
}
{
isSuccess = True,
message = ,
data = [
ReserveStockItem{ stockNo = 2330, market = Taiex, reservedShare = 5599 },
ReserveStockItem{ stockNo = 1260, market = Taiemg, reservedShare = 3000 }
]
}
auto result = sdk->stock->query_reserved_stocks(account);
result, err := sdk.Stock.QueryReservedStocks(account)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
Transfer
Query transferable inventory
Returns the transferable share quantity and market for each instrument. Query before applying for a transfer.
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_transfer_inventory(account)
print(result)
Result {
is_success: True,
message: None,
data : [
TransferInventoryItem { stock_no: "006205", market: Taiex, available_share: 5000 },
TransferInventoryItem { stock_no: "6279", market: Taisdaq, available_share: 2000 },
]
}
const result = sdk.stock.queryTransferInventory(account)
console.log(result)
{
isSuccess: true,
data: [
{ stockNo: "006205", market: Taiex, availableShare: 5000 },
{ stockNo: "6279", market: Taisdaq, availableShare: 2000 }
]
}
var result = sdk.Stock.QueryTransferInventory(account);
foreach (var record in result.data)
{
Console.WriteLine(record);
}
{
isSuccess = True,
message = ,
data = [
TransferInventoryItem{ stockNo = 006205, market = Taiex, availableShare = 5000 },
TransferInventoryItem{ stockNo = 6279, market = Taisdaq, availableShare = 2000 }
]
}
auto result = sdk->stock->query_transfer_inventory(account);
result, err := sdk.Stock.QueryTransferInventory(account)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
Apply for a transfer
Transfer stock out to a specified branch account. quantity is measured in shares (1 lot = 1,000 shares). market is optional—when omitted, the SDK resolves it automatically. Applications must be submitted during service hours and cannot be reversed; see Operational characteristics.
- Python
- Node.js
- C#
- C++
- Go
# When market is omitted, the SDK resolves it automatically
result = sdk.stock.transfer_stock(account, "960C", "7654321", "006205", 2000)
print(result)
Result {
is_success: True,
message: None,
data : TransferRecord {
date: "2026/07/28",
time: "10:53:48.340",
seq_no: "418181",
stock_no: "006205",
market: Taiex,
quantity: 2000,
target_branch_no: "960C",
target_account: "7654321",
status: 10
}}
// When market is omitted, the SDK resolves it automatically
const result = sdk.stock.transferStock(account, "960C", "7654321", "006205", 2000)
console.log(result)
{
isSuccess: true,
data: {
date: "2026/07/28",
time: "10:53:48.340",
seqNo: "418181",
stockNo: "006205",
market: Taiex,
quantity: 2000,
targetBranchNo: "960C",
targetAccount: "7654321",
status: 10
}
}
// When market is omitted, the SDK resolves it automatically
var result = sdk.Stock.TransferStock(account, "960C", "7654321", "006205", 2000);
Console.WriteLine(result);
{
isSuccess = True,
message = ,
data = TransferRecord{
date = 2026/07/28,
time = 10:53:48.340,
seqNo = 418181,
stockNo = 006205,
market = Taiex,
quantity = 2000,
targetBranchNo = 960C,
targetAccount = 7654321,
status = 10
}
}
// When market is omitted, the SDK resolves it automatically
auto result = sdk->stock->transfer_stock(account, "960C", "7654321", "006205", 2000, std::nullopt);
// When market is omitted, the SDK resolves it automatically
result, err := sdk.Stock.TransferStock(account, "960C", "7654321", "006205", 2000, nil)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
Query transfer records
- Python
- Node.js
- C#
- C++
- Go
result = sdk.stock.query_transfers(account)
print(result)
Result {
is_success: True,
message: None,
data : [ TransferRecord {
date: "2026/07/28",
time: "10:53:48.340",
seq_no: "418181",
stock_no: "006205",
market: Taiex,
quantity: 2000,
target_branch_no: "960C",
target_account: "7654321",
status: 10, } ]
}
const result = sdk.stock.queryTransfers(account)
console.log(result)
{
isSuccess: true,
data: [ {
date: "2026/07/28",
time: "10:53:48.340",
seqNo: "418181",
stockNo: "006205",
market: Taiex,
quantity: 2000,
targetBranchNo: "960C",
targetAccount: "7654321",
status: 10
} ]
}
var result = sdk.Stock.QueryTransfers(account);
foreach (var record in result.data)
{
Console.WriteLine(record);
}
{
isSuccess = True,
message = ,
data = [ TransferRecord{
date = 2026/07/28,
time = 10:53:48.340,
seqNo = 418181,
stockNo = 006205,
market = Taiex,
quantity = 2000,
targetBranchNo = 960C,
targetAccount = 7654321,
status = 10
} ]
}
auto result = sdk->stock->query_transfers(account, "20260701", "20260722", std::nullopt);
startDate := "20260701"
endDate := "20260722"
result, err := sdk.Stock.QueryTransfers(account, &startDate, &endDate, nil)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
Complete example
Buying a disposition stock (cash reservation → confirmation → order) and transferring between accounts:
The transfer-record query (query_transfers) does not immediately reflect a successful application, and its seq_no is an empty string, so it cannot be matched to the sequence number returned by the application.
Use the status in the application response (10 success; 90 failure) as the result, and retain the application's seq_no for later reconciliation with your broker or branch.
- Python
- Node.js
- C#
- C++
- Go
# 1. Reserve the settlement cash required to buy a disposition stock
result = sdk.stock.reserve_cash(account, 10000)
if not result.is_success:
print(result.message)
# 2. Wait several seconds, then query. Submit the buy order only after the reservation is accepted (see "Place Order")
reserves = sdk.stock.query_reserves(account)
print(reserves.data.reserved_amount) # Account-wide pre-collected amount
# --- Inter-account transfer: use the application response to determine acceptance ---
result = sdk.stock.transfer_stock(account, "960C", "7654321", "006205", 1000)
if result.is_success and result.data.status == 10:
print("Transfer accepted; sequence number:", result.data.seq_no)
else:
print("Transfer not accepted:", result.message)
// 1. Reserve the settlement cash required to buy a disposition stock
const result = sdk.stock.reserveCash(account, 10000)
if (!result.isSuccess) console.log(result.message)
// 2. Wait several seconds, then query. Submit the buy order only after the reservation is accepted (see "Place Order")
const reserves = sdk.stock.queryReserves(account)
console.log(reserves.data.reservedAmount) // Account-wide pre-collected amount
// --- Inter-account transfer: use the application response to determine acceptance ---
const transfer = sdk.stock.transferStock(account, "960C", "7654321", "006205", 1000)
if (transfer.isSuccess && transfer.data.status === 10) {
console.log("Transfer accepted; sequence number:", transfer.data.seqNo)
} else {
console.log("Transfer not accepted:", transfer.message)
}
// 1. Reserve the settlement cash required to buy a disposition stock
var result = sdk.Stock.ReserveCash(account, 10000);
if (!result.isSuccess) Console.WriteLine(result.message);
// 2. Wait several seconds, then query. Submit the buy order only after the reservation is accepted (see "Place Order")
var reserves = sdk.Stock.QueryReserves(account);
Console.WriteLine(reserves.data.reservedAmount); // Account-wide pre-collected amount
// --- Inter-account transfer: use the application response to determine acceptance ---
var transfer = sdk.Stock.TransferStock(account, "960C", "7654321", "006205", 1000);
if (transfer.isSuccess && transfer.data.status == 10) {
Console.WriteLine("Transfer accepted; sequence number: " + transfer.data.seqNo);
} else {
Console.WriteLine("Transfer not accepted: " + transfer.message);
}
// 1. Reserve the settlement cash required to buy a disposition stock
auto reserveCash = sdk->stock->reserve_cash(account, 10000);
if (!reserveCash.is_success) {
std::cerr << "Reserve cash was not accepted." << std::endl;
}
// 2. Wait several seconds, then query. Submit the buy order only after the reservation is accepted (see "Place Order")
auto reserves = sdk->stock->query_reserves(account);
// --- Inter-account transfer: use the application response to determine acceptance ---
auto transfer = sdk->stock->transfer_stock(account, "960C", "7654321", "006205", 1000, std::nullopt);
if (transfer.is_success && transfer.data.has_value() && transfer.data.value().status == 10) {
std::cout << "Transfer accepted; sequence number: " << transfer.data.value().seq_no << std::endl;
} else {
std::cerr << "Transfer not accepted." << std::endl;
}
// 1. Reserve the settlement cash required to buy a disposition stock
reserveCash, err := sdk.Stock.ReserveCash(account, 10000)
if err != nil || !reserveCash.IsSuccess {
fmt.Println("reserve cash was not accepted")
}
// 2. Wait several seconds, then query. Submit the buy order only after the reservation is accepted (see "Place Order")
reserves, err := sdk.Stock.QueryReserves(account)
if err != nil {
fmt.Println(err)
}
fmt.Println(reserves)
// --- Inter-account transfer: use the application response to determine acceptance ---
transfer, err := sdk.Stock.TransferStock(account, "960C", "7654321", "006205", 1000, nil)
if err == nil && transfer.IsSuccess && transfer.Data != nil && transfer.Data.Status == 10 {
fmt.Println("Transfer accepted; sequence number:", transfer.Data.SeqNo)
} else {
fmt.Println("Transfer not accepted")
}
On failure
When a call fails, is_success is False; obtain the reason from message.
| Scenario | Behavior |
|---|---|
| Amount or share quantity is ≤ 0 | The SDK returns failure without sending a request. |
| Not logged in, or the API key lacks the required permission | The SDK returns failure. |
A transfer omits market and no transferable inventory is found for the symbol | The SDK returns failure; its message asks you to provide an explicit market. |
| Backend rejection (for example, insufficient balance or inventory, an invalid account, or outside service hours) | message contains the reason returned by the server. |