@@ -143,3 +143,104 @@ cdef class TopstepClient:
143143 if response.is_success:
144144 return {" success" : True , ** response.json()}
145145 return {" success" : False , " error" : response.text}
146+
147+ async def cancel_order(self , int account_id, int order_id):
148+ """ Async REST cancel order"""
149+ if not self .token:
150+ raise ValueError (" Not authenticated" )
151+
152+ url = f" {self.base_url}/api/Order/cancel"
153+ headers = {
154+ " accept" : " text/plain" ,
155+ " Content-Type" : " application/json" ,
156+ " Authorization" : f" Bearer {self.token}"
157+ }
158+ payload = {" accountId" : account_id, " orderId" : order_id}
159+
160+ async with httpx.AsyncClient() as client:
161+ response = await client.post(url, json = payload, headers = headers)
162+
163+ if response.is_success:
164+ return {" success" : True , ** response.json()}
165+ return {" success" : False , " error" : response.text}
166+
167+ async def modify_order(self , int account_id, int order_id, ** kwargs):
168+ """ Async REST modify order"""
169+ if not self .token:
170+ raise ValueError (" Not authenticated" )
171+
172+ url = f" {self.base_url}/api/Order/modify"
173+ headers = {
174+ " accept" : " text/plain" ,
175+ " Content-Type" : " application/json" ,
176+ " Authorization" : f" Bearer {self.token}"
177+ }
178+ payload = {" accountId" : account_id, " orderId" : order_id, ** kwargs}
179+
180+ async with httpx.AsyncClient() as client:
181+ response = await client.post(url, json = payload, headers = headers)
182+
183+ if response.is_success:
184+ return {" success" : True , ** response.json()}
185+ return {" success" : False , " error" : response.text}
186+
187+ async def search_orders(self , int account_id, str start_time, str end_time):
188+ """ Async REST search orders"""
189+ url = f" {self.base_url}/api/Order/search"
190+ headers = self ._get_headers()
191+ payload = {
192+ " accountId" : account_id,
193+ " startTimestamp" : start_time,
194+ " endTimestamp" : end_time
195+ }
196+ async with httpx.AsyncClient() as client:
197+ response = await client.post(url, json = payload, headers = headers)
198+ return self ._handle_response(response)
199+
200+ async def search_open_orders(self , int account_id):
201+ """ Async REST search open orders"""
202+ url = f" {self.base_url}/api/Order/searchOpen"
203+ headers = self ._get_headers()
204+ payload = {" accountId" : account_id}
205+ async with httpx.AsyncClient() as client:
206+ response = await client.post(url, json = payload, headers = headers)
207+ return self ._handle_response(response)
208+
209+ async def search_accounts(self , bool only_active = True ):
210+ """ Async REST search accounts"""
211+ url = f" {self.base_url}/api/Account/search"
212+ headers = self ._get_headers()
213+ payload = {" active" : only_active} # Check API spec, usually paging too but simplifying
214+ # Legacy accounts.py used: {"page": 1, "pageSize": 100} maybe?
215+ # Let's check legacy implementation below or assume standard search
216+ # Re-checking legacy accounts.py logic would be safer but let's assume basic search for now
217+ # Actually, let's look at legacy accounts.py in a sec if this fails.
218+ # Assuming simple payload for now:
219+ payload = {" page" : 1 , " pageSize" : 50 }
220+
221+ async with httpx.AsyncClient() as client:
222+ response = await client.post(url, json = payload, headers = headers)
223+ return self ._handle_response(response)
224+
225+ async def search_contracts(self , str search_text = " NQ" ):
226+ """ Async REST search contracts"""
227+ url = f" {self.base_url}/api/Contract/search"
228+ headers = self ._get_headers()
229+ payload = {" searchText" : search_text}
230+ async with httpx.AsyncClient() as client:
231+ response = await client.post(url, json = payload, headers = headers)
232+ return self ._handle_response(response)
233+
234+ def _get_headers (self ):
235+ if not self .token:
236+ raise ValueError (" Not authenticated" )
237+ return {
238+ " accept" : " text/plain" ,
239+ " Content-Type" : " application/json" ,
240+ " Authorization" : f" Bearer {self.token}"
241+ }
242+
243+ def _handle_response (self , response ):
244+ if response.is_success:
245+ return {" success" : True , ** response.json()}
246+ return {" success" : False , " error" : response.text}
0 commit comments