Example #1
0
    def get_latest_candles(
        cls,
        account_id,
        candleSpecifications,
        units=1,
        smooth=False,
        dailyAlignment=17,
        alignmentTimeZone="America/New_York",
        weeklyAlignment="Friday",
    ):
        url = f"{cls._config['base_url']}/v3/accounts/{account_id}/candles/latest"
        if dailyAlignment < 0 or dailyAlignment > 23:
            raise ValueError(
                "dailyAlignment should be between 0 and 23 (inclusive)")

        response = RequestSender.send(
            url,
            cls._headers,
            RequestType.GET,
            params={
                "candleSpecifications": candleSpecifications,
                "units": units,
                "smooth": smooth,
                "dailyAlignment": dailyAlignment,
                "alignmentTimeZone": alignmentTimeZone,
                "weeklyAlignment": weeklyAlignment,
            },
        )
        return (response.json() if response.status_code == 200 else
                response.raise_for_status())
Example #2
0
 def create_order(
     cls,
     account_id,
     order_type,
     units,
     instrument,
     time_in_force,
     position_fill,
     other_params={},
 ):
     url = f"{cls._config['base_url']}/v3/accounts/{account_id}/orders"
     data = {
         "order": {
             "units": units,
             "instrument": instrument,
             "timeInForce": time_in_force,
             "type": order_type,
             "positionFill": position_fill,
         }
     }
     data["order"].update(other_params)
     response = RequestSender.send(url,
                                   cls._headers,
                                   RequestType.POST,
                                   data=data)
     return (response.json() if response.status_code == 201 else
             response.raise_for_status())
Example #3
0
    def get_trades(
        cls,
        account_id,
        ids=None,
        state="OPEN",
        instrument=None,
        count=50,
        beforeID=None,
    ):
        if state not in ["OPEN", "CLOSED", "CLOSE_WHEN_TRADEABLE", "ALL"]:
            raise ValueError(
                "state must be a valid TradeStateFilter (OPEN, CLOSED, CLOSE_WHEN_TRADEABLE, or ALL)"
            )
        if count < 1 or count > 500:
            raise ValueError("count must be positive and not exceed 500")

        url = f"{cls._config['base_url']}/v3/accounts/{account_id}/trades"
        params = {"state": state, "count": count}
        if ids:
            # required format is csv
            params["ids"] = ",".join(ids)
        if instrument:
            params["instrument"] = instrument
        if beforeID:
            params["beforeID"] = beforeID

        response = RequestSender.send(url,
                                      cls._headers,
                                      RequestType.GET,
                                      params=params)
        return (response.json() if response.status_code == 200 else
                response.raise_for_status())
Example #4
0
 def get_instrument_positions(cls, account_id, instrument):
     url = (
         f"{cls._config['base_url']}/v3/accounts/{account_id}/positions/{instrument}"
     )
     response = RequestSender.send(url, cls._headers, RequestType.GET)
     return (response.json() if response.status_code == 200 else
             response.raise_for_status())
Example #5
0
 def get_positionbook(cls, instrument_name, datetime=None):
     url = f"{cls._config['base_url']}/v3/instruments/{instrument_name}/positionBook"
     response = RequestSender.send(url,
                                   cls._headers,
                                   RequestType.GET,
                                   params={"time": datetime})
     return response.json(
     ) if response.status_code == 200 else response.raise_for_status()
Example #6
0
 def get_candles(cls, instrument_name, candle_params={}):
     url = f"{cls._config['base_url']}/v3/instruments/{instrument_name}/candles"
     response = RequestSender.send(url,
                                   cls._headers,
                                   RequestType.GET,
                                   params=candle_params)
     return response.json(
     ) if response.status_code == 200 else response.raise_for_status()
Example #7
0
 def get_account_changes(cls, account_id, since_transaction_id=None):
     url = f"{cls._config['base_url']}/v3/accounts/{account_id}/changes"
     response = RequestSender.send(
         url,
         cls._headers,
         RequestType.GET,
         params={"sinceTransactionID": since_transaction_id})
     return response.json(
     ) if response.status_code == 200 else response.raise_for_status()
Example #8
0
    def close_instrument_positions(cls, account_id, instrument, long_units=0, short_units=0):
        if long_units != 0 and short_units != 0:
            raise Exception("Only long_units or short_units")
        elif long_units and short_units:
            raise Exception("No units specified")

        url = f"{cls._config['base_url']}/v3/accounts/{account_id}/positions/{instrument}/close"
        data = {"shortUnits": str(short_units)} if short_units else {"longUnits": str(long_units)}
        response = RequestSender.send(url, cls._headers, RequestType.PUT, data=data)
        return response.json() if response.status_code == 200 else response.raise_for_status()
Example #9
0
    def get_orderbook(cls, instrument_name, time=None, df=True):
        url = f"{cls._config['base_url']}/v3/instruments/{instrument_name}/orderBook"
        response = RequestSender.send(
            url, cls._headers, RequestType.GET, params={"time": time}
        )

        if response.status_code == 200:
            orderbook = response.json()["orderBook"]
            if not df:
                return orderbook
            # orderbook['time'] is UTC time, so it is consistent with the time given in the candles
            # there is also orderbook['unixTime'], but it seems like it's Singapore time UTC+8
            orderbook["time"] = isoparse(orderbook["time"][:-1])
            orderbook["price"] = float(orderbook["price"])
            orderbook["bucketWidth"] = float(orderbook["bucketWidth"])
            orderbook["buckets"] = pd.DataFrame(orderbook["buckets"]).astype(float)
            return orderbook["buckets"]
        return response.raise_for_status()
