Spaces:
Running
Running
| /** | |
| * Test script to verify Alpaca orders retrieval | |
| * Run with: node scripts/test-alpaca-orders.js | |
| */ | |
| const Alpaca = require('@alpacahq/alpaca-trade-api'); | |
| require('dotenv').config(); | |
| async function testAlpacaOrders() { | |
| console.log('π Testing Alpaca Orders Retrieval\n'); | |
| console.log('='.repeat(60)); | |
| // Check credentials | |
| const key = process.env.ALPACA_KEY; | |
| const secret = process.env.ALPACA_SECRET; | |
| if (!key || !secret) { | |
| console.error('β ERROR: ALPACA_KEY or ALPACA_SECRET not found in environment'); | |
| process.exit(1); | |
| } | |
| console.log('β Credentials found'); | |
| console.log(' Key:', key.substring(0, 8) + '...'); | |
| console.log(''); | |
| try { | |
| // Initialize Alpaca client | |
| const alpaca = new Alpaca({ | |
| keyId: key, | |
| secretKey: secret, | |
| paper: true, | |
| }); | |
| console.log('π‘ Connecting to Alpaca API...\n'); | |
| // Get account info | |
| const account = await alpaca.getAccount(); | |
| console.log('β Account Connected'); | |
| console.log(' Equity: $' + parseFloat(account.equity).toFixed(2)); | |
| console.log(' Cash: $' + parseFloat(account.cash).toFixed(2)); | |
| console.log(''); | |
| // Get positions | |
| const positions = await alpaca.getPositions(); | |
| console.log('π Positions (' + positions.length + '):'); | |
| positions.forEach(p => { | |
| console.log(' - ' + p.symbol + ': ' + p.qty + ' shares'); | |
| }); | |
| console.log(''); | |
| // Get ALL orders (including filled, cancelled, etc.) | |
| console.log('π Fetching ALL orders (all statuses)...\n'); | |
| const allOrders = await alpaca.getOrders({ | |
| status: 'all', | |
| limit: 500, | |
| nested: true | |
| }); | |
| console.log('Total orders retrieved: ' + allOrders.length); | |
| console.log('='.repeat(60)); | |
| console.log(''); | |
| if (allOrders.length === 0) { | |
| console.log('β οΈ No orders found in Alpaca'); | |
| return; | |
| } | |
| // Group by status | |
| const byStatus = {}; | |
| allOrders.forEach(order => { | |
| const status = order.status; | |
| if (!byStatus[status]) byStatus[status] = []; | |
| byStatus[status].push(order); | |
| }); | |
| console.log('π Orders by Status:'); | |
| Object.keys(byStatus).forEach(status => { | |
| console.log(' ' + status.toUpperCase() + ': ' + byStatus[status].length); | |
| }); | |
| console.log(''); | |
| // Show OPEN orders in detail | |
| const openStatuses = ['new', 'pending_new', 'accepted', 'partially_filled']; | |
| const openOrders = allOrders.filter(o => openStatuses.includes(o.status)); | |
| console.log('='.repeat(60)); | |
| console.log('π’ OPEN ORDERS (' + openOrders.length + '):'); | |
| console.log('='.repeat(60)); | |
| if (openOrders.length === 0) { | |
| console.log('β οΈ No open orders found'); | |
| console.log(' (Filtering by statuses: ' + openStatuses.join(', ') + ')'); | |
| } else { | |
| openOrders.forEach((order, idx) => { | |
| console.log(''); | |
| console.log(`Order ${idx + 1}:`); | |
| console.log(' ID: ' + order.id); | |
| console.log(' Symbol: ' + order.symbol); | |
| console.log(' Side: ' + order.side.toUpperCase()); | |
| console.log(' Type: ' + order.type.toUpperCase()); | |
| console.log(' Status: ' + order.status.toUpperCase()); | |
| console.log(' Qty: ' + order.qty); | |
| if (order.limit_price) { | |
| console.log(' Limit Price: $' + parseFloat(order.limit_price).toFixed(2)); | |
| } | |
| if (order.stop_price) { | |
| console.log(' Stop Price: $' + parseFloat(order.stop_price).toFixed(2)); | |
| } | |
| if (order.order_class) { | |
| console.log(' Order Class: ' + order.order_class.toUpperCase()); | |
| } | |
| if (order.filled_qty && parseFloat(order.filled_qty) > 0) { | |
| console.log(' Filled Qty: ' + order.filled_qty); | |
| } | |
| if (order.filled_avg_price && parseFloat(order.filled_avg_price) > 0) { | |
| console.log(' Fill Price: $' + parseFloat(order.filled_avg_price).toFixed(2)); | |
| } | |
| // Show bracket legs | |
| if (order.legs && order.legs.length > 0) { | |
| console.log(' OCO Legs:'); | |
| order.legs.forEach((leg, legIdx) => { | |
| console.log(' Leg ' + (legIdx + 1) + ':'); | |
| console.log(' Type: ' + leg.type); | |
| if (leg.limit_price) { | |
| console.log(' TP: $' + parseFloat(leg.limit_price).toFixed(2)); | |
| } | |
| if (leg.stop_price) { | |
| console.log(' SL: $' + parseFloat(leg.stop_price).toFixed(2)); | |
| } | |
| }); | |
| } | |
| console.log(' Submitted: ' + new Date(order.submitted_at).toLocaleString()); | |
| }); | |
| } | |
| console.log(''); | |
| console.log('='.repeat(60)); | |
| console.log('π RECENT ORDERS (last 10, all statuses):'); | |
| console.log('='.repeat(60)); | |
| allOrders.slice(0, 10).forEach((order, idx) => { | |
| console.log(`${idx + 1}. [${order.status.toUpperCase()}] ${order.symbol} - ${order.side.toUpperCase()} ${order.qty} @ ${order.type} - ${new Date(order.submitted_at).toLocaleString()}`); | |
| }); | |
| console.log(''); | |
| console.log('='.repeat(60)); | |
| console.log('β Test Completed Successfully'); | |
| console.log('='.repeat(60)); | |
| } catch (error) { | |
| console.error(''); | |
| console.error('β ERROR:'); | |
| console.error(' Message:', error.message); | |
| console.error(' Stack:', error.stack); | |
| process.exit(1); | |
| } | |
| } | |
| // Run the test | |
| testAlpacaOrders().catch(err => { | |
| console.error('Unhandled error:', err); | |
| process.exit(1); | |
| }); | |