Small Python library and CLI for manually managing eToro agent-portfolios:
- create an agent-portfolio
- list agent-portfolios
- inspect parent and mirrored portfolio state
- resolve instruments
- open/close positions
- rebalance from percentage allocations
Secrets are read from environment variables:
export ETORO_USER_KEY="..."
export ETORO_AGENT_USER_KEY="..."ETORO_USER_KEY is your main account key. ETORO_AGENT_USER_KEY is the agent-portfolio key used for trading.
The default eToro public API key is built in because the workflow requires it, but you can override it with:
export ETORO_API_KEY="..."Install from this repo in editable mode:
python3 -m pip install -e .Verify the command is available:
etoro-agent --helpIf the build backend is missing, install it first:
python3 -m pip install hatchling
python3 -m pip install -e .You can also run the CLI without installing:
PYTHONPATH=src python3 -m etoro_agent_portfolio.cli --helpCreate an agent-portfolio from your main account key:
etoro-agent create --user-key "$ETORO_USER_KEY" --name Alpha1 --investment 500The command prints the generated agent-portfolio key once. Store that key securely, then use it as ETORO_AGENT_USER_KEY for trading commands:
export ETORO_AGENT_USER_KEY="the-key-printed-by-create"You can also choose the generated key label yourself:
etoro-agent create --user-key "$ETORO_USER_KEY" --name Alpha1 --investment 500 --token-name alpha1-key-123456List agent-portfolios on the main account:
etoro-agent list --user-key "$ETORO_USER_KEY"Show the agent-portfolio allocation:
etoro-agent allocation --user-key "$ETORO_AGENT_USER_KEY"Preview a rebalance:
etoro-agent rebalance --user-key "$ETORO_AGENT_USER_KEY" --target QQQ=45 --target SPY=30 --target GLD=15 --cash 10By default, rebalance only opens the underweight delta versus the current portfolio. To force full allocation opens, pass --open-full.
Execute the rebalance:
etoro-agent rebalance --user-key "$ETORO_AGENT_USER_KEY" --target QQQ=45 --target SPY=30 --target GLD=15 --cash 10 --executeThe CLI reports allocations as percentages. Raw dollar amounts remain available in Python objects for calculations.
Set these first:
export ETORO_API_KEY="${ETORO_API_KEY:API_KEY}"
export ETORO_USER_KEY="main-account-key"
export ETORO_AGENT_USER_KEY="agent-portfolio-key"List agent-portfolios:
curl -sS -X GET "https://public-api.etoro.com/api/v1/agent-portfolios" \
-H "x-request-id: $(uuidgen)" \
-H "x-api-key: $ETORO_API_KEY" \
-H "x-user-key: $ETORO_USER_KEY"Create an agent-portfolio:
curl -sS -X POST "https://public-api.etoro.com/api/v1/agent-portfolios" \
-H "x-request-id: $(uuidgen)" \
-H "x-api-key: $ETORO_API_KEY" \
-H "x-user-key: $ETORO_USER_KEY" \
-H "content-type: application/json" \
--data '{
"investmentAmountInUsd": 500,
"agentPortfolioName": "Alpha1",
"userTokenName": "alpha1-key-123456",
"scopeIds": [202]
}'The creation response contains userTokens[0].userToken. Store it securely and use it as ETORO_AGENT_USER_KEY.
Check an agent-portfolio:
curl -sS -X GET "https://public-api.etoro.com/api/v1/trading/info/real/pnl" \
-H "x-request-id: $(uuidgen)" \
-H "x-api-key: $ETORO_API_KEY" \
-H "x-user-key: $ETORO_AGENT_USER_KEY"Resolve an instrument ID:
curl -sS -X GET "https://public-api.etoro.com/api/v1/market-data/search?internalSymbolFull=QQQ" \
-H "x-request-id: $(uuidgen)" \
-H "x-api-key: $ETORO_API_KEY" \
-H "x-user-key: $ETORO_AGENT_USER_KEY"Use the exact items[] match where internalSymbolFull equals your symbol. The resolved ID is instrumentId, or internalInstrumentId when instrumentId is absent.
Open a position by amount:
curl -sS -X POST "https://public-api.etoro.com/api/v1/trading/execution/market-open-orders/by-amount" \
-H "x-request-id: $(uuidgen)" \
-H "x-api-key: $ETORO_API_KEY" \
-H "x-user-key: $ETORO_AGENT_USER_KEY" \
-H "content-type: application/json" \
--data '{
"InstrumentID": 3006,
"IsBuy": true,
"Leverage": 1,
"Amount": 1000,
"TakeProfitRate": 735.05
}'Close a position:
curl -sS -X POST "https://public-api.etoro.com/api/v1/trading/execution/market-close-orders/positions/1234567890" \
-H "x-request-id: $(uuidgen)" \
-H "x-api-key: $ETORO_API_KEY" \
-H "x-user-key: $ETORO_AGENT_USER_KEY" \
-H "content-type: application/json" \
--data '{
"InstrumentId": 100000,
"UnitsToDeduct": null
}'For multiple trade requests, wait at least 3 seconds between calls.