Example #10
0
    def get_positionbook(cls, instrument_name, time=None, df=True):
        url = f"{cls._config['base_url']}/v3/instruments/{instrument_name}/positionBook"
        response = RequestSender.send(
            url, cls._headers, RequestType.GET, params={"time": time}
        )

        if response.status_code == 200:
            positionbook = response.json()["positionBook"]
            if not df:
                return positionbook
            positionbook["time"] = isoparse(positionbook["time"][:-1])
            positionbook["price"] = float(positionbook["price"])
            positionbook["bucketWidth"] = float(positionbook["bucketWidth"])
            positionbook["buckets"] = pd.DataFrame(positionbook["buckets"]).astype(
                float
            )
            return positionbook["buckets"]
        return response.raise_for_status()
Example #11
0
    def get_candles(cls, instrument_name, candle_params={}, df=True):
        url = f"{cls._config['base_url']}/v3/instruments/{instrument_name}/candles"
        default_params = {
            "granularity": "S5",
            "count": 5000,
        }
        for k, v in default_params.items():
            if k not in candle_params:
                candle_params[k] = v
        response = RequestSender.send(
            url, cls._headers, RequestType.GET, params=candle_params
        )

        if response.status_code == 200:
            candles = response.json()
            if not df:
                return candles
            candles["candles"] = pd.DataFrame(candles["candles"])
            candles["candles"]["time"] = pd.to_datetime(
                candles["candles"]["time"], unit="s"
            )
            candles["candles"]["unixtime"] = (
                candles["candles"]["time"]
                .astype(str)
                .apply(lambda x: int(Utils.get_unix_timestamp(x)))
            )
            for price in ["mid", "bid", "ask"]:
                if price not in candles["candles"].columns:
                    continue
                candles["candles"][f"{price}.open"] = (
                    candles["candles"][price].map(lambda x: x["o"]).astype(float)
                )
                candles["candles"][f"{price}.high"] = (
                    candles["candles"][price].map(lambda x: x["h"]).astype(float)
                )
                candles["candles"][f"{price}.low"] = (
                    candles["candles"][price].map(lambda x: x["l"]).astype(float)
                )
                candles["candles"][f"{price}.close"] = (
                    candles["candles"][price].map(lambda x: x["c"]).astype(float)
                )
                del candles["candles"][price]
            return candles["candles"]
        return response.raise_for_status()
Example #12
0
 def get_tradeable_instruments(cls,
                               account_id,
                               names_only=False,
                               instruments=[]):
     if instruments and names_only:
         raise Exception(
             "names_only must be False if instruments is not empty")
     url = f"{cls._config['base_url']}/v3/accounts/{account_id}/instruments"
     response = RequestSender.send(url,
                                   cls._headers,
                                   RequestType.GET,
                                   params={"instruments": instruments})
     if response.status_code != 200:
         response.raise_for_status()
     if not names_only:
         return response.json()
     else:
         return [
             instrument["name"]
             for instrument in response.json()["instruments"]
         ]
Example #13
0
 def get_pricing(
     cls,
     account_id,
     instruments,
     since=None,
     includeUnitsAvailable=True,
     includeHomeConversions=False,
 ):
     url = f"{cls._config['base_url']}/v3/accounts/{account_id}/pricing"
     response = RequestSender.send(
         url,
         cls._headers,
         RequestType.GET,
         params={
             "instruments": ",".join(instruments),
             "since": since,
             "includeUnitsAvailable": includeUnitsAvailable,
             "includeHomeConversions": includeHomeConversions,
         },
     )
     return (response.json() if response.status_code == 200 else
             response.raise_for_status())
Example #14
0
 def get_open_positions(cls, account_id):
     url = f"{cls._config['base_url']}/v3/accounts/{account_id}/openPositions"
     response = RequestSender.send(url, cls._headers, RequestType.GET)
     return response.json() if response.status_code == 200 else response.raise_for_status()
Example #15
0
 def get_specific_trade(cls, account_id, tradeSpecifier):
     # tradeSpecifier is either TradeID or @ClientID
     url = f"{cls._config['base_url']}/v3/accounts/{account_id}/trades/{tradeSpecifier}"
     response = RequestSender.send(url, cls._headers, RequestType.GET)
     return (response.json() if response.status_code == 200 else
             response.raise_for_status())
Example #16
0
 def get_pending_orders(cls, account_id):
     url = f"{cls._config['base_url']}/v3/accounts/{account_id}/pendingOrders"
     response = RequestSender.send(url, cls._headers, RequestType.GET)
     return (response.json() if response.status_code == 200 else
             response.raise_for_status())
Example #17
0
 def get_accounts(cls):
     url = f"{cls._config['base_url']}/v3/accounts"
     response = RequestSender.send(url, cls._headers, RequestType.GET)
     return response.json(
     ) if response.status_code == 200 else response.raise_for_status()