|
| 1 | +# Alpaca Close Position Endpoint Analysis |
| 2 | + |
| 3 | +## Current Implementation Review |
| 4 | + |
| 5 | +### 1. Current SELL Order Flow |
| 6 | + |
| 7 | +The Trading Goose currently handles position closing through the following mechanism: |
| 8 | + |
| 9 | +1. **Position Management Detection** (`_shared/positionManagement.ts`): |
| 10 | + - When a SELL order's dollar amount exceeds the position value OR is within 5% of it |
| 11 | + - The system converts the order from dollar-based to share-based |
| 12 | + - Sets `shares` to the total shares in the position |
| 13 | + - Clears the `dollarAmount` field |
| 14 | + |
| 15 | +2. **Order Submission** (`execute-trade/index.ts`): |
| 16 | + - Submits a market SELL order to Alpaca using POST /v2/orders |
| 17 | + - Uses either `notional` (dollar amount) or `qty` (shares) parameter |
| 18 | + - For full position closures, uses `qty` with all shares |
| 19 | + |
| 20 | +### 2. Alpaca's Close Position Endpoint |
| 21 | + |
| 22 | +Alpaca provides a dedicated endpoint for closing positions: |
| 23 | +- **Endpoint**: `DELETE /v2/positions/{symbol_or_asset_id}` |
| 24 | +- **Purpose**: Immediately liquidates the entire position |
| 25 | +- **Benefits**: |
| 26 | + - Guaranteed to close the entire position |
| 27 | + - No need to track exact share count |
| 28 | + - Handles fractional shares automatically |
| 29 | + - Single API call with clear intent |
| 30 | + |
| 31 | +## Pros and Cons Analysis |
| 32 | + |
| 33 | +### Using DELETE /positions Endpoint |
| 34 | + |
| 35 | +**Pros:** |
| 36 | +1. **Simplicity**: Single API call that guarantees full position closure |
| 37 | +2. **Accuracy**: No risk of leaving fractional shares behind |
| 38 | +3. **Clarity**: Explicit intent to close position vs. partial sell |
| 39 | +4. **Error Reduction**: No need to calculate or track exact share counts |
| 40 | +5. **Consistency**: Works identically for whole and fractional share positions |
| 41 | +6. **API Efficiency**: Purpose-built for this exact use case |
| 42 | + |
| 43 | +**Cons:** |
| 44 | +1. **Limited Flexibility**: Can only close entire position (no partial capability) |
| 45 | +2. **Different Response Format**: Returns position data instead of order data |
| 46 | +3. **Tracking Complexity**: Need different handling for order tracking/status |
| 47 | +4. **No Order ID**: Doesn't create a traditional order, making tracking harder |
| 48 | +5. **Database Schema Impact**: Current system expects alpaca_order metadata |
| 49 | + |
| 50 | +### Current Approach (SELL all shares) |
| 51 | + |
| 52 | +**Pros:** |
| 53 | +1. **Unified Handling**: Same flow for partial and full sells |
| 54 | +2. **Order Tracking**: Creates standard order with ID for tracking |
| 55 | +3. **Status Polling**: Can monitor order status consistently |
| 56 | +4. **Database Compatibility**: Fits existing schema without changes |
| 57 | + |
| 58 | +**Cons:** |
| 59 | +1. **Fractional Share Risk**: Might leave tiny fractional amounts |
| 60 | +2. **Race Conditions**: Share count might change between read and submit |
| 61 | +3. **Complexity**: Requires accurate share count tracking |
| 62 | +4. **Two-Step Process**: Must fetch position first, then submit order |
| 63 | + |
| 64 | +## Recommendations |
| 65 | + |
| 66 | +### Recommended Approach: Hybrid Solution |
| 67 | + |
| 68 | +Implement a hybrid approach that uses the close position endpoint when appropriate: |
| 69 | + |
| 70 | +```typescript |
| 71 | +// Pseudocode for hybrid approach |
| 72 | +if (shouldCloseFullPosition && userPreference.useCloseEndpoint) { |
| 73 | + // Use DELETE /positions for clean full closure |
| 74 | + await closePositionViaDelete(ticker); |
| 75 | + // Create synthetic order record for tracking |
| 76 | +} else { |
| 77 | + // Use existing SELL order flow |
| 78 | + await submitSellOrder(shares || dollarAmount); |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +### Implementation Strategy |
| 83 | + |
| 84 | +#### Phase 1: Add Close Position Capability (Low Risk) |
| 85 | +1. Create new function `closePositionViaAlpaca()` in `_shared/alpacaClient.ts` |
| 86 | +2. Add configuration option `use_close_endpoint_for_full_sells` in user settings |
| 87 | +3. Modify `execute-trade/index.ts` to check this preference |
| 88 | + |
| 89 | +#### Phase 2: Handle Tracking (Medium Complexity) |
| 90 | +1. Create synthetic order record when using close endpoint |
| 91 | +2. Store close position response in metadata |
| 92 | +3. Mark as immediately "filled" since close is synchronous |
| 93 | + |
| 94 | +#### Phase 3: Improve Position Detection (Enhancement) |
| 95 | +1. Enhance `shouldCloseFullPosition()` logic |
| 96 | +2. Add explicit "CLOSE_POSITION" action type alongside BUY/SELL/HOLD |
| 97 | +3. Allow users to explicitly request position closure |
| 98 | + |
| 99 | +### Migration Plan |
| 100 | + |
| 101 | +```sql |
| 102 | +-- Add user preference for close endpoint usage |
| 103 | +ALTER TABLE api_settings |
| 104 | +ADD COLUMN use_alpaca_close_endpoint BOOLEAN DEFAULT false; |
| 105 | + |
| 106 | +-- Add tracking for close position operations |
| 107 | +ALTER TABLE trading_actions |
| 108 | +ADD COLUMN close_position_used BOOLEAN DEFAULT false; |
| 109 | +``` |
| 110 | + |
| 111 | +### Code Changes Required |
| 112 | + |
| 113 | +1. **New File**: `supabase/functions/_shared/alpacaClosePosition.ts` |
| 114 | + - Implement close position API call |
| 115 | + - Handle response and error cases |
| 116 | + - Create synthetic order tracking |
| 117 | + |
| 118 | +2. **Modify**: `supabase/functions/execute-trade/index.ts` |
| 119 | + - Check if order should use close endpoint |
| 120 | + - Route to appropriate execution path |
| 121 | + - Handle different response formats |
| 122 | + |
| 123 | +3. **Update**: `supabase/functions/_shared/positionManagement.ts` |
| 124 | + - Add `useCloseEndpoint` flag to validation response |
| 125 | + - Enhance detection logic |
| 126 | + |
| 127 | +## Risk Assessment |
| 128 | + |
| 129 | +### Low Risk Items |
| 130 | +- Adding new close position function (additive, non-breaking) |
| 131 | +- User preference setting (opt-in feature) |
| 132 | +- Synthetic order creation (backward compatible) |
| 133 | + |
| 134 | +### Medium Risk Items |
| 135 | +- Routing logic in execute-trade (needs careful testing) |
| 136 | +- Order status tracking differences (requires adaptation) |
| 137 | +- Error handling for new endpoint |
| 138 | + |
| 139 | +### High Risk Items |
| 140 | +- None identified - existing flow remains as fallback |
| 141 | + |
| 142 | +## Conclusion |
| 143 | + |
| 144 | +**Recommendation: Implement the hybrid approach in phases** |
| 145 | + |
| 146 | +The close position endpoint offers clear benefits for full position closures, particularly: |
| 147 | +- Eliminating fractional share remnants |
| 148 | +- Reducing race conditions |
| 149 | +- Simplifying the close process |
| 150 | + |
| 151 | +However, maintaining the existing flow as default ensures: |
| 152 | +- No breaking changes |
| 153 | +- Consistent order tracking |
| 154 | +- Gradual adoption via opt-in |
| 155 | + |
| 156 | +The phased implementation allows for: |
| 157 | +1. Safe introduction of new capability |
| 158 | +2. User testing and feedback |
| 159 | +3. Rollback capability if issues arise |
| 160 | +4. Gradual migration of users |
| 161 | + |
| 162 | +## Next Steps |
| 163 | + |
| 164 | +1. Create migration file for database changes |
| 165 | +2. Implement `alpacaClosePosition.ts` utility |
| 166 | +3. Add routing logic to `execute-trade` function |
| 167 | +4. Test with paper trading accounts |
| 168 | +5. Create user documentation |
| 169 | +6. Deploy as opt-in beta feature |
0 commit comments