# Transaction related

# Q1: How to use paper trading?

A:

# Overview

Paper trading is a simulation that allows you to practice trading without the risk of using real money.

# Trading time

Paper trading only supports trading during regular trading hours, and does not support trading outside regular trading hours, US market pre-market and after-hours, HK market and China A-shares market Opening and Closing Auction. For details, please click Rules of paper trading.

# Categories supported

For categories that OpenAPI supports by paper trading, please click here.

# Unlock Trade

Different from live trading, you do not need to unlock the account to place orders or modify or cancel orders when using paper trading.

# Orders

  1. Order Types: limit order and market order.
  2. Modify Order Operation: Paper trading does not support enabling, disabling, and deleting the order, but supports modifying and canceling the order.
  3. Deals: Paper trading does not support deals related operations, including Get today's deals, Get historical deals, and Respond to the transaction push.
  4. Valid Period: Paper trading only supports good for day order when setting valid period.
  5. Short Selling: Options and futures support short selling. Only US stocks support short selling.

# Platform

  1. Mobile clients: Me — Paper Trading.

sim-page

  1. Desktop clients: Left side tab Paper .

sim-page

  1. Web clients: Paper Trading Website.

  2. OpenAPI: When calling the interface, set the parameter trading environment to the simulated environment. Click How to use paper trading through OpenAPI for detail.

Tips

  • The four platforms shown above use the same paper trading accounts.

# How to use paper trading through OpenAPI?

# Create Connection

Firstly, create the corresponding connection. When the underlyings are stocks or options, please use OpenSecTradeContext. When the underlyings are futures, please use OpenFutureTradeContext.

# Get the List of Trading Accounts

Use the interface Get the List of Trading Accounts to view trading accounts (including paper trading accounts and live trading accounts). Take Python as an example: When the returned parameter trd_env is SIMULATE, it means the corresponding account is a paper trading account.

  • Example:Stocks and Options
from futu import *
trd_ctx = OpenSecTradeContext(filter_trdmarket=TrdMarket.HK, host='127.0.0.1', port=11111, security_firm=SecurityFirm.FUTUSECURITIES)
#trd_ctx = OpenFutureTradeContext(host='127.0.0.1', port=11111, is_encrypt=None, security_firm=SecurityFirm.FUTUSECURITIES)
ret, data = trd_ctx.get_acc_list()
if ret == RET_OK:
    print(data)
    print(data['acc_id'][0])  # get the first account id
    print(data['acc_id'].values.tolist())  # convert to list format
else:
    print('get_acc_list error: ', data)
trd_ctx.close()
1
2
3
4
5
6
7
8
9
10
11
  • Output
               acc_id   trd_env acc_type          card_num   security_firm  \
0  281756480572583411      REAL   MARGIN  1001318721909873  FUTUSECURITIES   
1             9053218  SIMULATE     CASH               N/A             N/A   
2             9048221  SIMULATE   MARGIN               N/A             N/A   

  sim_acc_type  trdmarket_auth  
0          N/A  [HK, US, HKCC]  
1        STOCK            [HK]  
2       OPTION            [HK] 
1
2
3
4
5
6
7
8
9

Tips

  • In paper trading, stock accounts and options accounts are distinguished. Stock accounts can only trade stocks, and options accounts can only trade options; take Python as an example: sim_acc_type in the returned field is STOCK, which means stock account; OPTION means option account.
  • Example: Futures
from futu import *
#trd_ctx = OpenSecTradeContext(filter_trdmarket=TrdMarket.HK, host='127.0.0.1', port=11111, security_firm=SecurityFirm.FUTUSECURITIES)
trd_ctx = OpenFutureTradeContext(host='127.0.0.1', port=11111, is_encrypt=None, security_firm=SecurityFirm.FUTUSECURITIES)
ret, data = trd_ctx.get_acc_list()
if ret == RET_OK:
    print(data)
    print(data['acc_id'][0])  # get the first account id
    print(data['acc_id'].values.tolist())  # convert to list format
else:
    print('get_acc_list error: ', data)
trd_ctx.close()
1
2
3
4
5
6
7
8
9
10
11
  • Output
    acc_id   trd_env acc_type card_num security_firm sim_acc_type  \
0  9497808  SIMULATE   MARGIN      N/A           N/A      FUTURES   
1  9497809  SIMULATE   MARGIN      N/A           N/A      FUTURES   
2  9497810  SIMULATE   MARGIN      N/A           N/A      FUTURES   
3  9497811  SIMULATE   MARGIN      N/A           N/A      FUTURES   

          trdmarket_auth  
0  [FUTURES_SIMULATE_HK]  
1  [FUTURES_SIMULATE_US]  
2  [FUTURES_SIMULATE_SG]  
3  [FUTURES_SIMULATE_JP]  
1
2
3
4
5
6
7
8
9
10
11

