firstrade 0.0.15__py3-none-any.whl → 0.0.17__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
firstrade/order.py CHANGED
@@ -1,13 +1,12 @@
1
1
  from enum import Enum
2
2
 
3
- from firstrade.account import FTSession
4
- from firstrade import urls
5
-
6
3
  from bs4 import BeautifulSoup
7
4
 
5
+ from firstrade import urls
6
+ from firstrade.account import FTSession
8
7
 
9
- class PriceType(str, Enum):
10
8
 
9
+ class PriceType(str, Enum):
11
10
  """
12
11
  This is an :class: 'enum.Enum'
13
12
  that contains the valid price types for an order.
@@ -22,7 +21,6 @@ class PriceType(str, Enum):
22
21
 
23
22
 
24
23
  class Duration(str, Enum):
25
-
26
24
  """
27
25
  This is an :class:'~enum.Enum'
28
26
  that contains the valid durations for an order.
@@ -36,7 +34,6 @@ class Duration(str, Enum):
36
34
 
37
35
 
38
36
  class OrderType(str, Enum):
39
-
40
37
  """
41
38
  This is an :class:'~enum.Enum'
42
39
  that contains the valid order types for an order.
@@ -49,11 +46,11 @@ class OrderType(str, Enum):
49
46
 
50
47
 
51
48
  class Order:
52
-
53
49
  """
54
50
  This class contains information about an order.
55
51
  It also contains a method to place an order.
56
52
  """
53
+
57
54
  def __init__(self, ft_session: FTSession):
58
55
  self.ft_session = ft_session
59
56
  self.order_confirmation = {}
@@ -164,3 +161,67 @@ class Order:
164
161
  order_confirmation["actiondata"] = action_data
165
162
  order_confirmation["errcode"] = order_data.find("errcode").text.strip()
166
163
  self.order_confirmation = order_confirmation
164
+
165
+
166
+ def get_orders(ft_session, account):
167
+ """
168
+ Retrieves existing order data for a given account.
169
+
170
+ Args:
171
+ ft_session (FTSession): The session object used for making HTTP requests to Firstrade.
172
+ account (str): Account number of the account to retrieve orders for.
173
+
174
+ Returns:
175
+ list: A list of dictionaries, each containing details about an order.
176
+ """
177
+
178
+ # Data dictionary to send with the request
179
+ data = {
180
+ 'accountId': account,
181
+ }
182
+
183
+ # Post request to retrieve the order data
184
+ response = ft_session.post(url=urls.order_list(), headers=urls.session_headers(), data=data).text
185
+
186
+ # Parse the response using BeautifulSoup
187
+ soup = BeautifulSoup(response, "html.parser")
188
+
189
+ # Find the table containing orders
190
+ table = soup.find('table', class_='tablesorter')
191
+ if not table:
192
+ return []
193
+
194
+ rows = table.find_all('tr')[1:] # skip the header row
195
+
196
+ orders = []
197
+ for row in rows:
198
+ try:
199
+ cells = row.find_all('td')
200
+ tooltip_content = row.find('a', {'class': 'info'}).get('onmouseover')
201
+ tooltip_soup = BeautifulSoup(tooltip_content.split('tooltip.show(')[1].strip("');"), 'html.parser')
202
+ order_ref = tooltip_soup.find(text=lambda text: 'Order Ref' in text)
203
+ order_ref_number = order_ref.split('#: ')[1] if order_ref else None
204
+ status = cells[8]
205
+ # print(status)
206
+ sub_status = status.find('strong')
207
+ # print(sub_status)
208
+ sub_status = sub_status.get_text(strip=True)
209
+ # print(sub_status)
210
+ status = status.find('strong').get_text(strip=True) if status.find('strong') else status.get_text(strip=True)
211
+ order = {
212
+ 'Date/Time': cells[0].get_text(strip=True),
213
+ 'Reference': order_ref_number,
214
+ 'Transaction': cells[1].get_text(strip=True),
215
+ 'Quantity': int(cells[2].get_text(strip=True)),
216
+ 'Symbol': cells[3].get_text(strip=True),
217
+ 'Type': cells[4].get_text(strip=True),
218
+ 'Price': float(cells[5].get_text(strip=True)),
219
+ 'Duration': cells[6].get_text(strip=True),
220
+ 'Instr.': cells[7].get_text(strip=True),
221
+ 'Status': status,
222
+ }
223
+ orders.append(order)
224
+ except Exception as e:
225
+ print(f"Error parsing order: {e}")
226
+
227
+ return orders
firstrade/symbols.py CHANGED
@@ -21,6 +21,8 @@ class SymbolQuote:
21
21
  low (float): The lowest price for the symbol during the trading day.
22
22
  volume (str): The volume of shares traded for the symbol.
23
23
  company_name (str): The name of the company associated with the symbol.
24
+ real_time (bool): If the quote is real-time or not
25
+ fractional (bool): If the stock can be traded fractionally, or not
24
26
  """
