FX BOT 2: Python ✕ OANDA API V20 12の基本操作と関連情報まとめ

FX BOT 2: Python ✕ OANDA API V20 12の基本操作と関連情報まとめ

自分でFXのBOTを作成するにあたりOANDA API V20のテストを行いました。それに伴って集めた情報とテストの備忘録(OANDAのBOT作成に必要なすべての情報)をここにまとめます。主に自分用ですが、一部の人にとっては大変役に立つ情報だと思います。

Python ✕ OANDA API V20 12の基本操作と関連情報

  1. Pythonにしかできないこと
  2. 参考
  3. APIを使用する準備
    1. Google Colab
    2. OANDA デモ口座
    3. アクセストークンの発行とアカウントID
    4. OANDAへのAPI接続
  4. 価格ストリーミングの取得 (1)
  5. ヒストリカルデータの取得 (2)
  6. 取引に関するAPIの基本的な挙動
  7. オーダーの操作
    1. オーダーを作成する (3)
    2. 保留中のオーダー情報を取得する (4)
    3. オーダーの詳細を取得する (5)
    4. オーダーをキャンセルする (6)
  8. ポジションの操作
    1. ポジションを決済する (7)
    2. ポジションの詳細を取得する (8)
  9. トレードの操作
    1. トレードの詳細を取得する (9)
    2. トレードの決済 (10)
    3. トレードに関連する注文を行う (11)
  10. アカウントの操作
    1. アカウントの残高などを取得する (12)

1. Pythonにしかできないこと

  • 機械学習を活用する
  • ファンダメンタル等の外部データの参照
  • MQL4単体ではできないデータ分析(優位性を探しやすい)
  • 複数銘柄でリスク分散するロジック

このあたりがPythonのメリットだと考える。

厳密にはMQL4でもできることも含まれている。しかし、ほとんどのケースでPythonの方がやりやすい。一方でMQL4には、トレードに特化している(必要な機能がパッケージ化されている)というメリットもある。

何よりも自由であることが最大のメリット。

目次へ

2. 参考

今回のテストを行うにあたって参考にした情報。

目次へ

3. APIを使用する準備

ここ掲載しているテストには以下の準備が必要。

  1. Google Colabの用意
  2. OANDA デモ口座の用意
  3. アクセストークンの発行とアカウントIDの確認
  4. OANDAへのAPI接続

目次へ

3―1. Google Colab

まずは、Google Colaboratory にアクセス。ログインしている場合は以下の画面が表示される。

Google Colaboratory にアクセス

「PYTHON3の新しいノートブック」(画像の赤枠部分)をクリックすると、空白のノートブックを開くことができる。これだけでPythonのテストを行うことができる。サーバーを用意して環境を構築する必要がない。

目次へ

3―2. OANDA デモ口座

OANDA: 無料デモ口座開設フォームにアクセス。

OANDA: 無料デモ口座開設フォーム

申し込みから数分でデモ環境を利用することができるようになる。

目次へ

3―3. アクセストークンの発行とアカウントIDを確認

デモ口座では、仮想で300万円入金された本番と同じ環境が用意されている。

OANDAデモ口座
  1. 「APIアクセスの管理」からアクセストークンを発行
  2. アカウントIDの確認

実際の口座でも同様の方法で確認できる。

目次へ

3―4. OANDAへのAPI接続

まず、Googla Colabで以下を実行してoandapyV20をインストールする。

モジュールのインストール

!pip install oandapyV20
oandapyV20をインストール

次に、APIへの接続(準備)を行う。

APIに接続(準備)

from oandapyV20 import API
accountID = "ここにアカウントIDを入力"
access_token = "ここにアクセストークンを入力"
api = API(access_token=access_token ,environment="practice")

※ 本番口座に接続する場合は,environment="practice"は必要ない

目次へ

4. 価格ストリーミングの取得

OANDA API 価格ストリーミングの取得

価格ストリーミングの取得

import json
from oandapyV20.exceptions import V20Error
from oandapyV20.endpoints.pricing import PricingStream

instruments = "EUR_USD,EUR_JPY"
s = PricingStream(accountID=accountID, params={"instruments":instruments})
MAXREC = 10
try:
    n = 0
    for R in api.request(s):
        print(json.dumps(R, indent=2))
        n += 1
        if n > MAXREC:
            s.terminate("maxrecs received {}".format(MAXREC)) 
