@@ -605,119 +605,6 @@ def candles_v3(self, request, pk=None):
605605 """
606606 return get_candles_v3 (self , request , pk )
607607
608- @staticmethod
609- def _parse_limit (request , default : int , maximum : int ) -> int :
610- """Parse and clamp the 'limit' query parameter."""
611- try :
612- return min (int (request .query_params .get ("limit" , default )), maximum )
613- except (ValueError , TypeError ):
614- return default
615-
616- @action (detail = True , methods = ["get" ], url_path = "option_chain" )
617- def option_chain (self , request , pk = None ):
618- """
619- Fetch the options chain (snapshots with quotes and greeks) for an underlying equity asset.
620-
621- Query Parameters:
622- expiration_date_gte: Filter options expiring on or after this date (YYYY-MM-DD).
623- expiration_date_lte: Filter options expiring on or before this date (YYYY-MM-DD).
624- type: Option type filter – 'call' or 'put'.
625- limit: Maximum number of contracts to return (default 200, max 1000).
626- page_token: Pagination token from a previous response.
627-
628- Returns:
629- {
630- "msg": "Ok",
631- "data": {
632- "snapshots": { "<symbol>": { "details": {...}, "greeks": {...}, ... } },
633- "next_page_token": null
634- }
635- }
636- """
637- asset = self .get_object ()
638-
639- if asset .asset_class != "us_equity" :
640- return Response (
641- {"msg" : "Options chain is only available for equity assets" },
642- status = status .HTTP_400_BAD_REQUEST ,
643- )
644-
645- expiration_date_gte = request .query_params .get ("expiration_date_gte" )
646- expiration_date_lte = request .query_params .get ("expiration_date_lte" )
647- option_type = request .query_params .get ("type" )
648- limit = self ._parse_limit (request , default = 200 , maximum = 1000 )
649- page_token = request .query_params .get ("page_token" )
650-
651- try :
652- data = alpaca_service .get_option_snapshots (
653- underlying_symbol = asset .symbol ,
654- expiration_date_gte = expiration_date_gte ,
655- expiration_date_lte = expiration_date_lte ,
656- option_type = option_type ,
657- limit = limit ,
658- page_token = page_token ,
659- )
660- return Response ({"msg" : "Ok" , "data" : data }, status = status .HTTP_200_OK )
661- except Exception as e :
662- logger .error (
663- f"Error fetching option chain for { asset .symbol } : { e } " , exc_info = True
664- )
665- return Response (
666- {"msg" : "Error fetching option chain" },
667- status = status .HTTP_500_INTERNAL_SERVER_ERROR ,
668- )
669-
670- @action (detail = False , methods = ["get" ], url_path = "option_bars" )
671- def option_bars (self , request ):
672- """
673- Fetch historical OHLCV bars for a specific option contract.
674-
675- Query Parameters:
676- symbol: Option contract symbol (required), e.g. AAPL240119C00180000.
677- timeframe: Bar timeframe – '1Min', '5Min', '1Hour', '1Day' (default '1Day').
678- start: Start date/time in ISO 8601 format.
679- end: End date/time in ISO 8601 format.
680- limit: Maximum number of bars to return (default 1000, max 10000).
681-
682- Returns:
683- {
684- "msg": "Ok",
685- "data": {
686- "bars": { "<symbol>": [{"t": ..., "o": ..., "h": ..., "l": ..., "c": ..., "v": ...}] },
687- "next_page_token": null
688- }
689- }
690- """
691- symbol = request .query_params .get ("symbol" )
692- if not symbol :
693- return Response (
694- {"msg" : "symbol parameter is required" },
695- status = status .HTTP_400_BAD_REQUEST ,
696- )
697-
698- timeframe = request .query_params .get ("timeframe" , "1Day" )
699- start = request .query_params .get ("start" )
700- end = request .query_params .get ("end" )
701- limit = self ._parse_limit (request , default = 1000 , maximum = 10000 )
702-
703- try :
704- data = alpaca_service .get_option_bars (
705- symbols = symbol ,
706- timeframe = timeframe ,
707- start = start ,
708- end = end ,
709- limit = limit ,
710- )
711- return Response ({"msg" : "Ok" , "data" : data }, status = status .HTTP_200_OK )
712- except Exception as e :
713- logger .error (
714- f"Error fetching option bars for { symbol } : { e } " , exc_info = True
715- )
716- return Response (
717- {"msg" : "Error fetching option bars" },
718- status = status .HTTP_500_INTERNAL_SERVER_ERROR ,
719- )
720-
721608
722609class WatchListViewSet (PublicReadOnlyMixin , viewsets .ModelViewSet ):
723610 """
0 commit comments