25
27
 
26
28
  def __init__(self, ft_session: FTSession, symbol: str):
@@ -41,17 +43,19 @@ class SymbolQuote:
41
43
  quote = soup.find("quote")
42
44
  self.symbol = quote.find("symbol").text
43
45
  self.exchange = quote.find("exchange").text
44
- self.bid = float(quote.find("bid").text)
45
- self.ask = float(quote.find("ask").text)
46
- self.last = float(quote.find("last").text)
47
- self.change = float(quote.find("change").text)
46
+ self.bid = float(quote.find("bid").text.replace(",", ""))
47
+ self.ask = float(quote.find("ask").text.replace(",", ""))
48
+ self.last = float(quote.find("last").text.replace(",", ""))
49
+ self.change = float(quote.find("change").text.replace(",", ""))
48
50
  if quote.find("high").text == "N/A":
49
51
  self.high = None
50
52
  else:
51
- self.high = float(quote.find("high").text)
53
+ self.high = float(quote.find("high").text.replace(",", ""))
52
54
  if quote.find("low").text == "N/A":
53
55
  self.low = "None"
54
56
  else:
55
- self.low = float(quote.find("low").text)
57
+ self.low = float(quote.find("low").text.replace(",", ""))
56
58
  self.volume = quote.find("vol").text
57
59
  self.company_name = quote.find("companyname").text
60
+ self.real_time = quote.find("realtime").text == "T"
61
+ self.fractional = quote.find("fractional").text == "T"
firstrade/urls.py CHANGED
@@ -25,6 +25,9 @@ def orderbar():
25
25
  def account_status():
26
26
  return "https://invest.firstrade.com/cgi-bin/account_status"
27
27
 
28
+ def order_list():
29
+ return "https://invest.firstrade.com/cgi-bin/orderstatus"
30
+
28
31
 
29
32
  def status():
30
33
  return "https://invest.firstrade.com/scripts/profile/margin_v2.php"