except V20Error as e:
    print("Error: {}".format(e))

目次へ

5. ヒストリカルデータの取得

ヒストリカルデータの取得

import json
import pandas as pd
import oandapyV20.endpoints.instruments as instruments
from oandapyV20.types import DateTime
from datetime import datetime ,timedelta
from dateutil.relativedelta import relativedelta

def get_equity_df( since ,until ,interval ,price ) :
    cnt = 'mid' if price=='M' else 'ask' if price=='A' else 'bid' if price=='B' else 'mid'
    params = { "from": DateTime( since ).value
              ,"to": DateTime( until ).value
              ,"price": price
              ,"granularity": interval }
    r = instruments.InstrumentsCandles( instrument="USD_JPY" ,params=params )
    api.request( r )    
    raw_list = []
    for raw in r.response['candles'] :
        raw_list.append( [ raw['time'] ,raw[cnt]['o'] ,raw[cnt]['h'] ,raw[cnt]['l'] ,raw[cnt]['c'] ,raw['volume'] ] )
    raw_df = pd.DataFrame( raw_list ,columns=[ 'Time' ,f'Open_{cnt}' ,f'High_{cnt}' ,f'Low_{cnt}' ,f'Close_{cnt}' ,'Volume' ] )
    return raw_df


start    = datetime.strptime( '2005-01-01' ,'%Y-%m-%d' )
end      = datetime.strptime( '2019-12-31' ,'%Y-%m-%d' )
month    = 12 * 2 #上限5000レコード
interval = 'H4'
restart  = 0

since = start + relativedelta( months=( restart ) )
until = start + relativedelta( months=( month + restart ) )
df = pd.DataFrame()

while True :
    if until > datetime.now() :
        until = datetime.now()
        if relativedelta( since ,until ).months==0 : break
    
    print( f'since:{ since } ,until:{ until }' )

    raw_a = get_equity_df( since ,until ,interval ,'A' )
    raw_b = get_equity_df( since ,until ,interval ,'B' )
    raw = pd.merge( raw_a ,raw_b )
    raw = raw.set_index( 'Time' )
    raw.index = pd.to_datetime( raw.index )

    df = pd.concat( [ df ,raw ] )

    since = until
    until = until + relativedelta( months=month )
    if since >= end : break

目次へ

6. 取引に関するAPIの基本的な挙動

APIの挙動の備忘録。

  • トランザクションのIDは全体で連番
  • IDにはorderIDとtradeIDがある
  • 同じ内容でも処理によって項目名が微妙に異なる
    • エントリーの日時を表す項目が
    • orders.OrderCreateの返り値ではtime
    • trades.tradeDetailの返り値ではopenTime
  • すべてのリクエストに対してlastTransactionIDが必ず返される
  • 近すぎるSTOPは発注できない(未確認)

※ トランザクションはざっくり言うと処理のこと(厳密には複数の処理を1つにまとめたもの)

目次へ

7. オーダーの操作

  • orders.OrderCreate( accountID ,data )オーダーを作成する
  • orders.OrdersPending( accountID ,orderID )保留中のオーダー情報を取得する
  • orders.OrderDetails( accountID ,orderID )オーダーの詳細を取得する
  • orders.OrderCancel( accountID ,orderID )オーダーをキャンセルする

7―1. オーダーを作成する

エントリーのオーダーを作成する。オーダーには成行注文(Market Order)と指値注文(Limit Order)、逆指値注文(Stop Order)がある。

dataの中でtradeIDを指定することで決済の注文を、stopLossOnFilltakeProfitOnFillを指定することでOCO注文を作成することもできる。

MARKET ORDER(成行注文でエントリー)

MARKET ORDER

import oandapyV20.endpoints.orders as orders
order_data = {
        "order": {
          "instrument": "USD_JPY",
            "units": "+100",
            "type": "MARKET",
          }
      }
o = orders.OrderCreate(accountID, data=order_data)
api.request( o )
o.response

「買いか売りか」は"units":"+100"で取引量と共に表現する。1000通貨の売りなら"-1000"と指定する。

作成した注文はorderCreateTransaction、実行された取引(trade)はorderFillTransactionとして返ってくる。この場合、成行注文のorderIDは139であり、tradeIDは140。

返り値

