-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.py
More file actions
99 lines (80 loc) · 3.72 KB
/
Copy pathexample.py
File metadata and controls
99 lines (80 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"""Read-only tour of a real DXtrade account: balance, positions, orders, live quotes.
pip install -e ".[examples]"
cp .env.example .env # fill in your broker URL and credentials
python example.py
It places no orders. Pass --demo-order to place (and immediately cancel) one far
from the market; use a DEMO account for that. This client follows the public
DXtrade spec but has not been verified against a live broker.
No broker account? Run examples/offline_demo.py instead.
"""
import logging
import os
import queue
import sys
import time
from dotenv import load_dotenv
from dxtrade_wrapper import DXTradeClient, DXTradeWrapperError
load_dotenv()
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
log = logging.getLogger("example")
SYMBOLS = os.getenv("DXTRADE_SYMBOLS", "EUR/USD,GBP/USD").split(",")
def main() -> int:
base_url = os.getenv("DXTRADE_BASE_URL", "")
if not base_url.startswith("https://") or not os.getenv("DXTRADE_USERNAME"):
log.error("Set DXTRADE_BASE_URL (https://...), DXTRADE_USERNAME and DXTRADE_PASSWORD "
"in .env (see .env.example).")
return 2
client = DXTradeClient(
base_url=base_url,
username=os.environ["DXTRADE_USERNAME"],
password=os.getenv("DXTRADE_PASSWORD", ""),
domain_or_vendor=os.getenv("DXTRADE_DOMAIN_VENDOR", "default"),
api_prefix=os.getenv("DXTRADE_API_PREFIX", "/dxsca-web"),
# Still honoured so .env files written for 0.1 keep working.
login_path=os.getenv("DXTRADE_LOGIN_PATH", "/login"),
websocket_path=os.getenv("DXTRADE_WEBSOCKET_PATH", "/websocket"),
account=os.getenv("DXTRADE_ACCOUNT") or None,
websocket_url=os.getenv("DXTRADE_WEBSOCKET_URL") or None,
)
try:
with client:
log.info("Accounts: %s", client.get_accounts())
log.info("Balance: %s", client.get_balance())
for position in client.get_positions():
log.info("Position: %s", position)
for order in client.get_orders():
log.info("Working order: %s", order)
if "--demo-order" in sys.argv:
demo_order(client)
if os.getenv("DXTRADE_WEBSOCKET_URL") or os.getenv("DXTRADE_WEBSOCKET_PATH"):
stream_quotes(client, seconds=15)
else:
log.info("Set DXTRADE_WEBSOCKET_URL (ask your broker) to stream quotes.")
except DXTradeWrapperError as exc:
log.error("%s: %s", type(exc).__name__, exc)
return 1
return 0
def demo_order(client: DXTradeClient) -> None:
"""A tiny LIMIT buy at DXTRADE_DEMO_PRICE (default 0.5, far below market), then cancelled."""
symbol = SYMBOLS[0]
price = float(os.getenv("DXTRADE_DEMO_PRICE", "0.5"))
code = client._generate_order_code()
log.info("Placing demo LIMIT BUY %s @ %s (orderCode %s)", symbol, price, code)
log.info("Response: %s", client.place_order(symbol, "BUY", 1000, "LIMIT", price=price,
orderCode=code))
log.info("Cancel: %s", client.cancel_order(code))
def stream_quotes(client: DXTradeClient, seconds: int) -> None:
client.connect_websocket()
client.subscribe_market_data(SYMBOLS)
client.subscribe_account_updates()
deadline = time.monotonic() + seconds
while time.monotonic() < deadline:
for name, q in (("quote", client.price_update_queue),
("order", client.order_update_queue),
("account", client.account_update_queue)):
try:
log.info("%s: %s", name, q.get(timeout=0.2))
except queue.Empty:
pass
if __name__ == "__main__":
sys.exit(main())