@@ -0,0 +1,81 @@
1
+ Metadata-Version: 2.1
2
+ Name: firstrade
3
+ Version: 0.0.17
4
+ Summary: An unofficial API for Firstrade
5
+ Home-page: https://github.com/MaxxRK/firstrade-api
6
+ Download-URL: https://github.com/MaxxRK/firstrade-api/archive/refs/tags/0017.tar.gz
7
+ Author: MaxxRK
8
+ Author-email: maxxrk@pm.me
9
+ License: MIT
10
+ Keywords: FIRSTRADE,API
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Internet :: WWW/HTTP :: Session
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: requests
23
+ Requires-Dist: beautifulsoup4
24
+ Requires-Dist: lxml
25
+
26
+ # firstrade-api
27
+
28
+ A reverse-engineered python API to interact with the Firstrade Trading platform.
29
+
30
+ This is not an official api! This api's functionality may change at any time.
31
+
32
+ This api provides a means of buying and selling stocks through Firstrade. It uses the Session class from requests to get authorization cookies. The rest is done with reverse engineered requests to Firstrade's API.
33
+
34
+ In order to use Fractional shares you must accept the agreement on the website before using it in this API.
35
+
36
+ ---
37
+
38
+ ## Contribution
39
+
40
+ I am new to coding and new to open-source. I would love any help and suggestions!
41
+
42
+ ## Setup
43
+
44
+ Install using pypi:
45
+
46
+ ```
47
+ pip install firstrade
48
+ ```
49
+
50
+ ## Quikstart
51
+
52
+ The code below will:
53
+
54
+ - Login and print account info.
55
+ - Get a quote for 'INTC' and print out the information
56
+ - Place a market order for 'INTC' on the first account in the `account_numbers` list
57
+ - Print out the order confirmation
58
+
59
+ `Checkout test.py for sample code.`
60
+
61
+ This code is also in test.py
62
+
63
+ ---
64
+
65
+ ## Implemented Features
66
+
67
+ - [x] Login
68
+ - [x] Get Quotes
69
+ - [x] Get Account Data
70
+ - [x] Place Orders and Receive order confirmation
71
+ - [x] Get Currently Held Positions
72
+ - [x] Fractional Trading support (thanks to @jiak94)
73
+ - [x] Check on placed order status. (thanks to @Cfomodz)
74
+
75
+ ## TO DO
76
+
77
+ - [ ] Cancel placed orders
78
+ - [ ] Options
79
+ - [ ] Give me some Ideas!
80
+
81
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/O5O6PTOYG)
@@ -0,0 +1,10 @@
1
+ firstrade/__init__.py,sha256=fNiWYgSTjElY1MNv0Ug-sVLMTR2z_Ngri_FY7Pekdrw,95
2
+ firstrade/account.py,sha256=xDgTMXDy2UWUNi4kboXAKKBrbmZGpXLJ11MCHlMvzB0,9218
3
+ firstrade/order.py,sha256=BK2OmIOr_LO4SrNRVWjkydaoc_4fLkl6Rr7_LCRTyLE,7635
4
+ firstrade/symbols.py,sha256=0lVuHgmrpwANyRlOlsXCTr6xsT5aWqBIIXH66q9ezb8,2675
5
+ firstrade/urls.py,sha256=OrfXGDsNpA2rTm4o55KAQzpeigG_pxufWyTDBlbhJYQ,1248
6
+ firstrade-0.0.17.dist-info/LICENSE,sha256=wPEQjDqm5zMBmEcZp219Labmq_YIjhudpZiUzyVKaFA,1057
7
+ firstrade-0.0.17.dist-info/METADATA,sha256=55lP4v_p1nwokaPvBwzJr0-2ANDeND3KqdwCDWCOGto,2307
8
+ firstrade-0.0.17.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
9
+ firstrade-0.0.17.dist-info/top_level.txt,sha256=tdA8v-KDxU1u4VV6soiNWGBlni4ojv_t_j2wFn5nZcs,10
10
+ firstrade-0.0.17.dist-info/RECORD,,
@@ -1,149 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: firstrade
3
- Version: 0.0.15
4
- Summary: An unofficial API for Firstrade
5
- Home-page: https://github.com/MaxxRK/firstrade-api
6
- Download-URL: https://github.com/MaxxRK/firstrade-api/archive/refs/tags/0015.tar.gz
7
- Author: MaxxRK
8
- Author-email: maxxrk@pm.me
9
- License: MIT
10
- Keywords: FIRSTRADE,API
11
- Classifier: Development Status :: 3 - Alpha
12
- Classifier: Intended Audience :: Developers
13
- Classifier: Topic :: Internet :: WWW/HTTP :: Session
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Classifier: Programming Language :: Python :: 3.11
20
- Description-Content-Type: text/markdown
21
- License-File: LICENSE
22
- Requires-Dist: requests
23
- Requires-Dist: beautifulsoup4
24
- Requires-Dist: lxml
25
-
26
- # firstrade-api
27
-
28
- A reverse-engineered python API to interact with the Firstrade Trading platform.
29
-
30
- This is not an official api! This api's functionality may change at any time.
31
-
32
- This api provides a means of buying and selling stocks through Firstrade. It uses the Session class from requests to get authorization cookies. The rest is done with reverse engineered requests to Firstrade's API.
33
-
34
- In order to use Fractional shares you must accept the agreement on the website before using it in this API.
35
-
36
- ---
37
-
38
- ## Contribution
39
-
40
- I am new to coding and new to open-source. I would love any help and suggestions!
41
-
42
- ## Setup
43
-
44
- Install using pypi:
45
-
46
- ```
47
- pip install firstrade
48
- ```
49
-
50
- ## Quikstart
51
-
52
- The code below will:
53
-
54
- - Login and print account info.
55
- - Get a quote for 'INTC' and print out the information
56
- - Place a market order for 'INTC' on the first account in the `account_numbers` list
57
- - Print out the order confirmation
58
-
59
- ```
60
- from firstrade import account, order, symbols
61
-
62
- # Create a session
63
- ft_ss = account.FTSession(username="", password="", pin="")
64
-
65
- # Get account data
66
- ft_accounts = account.FTAccountData(ft_ss)
67
- if len(ft_accounts.account_numbers) < 1:
68
- raise Exception("No accounts found or an error occured exiting...")
69
-
70
- # Print ALL account data
71
- print(ft_accounts.all_accounts)
72
-
73
- # Print 1st account number.
74
- print(ft_accounts.account_numbers[0])
75
-
76
- # Print ALL accounts market values.
77
- print(ft_accounts.account_balances)
78
-
79
- # Get quote for INTC
80
- quote = symbols.SymbolQuote(ft_ss, "INTC")
81
- print(f"Symbol: {quote.symbol}")
82
- print(f"Exchange: {quote.exchange}")
83
- print(f"Bid: {quote.bid}")
84
- print(f"Ask: {quote.ask}")
85
- print(f"Last: {quote.last}")
86
- print(f"Change: {quote.change}")
87
- print(f"High: {quote.high}")
88
- print(f"Low: {quote.low}")
89
- print(f"Volume: {quote.volume}")
90
- print(f"Company Name: {quote.company_name}")
91
-
92
- # Get positions and print them out for an account.
93
- positions = ft_accounts.get_positions(account=ft_accounts.account_numbers[1])
94
- for key in ft_accounts.securities_held:
95
- print(
96
- f"Quantity {ft_accounts.securities_held[key]['quantity']} of security {key} held in account {ft_accounts.account_numbers[1]}"
97
- )
98
-
99
- # Create an order object.
100
- ft_order = order.Order(ft_ss)
101
-
102
- # Place order and print out order confirmation data.
103
- ft_order.place_order(
104
- ft_accounts.account_numbers[0],
105
- symbol="INTC",
106
- price_type=order.PriceType.MARKET,
107
- order_type=order.OrderType.BUY,
108
- quantity=1, # number of shares or amount of dollar, depends on the value of notional
109
- duration=order.Duration.DAY,
110
- dry_run=True,
111
- notional=False, # set to True if quantity above is "dollar"
112
- )
113
-
114
- # Print Order data Dict
115
- print(ft_order.order_confirmation)
116
-
117
- # Check if order was successful
118
- if ft_order.order_confirmation["success"] == "Yes":
119
- print("Order placed successfully.")
120
- # Print Order ID
121
- print(f"Order ID: {ft_order.order_confirmation['orderid']}.")
122
- else:
123
- print("Failed to place order.")
124
- # Print errormessage
125
- print(ft_order.order_confirmation["actiondata"])
126
- # Delete cookies
127
- ft_ss.delete_cookies()
128
- ```
129
-
130
- This code is also in test.py
131
-
132
- ---
133
-
134
- ## Implemented Features
135
-
136
- - [x] Login
137
- - [x] Get Quotes
138
- - [x] Get Account Data
139
- - [x] Place Orders and Receive order confirmation
140
- - [x] Get Currently Held Positions
141
-
142
- ## TO DO
143
-
144
- - [ ] Check on placed order status.
145
- - [ ] Cancel placed orders
146
- - [ ] Options
147
- - [ ] Give me some Ideas!
148
-
149
- [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/O5O6PTOYG)
@@ -1,10 +0,0 @@
1
- firstrade/__init__.py,sha256=fNiWYgSTjElY1MNv0Ug-sVLMTR2z_Ngri_FY7Pekdrw,95
2
- firstrade/account.py,sha256=xDgTMXDy2UWUNi4kboXAKKBrbmZGpXLJ11MCHlMvzB0,9218
3
- firstrade/order.py,sha256=S9fg_pfYN_sDOerzxcoeC6Gyp4IXttHgnEZw4aD1l60,5205
4
- firstrade/symbols.py,sha256=m5v1QeY2crtNw7mymoV6wpD_J_M-avWK5Lz9DUZJpNE,2315
5
- firstrade/urls.py,sha256=nAKbOw30cediYI6JDaGc4gL7-m-7WKP3A--BEVrL_cI,1167
6
- firstrade-0.0.15.dist-info/LICENSE,sha256=wPEQjDqm5zMBmEcZp219Labmq_YIjhudpZiUzyVKaFA,1057
7
- firstrade-0.0.15.dist-info/METADATA,sha256=cGG02YGpwixRWyn-11IVie30zN5ScPDPHJu2JyAs0Lw,4312
8
- firstrade-0.0.15.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
9
- firstrade-0.0.15.dist-info/top_level.txt,sha256=tdA8v-KDxU1u4VV6soiNWGBlni4ojv_t_j2wFn5nZcs,10
10
- firstrade-0.0.15.dist-info/RECORD,,