{'lastTransactionID': '140',
 'orderCreateTransaction': {'accountID': '<accountID>',
  'batchID': '139',
  'id': '139',
  'instrument': 'USD_JPY',
  'positionFill': 'DEFAULT',
  'reason': 'CLIENT_ORDER',
  'requestID': '60632676041088500',
  'time': '2019-10-14T12:03:00.543969658Z',
  'timeInForce': 'FOK',
  'type': 'MARKET_ORDER',
  'units': '100',
  'userID': <userID>},
 'orderFillTransaction': {'accountBalance': '3003167.2000',
  'accountID': '<accountID>',
  'batchID': '139',
  'commission': '0.0000',
  'financing': '0.0000',
  'fullPrice': {'asks': [{'liquidity': '250000', 'price': '108.246'}],
   'bids': [{'liquidity': '250000', 'price': '108.242'}],
   'closeoutAsk': '108.265',
   'closeoutBid': '108.223',
   'timestamp': '2019-10-14T12:02:58.891477244Z'},
  'fullVWAP': '108.246',
  'gainQuoteHomeConversionFactor': '1',
  'guaranteedExecutionFee': '0.0000',
  'halfSpreadCost': '0.2000',
  'id': '140',
  'instrument': 'USD_JPY',
  'lossQuoteHomeConversionFactor': '1',
  'orderID': '139',
  'pl': '0.0000',
  'price': '108.246',
  'reason': 'MARKET_ORDER',
  'requestID': '60632676041088500',
  'requestedUnits': '100',
  'time': '2019-10-14T12:03:00.543969658Z',
  'tradeOpened': {'guaranteedExecutionFee': '0.0000',
   'halfSpreadCost': '0.2000',
   'initialMarginRequired': '432.9760',
   'price': '108.246',
   'tradeID': '140',
   'units': '100'},
  'type': 'ORDER_FILL',
  'units': '100',
  'userID': <userID>},
 'relatedTransactionIDs': ['139', '140']}

STOP ORDER(逆指値注文でエントリー)

STOP ORDER

import oandapyV20.endpoints.orders as orders
order_data = {
        "order": {
           "price": "107.765"
          ,"instrument": "USD_JPY"
          ,"units": "+10000"
          ,"type": "STOP"
          }
      }
o = orders.OrderCreate(accountID, data=order_data)
api.request( o )
o.response

指値注文や逆指値注文ですぐに取引が完了しなかった場合はorderFillTransactionが返ってこない。エントリーされたことを確認するにはorderDetailで確認するしかない。

返り値

{'lastTransactionID': '18',
 'orderCreateTransaction': {'accountID': '<accountID>',
  'batchID': '18',
  'id': '18',
  'instrument': 'USD_JPY',
  'partialFill': 'DEFAULT',
  'positionFill': 'DEFAULT',
  'price': '107.000',
  'reason': 'CLIENT_ORDER',
  'requestID': '42615646265393854',
  'time': '2019-10-07T05:47:18.751402370Z',
  'timeInForce': 'GTC',
  'triggerCondition': 'DEFAULT',
  'type': 'STOP_ORDER',
  'units': '10000',
  'userID': <userID>},
 'relatedTransactionIDs': ['18']}

目次へ

7―2. 保留中のオーダー情報を取得する

未約定のオーダーをリスト(配列)で取得することができる。オーダーはエントリーとイグジットどちらも含まれる。

OrdersPending

import oandapyV20.endpoints.orders as orders
c = orders.OrdersPending( accountID )
api.request( c )
c.response

返り値

{'lastTransactionID': '16',
 'orders': [{'createTime': '2019-10-07T05:39:33.418717612Z',
   'id': '16',
   'instrument': 'USD_JPY',
   'partialFill': 'DEFAULT_FILL',
   'positionFill': 'DEFAULT',
   'price': '107.000',
   'state': 'PENDING',
   'timeInForce': 'GTC',
   'triggerCondition': 'DEFAULT',
   'type': 'STOP',
   'units': '10000'}]}

目次へ

7―3. オーダーの詳細を取得する

OrderDetails

import oandapyV20.endpoints.orders as orders
c = orders.OrderDetails( accountID ,orderID='133' )
api.request( c )
c.response

オーダーの詳細は、エントリーやイグジット、注文の状態と種類など多岐に渡る。返り値を何パターンか記録しておく。

