@farazirfan/costar-server-executor 1.7.26 → 1.7.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +6 -3
- package/dist/server.js.map +1 -1
- package/dist/services/saxo-auth.d.ts +71 -0
- package/dist/services/saxo-auth.d.ts.map +1 -0
- package/dist/services/saxo-auth.js +201 -0
- package/dist/services/saxo-auth.js.map +1 -0
- package/dist/skills/sync.d.ts +13 -11
- package/dist/skills/sync.d.ts.map +1 -1
- package/dist/skills/sync.js +130 -27
- package/dist/skills/sync.js.map +1 -1
- package/package.json +1 -1
- package/public/index.html +1 -0
- package/skills/saxo/LEARNING.md +42 -0
- package/skills/saxo/SKILL.md +282 -0
- package/skills/saxo/references/api-reference.md +332 -0
- package/skills/saxo/references/asset-classes.md +249 -0
- package/skills/saxo/references/auth.md +210 -0
- package/skills/saxo/references/order-types.md +260 -0
- package/skills/saxo/scripts/saxo-auth.py +395 -0
- package/skills/saxo/scripts/saxo-trade.py +314 -0
- package/skills/trading/SKILL.md +7 -3
- package/skills/trading/references/crypto.md +13 -62
- package/skills/trading/references/forex.md +13 -63
- package/skills/trading/references/metals.md +13 -42
- package/skills/trading/references/risk-management.md +23 -51
- package/skills/trading/references/stocks.md +13 -62
- package/skills/trading/references/strategies.md +20 -85
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Saxo API Reference
|
|
2
|
+
|
|
3
|
+
> Agent-editable. Add notes about endpoints, quirks, rate limits as you discover them.
|
|
4
|
+
|
|
5
|
+
Complete reference for Saxo OpenAPI endpoints using `saxo_openapi` Python package.
|
|
6
|
+
|
|
7
|
+
## Client Setup
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
import saxo_openapi
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
client = saxo_openapi.API(
|
|
14
|
+
access_token=os.environ['SAXO_ACCESS_TOKEN'],
|
|
15
|
+
environment='simulation' # or 'live'
|
|
16
|
+
)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Root Services (Account Info)
|
|
20
|
+
|
|
21
|
+
### User Details
|
|
22
|
+
|
|
23
|
+
Get authenticated user information:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
import saxo_openapi.endpoints.rootservices as rs
|
|
27
|
+
|
|
28
|
+
r = rs.user.UserDetails()
|
|
29
|
+
client.request(r)
|
|
30
|
+
|
|
31
|
+
# Returns:
|
|
32
|
+
# - ClientKey
|
|
33
|
+
# - Name
|
|
34
|
+
# - Accounts (list with AccountKey, AccountType, Currency)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Client Details
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
r = rs.client.ClientDetails(ClientKey=client_key)
|
|
41
|
+
client.request(r)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Portfolio Endpoints
|
|
45
|
+
|
|
46
|
+
### Account Balances
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import saxo_openapi.endpoints.portfolio as pf
|
|
50
|
+
|
|
51
|
+
r = pf.balances.AccountBalances(params={'ClientKey': client_key})
|
|
52
|
+
client.request(r)
|
|
53
|
+
|
|
54
|
+
# Returns:
|
|
55
|
+
# - TotalValue
|
|
56
|
+
# - CashBalance
|
|
57
|
+
# - MarginAvailableForTrading
|
|
58
|
+
# - MarginUtilizationPct
|
|
59
|
+
# - UnrealizedPositionsValue
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Positions
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
# All positions
|
|
66
|
+
r = pf.positions.PositionsMe()
|
|
67
|
+
client.request(r)
|
|
68
|
+
|
|
69
|
+
# Specific position
|
|
70
|
+
r = pf.positions.PositionDetails(PositionId=position_id)
|
|
71
|
+
client.request(r)
|
|
72
|
+
|
|
73
|
+
# Returns:
|
|
74
|
+
# - PositionId
|
|
75
|
+
# - Uic, AssetType
|
|
76
|
+
# - Amount (positive = long, negative = short)
|
|
77
|
+
# - OpenPrice, CurrentPrice
|
|
78
|
+
# - ProfitLossOnTrade
|
|
79
|
+
# - MarginUsedIncludingPendingOrders
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Exposure
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
# Net exposure across all positions
|
|
86
|
+
r = pf.netpositions.NetPositionsMe()
|
|
87
|
+
client.request(r)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Trading Endpoints
|
|
91
|
+
|
|
92
|
+
### Place Order
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
import saxo_openapi.endpoints.trading as tr
|
|
96
|
+
|
|
97
|
+
order_data = {
|
|
98
|
+
'AccountKey': account_key,
|
|
99
|
+
'Uic': 21,
|
|
100
|
+
'AssetType': 'FxSpot',
|
|
101
|
+
'BuySell': 'Buy',
|
|
102
|
+
'Amount': 10000,
|
|
103
|
+
'OrderType': 'Market',
|
|
104
|
+
'OrderDuration': {'DurationType': 'DayOrder'}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
r = tr.orders.Order(data=order_data)
|
|
108
|
+
client.request(r)
|
|
109
|
+
|
|
110
|
+
# Success: status_code 201
|
|
111
|
+
# Response contains OrderId
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Order Status
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
# All orders
|
|
118
|
+
r = tr.orders.OrdersMe()
|
|
119
|
+
client.request(r)
|
|
120
|
+
|
|
121
|
+
# Specific order
|
|
122
|
+
r = tr.orders.OrderDetails(OrderId=order_id)
|
|
123
|
+
client.request(r)
|
|
124
|
+
|
|
125
|
+
# Returns:
|
|
126
|
+
# - OrderId
|
|
127
|
+
# - Status: Working, Filled, Cancelled, Rejected
|
|
128
|
+
# - FilledAmount
|
|
129
|
+
# - ExecutionTimeOpen
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Cancel Order
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
r = tr.orders.CancelOrder(AccountKey=account_key, OrderId=order_id)
|
|
136
|
+
client.request(r)
|
|
137
|
+
|
|
138
|
+
# Success: status_code 200 or 202
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Modify Order
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
# Update order price or duration
|
|
145
|
+
r = tr.orders.ModifyOrder(
|
|
146
|
+
AccountKey=account_key,
|
|
147
|
+
OrderId=order_id,
|
|
148
|
+
data={'OrderPrice': 1.0860}
|
|
149
|
+
)
|
|
150
|
+
client.request(r)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Info Prices (Real-Time Quotes)
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
r = tr.prices.InfoPrice(Uic=21, AssetType='FxSpot')
|
|
157
|
+
client.request(r)
|
|
158
|
+
|
|
159
|
+
# Returns:
|
|
160
|
+
# - Quote: {Bid, Ask, Mid}
|
|
161
|
+
# - PriceInfo: {High, Low, NetChange}
|
|
162
|
+
# - InstrumentPriceDetails: {IsMarketOpen, ValueDate}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Reference Data
|
|
166
|
+
|
|
167
|
+
### Search Instruments
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
import saxo_openapi.endpoints.referencedata as rd
|
|
171
|
+
|
|
172
|
+
params = {
|
|
173
|
+
'Keywords': 'EURUSD',
|
|
174
|
+
'AssetTypes': 'FxSpot',
|
|
175
|
+
'limit': 20
|
|
176
|
+
}
|
|
177
|
+
r = rd.instruments.Instruments(params=params)
|
|
178
|
+
client.request(r)
|
|
179
|
+
|
|
180
|
+
# Returns array with:
|
|
181
|
+
# - Identifier (Uic)
|
|
182
|
+
# - Symbol
|
|
183
|
+
# - Description
|
|
184
|
+
# - AssetType
|
|
185
|
+
# - ExchangeId
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Instrument Details
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
r = rd.instruments.InstrumentDetails(Uic=21, AssetType='FxSpot')
|
|
192
|
+
client.request(r)
|
|
193
|
+
|
|
194
|
+
# Returns:
|
|
195
|
+
# - MinimumTradeSize
|
|
196
|
+
# - TickSize
|
|
197
|
+
# - ContractSize
|
|
198
|
+
# - TradingStatus
|
|
199
|
+
# - Format (price decimals)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Exchanges
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
r = rd.exchanges.ExchangeList()
|
|
206
|
+
client.request(r)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Chart Data
|
|
210
|
+
|
|
211
|
+
### Historical Candles
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
import saxo_openapi.endpoints.chart as ch
|
|
215
|
+
|
|
216
|
+
params = {
|
|
217
|
+
'Uic': 21,
|
|
218
|
+
'AssetType': 'FxSpot',
|
|
219
|
+
'Horizon': 60, # 1-hour candles
|
|
220
|
+
'Count': 100 # Last 100 candles
|
|
221
|
+
}
|
|
222
|
+
r = ch.charts.Charts(params=params)
|
|
223
|
+
client.request(r)
|
|
224
|
+
|
|
225
|
+
# Returns array of candles with:
|
|
226
|
+
# - Time (Unix timestamp)
|
|
227
|
+
# - Open, High, Low, Close
|
|
228
|
+
# - Volume (if available)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Horizon Values:**
|
|
232
|
+
- `1` — 1 minute
|
|
233
|
+
- `5` — 5 minutes
|
|
234
|
+
- `15` — 15 minutes
|
|
235
|
+
- `60` — 1 hour
|
|
236
|
+
- `1440` — 1 day
|
|
237
|
+
- `10080` — 1 week
|
|
238
|
+
|
|
239
|
+
## Request/Response Format
|
|
240
|
+
|
|
241
|
+
All API calls follow the same pattern:
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
# 1. Create request object
|
|
245
|
+
r = module.endpoint.Method(params={...})
|
|
246
|
+
|
|
247
|
+
# 2. Execute request
|
|
248
|
+
client.request(r)
|
|
249
|
+
|
|
250
|
+
# 3. Check status
|
|
251
|
+
if r.status_code == 200: # or 201 for orders
|
|
252
|
+
data = r.response
|
|
253
|
+
else:
|
|
254
|
+
error = r.response # Error details
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Error Handling
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
try:
|
|
261
|
+
client.request(r)
|
|
262
|
+
except saxo_openapi.exceptions.OpenAPIError as e:
|
|
263
|
+
print(f"API Error: {e}")
|
|
264
|
+
print(f"Status: {e.status_code}")
|
|
265
|
+
print(f"Message: {e.message}")
|
|
266
|
+
except Exception as e:
|
|
267
|
+
print(f"Unexpected error: {e}")
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Common Errors
|
|
271
|
+
|
|
272
|
+
| Error Code | Message | Cause | Solution |
|
|
273
|
+
|-----------|---------|-------|----------|
|
|
274
|
+
| 401 | Unauthorized | Invalid/expired token | Refresh token |
|
|
275
|
+
| 400 | Bad Request | Invalid parameters | Check order data |
|
|
276
|
+
| 403 | Forbidden | Insufficient permissions | Check account permissions |
|
|
277
|
+
| 429 | Too Many Requests | Rate limit exceeded | Slow down requests |
|
|
278
|
+
| 500 | Internal Server Error | Saxo server issue | Retry with backoff |
|
|
279
|
+
|
|
280
|
+
## Rate Limits
|
|
281
|
+
|
|
282
|
+
Saxo enforces rate limits per endpoint category:
|
|
283
|
+
|
|
284
|
+
| Category | Limit | Window |
|
|
285
|
+
|----------|-------|--------|
|
|
286
|
+
| **Trading** (orders) | 100 req | 1 minute |
|
|
287
|
+
| **Portfolio** | 300 req | 1 minute |
|
|
288
|
+
| **Prices** | 100 req | 1 minute |
|
|
289
|
+
| **Chart** | 50 req | 1 minute |
|
|
290
|
+
|
|
291
|
+
**Best Practices:**
|
|
292
|
+
- Cache instrument searches (Uic lookup)
|
|
293
|
+
- Batch position/order queries when possible
|
|
294
|
+
- Use WebSocket for real-time prices (not polling)
|
|
295
|
+
- Implement exponential backoff on 429 errors
|
|
296
|
+
|
|
297
|
+
## WebSocket Streaming (Advanced)
|
|
298
|
+
|
|
299
|
+
For real-time price feeds, use WebSocket streaming:
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
# TODO: Agent should research and implement WebSocket streaming
|
|
303
|
+
# when polling becomes a bottleneck or rate limits are hit.
|
|
304
|
+
# See saxo_openapi documentation for streaming setup.
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Response Caching
|
|
308
|
+
|
|
309
|
+
Cache responses that don't change frequently:
|
|
310
|
+
|
|
311
|
+
```python
|
|
312
|
+
# Cache instrument details (rarely change)
|
|
313
|
+
instrument_cache = {}
|
|
314
|
+
|
|
315
|
+
def get_instrument_details(uic, asset_type):
|
|
316
|
+
key = f"{uic}:{asset_type}"
|
|
317
|
+
if key not in instrument_cache:
|
|
318
|
+
r = rd.instruments.InstrumentDetails(Uic=uic, AssetType=asset_type)
|
|
319
|
+
client.request(r)
|
|
320
|
+
instrument_cache[key] = r.response
|
|
321
|
+
return instrument_cache[key]
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Agent Evolution Notes
|
|
325
|
+
|
|
326
|
+
*(Add discoveries here as you use the API)*
|
|
327
|
+
|
|
328
|
+
- Which endpoints are most rate-limited?
|
|
329
|
+
- Best practices for batching requests?
|
|
330
|
+
- WebSocket setup and benefits
|
|
331
|
+
- Caching strategies that work
|
|
332
|
+
- Error patterns and how to handle them
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Saxo Asset Classes
|
|
2
|
+
|
|
3
|
+
> Agent-editable. Add notes about instruments you trade, quirks, best practices.
|
|
4
|
+
|
|
5
|
+
Saxo covers 71,000+ instruments across all major asset classes except crypto.
|
|
6
|
+
|
|
7
|
+
## Asset Type Codes
|
|
8
|
+
|
|
9
|
+
Saxo uses string codes for asset types. Always specify the correct `AssetType` in orders and queries.
|
|
10
|
+
|
|
11
|
+
| Asset Type Code | Description | Examples |
|
|
12
|
+
|----------------|-------------|----------|
|
|
13
|
+
| `FxSpot` | Spot Forex | EURUSD, GBPJPY, XAUUSD, XAGUSD |
|
|
14
|
+
| `FxForwards` | Forex Forwards | Long-dated forex contracts |
|
|
15
|
+
| `Stock` | Individual Stocks | AAPL, TSLA, VOO |
|
|
16
|
+
| `StockIndex` | Stock Indexes | S&P 500, DAX |
|
|
17
|
+
| `CfdOnStock` | Stock CFDs | Leveraged stock trading |
|
|
18
|
+
| `CfdOnIndex` | Index CFDs | Leveraged index trading |
|
|
19
|
+
| `CfdOnFutures` | Futures CFDs | Oil, gold futures |
|
|
20
|
+
| `Bond` | Bonds | US Treasuries, corporate bonds |
|
|
21
|
+
| `StockOption` | Equity Options | Call/put options on stocks |
|
|
22
|
+
| `FxOption` | FX Options | Currency options |
|
|
23
|
+
| `ContractFutures` | Futures Contracts | Commodities, indexes |
|
|
24
|
+
|
|
25
|
+
## Forex (FxSpot)
|
|
26
|
+
|
|
27
|
+
**Trading Hours:** 24/5 (Sunday 5pm ET — Friday 5pm ET)
|
|
28
|
+
|
|
29
|
+
### Major Pairs (Highest Liquidity)
|
|
30
|
+
|
|
31
|
+
| Pair | Uic | Description | Typical Spread | Sessions |
|
|
32
|
+
|------|-----|-------------|---------------|----------|
|
|
33
|
+
| EURUSD | 21 | Euro vs US Dollar | 0.1-0.5 pips | All |
|
|
34
|
+
| GBPUSD | 22 | British Pound vs USD | 0.5-1.5 pips | London, NY |
|
|
35
|
+
| USDJPY | 23 | US Dollar vs Japanese Yen | 0.2-0.8 pips | Tokyo, NY |
|
|
36
|
+
| USDCHF | 24 | USD vs Swiss Franc | 0.5-1.5 pips | All |
|
|
37
|
+
|
|
38
|
+
### Commodities (via FxSpot)
|
|
39
|
+
|
|
40
|
+
| Pair | Uic | Description | Contract Size | Notes |
|
|
41
|
+
|------|-----|-------------|--------------|-------|
|
|
42
|
+
| XAUUSD | 1639 | Gold vs USD | 1 troy ounce | Most liquid |
|
|
43
|
+
| XAGUSD | 1640 | Silver vs USD | 1 troy ounce | Higher volatility |
|
|
44
|
+
| XPTUSD | — | Platinum vs USD | 1 troy ounce | Lower liquidity |
|
|
45
|
+
| XPDUSD | — | Palladium vs USD | 1 troy ounce | Lower liquidity |
|
|
46
|
+
|
|
47
|
+
**Key Points:**
|
|
48
|
+
- Amount is in base currency units (EURUSD 10000 = 10k EUR)
|
|
49
|
+
- Price quoted to 4-5 decimal places (pipettes)
|
|
50
|
+
- Leverage typically 50:1 to 500:1 (check account settings)
|
|
51
|
+
- Spreads widen during low liquidity (Asian session, holidays, news)
|
|
52
|
+
- Best execution during session overlaps (London/NY)
|
|
53
|
+
|
|
54
|
+
**Search Example:**
|
|
55
|
+
```python
|
|
56
|
+
params = {'Keywords': 'EURUSD', 'AssetTypes': 'FxSpot'}
|
|
57
|
+
r = rd.instruments.Instruments(params=params)
|
|
58
|
+
client.request(r)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Stocks
|
|
62
|
+
|
|
63
|
+
**Trading Hours:** Exchange-specific (NYSE: 9:30am-4pm ET, etc.)
|
|
64
|
+
|
|
65
|
+
### Search by Exchange
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
# Search US stocks
|
|
69
|
+
params = {'Keywords': 'AAPL', 'AssetTypes': 'Stock', 'ExchangeId': 'NASDAQ'}
|
|
70
|
+
r = rd.instruments.Instruments(params=params)
|
|
71
|
+
client.request(r)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Key Points:**
|
|
75
|
+
- Amount is number of shares (integer for most, can be fractional for some)
|
|
76
|
+
- Price in exchange currency (USD for US stocks, EUR for EU, etc.)
|
|
77
|
+
- Leverage typically 4:1 to 10:1 (much lower than forex)
|
|
78
|
+
- Commissions per trade (not just spread)
|
|
79
|
+
- Check market hours — many exchanges have breaks or early closes
|
|
80
|
+
- Extended hours available for some exchanges (pre-market, after-hours)
|
|
81
|
+
|
|
82
|
+
**Common Exchanges:**
|
|
83
|
+
- `NASDAQ` — US tech stocks (AAPL, MSFT, TSLA)
|
|
84
|
+
- `NYSE` — US stocks (traditional companies)
|
|
85
|
+
- `XETRA` — German stocks (DAX components)
|
|
86
|
+
- `LSE` — London Stock Exchange
|
|
87
|
+
|
|
88
|
+
## CFDs (Contracts for Difference)
|
|
89
|
+
|
|
90
|
+
CFDs allow leveraged trading without owning the underlying asset.
|
|
91
|
+
|
|
92
|
+
### Stock CFDs
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
params = {'Keywords': 'AAPL', 'AssetTypes': 'CfdOnStock'}
|
|
96
|
+
r = rd.instruments.Instruments(params=params)
|
|
97
|
+
client.request(r)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Key Points:**
|
|
101
|
+
- Higher leverage than stocks (up to 20:1)
|
|
102
|
+
- No ownership — purely price speculation
|
|
103
|
+
- Overnight financing costs (rollover fees)
|
|
104
|
+
- Lower capital requirements
|
|
105
|
+
- Some jurisdictions restrict CFD trading
|
|
106
|
+
|
|
107
|
+
### Index CFDs
|
|
108
|
+
|
|
109
|
+
Trade stock indexes with leverage:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
params = {'Keywords': 'S&P 500', 'AssetTypes': 'CfdOnIndex'}
|
|
113
|
+
r = rd.instruments.Instruments(params=params)
|
|
114
|
+
client.request(r)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Popular Indexes:**
|
|
118
|
+
- SPX500 (S&P 500)
|
|
119
|
+
- NAS100 (Nasdaq 100)
|
|
120
|
+
- US30 (Dow Jones)
|
|
121
|
+
- GER40 (DAX)
|
|
122
|
+
|
|
123
|
+
## Bonds
|
|
124
|
+
|
|
125
|
+
Fixed-income securities. Lower volatility than stocks or forex.
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
params = {'Keywords': 'US Treasury', 'AssetTypes': 'Bond'}
|
|
129
|
+
r = rd.instruments.Instruments(params=params)
|
|
130
|
+
client.request(r)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Key Points:**
|
|
134
|
+
- Price quoted as percentage of par value
|
|
135
|
+
- Yields move inverse to prices
|
|
136
|
+
- Lower leverage (typically 2:1 to 5:1)
|
|
137
|
+
- Less volatile — good for capital preservation
|
|
138
|
+
- Interest rate sensitivity (duration)
|
|
139
|
+
|
|
140
|
+
## Options
|
|
141
|
+
|
|
142
|
+
Complex derivatives. High risk, high reward.
|
|
143
|
+
|
|
144
|
+
### Stock Options
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
params = {'Keywords': 'AAPL', 'AssetTypes': 'StockOption'}
|
|
148
|
+
r = rd.instruments.Instruments(params=params)
|
|
149
|
+
client.request(r)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Key Points:**
|
|
153
|
+
- Call = right to buy, Put = right to sell
|
|
154
|
+
- Strike price and expiration date critical
|
|
155
|
+
- Theta decay — options lose value over time
|
|
156
|
+
- Implied volatility affects pricing
|
|
157
|
+
- Can lose 100% of premium
|
|
158
|
+
- Require options trading approval
|
|
159
|
+
|
|
160
|
+
### FX Options
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
params = {'Keywords': 'EURUSD', 'AssetTypes': 'FxOption'}
|
|
164
|
+
r = rd.instruments.Instruments(params=params)
|
|
165
|
+
client.request(r)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Futures
|
|
169
|
+
|
|
170
|
+
Contracts for future delivery of assets.
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
params = {'Keywords': 'Crude Oil', 'AssetTypes': 'ContractFutures'}
|
|
174
|
+
r = rd.instruments.Instruments(params=params)
|
|
175
|
+
client.request(r)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Key Points:**
|
|
179
|
+
- Expiration dates — must close or roll before expiry
|
|
180
|
+
- High leverage (10:1 to 50:1)
|
|
181
|
+
- Margin calls if position moves against you
|
|
182
|
+
- Contango/backwardation in commodity futures
|
|
183
|
+
- Each contract has specific size (e.g., 1000 barrels of oil)
|
|
184
|
+
|
|
185
|
+
## Instrument Discovery
|
|
186
|
+
|
|
187
|
+
Always search before trading to get correct Uic:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
import saxo_openapi.endpoints.referencedata as rd
|
|
191
|
+
|
|
192
|
+
# General search
|
|
193
|
+
params = {
|
|
194
|
+
'Keywords': 'gold',
|
|
195
|
+
'AssetTypes': 'FxSpot,CfdOnFutures',
|
|
196
|
+
'limit': 20
|
|
197
|
+
}
|
|
198
|
+
r = rd.instruments.Instruments(params=params)
|
|
199
|
+
client.request(r)
|
|
200
|
+
|
|
201
|
+
# Get instrument details
|
|
202
|
+
for inst in r.response['Data']:
|
|
203
|
+
print(f"{inst['Symbol']}: Uic={inst['Identifier']}, Type={inst['AssetType']}")
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Product Details
|
|
207
|
+
|
|
208
|
+
Before trading any instrument, check its details:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
import saxo_openapi.endpoints.referencedata as rd
|
|
212
|
+
|
|
213
|
+
r = rd.instruments.InstrumentDetails(Uic=21, AssetType='FxSpot')
|
|
214
|
+
client.request(r)
|
|
215
|
+
|
|
216
|
+
# Returns:
|
|
217
|
+
# - MinimumTradeSize
|
|
218
|
+
# - TickSize (price increment)
|
|
219
|
+
# - ContractSize
|
|
220
|
+
# - TradingStatus
|
|
221
|
+
# - TradingHours
|
|
222
|
+
# - MarginRequirement
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Session Times (Critical for Forex/Commodities)
|
|
226
|
+
|
|
227
|
+
| Session | Hours (ET) | Best For |
|
|
228
|
+
|---------|-----------|----------|
|
|
229
|
+
| **Tokyo** | 7pm - 4am | JPY pairs |
|
|
230
|
+
| **London** | 3am - 12pm | EUR, GBP pairs |
|
|
231
|
+
| **New York** | 8am - 5pm | USD pairs |
|
|
232
|
+
| **Overlap (London/NY)** | 8am - 12pm | Highest liquidity |
|
|
233
|
+
|
|
234
|
+
**Avoid:**
|
|
235
|
+
- Sunday open (5pm ET) — low liquidity, wide spreads
|
|
236
|
+
- Friday close (5pm ET) — position squaring, unpredictable
|
|
237
|
+
- Major holidays — Christmas, New Year, etc.
|
|
238
|
+
- Low-liquidity hours — 5pm-7pm ET (Sydney only)
|
|
239
|
+
|
|
240
|
+
## Agent Evolution Notes
|
|
241
|
+
|
|
242
|
+
*(Add discoveries here as you trade different instruments)*
|
|
243
|
+
|
|
244
|
+
- Best instruments for each strategy
|
|
245
|
+
- Liquidity patterns: which sessions, which instruments?
|
|
246
|
+
- Spread behavior: when do spreads widen?
|
|
247
|
+
- Margin surprises: instruments with unexpectedly high requirements?
|
|
248
|
+
- Correlation discoveries: which instruments move together?
|
|
249
|
+
- Session-specific edges: patterns that only work in certain sessions?
|