Skip to content

Commit 4bb9bac

Browse files
authored
Merge pull request #11 from Patch-Code-Prosperity/dev
Dev
2 parents c1951e0 + d25eec8 commit 4bb9bac

File tree

3 files changed

+152
-2
lines changed

3 files changed

+152
-2
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ __pycache__/
33
.env
44
token_data.json
55
custom/*
6-
tmp/*
6+
tmp/*

algo_example_script.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
"""
2+
This is an example of how to use various functions/methods/classes in the repo.
3+
This is beyond not financial advice.
4+
This is for demonstration purposes only.
5+
Please do not ping me if you hook this chat-gpt-looking code up to a real brokerage account and just letterrip.
6+
"""
7+
8+
import json
9+
from datetime import datetime, timedelta
10+
import pandas as pd
11+
import urllib.parse as urll
12+
from accounts import Accounts
13+
from api_client import APIClient
14+
from orders import Orders
15+
from market_data import Quotes
16+
from tqdm import tqdm
17+
18+
19+
def actually_do_some_trading(orders_api, account_hash, valid_quotes):
20+
traded_tickers = []
21+
# Process valid trades
22+
for ticker, row in tqdm(valid_quotes.iterrows(), total=valid_quotes.shape[0], desc="Processing trades"):
23+
bid_price = row['bidPrice']
24+
ask_price = row['askPrice']
25+
last_price = row['lastPrice']
26+
print(f"{ticker}")
27+
print(f"Bid price: {bid_price} | Ask price: {ask_price} | Last price: {last_price}")
28+
29+
try:
30+
response = orders_api.place_order(account_hash=account_hash,
31+
symbol=ticker,
32+
side='BUY',
33+
quantity=6,
34+
order_type='LIMIT',
35+
limit_price=bid_price + 0.01,
36+
time_in_force='DAY')
37+
print(f"Order response: {response}")
38+
# write order number, ticker to algo_trades.json
39+
try:
40+
with open(f"algo_trades_{orders_api.client.config.initials}.json", "r") as f:
41+
data = json.load(f)
42+
except FileNotFoundError:
43+
data = []
44+
data.append({"ticker": ticker, "order_number": response['order_number']})
45+
with open(f"algo_trades_{orders_api.client.config.initials}.json", "w") as f:
46+
json.dump(data, f)
47+
traded_tickers.append(ticker)
48+
except Exception as e:
49+
print(f"Error placing order: {e}")
50+
return traded_tickers
51+
52+
53+
def find_trades_from_quotes(orders_api, quotes, account_hash):
54+
# Convert quotes to DataFrame
55+
quotes_df = pd.DataFrame.from_dict(quotes, orient='index')
56+
quotes_df.index = quotes_df.index.map(urll.unquote)
57+
58+
# Extract relevant quote data
59+
quotes_df = quotes_df['quote'].apply(pd.Series)
60+
61+
# Filter out quotes with missing data
62+
quotes_df = quotes_df.dropna(subset=['askPrice', 'askSize', 'bidPrice', 'bidSize', 'lastPrice'])
63+
64+
# Apply trading logic
65+
valid_quotes = quotes_df[
66+
(quotes_df['lastPrice'] >= 0.005) &
67+
(quotes_df['lastPrice'] <= 0.515) &
68+
((quotes_df['askPrice'] - quotes_df['bidPrice']) >= 0.06) &
69+
(quotes_df['regular']['regularMarketLastPrice'] / (quotes_df['askPrice'] - quotes_df['bidPrice']) <= 10) &
70+
(quotes_df['askSize'] <= 100) &
71+
(quotes_df['bidSize'] <= 100) &
72+
((quotes_df['lastPrice'] - quotes_df['bidPrice']) >= 0) &
73+
((quotes_df['lastPrice'] - quotes_df['askPrice']) >= 0) &
74+
((quotes_df['lastPrice'] - quotes_df['bidPrice']) <= 0.7 * (quotes_df['askPrice'] - quotes_df['bidPrice'])) &
75+
((quotes_df['lastPrice'] - quotes_df['askPrice']) <= 0.7 * (quotes_df['askPrice'] - quotes_df['bidPrice']))
76+
]
77+
return valid_quotes
78+
79+
80+
def sell_the_algo_buys(orders_api, account_hash, quotes_api):
81+
# Check order statuses and handle new trades
82+
try:
83+
with open(f"algo_trades_{orders_api.client.config.initials}.json", "r") as f:
84+
data = json.load(f)
85+
except FileNotFoundError:
86+
data = []
87+
data_tickers = [trade['ticker'] for trade in data]
88+
data_quotes = quotes_api.get_list(data_tickers)
89+
all_orders = orders_api.get_orders(account_hash=account_hash,
90+
maxResults=3000,
91+
fromEnteredTime=(datetime.now() - timedelta(days=360)).isoformat(timespec='seconds'),
92+
toEnteredTime=datetime.now().isoformat(timespec='seconds'))
93+
for trade in data:
94+
try:
95+
response = all_orders.get(trade['order_number'])
96+
print(f"Order status for {trade['ticker']}: {response['status']}")
97+
bought_price = response['price']
98+
if response['status'] in ['FILLED', 'PARTIAL']:
99+
new_quote = data_quotes.get(trade['ticker'])
100+
new_quote_data = new_quote.get("quote")
101+
if new_quote_data:
102+
ask_price = new_quote_data.get('askPrice')
103+
if ask_price and bought_price <= ask_price - 0.03:
104+
response = orders_api.place_order(account_hash=account_hash,
105+
symbol=trade['ticker'],
106+
side='SELL',
107+
quantity=1,
108+
order_type='LIMIT',
109+
limit_price=ask_price - 0.01,
110+
time_in_force='DAY')
111+
print(f"Order response: {response}")
112+
print(f"Order response: {response}")
113+
except Exception as e:
114+
print(f"Error checking order status: {e}")
115+
116+
117+
def check_cash_account(account_api, account_hash):
118+
account = account_api.get_account(account_hash=account_hash, fields="positions")
119+
print(account)
120+
cash_account = account['cash']
121+
return cash_account
122+
123+
124+
def main():
125+
# Initialize client
126+
client = APIClient(initials="your_initials_here")
127+
accounts_api = Accounts(client)
128+
orders_api = Orders(client)
129+
quotes_api = Quotes(client)
130+
131+
# Get account hash
132+
sample_account = client.account_numbers[0]
133+
account_hash = sample_account['hashValue']
134+
135+
# Check cash account
136+
if not check_cash_account(accounts_api, account_hash):
137+
print("Confirm pattern day trader status or using a cash account.")
138+
return
139+
140+
# Get quotes
141+
quotes = quotes_api.get_list(["AAPL", "AMD", "TSLA", "MSFT", "GOOGL", "AMZN", "NFLX", "NVDA", "INTC", "CSCO"])
142+
"""
143+
If you are wondering how to get a list of tickers that meet some given criteria, check out the get_finviz repo
144+
"""
145+
146+
# Find trades
147+
find_trades_from_quotes(orders_api, quotes, account_hash)
148+
149+
# Sell trades
150+
sell_the_algo_buys(orders_api, account_hash, quotes_api)

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
requests>=2.25.1
22
python-dotenv>=0.19.1
3-
websockets>=10.3
3+
websockets>=10.3

0 commit comments

Comments
 (0)