# Place Orders

When using the Interface Place Orders, set the trading environment to the simulated environment. Take Python as an example: trd_env = TrdEnv.SIMULATE.

  • Example
from futu import *
trd_ctx = OpenHKTradeContext(host='127.0.0.1', port=11111, security_firm=SecurityFirm.FUTUSECURITIES)
ret, data = trd_ctx.place_order(price=510.0, qty=100, code="HK.00700", trd_side=TrdSide.BUY, trd_env=TrdEnv.SIMULATE)
if ret == RET_OK:
    print(data)
else:
    print('place_order error: ', data)
trd_ctx.close()
1
2
3
4
5
6
7
8
  • Output
	code	stock_name	trd_side	order_type	order_status	order_id	qty	price	create_time	updated_time	dealt_qty	dealt_avg_price	last_err_msg	remark	time_in_force	fill_outside_rth
0	HK.00700	Tencent	BUY	NORMAL	SUBMITTING	4642000476506964749	100.0	510.0	2021-10-09 11:34:54	2021-10-09 11:34:54	0.0	0.0			DAY	N/A
1
2

# Modify or Cancel Orders

When using the Interface Modify or Cancel Orders, set the trading environment to the simulated environment. Take Python as an example: trd_env = TrdEnv.SIMULATE.

  • Example
from futu import *
trd_ctx = OpenHKTradeContext(host='127.0.0.1', port=11111, security_firm=SecurityFirm.FUTUSECURITIES)
order_id = "4642000476506964749"
ret, data = trd_ctx.modify_order(ModifyOrderOp.CANCEL, order_id, 0, 0, trd_env=TrdEnv.SIMULATE)
if ret == RET_OK:
    print(data)
else:
    print('modify_order error: ', data)
trd_ctx.close()
1
2
3
4
5
6
7
8
9
  • Output
    trd_env             order_id
0  SIMULATE  4642000476506964749
1
2

# Get Historical Orders

When using the Interface Get Historical Orders, set the trading environment to the simulated environment. Take Python as an example: trd_env = TrdEnv.SIMULATE.

  • Example
from futu import *
trd_ctx = OpenHKTradeContext(host='127.0.0.1', port=11111, security_firm=SecurityFirm.FUTUSECURITIES)
ret, data = trd_ctx.history_order_list_query(trd_env=TrdEnv.SIMULATE)
if ret == RET_OK:
    print(data)
else:
    print('history_order_list_query error: ', data)
trd_ctx.close()
1
2
3
4
5
6
7
8
  • Output
	code	stock_name	trd_side	order_type	order_status	order_id	qty	price	create_time	updated_time	dealt_qty	dealt_avg_price	last_err_msg	remark	time_in_force	fill_outside_rth
0	HK.00700	Tencent	BUY	ABSOLUTE_LIMIT	CANCELLED_ALL	4642000476506964749	100.0	510.0	2021-10-09 11:34:54	2021-10-09 11:37:08	0.0	0.0			DAY	N/A
1
2

# How to reset the paper trading account?

Currently, OpenAPI does not support resetting the paper trading account. You can use the reset card on the mobile clients. After the reset, net assets would be restored to the initial value and the historical orders would be emptied.

# Specific process

Modify clients: Me — Paper Trading — My Icon — My Card — Reset Card sim-page

# How to reset the paper trading account?

Currently, OpenAPI does not support resetting the paper trading account. You can use the reset card on the mobile clients. After the reset, net assets would be restored to the initial value and the historical orders would be emptied.

# Specific process

Modify clients: Me — Paper Trading — My Icon — My Card — Reset Card sim-page

# Q2: If support A-share trading or not?

A: Paper trading supports A-share trading. However, real trade can only be used to trade some A-shares through A-shares connect. For details, please refer to List of HKCC.

# Q3: Trading directions supported by each market

A: Except for futures, other stocks only support the two trading directions of BUY and SELL. In the case of a short position, SELL is passed in, and the direction of the resulting order is short selling.

# Q4: Order types supported in each market in real environment

A:

Market Variety Limit Orders Market Orders At-auction Limit Orders At-auction Market Orders Absolute Limit Orders Special Limit Orders AON Special Limit Orders Stop Orders Stop Limit Orders Market if Touched Orders Limit if Touched Orders Trailing Stop Orders Trailing Stop Limit Orders
HK Securities (including stocks, ETFs, warrants, CBBCs, Inline Warrants)
Options X - - - - - X X X
Futures - - - - X X X
US Securities (including stocks, ETFs) - - - - -
Options - - - - -
Futures - - - - - X X X
HKCC Securities (including stocks, ETFs) X - - - - - X X X
Singapore Futures X - - - - - X X X
Japanese Futures X - - - - - X X X