返り値

# キャンセルしたエントリーの注文に対する戻り値

{'lastTransactionID': '19',
 'order': {'cancelledTime': '2019-10-07T05:47:41.114658220Z',
  'cancellingTransactionID': '19',
  'createTime': '2019-10-07T05:47:18.751402370Z',
  'id': '18',
  'instrument': 'USD_JPY',
  'partialFill': 'DEFAULT_FILL',
  'positionFill': 'DEFAULT',
  'price': '107.000',
  'state': 'CANCELLED',
  'timeInForce': 'GTC',
  'triggerCondition': 'DEFAULT',
  'type': 'STOP',
  'units': '10000'}}
  
# 執行済みのエントリー注文に対する戻り値

{'lastTransactionID': '134',
 'order': {'createTime': '2019-10-10T13:49:55.429422636Z',
  'filledTime': '2019-10-10T13:49:55.429422636Z',
  'fillingTransactionID': '134',
  'id': '133',
  'instrument': 'USD_JPY',
  'partialFill': 'DEFAULT_FILL',
  'positionFill': 'DEFAULT',
  'price': '107.765',
  'state': 'FILLED',
  'timeInForce': 'GTC',
  'tradeOpenedID': '134',
  'triggerCondition': 'DEFAULT',
  'type': 'STOP',
  'units': '10000'}}

# 決済の注文に対する戻り値

{'lastTransactionID': '23',
 'order': {'createTime': '2019-10-07T05:51:17.637841229Z',
  'guaranteed': False,
  'id': '23',
  'price': '106.870',
  'state': 'PENDING',
  'timeInForce': 'GTC',
  'tradeID': '21',
  'triggerCondition': 'DEFAULT',
  'type': 'STOP_LOSS'}}
  
# 執行済みの決済注文に対する戻り値

{'lastTransactionID': '28',
 'order': {'createTime': '2019-10-07T05:56:45.327517046Z',
  'filledTime': '2019-10-07T05:56:45.810216477Z',
  'fillingTransactionID': '27',
  'id': '24',
  'price': '106.890',
  'state': 'FILLED',
  'timeInForce': 'GTC',
  'tradeClosedIDs': ['21'],
  'tradeID': '21',
  'triggerCondition': 'DEFAULT',
  'type': 'TAKE_PROFIT'}}

目次へ

7―4. オーダーをキャンセルする

指定するIDがtradeIDだとエラーが返ってくる。

OrderCancel

import oandapyV20.endpoints.orders as orders
c = orders.OrderCancel( accountID ,orderID='18' )
api.request( c )
c.response

返り値

{'lastTransactionID': '19',
 'orderCancelTransaction': {'accountID': '<accountID>',
  'batchID': '19',
  'id': '19',
  'orderID': '18',
  'reason': 'CLIENT_REQUEST',
  'requestID': '42615646361899207',
  'time': '2019-10-07T05:47:41.114658220Z',
  'type': 'ORDER_CANCEL',
  'userID': <userID>},
 'relatedTransactionIDs': ['19']}

目次へ

8. ポジションの操作

  • positions.PositionClose( acccountID )ポジションを決済する
  • positions.PositionDetails( accountID )ポジションの詳細を取得する

6―1. ポジションを決済する

"longUnits":"1000"で取引量を指定して決済、"longUnits":"ALL"ですべてのポジションを決済する。ポジションが存在しない場合はエラーが返ってくる

PositionClose

import oandapyV20.endpoints.positions as positions
position_data = { "longUnits": "ALL" }
p = positions.PositionClose( accountID=accountID, data=position_data, instrument="USD_JPY" )
api.request( p )
p.response

返り値

