Request builders, type validation, definitions, and utilities.
class MarketOrderRequest:
def __init__(
self,
instrument: str,
units: int, # Positive=buy, negative=sell
priceBound: float = None,
positionFill: str = "DEFAULT",
clientExtensions: dict = None,
takeProfitOnFill: dict = None,
timeInForce: str = "FOK",
stopLossOnFill: dict = None,
trailingStopLossOnFill: dict = None,
tradeClientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...
class LimitOrderRequest:
def __init__(
self,
instrument: str,
units: int,
price: float,
positionFill: str = "DEFAULT",
clientExtensions: dict = None,
takeProfitOnFill: dict = None,
timeInForce: str = "GTC",
gtdTime: str = None,
stopLossOnFill: dict = None,
trailingStopLossOnFill: dict = None,
tradeClientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...
class StopOrderRequest:
def __init__(
self,
instrument: str,
units: int,
price: float,
priceBound: float = None,
positionFill: str = "DEFAULT",
timeInForce: str = "GTC",
gtdTime: str = None,
clientExtensions: dict = None,
takeProfitOnFill: dict = None,
stopLossOnFill: dict = None,
trailingStopLossOnFill: dict = None,
tradeClientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...
class MITOrderRequest:
"""Market-If-Touched order."""
def __init__(
self,
instrument: str,
units: int,
price: float,
priceBound: float = None,
positionFill: str = "DEFAULT",
timeInForce: str = "GTC",
gtdTime: str = None,
clientExtensions: dict = None,
takeProfitOnFill: dict = None,
stopLossOnFill: dict = None,
trailingStopLossOnFill: dict = None,
tradeClientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...class TakeProfitDetails:
def __init__(
self,
price: float,
timeInForce: str = "GTC",
gtdTime: str = None,
clientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...
class StopLossDetails:
def __init__(
self,
price: float,
timeInForce: str = "GTC",
gtdTime: str = None,
clientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...
class TrailingStopLossDetails:
def __init__(
self,
distance: float, # Distance in price units
timeInForce: str = "GTC",
gtdTime: str = None,
clientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...class TradeCloseRequest:
def __init__(self, units: str = "ALL"): ... # "ALL" or number
@property
def data(self) -> dict: ...
class PositionCloseRequest:
def __init__(
self,
longUnits: str = None, # "ALL" or number
longClientExtensions: dict = None,
shortUnits: str = None,
shortClientExtensions: dict = None
): ...
@property
def data(self) -> dict: ...class ClientExtensions:
def __init__(
self,
clientID: str = None, # Max 128 chars
clientTag: str = None, # Max 128 chars
clientComment: str = None # Max 128 chars
): ...
@property
def data(self) -> dict: ...from oandapyV20.definitions.orders import (
OrderType, TimeInForce, OrderPositionFill, OrderState, OrderTriggerCondition
)
# Order types
OrderType.MARKET
OrderType.LIMIT
OrderType.STOP
OrderType.MARKET_IF_TOUCHED
OrderType.TAKE_PROFIT
OrderType.STOP_LOSS
OrderType.TRAILING_STOP_LOSS
# Time in force
TimeInForce.GTC # Good Till Cancelled
TimeInForce.GTD # Good Till Date
TimeInForce.GFD # Good For Day
TimeInForce.FOK # Fill Or Kill
TimeInForce.IOC # Immediate Or Cancel
# Position fill
OrderPositionFill.OPEN_ONLY
OrderPositionFill.REDUCE_FIRST
OrderPositionFill.REDUCE_ONLY
OrderPositionFill.DEFAULT
# Order states
OrderState.PENDING
OrderState.FILLED
OrderState.TRIGGERED
OrderState.CANCELLED
# Trigger conditions
OrderTriggerCondition.DEFAULT
OrderTriggerCondition.INVERSE
OrderTriggerCondition.BID
OrderTriggerCondition.ASK
OrderTriggerCondition.MIDfrom oandapyV20.definitions.instruments import CandlestickGranularity, PriceComponents
# Granularities: S5, S10, S15, S30, M1-M30, H1-H12, D, W, M
# (See market-data.md for full list)
# Price components
PriceComponents.M # Mid
PriceComponents.B # Bid
PriceComponents.A # Askfrom oandapyV20.definitions.trades import TradeState, TradePL
from oandapyV20.definitions.primitives import InstrumentType, Direction
# Trade states
TradeState.OPEN
TradeState.CLOSED
TradeState.CLOSE_WHEN_TRADABLE
# Trade P/L
TradePL.POSITIVE
TradePL.NEGATIVE
TradePL.ZERO
# Instrument types
InstrumentType.CURRENCY
InstrumentType.CFD
InstrumentType.METAL
# Direction
Direction.LONG
Direction.SHORTclass AccountID:
def __init__(self, accountID: str): ...
@property
def value(self) -> str: ...
class DateTime:
def __init__(self, dateTime): ... # datetime obj or RFC3339 string
@property
def value(self) -> str: ... # RFC3339 format
class Units:
def __init__(self, units): ... # int or float (max 2 decimals)
@property
def value(self) -> str: ...
class PriceValue:
def __init__(self, priceValue): ... # int or float
@property
def value(self) -> str: ... # Formatted to 5 decimals
class AccountUnits:
def __init__(self, units): ... # int or float
@property
def value(self) -> str: ... # Formatted to 5 decimals
class OrderID:
def __init__(self, orderID): ... # int or str
@property
def value(self) -> str: ...
class TradeID:
def __init__(self, tradeID): ... # int or str
@property
def value(self) -> str: ...
class ClientID:
def __init__(self, clientID: str): ... # Max 128 chars
@property
def value(self) -> str: ...
class ClientTag:
def __init__(self, clientTag: str): ... # Max 128 chars
@property
def value(self) -> str: ...
class ClientComment:
def __init__(self, clientComment: str): ... # Max 128 chars
@property
def value(self) -> str: ...from oandapyV20.types import AccountID, DateTime, Units, PriceValue
from datetime import datetime
# Validate account ID
account = AccountID("123-456-7890123-001")
print(account.value)
# Format datetime
dt = DateTime(datetime.utcnow())
print(dt.value) # RFC3339 format
# Format price
price = PriceValue(1.1)
print(price.value) # "1.10000"
# Format units
units = Units(1000)
print(units.value) # "1000"from oandapyV20.contrib.generic import secs2time, granularity_to_time
from oandapyV20.contrib.factories import InstrumentsCandlesFactory
# Convert epoch to datetime
dt = secs2time(1609459200)
# Convert granularity to seconds
seconds = granularity_to_time("H1") # 3600
seconds = granularity_to_time("M5") # 300
seconds = granularity_to_time("D") # 86400
# Large historical data (auto-pagination for >5000 candles)
params = {
"from": "2023-01-01T00:00:00Z",
"to": "2023-12-31T23:59:59Z",
"granularity": "H1"
}
all_candles = []
for endpoint in InstrumentsCandlesFactory("EUR_USD", params):
all_candles.extend(api.request(endpoint)['candles'])from oandapyV20.contrib.requests import (
LimitOrderRequest, TakeProfitDetails, StopLossDetails, ClientExtensions
)
from oandapyV20.definitions.orders import TimeInForce, OrderPositionFill
extensions = ClientExtensions(
clientID="trade-001",
clientTag="strategy-A",
clientComment="Entry signal"
).data
order = LimitOrderRequest(
instrument="EUR_USD",
units=10000,
price=1.1000,
timeInForce=TimeInForce.GTC,
positionFill=OrderPositionFill.DEFAULT,
clientExtensions=extensions,
takeProfitOnFill=TakeProfitDetails(price=1.1200).data,
stopLossOnFill=StopLossDetails(price=1.0900).data
).datafrom datetime import datetime, timedelta
expiry = datetime.utcnow() + timedelta(days=1)
gtd_time = expiry.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
order = LimitOrderRequest(
instrument="EUR_USD",
units=1000,
price=1.1000,
timeInForce="GTD",
gtdTime=gtd_time
).datafrom oandapyV20.types import AccountID, PriceValue, Units
def validate_order_inputs(account_id, price, units):
"""Validate and format order inputs."""
return {
'account_id': AccountID(account_id).value,
'price': PriceValue(price).value,
'units': Units(units).value
}
validated = validate_order_inputs("123-456-7890123-001", 1.1, 1000)