Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit aa214f1

Browse files
add WebSocket trading example
1 parent 4585ec5 commit aa214f1

File tree

2 files changed

+238
-105
lines changed

2 files changed

+238
-105
lines changed

‎Alpaca_trading_example.py

Lines changed: 130 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import alpaca_trade_api as tradeapi
2-
import threading
3-
from time import *
41
import json
52
import logging
3+
import threading
4+
from time import *
65

7-
#init
8-
logging.basicConfig(filename='errlog.log',level=logging.WARNING, format='%(asctime)s:%(levelname)s:%(message)s')
6+
import alpaca_trade_api as tradeapi
7+
8+
# init
9+
logging.basicConfig(
10+
filename='errlog.log',
11+
level=logging.WARNING,
12+
format='%(asctime)s:%(levelname)s:%(message)s',
13+
)
914

1015
api_key = 'insert_api_key'
1116
api_secret = 'insert_api_secret'
@@ -23,132 +28,152 @@
2328
active_trade = False
2429
done_for_the_day = False
2530

26-
#check if market is open
31+
#check if market is open
2732
api.cancel_all_orders()
2833
clock = api.get_clock()
2934

3035
if clock.is_open:
31-
pass
36+
pass
3237
else:
33-
time_to_open = clock.next_open - clock.timestamp
34-
sleep(time_to_open.total_seconds())
38+
time_to_open = clock.next_open - clock.timestamp
39+
sleep(time_to_open.total_seconds())
3540

3641
if len(api.list_positions()) == 0:
37-
searching_for_trade = True
42+
searching_for_trade = True
3843
else:
39-
active_trade = True
44+
active_trade = True
4045

41-
#init WebSocket
46+
#init WebSocket
4247
conn = tradeapi.stream2.StreamConn(api_key, api_secret, base_url)
4348

49+
4450
@conn.on(r'^account_updates$')
4551
async def on_account_updates(conn, channel, account):
46-
order_msg.append(account)
52+
order_msg.append(account)
53+
4754

4855
@conn.on(r'^trade_updates$')
4956
async def on_trade_updates(conn, channel, trade):
50-
trade_msg.append(trade)
51-
if 'fill' in trade.event:
52-
past_trades.append([trade.order['updated_at'], trade.order['symbol'], trade.order['side'],
53-
trade.order['filled_qty'], trade.order['filled_avg_price']])
54-
with open('past_trades.csv', 'w') as f:
55-
json.dump(past_trades, f, indent=4)
56-
print(past_trades[-1])
57+
trade_msg.append(trade)
58+
if 'fill' in trade.event:
59+
past_trades.append(
60+
[
61+
trade.order['updated_at'],
62+
trade.order['symbol'],
63+
trade.order['side'],
64+
trade.order['filled_qty'],
65+
trade.order['filled_avg_price'],
66+
]
67+
)
68+
with open('past_trades.csv', 'w') as f:
69+
json.dump(past_trades, f, indent=4)
70+
print(past_trades[-1])
71+
5772

5873
def ws_start():
59-
conn.run(['account_updates', 'trade_updates'])
74+
conn.run(['account_updates', 'trade_updates'])
75+
6076

61-
#start WebSocket in a thread
77+
#start WebSocket in a thread
6278
ws_thread = threading.Thread(target=ws_start, daemon=True)
6379
ws_thread.start()
6480
sleep(10)
6581

6682

67-
#functions
83+
#functions
6884
def time_to_market_close():
69-
clock = api.get_clock()
70-
closing = clock.next_close - clock.timestamp
71-
return round(closing.seconds/60)
72-
73-
def send_order(direction):
74-
if time_to_market_close() > 20:
75-
if direction == 'buy':
76-
sl = high-range_size
77-
tp = high+range_size
78-
elif direction == 'sell':
79-
sl = low+range_size
80-
tp = low-range_size
85+
clock = api.get_clock()
86+
closing = clock.next_close - clock.timestamp
87+
return round(closing.total_seconds() / 60)
8188

82-
api.submit_order(symbol='AAPL', qty=100, side=direction, type='market', time_in_force='day', order_class='bracket', stop_loss=dict(stop_price=str(sl)), take_profit=dict(limit_price=str(tp)))
83-
return True, False
8489

