TqSdk — open-source Python SDK for futures/options trading by Shinny Tech, providing real-time quotes, backtesting, and live trading.
homepage
https://github.com/shinnytech/tqsdk-python
TqSdk (Tianqin Quantitative SDK)
TqSdk is an open-source Python SDK by Shinny Tech for futures and options quantitative trading. It provides real-time market data, historical data, backtesting, and live trading through a unified async API.
from tqsdk import TqApi, TqAuth
api = TqApi(auth=TqAuth("user", "pass"))
# Limit order — buy open 2 lots
order = api.insert_order(
symbol="SHFE.cu2401",
direction="BUY", # "BUY" or "SELL"
offset="OPEN", # "OPEN", "CLOSE", "CLOSETODAY"
volume=2, # Number of lots
limit_price=68000.0# Limit price (None for market order)
)
# Market order (FAK — Fill and Kill)
order = api.insert_order(
symbol="SHFE.cu2401",
direction="BUY",
offset="OPEN",
volume=2
)
# Cancel order
api.cancel_order(order)
# Check order statuswhileTrue:
api.wait_update()
if order.status == "FINISHED":
print(f"Order finished: filled={order.volume_orign - order.volume_left}")
break
Position & Account
# Get account info
account = api.get_account()
# account.balance — Account balance# account.available — Available funds# account.margin — Used margin# account.float_profit — Floating PnL# account.position_profit — Position PnL# account.commission — Today's commission# Get position
position = api.get_position("SHFE.cu2401")
# position.pos_long — Long position volume# position.pos_short — Short position volume# position.pos_long_today — Today's long position# position.float_profit_long — Long floating PnL# position.float_profit_short — Short floating PnL# position.open_price_long — Long average open price# position.open_price_short — Short average open price
Backtesting
from tqsdk import TqApi, TqAuth, TqBacktest, TqSim
from datetime import date
# Create backtest API
api = TqApi(
backtest=TqBacktest(
start_dt=date(2024, 1, 1),
end_dt=date(2024, 6, 30)
),
account=TqSim(init_balance=1000000), # Simulated account with 1M initial
auth=TqAuth("user", "pass")
)
# Strategy logic (same code works for live and backtest)
klines = api.get_kline_serial("CFFEX.IF2401", 60 * 60) # 1-hour bars
position = api.get_position("CFFEX.IF2401")
whileTrue:
api.wait_update()
if api.is_changing(klines.iloc[-1], "close"):
ma5 = klines["close"].iloc[-5:].mean()
ma20 = klines["close"].iloc[-20:].mean()
if ma5 > ma20 and position.pos_long == 0:
api.insert_order("CFFEX.IF2401", "BUY", "OPEN", 1, klines.iloc[-1]["close"])
elif ma5 < ma20 and position.pos_long > 0:
api.insert_order("CFFEX.IF2401", "SELL", "CLOSE", 1, klines.iloc[-1]["close"])
api.close()
Advanced Examples
Dual-Contract Spread Trading
from tqsdk import TqApi, TqAuth
api = TqApi(auth=TqAuth("user", "pass"))
quote_near = api.get_quote("SHFE.rb2401") # Near-month rebar
quote_far = api.get_quote("SHFE.rb2405") # Far-month rebar
pos_near = api.get_position("SHFE.rb2401")
pos_far = api.get_position("SHFE.rb2405")
SPREAD_OPEN = 100# Open spread threshold
SPREAD_CLOSE = 20# Close spread thresholdwhileTrue:
api.wait_update()
spread = quote_near.last_price - quote_far.last_price
if spread > SPREAD_OPEN and pos_near.pos_short == 0:
# Spread too wide: sell near, buy far
api.insert_order("SHFE.rb2401", "SELL", "OPEN", 1, quote_near.bid_price1)
api.insert_order("SHFE.rb2405", "BUY", "OPEN", 1, quote_far.ask_price1)
print(f"Open spread trade: spread={spread:.0f}")
elif spread < SPREAD_CLOSE and pos_near.pos_short > 0:
# Spread converged: close both legs
api.insert_order("SHFE.rb2401", "BUY", "CLOSE", 1, quote_near.ask_price1)
api.insert_order("SHFE.rb2405", "SELL", "CLOSE", 1, quote_far.bid_price1)
print(f"Close spread trade: spread={spread:.0f}")