Client¶
The main entry point for the SDK. EToroTrading wraps REST
endpoints, WebSocket streaming, and instrument resolution behind a single
async interface.
EToroTrading¶
- class etoropy.EToroTrading(config=None, **kwargs)[source]¶
Bases:
objectHigh-level async client for the eToro Public API.
Wraps REST endpoints, WebSocket streaming, and instrument resolution behind a single entry point. Supports both
"demo"and"real"trading modes (set viaEToroConfig.mode).Use as an async context manager for automatic cleanup:
async with EToroTrading() as etoro: etoro.resolver.load_bundled_csv() await etoro.connect() rates = await etoro.get_rates(["AAPL"]) ... # WebSocket closed, HTTP client released
Events (register with
etoro.on(event, handler)):"price" -> (symbol, instrument_id, WsInstrumentRate) "order:update" -> (WsPrivateEvent) "connected" -> () "disconnected" -> () "error" -> (Exception) "ws:message" -> (WsEnvelope)
- Parameters:
config (
EToroConfig|None(default:None)) – SDK configuration. When None, settings are read fromETORO_-prefixed environment variables.kwargs (
Any) – Forwarded toEToroConfigwhen config is None.
- once(event, handler)[source]¶
Register handler for event, then auto-unregister after the first call.
- Parameters:
- Return type:
- remove_all_listeners(event=None)[source]¶
Remove all listeners, or only those for event if given.
- Parameters:
- Return type:
- async connect()[source]¶
Open the WebSocket connection and authenticate.
Must be called before
stream_prices()orwait_for_order(). Emits the"connected"event on success.- Return type:
- async disconnect()[source]¶
Close the WebSocket and release the HTTP client.
Emits the
"disconnected"event. Called automatically when exiting theasync withblock.- Return type:
- async buy_by_amount(symbol_or_id, amount, options=None)[source]¶
Open a long (buy) market order for a dollar amount.
- Parameters:
symbol_or_id (
str|int) – Instrument symbol ("AAPL") or numeric ID.amount (
float) – Dollar amount to invest.options (
OrderOptions|None(default:None)) – Optional leverage, stop-loss, and take-profit settings.
- Return type:
- Returns:
The order response including the assigned order ID.
- async buy_by_units(symbol_or_id, units, options=None)[source]¶
Open a long (buy) market order for a number of units.
- Parameters:
units (
float) – Number of units to buy.options (
OrderOptions|None(default:None)) – Optional leverage, stop-loss, and take-profit settings.
- Return type:
- Returns:
The order response including the assigned order ID.
- async sell_by_amount(symbol_or_id, amount, options=None)[source]¶
Open a short (sell) market order for a dollar amount.
- Parameters:
amount (
float) – Dollar amount to invest.options (
OrderOptions|None(default:None)) – Optional leverage, stop-loss, and take-profit settings.
- Return type:
- Returns:
The order response including the assigned order ID.
- async sell_by_units(symbol_or_id, units, options=None)[source]¶
Open a short (sell) market order for a number of units.
- Parameters:
units (
float) – Number of units to sell.options (
OrderOptions|None(default:None)) – Optional leverage, stop-loss, and take-profit settings.
- Return type:
- Returns:
The order response including the assigned order ID.
- async close_position(position_id, units_to_deduct=None)[source]¶
Close an open position.
- Parameters:
- Raises:
EToroValidationError – If position_id is not found in the portfolio.
- Return type:
- async close_all_positions()[source]¶
Close all open positions in the portfolio (runs in parallel).
- Return type:
- async place_limit_order(symbol_or_id, is_buy, trigger_rate, amount, options=None)[source]¶
Place a limit order that triggers at trigger_rate.
- Parameters:
is_buy (
bool) –Truefor buy,Falsefor sell.trigger_rate (
float) – Price at which the order triggers.amount (
float) – Dollar amount to invest.options (
OrderOptions|None(default:None)) – Optional leverage, stop-loss, and take-profit settings.
- Return type:
- async cancel_order(order_id)[source]¶
Cancel a pending market order.
- Parameters:
order_id (
int)- Return type:
- async cancel_limit_order(order_id)[source]¶
Cancel a pending limit order.
- Parameters:
order_id (
int)- Return type:
- async cancel_all_orders()[source]¶
Cancel all pending market orders (runs in parallel).
- Return type:
- async cancel_all_limit_orders()[source]¶
Cancel all pending limit orders (runs in parallel).
- Return type:
- async get_portfolio()[source]¶
Fetch the full portfolio (positions, mirrors, pending orders).
- Return type:
- async get_pending_orders()[source]¶
Fetch all pending orders (limit orders and orders-for-open).
- Return type:
- async get_rates(symbols_or_ids)[source]¶
Fetch live bid/ask rates for the given instruments.
- Parameters:
- Return type:
- async get_candles(symbol_or_id, interval, count, direction=CandleDirection.DESC)[source]¶
Fetch historical candlestick data.
- Parameters:
interval (
CandleInterval) – Candle interval (e.g.CandleInterval.ONE_DAY).count (
int) – Number of candles to fetch (max 1000).direction (
CandleDirection(default:<CandleDirection.DESC: 'desc'>)) – Sort direction (ASCorDESC).
- Return type:
- async stream_prices(symbols_or_ids, snapshot=True)[source]¶
Subscribe to real-time price updates for the given instruments.
Price ticks are emitted as
"price"events with(symbol, instrument_id, WsInstrumentRate)arguments. Requires a prior call toconnect().
- async stop_streaming_prices(symbols_or_ids)[source]¶
Unsubscribe from price updates for the given instruments.
- subscribe_to_private_events()[source]¶
Subscribe to private account events (order fills, cancellations, etc.).
- Return type:
- async wait_for_order(order_id, timeout_s=30.0)[source]¶
Block until an order reaches a terminal state.
Uses a hybrid approach: listens for WebSocket private events and, after a 3-second grace period, starts polling the REST
GET /orders/{id}endpoint as a fallback.- Parameters:
- Return type:
- Returns:
The
WsPrivateEventdescribing the terminal state.- Raises:
EToroError – If the order fails, is cancelled, or times out.
- async preload_instruments(symbols)[source]¶
Pre-resolve a list of symbols so later lookups are instant.
- async get_display_name(symbol_or_id)[source]¶
Return the human-readable display name for an instrument.
- async get_instrument_info(symbol_or_id)[source]¶
Fetch full metadata for an instrument.
- Parameters:
- Return type:
OrderOptions¶
- class etoropy.OrderOptions(leverage=1, stop_loss=None, take_profit=None, trailing_stop_loss=None)[source]¶
Bases:
objectOptional parameters for market and limit orders.
- Parameters:
leverage (
int(default:1)) – Leverage multiplier (1 = no leverage).stop_loss (
float|None(default:None)) – Stop-loss rate (absolute price level).take_profit (
float|None(default:None)) – Take-profit rate (absolute price level).trailing_stop_loss (
bool|None(default:None)) – Enable trailing stop-loss.
InstrumentResolver¶
- class etoropy.InstrumentResolver(market_data)[source]¶
Bases:
objectTranslate human-readable symbols to eToro integer instrument IDs.
Resolution goes through three tiers, in order:
In-memory cache – populated from the bundled CSV (
load_bundled_csv()) or viaregister(). Instant, no network call.API exact match – queries
/market-data/searchwith theinternalSymbolFullfilter.API text search – free-text fallback on the same endpoint.
Every successful lookup is cached for the lifetime of the resolver, so repeated calls for the same symbol are free.
Example:
resolver = InstrumentResolver(market_data_client) resolver.load_bundled_csv() instrument_id = await resolver.resolve("AAPL") info = await resolver.get_instrument_info("AAPL")
- Parameters:
market_data (
MarketDataClient) – TheMarketDataClientused for API lookups.
- load_bundled_csv()[source]¶
Load the bundled
instruments.csv(5,200+ symbols).- Return type:
- Returns:
Number of symbols loaded.
- async resolve(symbol_or_id)[source]¶
Resolve a symbol or ID to an instrument ID.
If symbol_or_id is already an
int, it is returned as-is. Otherwise, the three-tier lookup (cache, exact match, text search) is applied.- Parameters:
symbol_or_id (
str|int) – Ticker symbol ("AAPL") or numeric ID.- Return type:
- Returns:
The eToro instrument ID.
- Raises:
EToroValidationError – If the symbol cannot be resolved.
- async get_instrument_info(symbol_or_id)[source]¶
Fetch display metadata for a single instrument.
- Parameters:
- Raises:
EToroValidationError – If metadata cannot be found.
- Return type:
- async get_instrument_info_batch(instrument_ids)[source]¶
Fetch display metadata for multiple instruments.
Only uncached IDs trigger an API call.
- Parameters:
- Return type:
- async get_display_name(symbol_or_id)[source]¶
Return the human-readable display name for an instrument.
- get_cached_display_name(instrument_id)[source]¶
Return the cached display name, or
Noneif not yet fetched.
- get_cached_info(instrument_id)[source]¶
Return cached
InstrumentInfo, orNone.- Parameters:
instrument_id (
int)- Return type:
InstrumentInfo¶
- class etoropy.InstrumentInfo(instrument_id, display_name, symbol_full, instrument_type_id, exchange_id, instrument_type_sub_category_id=None, price_source='', has_expiration_date=False, is_internal_instrument=False, image_url=None)[source]¶
Bases:
objectMetadata for a resolved instrument.
- Parameters:
instrument_id (
int) – eToro numeric instrument ID.display_name (
str) – Human-readable name (e.g."Apple Inc").symbol_full (
str) – Ticker symbol (e.g."AAPL").instrument_type_id (
int) – Instrument type category.exchange_id (
int) – Exchange identifier.instrument_type_sub_category_id (
int|None(default:None)) – Sub-category, if any.price_source (
str(default:'')) – Price feed source.has_expiration_date (
bool(default:False)) – Whether the instrument expires.is_internal_instrument (
bool(default:False)) – Whether it is an internal instrument.image_url (
str|None(default:None)) – URL to the instrument logo, if available.