PythonとRequestsを使ってOANDA APIを実行する方法(その2)
はじめに
今回の記事は、前回の続きとなります。現在価格、ロウソク足、成行注文の実行例は前回の記事を参照ください。
OANDA APIで自動取引BOTを作成するために、最低限必要なAPIの実行サンプルを紹介します。今回は、ポジション(建玉)情報や、口座情報から利益関連情報を取得する方法の説明です。
if文やfor文等、プログラムに関する簡単な知識はある前提で記載していきます。基礎は覚えたけれども、何を作って良いか迷っている人の参考になれば幸いです。
前回は実行例にコードの全文をつけたり、コードに丁寧なコメントを付けましたが、冗長に感じたので今回はシンプルに行きます。
「環境」と「前提」は前回と同じ内容なので、読まれた方は建玉情報の取得(Position)に飛んでください。
さっそく行きましょうか。
環境
Python 3.9.6
requests 2.26.0
前提
1.APIのトークン取得が完了していること。
2.口座IDとトークンはjsonファイルから読み取る。
key.jsonの形式
{
"id":"my-account-id",
"key":"my-api-key"
}
3.key.jsonは以下の関数で読み取る
def load_key(file_path):
# file_path (str): key.jsonのパス
with open(file_path,"r") as f:
return json.load(f)
4.ヘッダは以下のように取得
def default_header(api_key):
return {
"Content-Type": "application/json",
"Authorization": "Bearer " + api_key
}
5.liveのURLを使用。
# 本番 URL
LIVE_URL = "https://api-fxtrade.oanda.com"
建玉情報の取得(Position)
ドキュメント
ポジション情報のドキュメントの上から3番目を説明します。 指定した通貨ペアの建玉情報の取得が出来ます。
エンドポイント
/v3/accounts/{accountID}/positions/{instrument}
サンプル
# conf (dict): key.jsonを読み取ったもの
# pair (stsr): "USD_JPY","EUR_USD"等
def position(conf, pair):
account_id = conf["id"]
url = LIVE_URL + f"/v3/accounts/{account_id}/positions/{pair}"
header = default_header(conf["key"])
res = requests.get(url, headers=header)
return res.json()
# 口座IDとapi-keyをファイルから取得
conf = load_key("./key.json")
# 建玉情報を取得
pos = position(conf,"USD_JPY")
実行結果
建玉はpos["position"]["long"]
、売玉はpos["position"]["short"]
です。unitsが保有量、unrealizedPLは建玉の未実現損益です。
plは、その通貨ペアの買、売の累計損益です。現在の建玉の利益ではありません。
{'lastTransactionID': '1212',
'position': {'commission': '0.0000',
'dividendAdjustment': '0.0000',
'financing': '7555.0732',
'guaranteedExecutionFees': '0.0000',
'instrument': 'USD_JPY',
'long': {'averagePrice': '132.740',
'dividendAdjustment': '0.0000',
'financing': '34394.0540',
'guaranteedExecutionFees': '0.0000',
'pl': '218422.0000',
'resettablePL': '218422.0000',
'tradeIDs': ['1212'],
'units': '10000',
'unrealizedPL': '-60.0000'},
'marginUsed': '53095.2000',
'pl': '28455.0000',
'resettablePL': '28455.0000',
'short': {'dividendAdjustment': '0.0000',
'financing': '-26838.9808',
'guaranteedExecutionFees': '0.0000',
'pl': '-189967.0000',
'resettablePL': '-189967.0000',
'units': '0',
'unrealizedPL': '0.0000'},
'unrealizedPL': '-60.0000'}}
口座情報の取得(Account)
ドキュメント
口座情報のドキュメント。上から2つ目と3つ目を説明します。
2つ目が口座のフル情報で、3つ目がサマリー版です。
エンドポイント
- /v3/accounts/{accountID}
- /v3/accounts/{accountID}/summary
サンプル
口座のフル情報(/v3/accounts/{accountID})
# conf (dict): key.jsonを読み取ったもの
def account(conf):
account_id = conf["id"]
url = LIVE_URL + f"/v3/accounts/{account_id}"
header = default_header(conf["key"])
res = requests.get(url, headers=header)
return res.json()
# 口座IDとapi-keyをファイルから取得
conf = load_key("./key.json")
# 口座情報を取得して表示
acc = account(conf)
サマリー版(/v3/accounts/{accountID}/summary)
# conf (dict): key.jsonを読み取ったもの
def account_summary(conf):
account_id = conf["id"]
url = LIVE_URL + f"/v3/accounts/{account_id}/summary"
header = default_header(conf["key"])
res = requests.get(url, headers=header)
return res.json()
# 口座IDとapi-keyをファイルから取得
conf = load_key("./key.json")
# 口座サマリー表示
acc = account_summary(conf)
実行結果(フル)
すごい情報量だ!それもそのはずで、取引したことのある通貨ペアごとに'positions'配列にデータが入っています。そこからさらに買、売ごとに分かれています。
acc["account"]
のbalanceが口座残高、unrealizedPLが全体の未実現損益です。利益計算をするのに使えそうですね。plは口座通算の損益になります。これも使えそうですが、手動での取引を行っているとその損益も含まる点に注意です。
marginUsedが使用している証拠金の額です。例えば、残高の一定割合を使用するように取引量を決めたい場合などに使えると思います。
{'account': {'NAV': '183866.5043',
'alias': 'Primary',
'balance': '181006.5043',
'commission': '0.0000',
'createdByUserID': 7411475,
'createdTime': '2022-01-17T03:33:03.210215550Z',
'currency': 'JPY',
'dividendAdjustment': '0',
'financing': '-4038.9615',
'guaranteedExecutionFees': '0.0000',
'guaranteedStopLossOrderMode': 'DISABLED',
'hedgingEnabled': False,
'id': '001-009-7411475-001',
'lastTransactionID': '1212',
'marginAvailable': '130654.5043',
'marginCloseoutMarginUsed': '53212.0000',
'marginCloseoutNAV': '183906.5043',
'marginCloseoutPercent': '0.28934',
'marginCloseoutPositionValue': '1330300.0000',
'marginCloseoutUnrealizedPL': '2900.0000',
'marginRate': '0.04',
'marginUsed': '53212.0000',
'openPositionCount': 1,
'openTradeCount': 1,
'orders': [],
'pendingOrderCount': 0,
'pl': '-115067.5342',
'positionValue': '1330300.0000',
'positions': [{'commission': '0.0000',
'dividendAdjustment': '0.0000',
'financing': '-11594.0347',
'guaranteedExecutionFees': '0.0000',
'instrument': 'EUR_USD',
'long': {'dividendAdjustment': '0.0000',
'financing': '-12128.4193',
'guaranteedExecutionFees': '0.0000',
'pl': '-78459.0153',
'resettablePL': '-78459.0153',
'units': '0',
'unrealizedPL': '0.0000'},
'pl': '-143522.5342',
'resettablePL': '-143522.5342',
'short': {'dividendAdjustment': '0.0000',
'financing': '534.3846',
'guaranteedExecutionFees': '0.0000',
'pl': '-65063.5189',
'resettablePL': '-65063.5189',
'units': '0',
'unrealizedPL': '0.0000'},
'unrealizedPL': '0.0000'},
{'commission': '0.0000',
'dividendAdjustment': '0.0000',
'financing': '7555.0732',
'guaranteedExecutionFees': '0.0000',
'instrument': 'USD_JPY',
'long': {'averagePrice': '132.740',
'dividendAdjustment': '0.0000',
'financing': '34394.0540',
'guaranteedExecutionFees': '0.0000',
'pl': '218422.0000',
'resettablePL': '218422.0000',
'tradeIDs': ['1212'],
'units': '10000',
'unrealizedPL': '2860.0000'},
'marginUsed': '53212.0000',
'pl': '28455.0000',
'resettablePL': '28455.0000',
'short': {'dividendAdjustment': '0.0000',
'financing': '-26838.9808',
'guaranteedExecutionFees': '0.0000',
'pl': '-189967.0000',
'resettablePL': '-189967.0000',
'units': '0',
'unrealizedPL': '0.0000'},
'unrealizedPL': '2860.0000'}],
'resettablePL': '-115067.5342',
'resettablePLTime': '0',
'trades': [{'currentUnits': '10000',
'dividendAdjustment': '0.0000',
'financing': '0.0000',
'id': '1212',
'initialMarginRequired': '53094.4000',
'initialUnits': '10000',
'instrument': 'USD_JPY',
'marginUsed': '53212.0000',
'openTime': '2022-12-23T01:40:01.387245503Z',
'price': '132.740',
'realizedPL': '0.0000',
'state': 'OPEN',
'unrealizedPL': '2860.0000'}],
'unrealizedPL': '2860.0000',
'withdrawalLimit': '130654.5043'},
'lastTransactionID': '1212'}
実行結果(サマリー)
フル版と比べると、通貨ペア別の利益・ポジション情報が無くスッキリしています。balanceやpl、unrealizedPL、marginUsed等はこちらでも取れるので、通貨ペア別の情報が不要ならサマリーのほうが扱いやすいと思います。
{'account': {'NAV': '181673.8370',
'alias': 'Primary',
'balance': '181103.8370',
'commission': '0.0000',
'createdByUserID': 7411475,
'createdTime': '2022-01-17T03:33:03.210215550Z',
'currency': 'JPY',
'dividendAdjustment': '0',
'financing': '-3941.6288',
'guaranteedExecutionFees': '0.0000',
'guaranteedStopLossOrderMode': 'DISABLED',
'hedgingEnabled': False,
'id': '001-009-7411475-001',
'lastTransactionID': '1213',
'marginAvailable': '128543.0370',
'marginCloseoutMarginUsed': '53130.8000',
'marginCloseoutNAV': '181973.8370',
'marginCloseoutPercent': '0.29197',
'marginCloseoutPositionValue': '1328270.0000',
'marginCloseoutUnrealizedPL': '870.0000',
'marginRate': '0.04',
'marginUsed': '53130.8000',
'openPositionCount': 1,
'openTradeCount': 1,
'pendingOrderCount': 0,
'pl': '-115067.5342',
'positionValue': '1328270.0000',
'resettablePL': '-115067.5342',
'resettablePLTime': '0',
'unrealizedPL': '570.0000',
'withdrawalLimit': '128543.0370'},
'lastTransactionID': '1213'}
最後に
今回は建玉情報と、口座情報取得のサンプルを紹介しました。前回の記事では現在価格、ロウソク足、成行注文の紹介をしていますので、合わせれば、簡単な自動取引BOTに最低限必要なパーツの説明は出来たと思います。
せっかくなので、簡易的なBOTの製作まで今後記事にしていこうと思います。
その前に、、、注文方法は成行注文しかサンプル提示していませんが、指値注文、ストップ注文、利確注文、トレーリングストップと様々な注文が可能です。BOT製作を記事にする前に、次回は成行以外の注文方法を紹介したいと思います。