# Q5: Order operations supported by each market

A:

  • HK stocks support order modification, cancellation, entry into force, invalidation, and deletion
  • US stocks only support order modification and cancellation
  • HKCC only supports cancellation of orders
  • Futures supports order modification, cancellation, and deletion

# Q6: How to use OpenD startup parameter future_trade_api_time_zone?

A: Since the types of futures supported for trading account are distributed in multiple exchanges around the world, and the time zones of the exchanges are different, the time display of the futures trading API has become a problem. The future_trade_api_time_zone parameter has been added to the OpenD startup parameters, allowing futures traders in different regions of the world to flexibly specify the time zone. The default time zone is UTC+8. If you are more accustomed to Eastern Time, you only need to configure this parameter to UTC-5.

Tips

  • This parameter is only valid for futures trading interface objects. The time zone of HK stock trading, US stock trading, and HKCC trading interface objects is still displayed in accordance with the time zone of the exchange.
  • The interfaces affected by this parameter include: responding to order push callbacks, responding to transaction push callbacks, querying today's orders, querying historical orders, querying current transactions, querying historical transactions, and placing orders.

# Q7: Can I see the order placed through OpenAPI, in APP?

A:Yes, you can.
After the order is successfully placed through OpenAPI, you can view today's orders, order status change in the trade page of APP, and you can also receive Order Notice in the APP.

download-page

# Q8: Which trading targets support Off-Market order?