{'lastTransactionID': '48',
 'longOrderCreateTransaction': {'accountID': '<accountID>',
  'batchID': '47',
  'id': '47',
  'instrument': 'USD_JPY',
  'longPositionCloseout': {'instrument': 'USD_JPY', 'units': 'ALL'},
  'positionFill': 'REDUCE_ONLY',
  'reason': 'POSITION_CLOSEOUT',
  'requestID': '60630740234934498',
  'time': '2019-10-09T03:50:48.377768343Z',
  'timeInForce': 'FOK',
  'type': 'MARKET_ORDER',
  'units': '-11000',
  'userID': <userID>},
 'longOrderFillTransaction': {'accountBalance': '3002262.4000',
  'accountID': '<accountID>',
  'batchID': '47',
  'commission': '0.0000',
  'financing': '0.0000',
  'fullPrice': {'asks': [{'liquidity': '250000', 'price': '107.162'}],
   'bids': [{'liquidity': '250000', 'price': '107.158'}],
   'closeoutAsk': '107.181',
   'closeoutBid': '107.139',
   'timestamp': '2019-10-09T03:48:05.569135841Z'},
  'fullVWAP': '107.158',
  'gainQuoteHomeConversionFactor': '1',
  'guaranteedExecutionFee': '0.0000',
  'halfSpreadCost': '22.0000',
  'id': '48',
  'instrument': 'USD_JPY',
  'lossQuoteHomeConversionFactor': '1',
  'orderID': '47',
  'pl': '1896.0000',
  'price': '107.158',
  'reason': 'MARKET_ORDER_POSITION_CLOSEOUT',
  'requestID': '60630740234934498',
  'requestedUnits': '-11000',
  'time': '2019-10-09T03:50:48.377768343Z',
  'tradesClosed': [{'financing': '0.0000',
    'guaranteedExecutionFee': '0.0000',
    'halfSpreadCost': '20.0000',
    'price': '107.158',
    'realizedPL': '1820.0000',
    'tradeID': '36',
    'units': '-10000'},
   {'financing': '0.0000',
    'guaranteedExecutionFee': '0.0000',
    'halfSpreadCost': '2.0000',
    'price': '107.158',
    'realizedPL': '76.0000',
    'tradeID': '40',
    'units': '-1000'}],
  'type': 'ORDER_FILL',
  'units': '-11000',
  'userID': <userID>},
 'relatedTransactionIDs': ['47', '48']}

目次へ

6―2. ポジションの詳細を取得する

PositionDetails

import oandapyV20.endpoints.positions as positions
p = positions.PositionDetails(accountID=accountID, instrument="USD_JPY")
api.request( p )
p.response

返り値

 {'lastTransactionID': '138',
 'trade': {'averageClosePrice': '106.890',
  'closeTime': '2019-10-07T05:56:45.810216477Z',
  'closingTransactionIDs': ['27'],
  'currentUnits': '0',
  'dividend': '0.0000',
  'financing': '0.0000',
  'id': '21',
  'initialMarginRequired': '42744.0000',
  'initialUnits': '10000',
  'instrument': 'USD_JPY',
  'openTime': '2019-10-07T05:48:02.507227911Z',
  'price': '106.862',
  'realizedPL': '280.0000',
  'state': 'CLOSED',
  'stopLossOrder': {'cancelledTime': '2019-10-07T05:56:45.810216477Z',
   'cancellingTransactionID': '28',
   'createTime': '2019-10-07T05:56:45.327517046Z',
   'guaranteed': False,
   'id': '26',
   'price': '106.870',
   'replacesOrderID': '23',
   'state': 'CANCELLED',
   'timeInForce': 'GTC',
   'tradeID': '21',
   'triggerCondition': 'DEFAULT',
   'type': 'STOP_LOSS'},
  'takeProfitOrder': {'createTime': '2019-10-07T05:56:45.327517046Z',
   'filledTime': '2019-10-07T05:56:45.810216477Z',
   'fillingTransactionID': '27',
   'id': '24',
   'price': '106.890',
   'state': 'FILLED',
   'timeInForce': 'GTC',
   'tradeClosedIDs': ['21'],
   'tradeID': '21',
   'triggerCondition': 'DEFAULT',
   'type': 'TAKE_PROFIT'}}}

目次へ

9. 取引系の操作

  • trades.TradeDetails( accountID ,tradeID )トレードの詳細を取得する
  • trades.TradeClose( accountID ,tradeID ,data )トレードの決済
  • trades.TradeCRCDO( accountID ,tradeID ,data )トレードに関連する注文を行う

PositionCloseは、tradeIDの垣根を超えた決済を行えるイメージ。勝手に調整してくれる。対してTradeCloseは、tradeIDに紐付いた決済。

9―1. トレードの詳細を取得する

TradeDetails

import oandapyV20.endpoints.trades as trades
r = trades.TradeDetails( accountID ,tradeID='21' )
api.request( r )
r.response

返り値

# 決済済みのトレードの詳細
    
