diff --git a/README.md b/README.md
index 8ca9606..1f40127 100644
--- a/README.md
+++ b/README.md
@@ -24,9 +24,9 @@ The code below will:
- Print out the order confirmation
```
-import account
-import symbols
-import order
+from firstrade import account
+from firstrade import symbols
+from firstrade import order
# Create a session
ft_ss = account.FTSession(username='', password='', pin='')
diff --git a/build/lib/firstrade/__init__.py b/build/lib/firstrade/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/build/lib/firstrade/account.py b/build/lib/firstrade/account.py
deleted file mode 100644
index 6d05d54..0000000
--- a/build/lib/firstrade/account.py
+++ /dev/null
@@ -1,143 +0,0 @@
-import requests
-import pickle
-import re
-import urls
-
-
-class FTSession:
- """
- Class creating a session for Firstrade.
- """
- def __init__(self, username, password, pin, persistent_session=False):
- """
- Initializes a new instance of the FTSession class.
-
- Args:
- username (str): Firstrade login username.
- password (str): Firstrade login password.
- pin (str): Firstrade login pin.
- persistent_session (bool, optional): Whether the user wants to save the session cookies. Defaults to False.
- """
- self.username = username
- self.password = password
- self.pin = pin
- self.persistent_session = persistent_session
- self.session = requests.Session()
- self.cookies = {}
- self.login()
-
- def login(self):
- """
- Method to validate and login to the Firstrade platform.
- """
- headers = urls.session_headers()
- cookies = self.load_cookies()
- cookies = requests.utils.cookiejar_from_dict(cookies)
- self.session.cookies.update(cookies)
- if "/cgi-bin/sessionfailed?reason=6" in self.session.get(
- url=urls.get_xml(), headers=urls.session_headers(), cookies=cookies
- ).text:
- self.session.get(url=urls.login(), headers=headers)
- data = {
- 'redirect': '',
- 'ft_locale': 'en-us',
- 'login.x': 'Log In',
- 'username': self.username,
- 'password': self.password,
- 'destination_page': 'home'
- }
-
- self.session.post(
- url=urls.login(), headers=headers,
- cookies=self.session.cookies, data=data
- )
- data = {
- 'destination_page': 'home',
- 'pin': self.pin,
- 'pin.x': '++OK++',
- 'sring': '0',
- 'pin': self.pin
- }
-
- self.session.post(
- url=urls.pin(), headers=headers,
- cookies=self.session.cookies, data=data
- )
- if self.persistent_session:
- self.save_cookies()
- self.cookies = self.session.cookies
-
- def load_cookies(self):
- """
- Checks if session cookies were saved.
-
- Returns:
- Dict: Dictionary of cookies. Nom Nom
- """
- try:
- with open('cookies.pkl', 'rb') as f:
- cookies = pickle.load(f)
- except FileNotFoundError:
- cookies = {}
- return cookies
-
- def save_cookies(self):
- """
- Saves session cookies to a file.
- """
- with open('cookies.pkl', 'wb') as f:
- pickle.dump(self.session.cookies.get_dict(), f)
-
- def __getattr__(self, name):
- """
- Forwards unknown attribute access to session object.
-
- Args:
- name (str): The name of the attribute to be accessed.
-
- Returns:
- The value of the requested attribute from the session object.
- """
- return getattr(self.session, name)
-
-
-class FTAccountData:
- """
- Dataclass for storing account information.
- """
- def __init__(self, session):
- """
- Initializes a new instance of the FTAccountData class.
-
- Args:
- session (requests.Session): The session object used for making HTTP requests.
- """
- self.session = session
- self.cookies = self.session.cookies
- self.all_accounts = []
- self.account_numbers = []
- self.account_types = []
- self.account_owners = []
- self.account_balances = []
- all_account_info = []
- html_string = self.session.get(
- url=urls.account_list(),
- headers=urls.session_headers(),
- cookies=self.cookies
- ).text
- regex_accounts = re.findall(
- r'
(.*?) | (.*?) |
', html_string
- )
- for match in regex_accounts:
- start = match[0].split('-')[1]
- type = start.split(' ')[0]
- owner = start.split(' ')[1] + start.split(' ')[2]
- account = match[0].split('-')[0]
- balance = float(match[1].replace(',', ''))
- self.account_types.append(type)
- self.account_owners.append(owner)
- self.account_numbers.append(account)
- self.account_balances.append(balance)
- all_account_info.append({account: {'Type': type, 'Owner': owner, 'Balance': balance}})
- self.all_accounts = all_account_info
-
diff --git a/build/lib/firstrade/order.py b/build/lib/firstrade/order.py
deleted file mode 100644
index bac6f5a..0000000
--- a/build/lib/firstrade/order.py
+++ /dev/null
@@ -1,131 +0,0 @@
-from account import FTSession
-import urls
-from enum import Enum
-from bs4 import BeautifulSoup
-
-
-class PriceType(str, Enum):
- """
- This is an :class: 'enum.Enum' that contains the valid price types for an order.
- """
- LIMIT = '2'
- MARKET = '1'
- STOP = '3'
- STOP_LIMIT = '4'
- TRAILING_STOP_DOLLAR = '5'
- TRAILING_STOP_PERCENT = '6'
-
-
-class Duration(str, Enum):
- """
- This is an :class:'~enum.Enum' that contains the valid durations for an order.
- """
- DAY = '0'
- GT90 = '1'
- PRE_MARKET = 'A'
- AFTER_MARKET = 'P'
- DAY_EXT = 'D'
-
-
-class Order:
- """
- This class contains information about an order. It also contains a method to place an order.
- """
- def __init__(self, ft_session: FTSession):
- self.ft_session = ft_session
- self.order_confirmation = {}
-
- def place_order(
- self, account, symbol, order_type: PriceType,
- quantity, duration: Duration, price=0.00, dry_run=True
- ):
-
- """
- Builds and places an order.
- :attr: 'order_confirmation` contains the order confirmation data after order placement.
-
- Args:
- account (str): Account number of the account to place the order in.
- symbol (str): Ticker to place the order for.
- order_type (PriceType): Price Type i.e. LIMIT, MARKET, STOP, etc.
- quantity (float): The number of shares to buy.
- duration (Duration): Duration of the order i.e. DAY, GT90, etc.
- price (float, optional): The price to buy the shares at. Defaults to 0.00.
- dry_run (bool, optional): Whether you want the order to be placed or not.
- Defaults to True.
-
- Returns:
- Order:order_confirmation: Dictionary containing the order confirmation data.
- """
-
- if dry_run:
- previewOrders = '1'
- else:
- previewOrders = ''
-
- if order_type == PriceType.MARKET:
- price = ''
-
- data = {
- 'submiturl': '/cgi-bin/orderbar',
- 'orderbar_clordid': '',
- 'orderbar_accountid': '',
- 'stockorderpage': 'yes',
- 'submitOrders': '1',
- 'previewOrders': previewOrders,
- 'lotMethod': '1',
- 'accountType': '1',
- 'quoteprice': '',
- 'viewederror': '',
- 'stocksubmittedcompanyname1': '',
- 'accountId': account,
- 'transactionType': 'B',
- 'quantity': quantity,
- 'symbol': symbol,
- 'priceType': order_type,
- 'limitPrice': price,
- 'duration': duration,
- 'qualifier': '0',
- 'cond_symbol0_0': '',
- 'cond_type0_0': '2',
- 'cond_compare_type0_0': '2',
- 'cond_compare_value0_0': '',
- 'cond_and_or0': '1',
- 'cond_symbol0_1': '',
- 'cond_type0_1': '2',
- 'cond_compare_type0_1': '2',
- 'cond_compare_value0_1': ''
- }
-
- order_data = BeautifulSoup(self.ft_session.post(
- url=urls.orderbar(),
- headers=urls.session_headers(),
- data=data
- ).text, 'xml')
- order_confirmation = {}
- order_success = order_data.find('success').text.strip()
- order_confirmation['success'] = order_success
- action_data = order_data.find('actiondata').text.strip()
- if order_success != "No":
- # Extract the table data
- table_start = action_data.find('')
- table_data = action_data[table_start:table_end]
- table_data = BeautifulSoup(table_data, 'xml')
- titles = table_data.find_all('th')
- data = table_data.find_all('td')
- for i, title in enumerate(titles):
- order_confirmation[f'{title.get_text()}'] = data[i].get_text()
- if not dry_run:
- start_index = action_data.find('Your order reference number is: ') + len('Your order reference number is: ')
- end_index = action_data.find('', start_index)
- order_number = action_data[start_index:end_index]
- else:
- start_index = action_data.find('id="') + len('id="')
- end_index = action_data.find('" style=', start_index)
- order_number = action_data[start_index:end_index]
- order_confirmation['orderid'] = order_number
- else:
- order_confirmation['actiondata'] = action_data
- order_confirmation['errcode'] = order_data.find('errcode').text.strip()
- self.order_confirmation = order_confirmation
diff --git a/build/lib/firstrade/symbols.py b/build/lib/firstrade/symbols.py
deleted file mode 100644
index 79416f4..0000000
--- a/build/lib/firstrade/symbols.py
+++ /dev/null
@@ -1,48 +0,0 @@
-from bs4 import BeautifulSoup
-from account import FTSession
-import urls
-
-
-class SymbolQuote:
- """
- Dataclass containing quote information for a symbol.
-
- Attributes:
- ft_session (FTSession): The session object used for making HTTP requests to Firstrade.
- symbol (str): The symbol for which the quote information is retrieved.
- exchange (str): The exchange where the symbol is traded.
- bid (float): The bid price for the symbol.
- ask (float): The ask price for the symbol.
- last (float): The last traded price for the symbol.
- change (float): The change in price for the symbol.
- high (float): The highest price for the symbol during the trading day.
- low (float): The lowest price for the symbol during the trading day.
- volume (str): The volume of shares traded for the symbol.
- company_name (str): The name of the company associated with the symbol.
- """
- def __init__(self, ft_session: FTSession, symbol: str):
- """
- Initializes a new instance of the SymbolQuote class.
-
- Args:
- ft_session (FTSession): The session object used for making HTTP requests to Firstrade.
- symbol (str): The symbol for which the quote information is retrieved.
- """
- self.ft_session = ft_session
- self.symbol = symbol
- symbol_data = self.ft_session.get(
- url=urls.quote(self.symbol),
- headers=urls.session_headers()
- )
- soup = BeautifulSoup(symbol_data.text, 'xml')
- quote = soup.find('quote')
- self.symbol = quote.find('symbol').text
- self.exchange = quote.find('exchange').text
- self.bid = float(quote.find('bid').text)
- self.ask = float(quote.find('ask').text)
- self.last = float(quote.find('last').text)
- self.change = float(quote.find('change').text)
- self.high = float(quote.find('high').text)
- self.low = float(quote.find('low').text)
- self.volume = quote.find('vol').text
- self.company_name = quote.find('companyname').text
diff --git a/build/lib/firstrade/urls.py b/build/lib/firstrade/urls.py
deleted file mode 100644
index 9bb9ca0..0000000
--- a/build/lib/firstrade/urls.py
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-def get_xml():
- return 'https://invest.firstrade.com/cgi-bin/getxml'
-
-
-def login():
- return 'https://invest.firstrade.com/cgi-bin/login'
-
-
-def pin():
- return 'https://invest.firstrade.com/cgi-bin/enter_pin?destination_page=home'
-
-
-def account_list():
- return 'https://invest.firstrade.com/cgi-bin/getaccountlist'
-
-
-def quote(symbol):
- return f'https://invest.firstrade.com/cgi-bin/getxml?page=quo"eSymbol={symbol}'
-
-
-def orderbar():
- return 'https://invest.firstrade.com/cgi-bin/orderbar'
-
-
-def session_headers():
- headers = {
- 'Accept': '*/*',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Accept-Language': 'en-US,en;q=0.9',
- 'Host': 'invest.firstrade.com',
- 'Referer': 'https://invest.firstrade.com/cgi-bin/main',
- 'Connection': 'keep-alive',
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81'
- }
- return headers
diff --git a/firstrade/__init__.py b/firstrade/__init__.py
index e69de29..2c4d592 100644
--- a/firstrade/__init__.py
+++ b/firstrade/__init__.py
@@ -0,0 +1,4 @@
+from firstrade import account
+from firstrade import order
+from firstrade import symbols
+from firstrade import urls
diff --git a/firstrade_api.egg-info/PKG-INFO b/firstrade_api.egg-info/PKG-INFO
deleted file mode 100644
index 48bc531..0000000
--- a/firstrade_api.egg-info/PKG-INFO
+++ /dev/null
@@ -1,7 +0,0 @@
-Metadata-Version: 2.1
-Name: firstrade-api
-Version: 0.0.1
-Summary: An unofficial API for Firstrade
-Author: MaxxRK
-Author-email: maxxrk@pm.me
-License-File: LICENSE
diff --git a/firstrade_api.egg-info/SOURCES.txt b/firstrade_api.egg-info/SOURCES.txt
deleted file mode 100644
index ef250f4..0000000
--- a/firstrade_api.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-LICENSE
-README.md
-setup.py
-firstrade/__init__.py
-firstrade/account.py
-firstrade/order.py
-firstrade/symbols.py
-firstrade/urls.py
-firstrade_api.egg-info/PKG-INFO
-firstrade_api.egg-info/SOURCES.txt
-firstrade_api.egg-info/dependency_links.txt
-firstrade_api.egg-info/top_level.txt
\ No newline at end of file
diff --git a/firstrade_api.egg-info/dependency_links.txt b/firstrade_api.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/firstrade_api.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/firstrade_api.egg-info/top_level.txt b/firstrade_api.egg-info/top_level.txt
deleted file mode 100644
index a47ec49..0000000
--- a/firstrade_api.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-firstrade