Metadata-Version: 2.1
Name: asklora-portal
Version: 1.1.8
Summary: portal to use various api data service
License: MIT
Author: redloratech
Author-email: rede.akbar@loratechai.com
Requires-Python: >=3.9,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Dist: pydantic-xml[lxml] (==0.6.0)
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
Requires-Dist: python-dotenv (>=0.20.0,<0.21.0)
Requires-Dist: python-gnupg (>=0.5.0,<0.6.0)
Requires-Dist: requests (>=2.28.1,<3.0.0)
Requires-Dist: sseclient-py (>=1.7.2,<2.0.0)
Requires-Dist: structlog (>=22.3.0,<23.0.0)
Description-Content-Type: text/markdown

# Asklora Portal

Shared utilities and helper classes used in Asklora projects

## Contents

1. Clients for external services (MarketData, Broker, PriceData, DAMECAClient, DAMFBClient) and their supporting classes (DAM, pydantic models for xml serialising and de-serialising)
2. Helper classes (SingletonMeta, ExtendedEnum, PGPHelper)
3. Helper functions (deep_get, get_file_size, get_file_sha1)

## Information on specific sections

### Broker, PriceData and MarketData client

#### required .env config when importing these

- `BROKER_API_URL=brokerurl`
- `MARKET_API_URL=market url`
- `BROKER_KEY=key`
- `BROKER_SECRET=secret`

#### usage

```python
from asklora import Broker

broker = Broker()
broker.create_account(...)
```

or you can use our Portal class to get the specific model

```python
import asklora

portal = asklora.Portal()

rest = portal.get_broker_client() # get a REST client for trade, user, position , order
marketrest = portal.get_market_client() # get a REST client for market data
eventclient = portal.get_event_client() # get an event client for trade, user, position, order
```

### PriceData (for IEX)

#### required .env config

- `IEX_API_URL`
- `IEX_TOKEN`

#### usage

```python
from asklora import PriceData

price_data = PriceData()
price_data.get_lastestPrice("MSFT")
```

### DAMECAClient and DAMFBClient

#### required .env config

- `DAM_URL`
- `DAM_CSID`

#### usage

For these clients, you can find the Pydantic models needed by some of the class methods in the `models` and `enums` module.

for example, in the `DAMECAClient`, in the `generate_application_payload` method, the first argument accepts `DAMApplicationPayload` model that will automatically processed to xml the API endpoint needs.

### examples

- DAMECAClient

  ```python
  from asklora import DAMECAClient, PGPHelper
  from asklora.models import DAMApplicationPayload

  client = DAMECAClient()

  # Build payload
  payload = DAMApplicationPayload(
      user_id=56,
      first_name="Jane",
      last_name="Smith",
      ...
  )

  # Needed for encryption
  pgp_helper = PGPHelper(
      private_key_path=...,
      public_key_path=...,
      remote_public_key_path=...,
  )

  # Send the request
  client.create_account(payload, pgp_helper=pgp_helper)
  ```

- DAMFBClient

  ```python
  from asklora import DAMFBClient, PGPHelper
  from asklora.models import InstructionSet, InternalCashTransfer, CancelTransaction

  client = DAMFBClient()

  instruction_set = InstructionSet(
      instructions=[
          InternalCashTransfer(
             id=4,
             source="U199516",
             destination="U34516",
             amount=1000,
             currency="USD",
          ),
          CancelTransaction(
             id=5,
             ib_instr_id="3",
             reason="Wrong destination",
          ),
      ]
  )
  pgp_helper = PGPHelper(
      private_key_path=...,
      public_key_path=...,
      remote_public_key_path=...,
  )

  client.create_instruction(instruction_set, pgp_helper=pgp_helper)

  # if needed, you can also send xml directly
  payload = """<?xml version="1.0" encoding="UTF-8"?>
  <instruction_set
    xmlns="http://www.interactivebrokers.com/fbfb_instruction_set"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.interactivebrokers.com/fbfb_instruction_set fbfb_instruction_set.xsd "
    creation_date="2019-01-11" id="2450" version="1">
    <close_account id="2450">
        <client_ib_acct_id>U1234567</client_ib_acct_id>
        <close_reason> No longer needed </close_reason>
    </close_account>
  </instruction_set>"""

  client.create_instruction(payload, pgp_helper=pgp_helper)
  ```

- Both

  You can also initialise one or both of the classes above like this:

  ```python
  from asklora import IBClient

  eca_client = IBClient.get_ECA_client()
  fb_client = IBClient.get_FB_client()
  ```