85-
else:
86-
return False, True
87-
88-
89-
#main loop
90+
def send_order(direction):
91+
if time_to_market_close() > 20:
92+
if direction == 'buy':
93+
sl = high - range_size
94+
tp = high + range_size
95+
elif direction == 'sell':
96+
sl = low + range_size
97+
tp = low - range_size
98+
99+
api.submit_order(
100+
symbol='AAPL',
101+
qty=100,
102+
side=direction,
103+
type='market',
104+
time_in_force='day',
105+
order_class='bracket',
106+
stop_loss=dict(stop_price=str(sl)),
107+
take_profit=dict(limit_price=str(tp)),
108+
)
109+
return True, False
110+
111+
else:
112+
return False, True
113+
114+
115+
# main loop
90116
while True:
91117

92-
try:
93-
94-
candlesticks = api.get_barset('AAPL', 'minute', limit=10)
95-
high = candlesticks['AAPL'][0].h
96-
low = candlesticks['AAPL'][0].l
97-
range_size = high - low
98-
if range_size / candlesticks['AAPL'][0].c < 0.003:
99-
range_size = candlesticks['AAPL'][0].c * 0.003
100-
for candle in candlesticks['AAPL']:
101-
if candle.h > high:
102-
high = candle.h
103-
elif candle.l < low:
104-
low = candle.l
105-
range_size = high - low
106-
107-
while searching_for_trade:
108-
clock = api.get_clock()
109-
sleep(60-clock.timestamp.second)
110-
candlesticks = api.get_barset('AAPL', 'minute', limit=1)
111-
if candlesticks['AAPL'][0].c > high:
112-
searching_for_trade = False
113-
order_sent, done_for_the_day = send_order('buy')
114-
115-
elif candlesticks['AAPL'][0].c < low:
116-
searching_for_trade = False
117-
order_sent, done_for_the_day = send_order('sell')
118-
119-
while order_sent:
120-
sleep(1)
121-
for item in trade_msg:
122-
if item.event == 'new':
123-
order_submitted = True
124-
order_sent = False
125-
126-
while order_submitted:
127-
sleep(1)
128-
for item in trade_msg:
129-
if item.order['filled_qty'] == '100':
130-
order_submitted = False
131-
active_trade = True
132-
trade_msg = []
133-
134-
135-
while active_trade:
136-
for i in range(time_to_market_close()-5):
137-
sleep(60)
138-
if len(api.list_positions()) == 0:
139-
active_trade = False
140-
searching_for_trade = True
141-
break
142-
if active_trade:
143-
done_for_the_day = True
144-
active_trade = False
145-
146-
while done_for_the_day:
147-
api.close_all_positions()
148-
clock = api.get_clock()
149-
next_market_open = clock.next_open - clock.timestamp
150-
sleep(next_market_open.total_seconds())
151-
searching_for_trade = True
152-
153-
except Exception as e:
154-
logging.exception(e)
118+
try:
119+
120+
candlesticks = api.get_barset('AAPL', 'minute', limit=10)
121+
high = candlesticks['AAPL'][0].h
122+
low = candlesticks['AAPL'][0].l
123+
range_size = high - low
124+
if range_size / candlesticks['AAPL'][0].c < 0.003:
125+
range_size = candlesticks['AAPL'][0].c * 0.003
126+
for candle in candlesticks['AAPL']:
127+
if candle.h > high:
128+
high = candle.h
129+
elif candle.l < low:
130+
low = candle.l
131+
range_size = high - low
132+
133+
while searching_for_trade:
134+
clock = api.get_clock()
135+
sleep(60 - clock.timestamp.second)
136+
candlesticks = api.get_barset('AAPL', 'minute', limit=1)
137+
if candlesticks['AAPL'][0].c > high:
138+
searching_for_trade = False
139+
order_sent, done_for_the_day = send_order('buy')
140+
141+
elif candlesticks['AAPL'][0].c < low:
142+
searching_for_trade = False
143+
order_sent, done_for_the_day = send_order('sell')
144+
145+
while order_sent:
146+
sleep(1)
147+
for item in trade_msg:
148+
if item.event == 'new':
149+
order_submitted = True
150+
order_sent = False
151+
152+
while order_submitted:
153+
sleep(1)
154+
for item in trade_msg:
155+
if item.order['filled_qty'] == '100':
156+
order_submitted = False
157+
active_trade = True
158+
trade_msg = []
159+
160+
while active_trade:
161+
for i in range(time_to_market_close() - 5):
162+
sleep(60)
163+
if len(api.list_positions()) == 0:
164+
active_trade = False
165+
searching_for_trade = True
166+
break
167+
if active_trade:
168+
done_for_the_day = True
169+
active_trade = False
170+
171+
while done_for_the_day:
172+
api.close_all_positions()
173+
clock = api.get_clock()
174+
next_market_open = clock.next_open - clock.timestamp
175+
sleep(next_market_open.total_seconds())
176+
searching_for_trade = True
177+
178+
except Exception as e:
179+
logging.exception(e)