A:All orders can only be filled during the market opening period.
Orders made outside market hours and extended hours trading are queued and fulfilled either at or near the beginning of extended hours trading or at or near the market open, according to your instructions. These orders may be named as off market orders or overnight order. OpenAPI supports Off-Market order for a part of trading targets (APP supports much more trading targets' Off-Market order), as follows:

Market Contracts Paper Trading Live Trading
FUTU HK Moomoo Financial Inc. Moomoo Financial Singapore Pte. Ltd. FUTU AU
HK Market Securities
(including stocks, ETFs, warrants, CBBCs, Inline Warrants)
Options X X X X
Futures X X X X X
US Market Securities (including stocks, ETFs) X X X X
Options X X X X
Futures X X X X X
A-share Market HKCC stocks X X X X
Non-HKCC stocks X X X X
Singapore Market Futures X X X X X
Japanese Market Futures X X X X X

Tip

  • ✓:support Off-Market order
  • X:do not support Off-Market order(or non-tradable)

# Q9: For each order type,mandatory parameters of PlaceOrder as follows.

A:

Parameters Limit Orders Market Orders At-auction Limit Orders At-auction Market Orders Absolute Limit Orders Special Limit Orders AON Special Limit Orders Stop Orders Stop Limit Orders Market if Touched Orders Limit if Touched Orders Trailing Stop Orders Trailing Stop Limit Orders
price
qty
code
trd_side
order_type
trd_env
aux_price
trail_type
trail_value
trail_spread

Python users should note that, place_order does not set a default value for price. For the five types of orders mentioned above, you still need to pass in price, which can be any value.

# Q10: For each order type, when modifying the order, mandatory parameters of ModifyOrder as follows.

Parameters Limit Orders Market Orders At-auction Limit Orders At-auction Market Orders Absolute Limit Orders Special Limit Orders AON Special Limit Orders Stop Orders Stop Limit Orders Market if Touched Orders Limit if Touched Orders Trailing Stop Orders Trailing Stop Limit Orders
modify_order_op
order_id
price
qty
trd_env
aux_price
trail_type
trail_value
trail_spread

Python users should note that, modify_order does not set a default value for price. For the five types of orders mentioned above, you still need to pass in price, which can be any value.

# Q11: The Trade API returns "The current securities account has not yet agreed to the disclaimer."?

A:
Click the link below to confirm the agreement, and restart OpenD to use trading functions normally.

Securities Firm Aggrement Link
FUTU HK Click here
Moomoo Financial Inc. Click here
Moomoo Financial Singapore Pte. Ltd. Click here
FUTU AU Click here

# Q12: Pattern Day Trader (PDT)

# Overview

When clients use Moomoo US accounts for intraday trading, they are subject to regulations by the US Financial Industry Regulatory Authority (FINRA). This is a regulatory requirement for US brokers and has nothing to do with the market to which a stock being traded belongs. The trading accounts of brokers in other countries or regions, such as Futu HK and Moomoo SG accounts, are not subject to this restriction. If a client conducts over 3 day trades in any 5 consecutive trading days, the client will be labelled as a pattern day trader (PDT).
For more details, refer to Help Center - Day Trade Rules.

# Day Trading Flowchart

PDT_process

# How to turn off "Pattern Day Trade Protection", if I'm willing to be labelled as a PDT and do not want the quant trading program to be interrupted?

A:
To prevent you from being unintentionally labelled as a PDT, the server will automatically intercept your 4th day trade in any 5 consecutive trading days. If you are willing to be labelled as a PDT and do not want the server to intercept your trade, you can take the following step:
Via Command Line OpenD, modify the value of the startup parameter "pdt_protection" to "0".

US_para NOTE: You will not be able to establish new positions when you are labelled as a PDT and your account equity is below $25000.

# How to turn off the Day-Trading Call Warning?

A:
Once you are labelled as a PDT, you need to pay attention to the day trading buying power (DTBP) of your account. When the DTBP is insufficient, you will receive a DTCall. The server will intercept your order that exceeds the DTBP. If you still want to place the order and do not want the server to intercept it, you can take the following step:
Via Command Line OpenD, modify the value of the startup parameter "dtcall_confirmation" to "0".

US_para2 NOTE: If the market value of a newly established position exceeds your remaining DTBP and you close the position in the same day, you will receive a DTCall, which can only be met by depositing funds.

# How to check my DTBP?

A:
Via Get Account Funds Interface, you can request values related to day trading, such as Day Trades Left, Beginning DTBP, Remaining DTBP, etc.

# Q13: How to track the status of orders?

A:
The two interfaces can be uesed to track the status of orders, after which have been placed.

Trading Enviroment Interfaces
Real Orders Push Callback, Deals Push Callback
Simulate Orders Push Callback

Note: Non-python users need to Subscribe to Transaction Push before using the above two interfaces.

# Orders Push Callback:

Feedback changes of the entire order. The order push will be triggered when the following 8 fields change:
Order status, Order price, Order quantity, Deal quantity, Traget price, Trailing type, Trailing amount/ratio, Specify spread

Therefore, when you place, modify, cancel, enable, or disable the order, or when an advanced order is triggered or an order has transaction changes, it will cause orders push. You just need to call the Orders Push Callback to listen for these messages.

# Deals Push Callback:

Feedback changes of a transaction. The order push will be triggered when the following field change:
Deal status

Fot example: Suppose a limit order of 900 shares is divided into 3 transactions before it is completely filled, with each transaction being 200, 300 and 400 shares. example

# Q14: Why does the order interface return “Invalid price”?

A:
Different exchanges have different rules on order price spreads. If the price of a submitted order does not follow relevant rules, the order will be rejected.

# Rules on Price Spread

# Hong Kong Market

Refer to the official HKEX Spread Table

# China A-Shares

Stock price spread: 0.01

# US Market

Stock Price Spreads:

Price Spread
Below $1 $0.0001
$1 or above $0.01
Option Price Spreads:
Price Spread
$0.10 - $3.00 $0.01 or $0.05
$3.00+ $0.05 or $0.10

Futures Price Spreads:
Different contracts have different price spreads, which can be obtained via the Price change step of Get Futures Contract Information interface.

# How to ensure an order price meets spread rules?

  • Method 1: Valid order prices can be obtained via the Get Real-time Order Book interface, since the prices of orders on the order book must be valid.

  • Method 2: Auto-adjust an order price to a valid value via the Price adjustment range parameter in the Place Orders interface.

    How it works:

    Suppose the Adjust Limit is set to 0.0015. A positive value means that OpenD will auto-adjust upward the price of a submitted order to a valid value within +0.15% of the original price.

    Suppose the current market price of Tencent Holdings is 359.600, so the spread is 0.200 according to the HKEX Spread Table. Let’s say an order priced at 359.678 is submitted. In this case, the nearest upward valid price is 359.800, which means the order price only needs to be adjusted by 0.034%. The adjustment satisfies the Adjust Limit, so the final price of the submitted order is 359.800.

    If the actual adjustment exceeds the Adjust Limit, OpenD will fail to auto-adjust the price, and the order submission will still return the error prompt "Invalid price".

# Q15: Why did it say "Insufficient Buying Power" when I place a market order with enough buying power in my account?

A:

# Why it indicates insufficient buying power when you place a market order

  • For the sake of risk management, the system poses a higher buying power coefficient on market orders. With the same order parameters, a market order takes up more buying power than a limit order.
  • Depending on different product types and market conditions, the risk management system dynamically adjusts the buying power coefficient of market orders. Therefore, when placing a market order, if you calculate the maximum buyable quantity using your maximum buying power, you are likely to get an inaccurate result.

# How to get the correct buyable quantity

Instead of calculating it, you can obtain the correct buyable quantity through the [Query the Maximum Quantity that Can be Bought or Sold] (../trade/get-max-trd-qtys.html) API.

# How to buy as much as possible

You can place a limit order at the BBO, instead of a market order. In particular, the BBO means the best bid (or Bid 1) in the case of a sell order, or the best ask (or Ask 1) for a buy order.