はじめに
使用するライブラリ
接続までの箇所は、接続ページとほぼ同じですが、import oandapyV20.endpoints.transactions as transをインポートして使用します。
トレードのログ(トランザクション)をストリーミングで取得
仕様の説明
新たなトレードのログ(トランザクション)をリアルタイムに取得します。
res = trans.TransactionsStream(accountID=accountID)
api.request(res)
for Transactions in res.response:
print(json.dumps(Transactions, indent=4), ",")trans.TransactionsStreamにaccountIDを渡すだけです。res.responseに逐次新たなログ(トランザクション)が受け渡されます。なお無限ループになります。
返り値について
typeとreasonによって、そのログのアクションを読み取ることができます。
type:種類HEARTBEAT:何も変化がない。MARKET_ORDER:成り行き注文を実行した。ORDER_FILL:注文が確約した。- その他・・・
reason:理由- type = MARKET_ORDER
CLIENT_ORDER:自身による注文TRADE_CLOSE:決済- その他・・・
- type = ORDER_FILL
MARKET_ORDER:成行MARKET_ORDER_TRADE_CLOSE:決済- その他・・・
- type = MARKET_ORDER
システム例
import oandapyV20.endpoints.transactions as trans
# APIに接続
api = API(environment="practice", access_token=access_token)
res = trans.TransactionsStream(accountID=accountID)
api.request(res)
for Transactions in res.response:
print(json.dumps(Transactions, indent=4), ",")
# {
# "type": "HEARTBEAT",
# "lastTransactionID": "23808",
# "time": "2020-07-10T01:01:21.117466675Z"
# } ,
# {
# "type": "HEARTBEAT",
# "lastTransactionID": "23808",
# "time": "2020-07-10T01:01:26.156492373Z"
# } ,
# {
# "type": "MARKET_ORDER",
# "instrument": "USD_JPY",
# "units": "1000",
# "timeInForce": "FOK",
# "positionFill": "DEFAULT",
# "reason": "CLIENT_ORDER",
# "id": "23809",
# "accountID": "",
# "userID": ,
# "batchID": "23809",
# "requestID": "60730354280635712",
# "time": "2020-07-10T01:01:27.370946549Z"
# } ,
# {
# "type": "ORDER_FILL",
# "orderID": "23809",
# "instrument": "USD_JPY",
# "units": "1000",
# "requestedUnits": "1000",
# "price": "107.077",
# "pl": "0.0000",
# "financing": "0.0000",
# "commission": "0.0000",
# "accountBalance": "3123369.6517",
# "gainQuoteHomeConversionFactor": "1",
# "lossQuoteHomeConversionFactor": "1",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "fullVWAP": "107.077",
# "reason": "MARKET_ORDER",
# "tradeOpened": {
# "price": "107.077",
# "tradeID": "23810",
# "units": "1000",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "initialMarginRequired": "4283.0000"
# },
# "fullPrice": {
# "closeoutBid": "107.066",
# "closeoutAsk": "107.084",
# "timestamp": "2020-07-10T01:01:23.686445408Z",
# "bids": [
# {
# "price": "107.073",
# "liquidity": "250000"
# }
# ],
# "asks": [
# {
# "price": "107.077",
# "liquidity": "250000"
# }
# ]
# },
# "id": "23810",
# "accountID": "",
# "userID":,
# "batchID": "23809",
# "requestID": "60730354280635712",
# "time": "2020-07-10T01:01:27.370946549Z"
# } ,
# {
# "type": "HEARTBEAT",
# "lastTransactionID": "23810",
# "time": "2020-07-10T01:01:31.213494977Z"
# } ,
# {
# "type": "HEARTBEAT",
# "lastTransactionID": "23810",
# "time": "2020-07-10T01:01:36.223801172Z"
# } ,
# {
# "type": "HEARTBEAT",
# "lastTransactionID": "23810",
# "time": "2020-07-10T01:01:41.287440968Z"
# } ,
# {
# "type": "MARKET_ORDER",
# "instrument": "USD_JPY",
# "units": "-1000",
# "timeInForce": "FOK",
# "positionFill": "REDUCE_ONLY",
# "reason": "TRADE_CLOSE",
# "tradeClose": {
# "units": "1000",
# "tradeID": "23810"
# },
# "id": "23811",
# "accountID": "",
# "userID":,
# "batchID": "23811",
# "requestID": "60730354343580892",
# "time": "2020-07-10T01:01:42.282680258Z"
# } ,
# {
# "type": "ORDER_FILL",
# "orderID": "23811",
# "instrument": "USD_JPY",
# "units": "-1000",
# "requestedUnits": "-1000",
# "price": "107.062",
# "pl": "-15.0000",
# "financing": "0.0000",
# "commission": "0.0000",
# "accountBalance": "3123354.6517",
# "gainQuoteHomeConversionFactor": "1",
# "lossQuoteHomeConversionFactor": "1",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "fullVWAP": "107.062",
# "reason": "MARKET_ORDER_TRADE_CLOSE",
# "tradesClosed": [
# {
# "tradeID": "23810",
# "units": "-1000",
# "realizedPL": "-15.0000",
# "financing": "0.0000",
# "price": "107.062",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000"
# }
# ],
# "fullPrice": {
# "closeoutBid": "107.055",
# "closeoutAsk": "107.073",
# "timestamp": "2020-07-10T01:01:39.103933136Z",
# "bids": [
# {
# "price": "107.062",
# "liquidity": "250000"
# }
# ],
# "asks": [
# {
# "price": "107.066",
# "liquidity": "250000"
# }
# ]
# },
# "id": "23812",
# "accountID": "",
# "userID":,
# "batchID": "23811",
# "requestID": "60730354343580892",
# "time": "2020-07-10T01:01:42.282680258Z"
# } ,
# {
# "type": "HEARTBEAT",
# "lastTransactionID": "23812",
# "time": "2020-07-10T01:01:46.288542506Z"
# } ,
# {
# "type": "HEARTBEAT",
# "lastTransactionID": "23812",
# "time": "2020-07-10T01:01:51.296286157Z"
# } ,ログの詳細を取得
res = trans.TransactionDetails(accountID=accountID, transactionID=12345) api.request(res)
trans.TransactionDetailsにaccountIDとtransactionID(ログID)を渡すだけです。
orders.OrderDetailsとの大きな違いは以下の通りです。
reasonを取得できる。typeの値に_ORDERが追加され、TAKE_PROFITではなく、TAKE_PROFIT_ORDERとなる。orders.OrderClientExtensionsでオーダーに設定したクライアント拡張機能の値を取得できない。
システム例
出力結果はログのトレードのタイプにより異なります。
transactionID = 23809
res = trans.TransactionDetails(accountID=accountID, transactionID=transactionID)
api.request(res)
print(json.dumps(res.response, indent=4), ",")
# {
# "transaction": {
# "type": "MARKET_ORDER",
# "instrument": "USD_JPY",
# "units": "1000",
# "timeInForce": "FOK",
# "positionFill": "DEFAULT",
# "reason": "CLIENT_ORDER",
# "id": "23809",
# "accountID": "",
# "userID": ,
# "batchID": "23809",
# "requestID": "60730354280635712",
# "time": "2020-07-10T01:01:27.370946549Z"
# },
# "lastTransactionID": "24600"
# } ,指定したログIDからログ一覧を取得
仕様の説明
指定したログID以降のログ(トランザクションを)を取得します。
params = {
"id": 23809
}
res = trans.TransactionsSinceID(accountID=accountID, params=params)
api.request(res)
print(json.dumps(res.response, indent=4), ",")trans.TransactionsSinceIDにaccountIDとログIDを指定したparamsを渡します。
システム例
params = {
"id": 23809
}
res = trans.TransactionsSinceID(accountID=accountID, params=params)
api.request(res)
print(json.dumps(res.response, indent=4), ",")
# {
# "transactions": [
# {
# "type": "ORDER_FILL",
# "orderID": "23809",
# "instrument": "USD_JPY",
# "units": "1000",
# "requestedUnits": "1000",
# "price": "107.077",
# "pl": "0.0000",
# "financing": "0.0000",
# "commission": "0.0000",
# "accountBalance": "3123369.6517",
# "gainQuoteHomeConversionFactor": "1",
# "lossQuoteHomeConversionFactor": "1",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "fullVWAP": "107.077",
# "reason": "MARKET_ORDER",
# "tradeOpened": {
# "price": "107.077",
# "tradeID": "23810",
# "units": "1000",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "initialMarginRequired": "4283.0000"
# },
# "fullPrice": {
# "closeoutBid": "107.066",
# "closeoutAsk": "107.084",
# "timestamp": "2020-07-10T01:01:23.686445408Z",
# "bids": [
# {
# "price": "107.073",
# "liquidity": "250000"
# }
# ],
# "asks": [
# {
# "price": "107.077",
# "liquidity": "250000"
# }
# ]
# },
# "id": "23810",
# "accountID": "",
# "userID":,
# "batchID": "23809",
# "requestID": "60730354280635712",
# "time": "2020-07-10T01:01:27.370946549Z"
# },
# {
# "type": "MARKET_ORDER",
# "instrument": "USD_JPY",
# "units": "-1000",
# "timeInForce": "FOK",
# "positionFill": "REDUCE_ONLY",
# "reason": "TRADE_CLOSE",
# "tradeClose": {
# "units": "1000",
# "tradeID": "23810"
# },
# "id": "23811",
# "accountID": "",
# "userID":,
# "batchID": "23811",
# "requestID": "60730354343580892",
# "time": "2020-07-10T01:01:42.282680258Z"
# },
# {
# "type": "ORDER_FILL",
# "orderID": "23811",
# "instrument": "USD_JPY",
# "units": "-1000",
# "requestedUnits": "-1000",
# "price": "107.062",
# "pl": "-15.0000",
# "financing": "0.0000",
# "commission": "0.0000",
# "accountBalance": "3123354.6517",
# "gainQuoteHomeConversionFactor": "1",
# "lossQuoteHomeConversionFactor": "1",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "fullVWAP": "107.062",
# "reason": "MARKET_ORDER_TRADE_CLOSE",
# "tradesClosed": [
# {
# "tradeID": "23810",
# "units": "-1000",
# "realizedPL": "-15.0000",
# "financing": "0.0000",
# "price": "107.062",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000"
# }
# ],
# "fullPrice": {
# "closeoutBid": "107.055",
# "closeoutAsk": "107.073",
# "timestamp": "2020-07-10T01:01:39.103933136Z",
# "bids": [
# {
# "price": "107.062",
# "liquidity": "250000"
# }
# ],
# "asks": [
# {
# "price": "107.066",
# "liquidity": "250000"
# }
# ]
# },
# "id": "23812",
# "accountID": "",
# "userID":,
# "batchID": "23811",
# "requestID": "60730354343580892",
# "time": "2020-07-10T01:01:42.282680258Z"
# }
# ],
# "lastTransactionID": "23812"
# } ,決済ログからどの新規注文かを判別する方法
OANDA JAPANのAPIには残念ながら遡る仕様はありません。
以下のような流れであれば新規注文のログを取得することができます。
- 決済が確定したログ(type = ORDER_FILL)を取得します。
- その取得したログにある
orderIDを取得します。このorderIDは決済注文のログIDになります。 - その決済注文の
orderIDを用いて、決済注文のログを取得します。 - その取得したログにある以下の
tradeIDを取得します。
2が無ければ1を取得という形でも良いと思います。- 成行の場合:
tradeClose->tradeID - 指値の場合:
tradeID
- 成行の場合:
- その決済注文の
tradeIDを用いて、新規注文が確定したログ(type = ORDER_FILL)を取得します。 - その取得したログにある
orderIDを取得します。このorderIDは新規注文したログのIDになります。 - その決済注文の
orderIDを用いて、新規注文のログを取得します。
システム例
transactionID = 23812
res = trans.TransactionDetails(accountID=accountID, transactionID=transactionID)
api.request(res)
print(json.dumps(res.response, indent=4), ",")
transactionID = res.response["transaction"]["orderID"]
print(transactionID)
res = trans.TransactionDetails(accountID=accountID, transactionID=transactionID)
api.request(res)
print(json.dumps(res.response, indent=4), ",")
transactionID = res.response["transaction"]["tradeClose"]["tradeID"]
print(transactionID)
res = trans.TransactionDetails(accountID=accountID, transactionID=transactionID)
api.request(res)
print(json.dumps(res.response, indent=4), ",")
transactionID = res.response["transaction"]["orderID"]
print(transactionID)
res = trans.TransactionDetails(accountID=accountID, transactionID=transactionID)
api.request(res)
print(json.dumps(res.response, indent=4), ",")
# {
# "transaction": {
# "type": "ORDER_FILL",
# "orderID": "23811",
# "instrument": "USD_JPY",
# "units": "-1000",
# "requestedUnits": "-1000",
# "price": "107.062",
# "pl": "-15.0000",
# "financing": "0.0000",
# "commission": "0.0000",
# "accountBalance": "3123354.6517",
# "gainQuoteHomeConversionFactor": "1",
# "lossQuoteHomeConversionFactor": "1",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "fullVWAP": "107.062",
# "reason": "MARKET_ORDER_TRADE_CLOSE",
# "tradesClosed": [
# {
# "tradeID": "23810",
# "units": "-1000",
# "realizedPL": "-15.0000",
# "financing": "0.0000",
# "price": "107.062",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000"
# }
# ],
# "fullPrice": {
# "closeoutBid": "107.055",
# "closeoutAsk": "107.073",
# "timestamp": "2020-07-10T01:01:39.103933136Z",
# "bids": [
# {
# "price": "107.062",
# "liquidity": "250000"
# }
# ],
# "asks": [
# {
# "price": "107.066",
# "liquidity": "250000"
# }
# ]
# },
# "id": "23812",
# "accountID": "",
# "userID": ,
# "batchID": "23811",
# "requestID": "60730354343580892",
# "time": "2020-07-10T01:01:42.282680258Z"
# },
# "lastTransactionID": "24596"
# } ,
# 23811
# {
# "transaction": {
# "type": "MARKET_ORDER",
# "instrument": "USD_JPY",
# "units": "-1000",
# "timeInForce": "FOK",
# "positionFill": "REDUCE_ONLY",
# "reason": "TRADE_CLOSE",
# "tradeClose": {
# "units": "1000",
# "tradeID": "23810"
# },
# "id": "23811",
# "accountID": "",
# "userID": ,
# "batchID": "23811",
# "requestID": "60730354343580892",
# "time": "2020-07-10T01:01:42.282680258Z"
# },
# "lastTransactionID": "24596"
# } ,
# 23810
# {
# "transaction": {
# "type": "ORDER_FILL",
# "orderID": "23809",
# "instrument": "USD_JPY",
# "units": "1000",
# "requestedUnits": "1000",
# "price": "107.077",
# "pl": "0.0000",
# "financing": "0.0000",
# "commission": "0.0000",
# "accountBalance": "3123369.6517",
# "gainQuoteHomeConversionFactor": "1",
# "lossQuoteHomeConversionFactor": "1",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "fullVWAP": "107.077",
# "reason": "MARKET_ORDER",
# "tradeOpened": {
# "price": "107.077",
# "tradeID": "23810",
# "units": "1000",
# "guaranteedExecutionFee": "0.0000",
# "halfSpreadCost": "2.0000",
# "initialMarginRequired": "4283.0000"
# },
# "fullPrice": {
# "closeoutBid": "107.066",
# "closeoutAsk": "107.084",
# "timestamp": "2020-07-10T01:01:23.686445408Z",
# "bids": [
# {
# "price": "107.073",
# "liquidity": "250000"
# }
# ],
# "asks": [
# {
# "price": "107.077",
# "liquidity": "250000"
# }
# ]
# },
# "id": "23810",
# "accountID": "",
# "userID": ,
# "batchID": "23809",
# "requestID": "60730354280635712",
# "time": "2020-07-10T01:01:27.370946549Z"
# },
# "lastTransactionID": "24596"
# } ,
# 23809
# {
# "transaction": {
# "type": "MARKET_ORDER",
# "instrument": "USD_JPY",
# "units": "1000",
# "timeInForce": "FOK",
# "positionFill": "DEFAULT",
# "reason": "CLIENT_ORDER",
# "id": "23809",
# "accountID": "",
# "userID": ,
# "batchID": "23809",
# "requestID": "60730354280635712",
# "time": "2020-07-10T01:01:27.370946549Z"
# },
# "lastTransactionID": "24596"
# } ,

コメント