‎Alpaca_trading_example_ws.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import logging
2+
from time import sleep
3+
4+
import alpaca_trade_api as tradeapi
5+
import pandas as pd
6+
7+
# init
8+
logging.basicConfig(
9+
filename='errlog.log',
10+
level=logging.WARNING,
11+
format='%(asctime)s:%(levelname)s:%(message)s',
12+
)
13+
14+
api_key = 'insert_api_key'
15+
api_secret = 'insert_api_secret'
16+
base_url = 'https://paper-api.alpaca.markets'
17+
data_url = 'wss://data.alpaca.markets'
18+
19+
20+
# instantiate REST API
21+
api = tradeapi.REST(api_key, api_secret, base_url, api_version='v2')
22+
23+
# init WebSocket
24+
conn = tradeapi.stream2.StreamConn(
25+
api_key,
26+
api_secret,
27+
base_url=base_url,
28+
data_url=data_url,
29+
data_stream='alpacadatav1',
30+
)
31+
32+
33+
def time_to_market_close():
34+
clock = api.get_clock()
35+
return (clock.next_close - clock.timestamp).total_seconds()
36+
37+
38+
def wait_for_market_open():
39+
clock = api.get_clock()
40+
if not clock.is_open:
41+
time_to_open = (clock.next_open - clock.timestamp).total_seconds()
42+
sleep(round(time_to_open))
43+
44+
45+
def set_trade_params(df):
46+
return {
47+
'high': df.high.tail(10).max(),
48+
'low': df.low.tail(10).min(),
49+
'trade_taken': False,
50+
}
51+
52+
53+
def send_order(direction, bar):
54+
if time_to_market_close() > 120:
55+
print(f'sent {direction} trade')
56+
range_size = trade_params['high'] - trade_params['low']
57+
58+
if direction == 'buy':
59+
sl = bar.high - range_size
60+
tp = bar.high + range_size
61+
elif direction == 'sell':
62+
sl = bar.low + range_size
63+
tp = bar.low - range_size
64+
65+
api.submit_order(
66+
symbol='AAPL',
67+
qty=100,
68+
side=direction,
69+
type='market',
70+
time_in_force='day',
71+
order_class='bracket',
72+
stop_loss=dict(stop_price=str(sl)),
73+
take_profit=dict(limit_price=str(tp)),
74+
)
75+
76+
return True
77+
78+
wait_for_market_open()
79+
return False
80+
81+
82+
@conn.on(r'^AM.AAPL$')
83+
async def on_minute_bars(conn, channel, bar):
84+
if isinstance(candlesticks.df, pd.DataFrame):
85+
ts = pd.to_datetime(bar.timestamp, unit='ms')
86+
candlesticks.df.loc[ts] = [bar.open, bar.high, bar.low, bar.close, bar.volume]
87+
88+
if not trade_params['trade_taken']:
89+
if bar.high > trade_params['high']:
90+
trade_params['trade_taken'] = send_order('buy', bar)
91+
92+
elif bar.low < trade_params['low']:
93+
trade_params['trade_taken'] = send_order('sell', bar)
94+
95+
if time_to_market_close() > 120:
96+
wait_for_market_open()
97+
98+
99+
@conn.on(r'^trade_updates$')
100+
async def on_trade_updates(conn, channel, trade):
101+
if trade.order['order_type'] != 'market' and trade.order['filled_qty'] == '100':
102+
# trade closed - look for new trade
103+
trade_params = set_trade_params(candlesticks.df.AAPL)
104+
105+
106+
candlesticks = api.get_barset('AAPL', 'minute', limit=10)
107+
trade_params = set_trade_params(candlesticks.df.AAPL)
108+
conn.run(['AM.AAPL', 'trade_updates'])

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /