直接pip install起來,台灣應該沒有其他券商的api那麼方便了。
pip install shioaji
我們也準備好了docker image給各位直接使用,有需要那些其他的linux distribution歡迎在github上跟我們講。
docker run -it sinotrade/shioaji:latest bash
這邊沒有在使用docker的可以忽略,docker主要就是幫各位處理好各種環境問題,但是基本上大家應該pip install就可以開了
這邊也幫大家build好jupyter的環境,執行下面docker指令連到localhost:8888就可以使用了
docker run -p 8888:8888 sinotrade/shioaji:jupyter
pip install shioaji 了之後,接著我們就可以用 python, ipython, jupyter notebook 或 JupyterLab 等編輯器開始接下來旅程。
在這邊我們還需要一個條件,就是請先開好永豐金證券的帳戶,實體開戶或是直接線上開戶。
準備好永豐帳戶就讓我們開始吧!
起手式 import我們的api就像import tensorflow pandas等等一樣
import shioaji as sj
接著我們需要初始化Shioaji這個物件來開始接下來要做的事
ipython有個很方便的方法可以看這個物件或函式的文件,就是直接在function或object後面加上?
下面文件部分可以看到我們api底下所有可以用的function跟object以及初始化Shioaji的參數說明
input
sj.Shioaji?
output
Init signature: sj.Shioaji(backend='http', simulation=True, proxies={}, currency='NTD')
Docstring:
shioaji api
Functions:
login
activate_ca
list_accounts
set_default_account
get_account_margin
get_account_openposition
get_account_settle_profitloss
place_order
update_order
update_status
list_trades
Objects:
Contracts
Order
Init docstring:
initialize Shioaji to start trading
Args:
backend (str): {http, socket}
use http or socket as backend currently only support http, async socket backend coming soon.
simulation (bool):
- False: to trading on real market (just use your Sinopac account to start trading)
- True: become simulation account(need to contract as to open simulation account)
proxies (dict): specific the proxies of your https
ex: {'https': 'your-proxy-url'}
currency (str): {NTX, USX, NTD, USD, HKD, EUR, JPY, GBP}
set the default currency for display
這邊我們選擇http為backend,並且關閉模擬模式,如果有需要使用模擬的客戶麻煩在gitter中聯絡我們,http比較完整socket會在近日釋出敬請期待。
input
api = sj.Shioaji(backend='http', simulation=False)
接著我們要登入才有辦法開始使用api,登入帳號就是永豐金證券電子平台(如:eLeader)的登入帳號密碼。
input
api.login?
output
Signature: api.login(person_id, passwd)
Docstring:
login to trading server
Args:
person_id (str): Same as your eleader, ileader login id(usually your person ID)
passwd (str): the password of your eleader login password(not ca password)
登入後會預設抓出第一個期貨帳戶與證券戶作為預設帳戶
input
api.login(person_id=person_id, passwd='2222')
api.fut_account
output
FutureAccount(person_id='SCCEIEFAJA', broker_id='F002000', account_id='9104000', username='莊*芬')
也可以列出我們所有帳戶,並使用api.set_default_account
將常用設為預設的帳戶
input
api.list_accounts()
output
[Account(account_type='H', person_id='QCCAHIFFDH', broker_id='1300', account_id='09800762', username='n*m'),
FutureAccount(person_id='SCCEIEFAJA', broker_id='F002000', account_id='9104000', username='莊*芬'),
StockAccount(person_id='SCCEIEFAJA', broker_id='9A92', account_id='9802195', username='莊*芬')]
以上動作已經完成與下單無關的動作的初始化了,需要下單的話必須啟動憑證,若只是帳務相關等功能無需憑證。
input
api.activate_ca?
output
Signature: api.activate_ca(ca_path, ca_passwd, person_id)
Docstring:
activate your ca for trading
Args:
ca_path (str):
the path of your ca, support both absloutely and relatively path, use same ca with eleader
ca_passwd (str): password of your ca
person_id (str): the ca belong which person ID
input
api.activate_ca(ca_path='../ca/Sinopac.pfx', ca_passwd='SCCEIEFAJA', person_id=person_id)
output
Ca Initial Done.
0
開始下單的部分吧!首先api的place_order下單的函式中,需要傳入兩個物件,分別是Contract及Order,我們可以從Contracts物件中找到我們要交易的商品Contract,以及用Order製作出一筆order物件,然後丟進函式中,這個函式會回傳一個Trade物件包含Contract, Order及這筆單的狀態物件(OrderStatus)。
Order物件需要帶入的參數部分一樣可以用?直接看到文件
input
api.Order?
output
Init signature: api.Order(action, price_type, order_type, price, quantity, *args, **kwargs) Docstring: The basic order object to place order Attributes: product_id (str): the code of product that order to placing action (srt): {B, S}, order action to buy or sell - B: buy - S: sell price_type (str): {LMT, MKT, MKP}, pricing type of order - LMT: limit - MKT: market - MKP: market range order_type (str): {ROD, IOC, FOK}, the type of order - ROD: Rest of Day - IOC: Immediate-or-Cancel - FOK: Fill-or-Kill octype (str): {' ', '0', '1', '6'}, the type or order to open new position or close position - ' ': auto - '0': new position - '1': close position - '6': day trade price (float or int): the price of order quantity (int): the quantity of order account (:obj:Account): which account to place this order ca (binary): the ca of this order
接著我們有做一件方便大家開發的事,有兩個物件api.OrderProps
跟api.Contracts
這兩個物件可以快速輔助開發的時候直接用tab自動補齊的方式找到Order物件中需要填入的欄位。
input
api.OrderProps.</tab> api.Contracts.</tab>
這邊我們以期貨為範例按tab鍵自動補齊可交易的合約,回傳的Future物件就是一個期貨的Contract物件,可以以
isinstance(api.Contracts.Futures.TXF.TXF201903, shioaji.contracts.Contract)
來確認他確實是個Contract物件 inputapi.Contracts.Futures.TXF
output
TXF(TXF201903, TXF201906, TXF201809, TXF201810, TXF201811, TXF201812)
input
api.Contracts.Futures.TXF.TXF201903
output
Future(symbol='TXF201903', code='TXFC9', name='台指期貨', category='TXF', delivery_month='201903', underlying_kind='I', underlying_code='#001', unit=1.0)
知道使用方式後我們直接用自動補齊的方式幫我快速創建一筆Order,參數在OrderProps都有相對應的欄位可以幫我們免去用文件的選項輸入,當然也可以直接使用文件的選項直接填入。
sample_order = api.Order(price=9600,
action=api.OrderProps.action.Buy,
price_type=api.OrderProps.price_type.LMT,
order_type=api.OrderProps.order_type.ROD,
octype=api.OrderProps.octype.auto,
quantity=5,
account=api.fut_account,
)
另外為了不用煩鎖的Order我們可以直接使用MarketOrder, LimitOrder物件,需要填的選項就會很少。
MarketOrder
Args:
product_id (str, optional): the code of product that order to placing
if not provide will gen from contract when placing order
action (srt): {B, S}, order action to buy or sell
- B: buy
- S: sell
quantity (int): the quantity of order
order_type (str, optional): {IOC, FOK}, the type of order
- IOC: Immediate-or-Cancel
- FOK: Fill-or-Kill
octype (str, optional): {' ', '0', '1', '6'}, the type or order
to open new position or close position
if not provide will become auto mode
- ' ': auto
- '0': new position
- '1': close position
- '6': day trade
製作一個MarketOrder物件就非常簡單,用下面填入買或賣,及口數就完成了。 > input
sample_mkt_order = api.MarketOrder('B', 5)
sample_mkt_order
output
MarketOrder(action='B', order_type='IOC', quantity=5)
LimitOrder
Args:
product_id (str, optional): the code of product that order to placing
if not provide will gen from contract when placing order
action (srt): {B, S}, order action to buy or sell
- B: buy
- S: sell
price (float or int): the price of order
quantity (int): the quantity of order
order_type (str, optional): {ROD, IOC, FOK}, the type of order
- ROD: Rest of Day
- IOC: Immediate-or-Cancel
- FOK: Fill-or-Kill
octype (str, optional): {' ', '0', '1', '6'}, the type or order
to open new position or close position
if not provide will become auto mode
- ' ': auto
- '0': new position
- '1': close position
- '6': day trade
限價單的部分就多一個參數,價格就完成了。
input
sample_limit_order = api.LimitOrder('B', 9700, 5) sample_limit_order
output
LimitOrder(action='B', order_type='ROD', price=9700, quantity=5)
接著我們把製作好的Contract及Order物件傳進place_order
函式中就會送出委託單了,這時候會回傳trade物件,Trade.status底下會是這筆交易的狀態,目前可以看到剛下出去是PendingSubmit。
input
txf = api.Contracts.Futures.TXF.TXF201903 trade = api.place_order(txf, sample_order)
output
Trade(contract=Future(symbol='TXF201903', code='TXFC9', name='台指期貨', category='TXF', delivery_month='201903', underlying_kind='I', underlying_code='#001', unit=1.0), order=Order(product_id='TXFC9', action='B', price_type='LMT', order_type='ROD', price=9600, quantity=5, account=FutureAccount(person_id='SCCEIEFAJA', broker_id='F002000', account_id='9104000', username='莊*芬')), status=OrderStatus(seqno='701124', order_id='7521840eb43914f94f98f025b1762e0b250ded21', status='PendingSubmit', order_datetime=datetime.datetime(2019, 1, 16, 12, 39, 28)))
拿到的Trade物件我可以透過update_status
函式來更新所有Trade的狀態,這時候就會看到狀態變為Submitted,成交後會變為Filled。
input
api.update_status() trade
output
Trade(contract=Future(symbol='TXF201903', code='TXFC9', name='台指期貨', category='TXF', delivery_month='201903', underlying_kind='I', underlying_code='#001', unit=1.0), order=Order(product_id='TXFC9', action='B', price_type='LMT', order_type='ROD', price=9600, quantity=5, account=FutureAccount(person_id='SCCEIEFAJA', broker_id='F002000', account_id='9104000', username='莊*芬')), status=OrderStatus(seqno='701124', ordno='ky00P', order_id='7521840eb43914f94f98f025b1762e0b250ded21', status='Submitted', status_code='0000', msg='ky00P', modified_price=9600.0, remaining=5, order_datetime=datetime.datetime(2019, 1, 16, 12, 39, 28)))
改價或改量的部分使用
api.update_order
函式傳入Trade物件,可以看到modified_price就變成9800並input
trade = api.update_order(trade, price=9800, qty=1) trade
output
Trade(contract=Future(symbol='TXF201903', code='TXFC9', name='台指期貨', category='TXF', delivery_month='201903', underlying_kind='I', underlying_code='#001', unit=1.0), order=Order(product_id='TXFC9', action='B', price_type='LMT', order_type='ROD', price=9600, quantity=5, account=FutureAccount(person_id='SCCEIEFAJA', broker_id='F002000', account_id='9104000', username='莊*芬')), status=OrderStatus(seqno='701124', ordno='ky00P', order_id='7521840eb43914f94f98f025b1762e0b250ded21', status='Submitted', status_code='0000', msg='ky00P', modified_price=9800.0, remaining=5, order_datetime=datetime.datetime(2019, 1, 16, 12, 39, 28)))
取消委託使用api.cancel_order
函式並傳入欲取消的trade物件,就不寫出範例code了。
下單ok後接著看帳務部分,帳務部份我們為了方便的與python的ecosystem結合,我們製作了將帳務的物件快速地轉換,就可以直接地變成pandas的Dataframe方便各位與自己的機器學習或深度學習模型直接介接。
input
api.get_account_margin?
output
Signature: api.get_account_margin(currency='NTD', margin_type='1', account={})
Docstring:
query margin currency: {NTX, USX, NTD, USD, HKD, EUR, JPY, GBP}
the margin calculate in which currency
- NTX: 約當台幣
- USX: 約當美金
- NTD: 新台幣
- USD: 美元
- HKD: 港幣
- EUR: 歐元
- JPY: 日幣
- GBP: 英鎊
margin_type: {'1', '2'}
query margin type
- 1 : 即時
- 2 : 風險
input
account_margin = api.get_account_margin()
account_margin
output
AccountMargin
Currency: NTD
Account: F0020009104000
Detail:
OrderPSecurity: 207000.0
ProfitAccCount: 207000.0
FProfit: 0.0
FMissConProfit: 0.0
OMissConProfit: 0.0
OColse: 0.0
OMarketPrice: 0.0
OTodayDiff: 0.0
HandCharge: 0.0
TradeTax: 0.0
Security: 0.0
StartSecurity: 0.0
UpKeepSecurity: 0.0
Statistics: 99999.0
Flow: 999.0
orderBid: 0.0
orderAsk: 0.0
Conclusionbid: 0.0
Conclusionask: 0.0
YesterdayBalance: 207000.0
PayMoney: 0.0
Equity: 207000.0
Ogain: 0.0
exrate: 1.0
xgdamt: 0.0
agtamt: 0.0
YesterdayEquity: 207000.0
Munet: 0.0
Cashamt: 207000.0
Bapamt: 0.0
Sapamt: 0.0
Adps: 0.0
Adamt: 0.0
Ybaln: 207000.0
直接用將物件傳入pandas.DataFrame
就可以簡單的拿到常用的dataframe了
input
df_margin = pd.DataFrame([{**account_margin}])
df_margin
output
Adamt | Adps | Bapamt | Cashamt | Conclusionask | Conclusionbid | Equity | FMissConProfit | FProfit | Flow | … | TradeTax | UpKeepSecurity | Ybaln | YesterdayBalance | YesterdayEquity | agtamt | exrate | orderAsk | orderBid | xgdamt | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.0 | 0.0 | 0.0 | 288000.0 | 0.0 | 0.0 | 288000.0 | 0.0 | 0.0 | 999.0 | … | 0.0 | 0.0 | 207000.0 | 207000.0 | 207000.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 |
1 rows × 34 columns
input
api.get_account_openposition?
output
Signature: api.get_account_openposition(product_type='0', query_type='0', account={})
Docstring:
query open position
product_type: {0, 1, 2, 3}
filter product type of open position
- 0: all
- 1: future
- 2: option
- 3: usd base
query_type: {0, 1}
query return with detail or summary
- 0: detail
- 1: summary
input
positions = api.get_account_openposition(query_type='1', account=api.fut_account)
positions
output
AccountOpenPosition
轉換成dataframe
input
df_positions = pd.DataFrame(positions.data())
df_positions
output
Account | Code | CodeName | ContractAverPrice | Currency | Date | FlowProfitLoss | MTAMT | OTAMT | OrderBS | OrderNum | OrderType | RealPrice | SettlePrice | SettleProfitLoss | StartSecurity | UpKeepSecurity | Volume | paddingByte | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | FF0020009104000 | TXFA9 | 台指期貨 01 | 9508.4137 | NTD | 00000000 | 4795201.620000 | 6438000.000000 | 8352000.000000 | B | 9784.0 | 9784.00 | 4795201.620000 | 8352000.000000 | 6438000.000000 | 87.000000 | |||
1 | FF0020009104000 | XJFF9 | 日圓期貨 06 | 80.0000 | JPY | 00000000 | 31400.000000 | 47000.000000 | 61000.000000 | B | 0.0 | 81.57 | 31400.000000 | 61000.000000 | 47000.000000 | 1.000000 | |||
2 | FF0020009104000 | TXO08000L8 | 台指選擇權 8000 C 12 | 1870.0000 | NTD | 00000000 | -14000.000000 | 0.000000 | 0.000000 | B | 1730.0 | 1810.00 | -6000.000000 | 0.000000 | 0.000000 | 2.000000 | |||
3 | FF0020009104000 | TXO09200L8 | 台指選擇權 9200 C 12 | 720.0000 | NTD | 00000000 | 11250.000000 | 147000.000000 | 162000.000000 | S | 645.0 | 660.00 | 9000.000000 | 162000.000000 | 147000.000000 | 3.000000 | |||
4 | FF0020009104000 | TXO09400X8 | 台指選擇權 9400 P 12 | 199.0000 | NTD | 00000000 | 21200.000000 | 57600.000000 | 65600.000000 | S | 93.0 | 93.00 | 21200.000000 | 65600.000000 | 57600.000000 | 4.000000 | |||
5 | FF0020009104000 | TXO10200L8 | 台指選擇權 10200 C 12 | 111.0000 | NTD | 00000000 | 33550.000000 | 125950.000000 | 147950.000000 | S | 50.0 | 50.00 | 33550.000000 | 147950.000000 | 125950.000000 | 11.000000 |
input
api.get_account_settle_profitloss?
output
Signature: api.get_account_settle_profitloss(product_type='0', summary='Y', start_date='', end_date='', currency='', account={})
Docstring:
query settlement profit loss
product_type: {0, 1, 2}
filter product type of open position
- 0: all
- 1: future
- 2: option
summary: {Y, N}
query return with detail or summary
- Y: summary
- N: detail
start_date: str
the start date of query range format with %Y%m%d
ex: 20180101
end_date: str
the end date of query range format with %Y%m%d
ex: 20180201
currency: {NTD, USD, HKD, EUR, CAD, BAS}
the profit loss calculate in which currency
- NTD: 新台幣
- USD: 美元
- HKD: 港幣
- EUR: 歐元
- CAD: 加幣
- BAS: 基幣
input
st_date = (date.today() - timedelta(days=60)).strftime('%Y%m%d')
settle_profitloss = api.get_account_settle_profitloss(summary='Y', start_date=st_date)
settle_profitloss
output
AccountSettleProfitLoss
轉換成dataframe
input
df_profitloss = pd.DataFrame(settle_profitloss.data())
df_profitloss
output
account | averagePrice | code | codeName | currency | floatProfitLoss | handCharge | ord_bs | ord_type | ordno | ordno_b | settleAvgPrc | settleDate | settleVolume | tFlag | tdate | tradeProfitLoss | tradeTax | unVolume | volume | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | F0020009104000 | 9900.0 | TXFK8 | 台指期貨 11 | NTD | 460.000000 | 60.000000 | S | 00 | kY002 | kY003 | 9897.0 | 20181022 | 1.000000 | 1 | 20181022 | 600.000000 | 80.000000 | 0.000000 | 1.000000 |
Windows開發環境安裝app清單
下載window版本Git 安裝時請選Use Git and optional Unix tools from the Windows Command Prompt
下載Windows版本VSCode 安裝後到插件管理中搜尋python並安裝
下載miniconda
我們在windows中使用miniconda來安裝我們的環境,安裝完成後打開cmd,輸入 conda install jupyterlab pandas -y
把相關的套件裝好接著輸入jupyter lab
,打開瀏覽器連到 localhost:8888 就可以連到jupyter開始使用。