{'lastTransactionID': '138',
 'trade': {'averageClosePrice': '106.890',
  'closeTime': '2019-10-07T05:56:45.810216477Z',
  'closingTransactionIDs': ['27'],
  'currentUnits': '0',
  'dividend': '0.0000',
  'financing': '0.0000',
  'id': '21',
  'initialMarginRequired': '42744.0000',
  'initialUnits': '10000',
  'instrument': 'USD_JPY',
  'openTime': '2019-10-07T05:48:02.507227911Z',
  'price': '106.862',
  'realizedPL': '280.0000',
  'state': 'CLOSED',
  'stopLossOrder': {'cancelledTime': '2019-10-07T05:56:45.810216477Z',
   'cancellingTransactionID': '28',
   'createTime': '2019-10-07T05:56:45.327517046Z',
   'guaranteed': False,
   'id': '26',
   'price': '106.870',
   'replacesOrderID': '23',
   'state': 'CANCELLED',
   'timeInForce': 'GTC',
   'tradeID': '21',
   'triggerCondition': 'DEFAULT',
   'type': 'STOP_LOSS'},
  'takeProfitOrder': {'createTime': '2019-10-07T05:56:45.327517046Z',
   'filledTime': '2019-10-07T05:56:45.810216477Z',
   'fillingTransactionID': '27',
   'id': '24',
   'price': '106.890',
   'state': 'FILLED',
   'timeInForce': 'GTC',
   'tradeClosedIDs': ['21'],
   'tradeID': '21',
   'triggerCondition': 'DEFAULT',
   'type': 'TAKE_PROFIT'}}}

目次へ

9―2. トレードの決済

成行注文で決済する。data={"units":"10"}などとして取引量を調整することも可能。

TradeClose

import oandapyV20.endpoints.trades as trades
r = trades.TradeClose( accountID ,tradeID='13' )
api.request( r )
r.response

返り値

{'lastTransactionID': '15',
 'orderCreateTransaction': {'accountID': '<accountID>',
  'batchID': '14',
  'id': '14',
  'instrument': 'USD_JPY',
  'positionFill': 'REDUCE_ONLY',
  'reason': 'TRADE_CLOSE',
  'requestID': '42615643621954763',
  'time': '2019-10-07T05:36:47.993201609Z',
  'timeInForce': 'FOK',
  'tradeClose': {'tradeID': '13', 'units': 'ALL'},
  'type': 'MARKET_ORDER',
  'units': '-10000',
  'userID': <userID>},
 'orderFillTransaction': {'accountBalance': '2999890.0000',
  'accountID': '<accountID>',
  'batchID': '14',
  'commission': '0.0000',
  'financing': '0.0000',
  'fullPrice': {'asks': [{'liquidity': '250000', 'price': '106.855'}],
   'bids': [{'liquidity': '250000', 'price': '106.851'}],
   'closeoutAsk': '106.874',
   'closeoutBid': '106.832',
   'timestamp': '2019-10-07T05:36:31.723734747Z'},
  'fullVWAP': '106.851',
  'gainQuoteHomeConversionFactor': '1',
  'guaranteedExecutionFee': '0.0000',
  'halfSpreadCost': '20.0000',
  'id': '15',
  'instrument': 'USD_JPY',
  'lossQuoteHomeConversionFactor': '1',
  'orderID': '14',
  'pl': '-110.0000',
  'price': '106.851',
  'reason': 'MARKET_ORDER_TRADE_CLOSE',
  'requestID': '42615643621954763',
  'requestedUnits': '-10000',
  'time': '2019-10-07T05:36:47.993201609Z',
  'tradesClosed': [{'financing': '0.0000',
    'guaranteedExecutionFee': '0.0000',
    'halfSpreadCost': '20.0000',
    'price': '106.851',
    'realizedPL': '-110.0000',
    'tradeID': '13',
    'units': '-10000'}],
  'type': 'ORDER_FILL',
  'units': '-10000',
  'userID': <userID>},
 'relatedTransactionIDs': ['14', '15']}

目次へ

9―3. トレードに関連する注文を行う

利確、損切り、トレーリングストップなどの注文を行うことができる。

TradeCRCDO

import oandapyV20.endpoints.trades as trades
r = trades.TradeCRCDO( accountID ,tradeID='21' ,data={
    'stopLoss': {
        'timeInForce': 'GTC'
        ,'price': '106.870'
    }
    ,'takeProfit': {
        'timeInForce': 'GTC'
        ,'price': '106.89'
    }
} )
api.request( r )
r.response

返り値

{'lastTransactionID': '26',
 'relatedTransactionIDs': ['24', '25', '26'],
 'stopLossOrderCancelTransaction': {'accountID': '<accountID>',
  'batchID': '24',
  'id': '25',
  'orderID': '23',
  'reason': 'CLIENT_REQUEST_REPLACED',
  'replacedByOrderID': '26',
  'requestID': '78644445666300450',
  'time': '2019-10-07T05:56:45.327517046Z',
  'type': 'ORDER_CANCEL',
  'userID': <userID>},
 'stopLossOrderTransaction': {'accountID': '<accountID>',
  'batchID': '24',
  'cancellingTransactionID': '25',
  'guaranteed': False,
  'id': '26',
  'price': '106.870',
  'reason': 'REPLACEMENT',
  'replacesOrderID': '23',
  'requestID': '78644445666300450',
  'time': '2019-10-07T05:56:45.327517046Z',
  'timeInForce': 'GTC',
  'tradeID': '21',
  'triggerCondition': 'DEFAULT',
  'type': 'STOP_LOSS_ORDER',
  'userID': <userID>},
 'takeProfitOrderTransaction': {'accountID': '<accountID>',
  'batchID': '24',
  'id': '24',
  'price': '106.890',
  'reason': 'CLIENT_ORDER',
  'requestID': '78644445666300450',
  'time': '2019-10-07T05:56:45.327517046Z',
  'timeInForce': 'GTC',
  'tradeID': '21',
  'triggerCondition': 'DEFAULT',
  'type': 'TAKE_PROFIT_ORDER',
  'userID': <userID>}}

目次へ

10. 取引系の操作

  • accounts.AccountSummary( accountID )アカウントの残高などを取得する

10―1. アカウントの残高などを取得する

AccountSummary

import oandapyV20.endpoints.accounts as accounts
r = accounts.AccountSummary( accountID )
api.request( r )
r.response

返り値

{'account': {'NAV': '3000130.0000',
  'alias': 'Primary',
  'balance': '3000170.0000',
  'commission': '0.0000',
  'createdByUserID': <userID>,
  'createdTime': '2019-09-18T14:15:24.150417961Z',
  'currency': 'JPY',
  'dividend': '0',
  'financing': '0.0000',
  'guaranteedExecutionFees': '0.0000',
  'guaranteedStopLossOrderMode': 'DISABLED',
  'hedgingEnabled': False,
  'id': '<accountID>',
  'lastTransactionID': '30',
  'marginAvailable': '2957341.2000',
  'marginCloseoutMarginUsed': '42788.8000',
  'marginCloseoutNAV': '3000150.0000',
  'marginCloseoutPercent': '0.01426',
  'marginCloseoutPositionValue': '1069720.0000',
  'marginCloseoutUnrealizedPL': '-20.0000',
  'marginRate': '0.04',
  'marginUsed': '42788.8000',
  'openPositionCount': 1,
  'openTradeCount': 1,
  'pendingOrderCount': 0,
  'pl': '170.0000',
  'positionValue': '1069720.0000',
  'resettablePL': '170.0000',
  'resettablePLTime': '0',
  'unrealizedPL': '-40.0000',
  'withdrawalLimit': '2957341.2000'},
 'lastTransactionID': '30'}

目次へ

Back to Top

abbamboo

タカハシ / 7年目の兼業トレーダー

このブログの目的は、「学習の備忘録」と「アウトプットして理解を深めること」。「トレードで稼ぐために学んだこと」を徹底的に公開していきます。

元・日本料理の板前、現・金融畑のウェブ屋さん
保有資格:証券外務員1種、認定テクニカルアナリスト

更新のお知らせは、各SNSやLINEで。LINEだと1対1でお話することもできます!

>> このブログと著者についての詳細
>> 使っているツールの紹介

Investment Tech Hack

Sorry... doesn't support your browser

To get the best possible experience using our site we recommend that you upgrade to a modern web browser. Investment Tech Hackではご利用中のブラウザサポートはしていません。
Internet Explorerのアップグレード行う、もしくはその他のブラウザを使用しての閲覧をお願いします。