wiz-trader 0.1.0__tar.gz → 0.3.0__tar.gz
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.
- wiz_trader-0.3.0/MANIFEST.in +7 -0
- wiz_trader-0.3.0/PKG-INFO +165 -0
- wiz_trader-0.3.0/README.md +138 -0
- wiz_trader-0.3.0/pyproject.toml +39 -0
- {wiz_trader-0.1.0 → wiz_trader-0.3.0}/setup.py +2 -1
- wiz_trader-0.3.0/src/wiz_trader/__init__.py +8 -0
- wiz_trader-0.3.0/src/wiz_trader/apis/__init__.py +6 -0
- wiz_trader-0.3.0/src/wiz_trader/apis/client.py +169 -0
- wiz_trader-0.3.0/src/wiz_trader/quotes/__init__.py +5 -0
- {wiz_trader-0.1.0/ticker → wiz_trader-0.3.0/src/wiz_trader/quotes}/client.py +3 -6
- wiz_trader-0.3.0/src/wiz_trader.egg-info/PKG-INFO +165 -0
- wiz_trader-0.3.0/src/wiz_trader.egg-info/SOURCES.txt +16 -0
- wiz_trader-0.3.0/src/wiz_trader.egg-info/requires.txt +2 -0
- wiz_trader-0.3.0/src/wiz_trader.egg-info/top_level.txt +1 -0
- wiz_trader-0.1.0/MANIFEST.in +0 -1
- wiz_trader-0.1.0/PKG-INFO +0 -43
- wiz_trader-0.1.0/README.md +0 -14
- wiz_trader-0.1.0/apis/__init__.py +0 -3
- wiz_trader-0.1.0/apis/client.py +0 -2
- wiz_trader-0.1.0/pyproject.toml +0 -3
- wiz_trader-0.1.0/ticker/__init__.py +0 -5
- wiz_trader-0.1.0/wiz_trader.egg-info/PKG-INFO +0 -43
- wiz_trader-0.1.0/wiz_trader.egg-info/SOURCES.txt +0 -15
- wiz_trader-0.1.0/wiz_trader.egg-info/requires.txt +0 -2
- wiz_trader-0.1.0/wiz_trader.egg-info/top_level.txt +0 -2
- {wiz_trader-0.1.0 → wiz_trader-0.3.0}/setup.cfg +0 -0
- {wiz_trader-0.1.0 → wiz_trader-0.3.0/src}/wiz_trader.egg-info/dependency_links.txt +0 -0
- {wiz_trader-0.1.0 → wiz_trader-0.3.0}/tests/test_apis.py +0 -0
- {wiz_trader-0.1.0 → wiz_trader-0.3.0}/tests/test_quotes.py +0 -0
@@ -0,0 +1,165 @@
|
|
1
|
+
Metadata-Version: 2.2
|
2
|
+
Name: wiz_trader
|
3
|
+
Version: 0.3.0
|
4
|
+
Summary: A Python SDK for connecting to the Wizzer.
|
5
|
+
Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
6
|
+
Author: Pawan Wagh
|
7
|
+
Author-email: Pawan Wagh <pawan@wizzer.in>
|
8
|
+
License: MIT
|
9
|
+
Project-URL: Homepage, https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
10
|
+
Project-URL: Bug Tracker, https://bitbucket.org/wizzer-tech/quotes_sdk/issues
|
11
|
+
Keywords: finance,trading,sdk
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
14
|
+
Classifier: Intended Audience :: Developers
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
16
|
+
Classifier: Operating System :: OS Independent
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
18
|
+
Classifier: Topic :: Office/Business :: Financial
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
20
|
+
Requires-Python: >=3.6
|
21
|
+
Description-Content-Type: text/markdown
|
22
|
+
Requires-Dist: websockets
|
23
|
+
Requires-Dist: requests
|
24
|
+
Dynamic: author
|
25
|
+
Dynamic: home-page
|
26
|
+
Dynamic: requires-python
|
27
|
+
|
28
|
+
# WizTrader SDK
|
29
|
+
|
30
|
+
A Python SDK for connecting to the Wizzer trading platform.
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
You can install the package directly from PyPI:
|
35
|
+
|
36
|
+
```bash
|
37
|
+
pip install wiz_trader
|
38
|
+
```
|
39
|
+
|
40
|
+
## Features
|
41
|
+
|
42
|
+
- Real-time market data through WebSocket connection
|
43
|
+
- REST API for accessing market data and indices
|
44
|
+
- Automatic WebSocket reconnection with exponential backoff
|
45
|
+
- Subscribe/unsubscribe to instruments
|
46
|
+
- Customizable logging levels
|
47
|
+
|
48
|
+
## Quick Start - Quotes Client
|
49
|
+
|
50
|
+
```python
|
51
|
+
import asyncio
|
52
|
+
from wiz_trader import QuotesClient
|
53
|
+
|
54
|
+
# Callback function to process market data
|
55
|
+
def process_tick(data):
|
56
|
+
print(f"Received tick: {data}")
|
57
|
+
|
58
|
+
async def main():
|
59
|
+
# Initialize client with direct parameters
|
60
|
+
client = QuotesClient(
|
61
|
+
base_url="wss://websocket-url/quotes",
|
62
|
+
token="your-jwt-token",
|
63
|
+
log_level="info" # Options: "error", "info", "debug"
|
64
|
+
)
|
65
|
+
|
66
|
+
# Set callback
|
67
|
+
client.on_tick = process_tick
|
68
|
+
|
69
|
+
# Connect in the background
|
70
|
+
connection_task = asyncio.create_task(client.connect())
|
71
|
+
|
72
|
+
# Subscribe to instruments
|
73
|
+
await client.subscribe(["NSE:SBIN:3045"])
|
74
|
+
|
75
|
+
# Keep the connection running
|
76
|
+
try:
|
77
|
+
await asyncio.sleep(3600) # Run for 1 hour
|
78
|
+
except KeyboardInterrupt:
|
79
|
+
# Unsubscribe and close
|
80
|
+
await client.unsubscribe(["NSE:SBIN:3045"])
|
81
|
+
await client.close()
|
82
|
+
|
83
|
+
await connection_task
|
84
|
+
|
85
|
+
if __name__ == "__main__":
|
86
|
+
asyncio.run(main())
|
87
|
+
```
|
88
|
+
|
89
|
+
## Quick Start - DataHub Client
|
90
|
+
|
91
|
+
```python
|
92
|
+
from wiz_trader import WizzerClient
|
93
|
+
|
94
|
+
# Initialize client
|
95
|
+
client = WizzerClient(
|
96
|
+
base_url="https://api-url.in",
|
97
|
+
token="your-jwt-token",
|
98
|
+
log_level="info" # Options: "error", "info", "debug"
|
99
|
+
)
|
100
|
+
|
101
|
+
# Get list of indices
|
102
|
+
indices = client.get_indices(exchange="NSE")
|
103
|
+
print(indices)
|
104
|
+
|
105
|
+
# Get index components
|
106
|
+
components = client.get_index_components(
|
107
|
+
trading_symbol="NIFTY 50",
|
108
|
+
exchange="NSE"
|
109
|
+
)
|
110
|
+
print(components)
|
111
|
+
|
112
|
+
# Get historical OHLCV data
|
113
|
+
historical_data = client.get_historical_ohlcv(
|
114
|
+
instruments=["NSE:SBIN:3045"],
|
115
|
+
start_date="2024-01-01",
|
116
|
+
end_date="2024-01-31",
|
117
|
+
ohlcv=["open", "high", "low", "close", "volume"]
|
118
|
+
)
|
119
|
+
print(historical_data)
|
120
|
+
```
|
121
|
+
|
122
|
+
## Configuration
|
123
|
+
|
124
|
+
You can configure the clients in two ways:
|
125
|
+
|
126
|
+
1. **Direct parameter passing** (recommended):
|
127
|
+
```python
|
128
|
+
quotes_client = QuotesClient(
|
129
|
+
base_url="wss://websocket-url/quotes",
|
130
|
+
token="your-jwt-token",
|
131
|
+
log_level="info"
|
132
|
+
)
|
133
|
+
|
134
|
+
wizzer_client = WizzerClient(
|
135
|
+
base_url="https://api-url.in",
|
136
|
+
token="your-jwt-token",
|
137
|
+
log_level="info"
|
138
|
+
)
|
139
|
+
```
|
140
|
+
|
141
|
+
2. **System environment variables**:
|
142
|
+
- `WZ__QUOTES_BASE_URL`: WebSocket URL for the quotes server
|
143
|
+
- `WZ__API_BASE_URL`: Base URL for the Wizzer's REST API
|
144
|
+
- `WZ__TOKEN`: JWT token for authentication
|
145
|
+
|
146
|
+
```python
|
147
|
+
# The clients will automatically use the environment variables if parameters are not provided
|
148
|
+
quotes_client = QuotesClient(log_level="info")
|
149
|
+
wizzer_client = WizzerClient(log_level="info")
|
150
|
+
```
|
151
|
+
|
152
|
+
## Advanced Usage
|
153
|
+
|
154
|
+
Check the `examples/` directory for more detailed examples:
|
155
|
+
|
156
|
+
- `example_manual.py`: Demonstrates direct configuration with parameters
|
157
|
+
- `example_wizzer.py`: Demonstrates usage of the Wizzer client
|
158
|
+
|
159
|
+
## License
|
160
|
+
|
161
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
162
|
+
|
163
|
+
## Contributing
|
164
|
+
|
165
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# WizTrader SDK
|
2
|
+
|
3
|
+
A Python SDK for connecting to the Wizzer trading platform.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
You can install the package directly from PyPI:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
pip install wiz_trader
|
11
|
+
```
|
12
|
+
|
13
|
+
## Features
|
14
|
+
|
15
|
+
- Real-time market data through WebSocket connection
|
16
|
+
- REST API for accessing market data and indices
|
17
|
+
- Automatic WebSocket reconnection with exponential backoff
|
18
|
+
- Subscribe/unsubscribe to instruments
|
19
|
+
- Customizable logging levels
|
20
|
+
|
21
|
+
## Quick Start - Quotes Client
|
22
|
+
|
23
|
+
```python
|
24
|
+
import asyncio
|
25
|
+
from wiz_trader import QuotesClient
|
26
|
+
|
27
|
+
# Callback function to process market data
|
28
|
+
def process_tick(data):
|
29
|
+
print(f"Received tick: {data}")
|
30
|
+
|
31
|
+
async def main():
|
32
|
+
# Initialize client with direct parameters
|
33
|
+
client = QuotesClient(
|
34
|
+
base_url="wss://websocket-url/quotes",
|
35
|
+
token="your-jwt-token",
|
36
|
+
log_level="info" # Options: "error", "info", "debug"
|
37
|
+
)
|
38
|
+
|
39
|
+
# Set callback
|
40
|
+
client.on_tick = process_tick
|
41
|
+
|
42
|
+
# Connect in the background
|
43
|
+
connection_task = asyncio.create_task(client.connect())
|
44
|
+
|
45
|
+
# Subscribe to instruments
|
46
|
+
await client.subscribe(["NSE:SBIN:3045"])
|
47
|
+
|
48
|
+
# Keep the connection running
|
49
|
+
try:
|
50
|
+
await asyncio.sleep(3600) # Run for 1 hour
|
51
|
+
except KeyboardInterrupt:
|
52
|
+
# Unsubscribe and close
|
53
|
+
await client.unsubscribe(["NSE:SBIN:3045"])
|
54
|
+
await client.close()
|
55
|
+
|
56
|
+
await connection_task
|
57
|
+
|
58
|
+
if __name__ == "__main__":
|
59
|
+
asyncio.run(main())
|
60
|
+
```
|
61
|
+
|
62
|
+
## Quick Start - DataHub Client
|
63
|
+
|
64
|
+
```python
|
65
|
+
from wiz_trader import WizzerClient
|
66
|
+
|
67
|
+
# Initialize client
|
68
|
+
client = WizzerClient(
|
69
|
+
base_url="https://api-url.in",
|
70
|
+
token="your-jwt-token",
|
71
|
+
log_level="info" # Options: "error", "info", "debug"
|
72
|
+
)
|
73
|
+
|
74
|
+
# Get list of indices
|
75
|
+
indices = client.get_indices(exchange="NSE")
|
76
|
+
print(indices)
|
77
|
+
|
78
|
+
# Get index components
|
79
|
+
components = client.get_index_components(
|
80
|
+
trading_symbol="NIFTY 50",
|
81
|
+
exchange="NSE"
|
82
|
+
)
|
83
|
+
print(components)
|
84
|
+
|
85
|
+
# Get historical OHLCV data
|
86
|
+
historical_data = client.get_historical_ohlcv(
|
87
|
+
instruments=["NSE:SBIN:3045"],
|
88
|
+
start_date="2024-01-01",
|
89
|
+
end_date="2024-01-31",
|
90
|
+
ohlcv=["open", "high", "low", "close", "volume"]
|
91
|
+
)
|
92
|
+
print(historical_data)
|
93
|
+
```
|
94
|
+
|
95
|
+
## Configuration
|
96
|
+
|
97
|
+
You can configure the clients in two ways:
|
98
|
+
|
99
|
+
1. **Direct parameter passing** (recommended):
|
100
|
+
```python
|
101
|
+
quotes_client = QuotesClient(
|
102
|
+
base_url="wss://websocket-url/quotes",
|
103
|
+
token="your-jwt-token",
|
104
|
+
log_level="info"
|
105
|
+
)
|
106
|
+
|
107
|
+
wizzer_client = WizzerClient(
|
108
|
+
base_url="https://api-url.in",
|
109
|
+
token="your-jwt-token",
|
110
|
+
log_level="info"
|
111
|
+
)
|
112
|
+
```
|
113
|
+
|
114
|
+
2. **System environment variables**:
|
115
|
+
- `WZ__QUOTES_BASE_URL`: WebSocket URL for the quotes server
|
116
|
+
- `WZ__API_BASE_URL`: Base URL for the Wizzer's REST API
|
117
|
+
- `WZ__TOKEN`: JWT token for authentication
|
118
|
+
|
119
|
+
```python
|
120
|
+
# The clients will automatically use the environment variables if parameters are not provided
|
121
|
+
quotes_client = QuotesClient(log_level="info")
|
122
|
+
wizzer_client = WizzerClient(log_level="info")
|
123
|
+
```
|
124
|
+
|
125
|
+
## Advanced Usage
|
126
|
+
|
127
|
+
Check the `examples/` directory for more detailed examples:
|
128
|
+
|
129
|
+
- `example_manual.py`: Demonstrates direct configuration with parameters
|
130
|
+
- `example_wizzer.py`: Demonstrates usage of the Wizzer client
|
131
|
+
|
132
|
+
## License
|
133
|
+
|
134
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
135
|
+
|
136
|
+
## Contributing
|
137
|
+
|
138
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
@@ -0,0 +1,39 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "wiz_trader"
|
7
|
+
version = "0.3.0"
|
8
|
+
description = "A Python SDK for connecting to the Wizzer."
|
9
|
+
readme = "README.md"
|
10
|
+
authors = [
|
11
|
+
{name = "Pawan Wagh", email = "pawan@wizzer.in"},
|
12
|
+
]
|
13
|
+
license = {text = "MIT"}
|
14
|
+
classifiers = [
|
15
|
+
"Development Status :: 3 - Alpha",
|
16
|
+
"Intended Audience :: Financial and Insurance Industry",
|
17
|
+
"Intended Audience :: Developers",
|
18
|
+
"Programming Language :: Python :: 3",
|
19
|
+
"Operating System :: OS Independent",
|
20
|
+
"License :: OSI Approved :: MIT License",
|
21
|
+
"Topic :: Office/Business :: Financial",
|
22
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
23
|
+
]
|
24
|
+
keywords = ["finance", "trading", "sdk"]
|
25
|
+
requires-python = ">=3.6"
|
26
|
+
dependencies = [
|
27
|
+
"websockets",
|
28
|
+
"requests",
|
29
|
+
]
|
30
|
+
|
31
|
+
[project.urls]
|
32
|
+
Homepage = "https://bitbucket.org/wizzer-tech/quotes_sdk.git"
|
33
|
+
"Bug Tracker" = "https://bitbucket.org/wizzer-tech/quotes_sdk/issues"
|
34
|
+
|
35
|
+
[tool.setuptools]
|
36
|
+
package-dir = {"" = "src"}
|
37
|
+
|
38
|
+
[tool.setuptools.packages.find]
|
39
|
+
where = ["src"]
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
2
2
|
|
3
3
|
setup(
|
4
4
|
name='wiz_trader',
|
5
|
-
version='0.
|
5
|
+
version='0.3.0',
|
6
6
|
description='A Python SDK for connecting to the Wizzer.',
|
7
7
|
long_description=open('README.md').read() if open('README.md') else "",
|
8
8
|
long_description_content_type='text/markdown',
|
@@ -12,6 +12,7 @@ setup(
|
|
12
12
|
packages=find_packages(),
|
13
13
|
install_requires=[
|
14
14
|
'websockets',
|
15
|
+
'requests',
|
15
16
|
'python-dotenv'
|
16
17
|
],
|
17
18
|
classifiers=[
|
@@ -0,0 +1,169 @@
|
|
1
|
+
import os
|
2
|
+
import json
|
3
|
+
import logging
|
4
|
+
from typing import Dict, List, Optional, Union, Any
|
5
|
+
|
6
|
+
import requests
|
7
|
+
|
8
|
+
# Setup module-level logger with a default handler if none exists.
|
9
|
+
logger = logging.getLogger(__name__)
|
10
|
+
if not logger.handlers:
|
11
|
+
handler = logging.StreamHandler()
|
12
|
+
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
13
|
+
handler.setFormatter(formatter)
|
14
|
+
logger.addHandler(handler)
|
15
|
+
|
16
|
+
class WizzerClient:
|
17
|
+
"""
|
18
|
+
A Python SDK for connecting to the Wizzer's REST API.
|
19
|
+
|
20
|
+
Attributes:
|
21
|
+
base_url (str): Base URL of the Wizzer's API server.
|
22
|
+
token (str): JWT token for authentication.
|
23
|
+
log_level (str): Logging level. Options: "error", "info", "debug".
|
24
|
+
"""
|
25
|
+
|
26
|
+
def __init__(
|
27
|
+
self,
|
28
|
+
base_url: Optional[str] = None,
|
29
|
+
token: Optional[str] = None,
|
30
|
+
log_level: str = "error" # default only errors
|
31
|
+
):
|
32
|
+
# Configure logger based on log_level.
|
33
|
+
valid_levels = {"error": logging.ERROR, "info": logging.INFO, "debug": logging.DEBUG}
|
34
|
+
if log_level not in valid_levels:
|
35
|
+
raise ValueError(f"log_level must be one of {list(valid_levels.keys())}")
|
36
|
+
logger.setLevel(valid_levels[log_level])
|
37
|
+
|
38
|
+
self.log_level = log_level
|
39
|
+
# System env vars take precedence over .env
|
40
|
+
self.base_url = base_url or os.environ.get("WZ__API_BASE_URL")
|
41
|
+
self.token = token or os.environ.get("WZ__TOKEN")
|
42
|
+
if not self.token:
|
43
|
+
raise ValueError("JWT token must be provided as an argument or in .env (WZ__TOKEN)")
|
44
|
+
if not self.base_url:
|
45
|
+
raise ValueError("Base URL must be provided as an argument or in .env (WZ__API_BASE_URL)")
|
46
|
+
|
47
|
+
# Prepare the authorization header
|
48
|
+
self.headers = {
|
49
|
+
"Authorization": f"Bearer {self.token}",
|
50
|
+
"Content-Type": "application/json"
|
51
|
+
}
|
52
|
+
|
53
|
+
logger.debug("Initialized WizzerClient with URL: %s", self.base_url)
|
54
|
+
|
55
|
+
def get_indices(self, trading_symbol: Optional[str] = None, exchange: Optional[str] = None) -> List[Dict[str, Any]]:
|
56
|
+
"""
|
57
|
+
Get list of indices available on the exchange.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
trading_symbol (Optional[str]): Filter by specific index symbol.
|
61
|
+
exchange (Optional[str]): Filter by specific exchange (NSE, BSE).
|
62
|
+
|
63
|
+
Returns:
|
64
|
+
List[Dict[str, Any]]: List of index information.
|
65
|
+
"""
|
66
|
+
endpoint = "/datahub/indices"
|
67
|
+
params = {}
|
68
|
+
|
69
|
+
if trading_symbol:
|
70
|
+
params["tradingSymbol"] = trading_symbol
|
71
|
+
if exchange:
|
72
|
+
params["exchange"] = exchange
|
73
|
+
|
74
|
+
logger.debug("Fetching indices with params: %s", params)
|
75
|
+
response = self._make_request("GET", endpoint, params=params)
|
76
|
+
return response
|
77
|
+
|
78
|
+
def get_index_components(self, trading_symbol: str, exchange: str) -> List[Dict[str, Any]]:
|
79
|
+
"""
|
80
|
+
Get list of components (stocks) for a specific index.
|
81
|
+
|
82
|
+
Args:
|
83
|
+
trading_symbol (str): Index symbol (e.g., "NIFTY 50").
|
84
|
+
exchange (str): Exchange name (NSE, BSE).
|
85
|
+
|
86
|
+
Returns:
|
87
|
+
List[Dict[str, Any]]: List of component stocks in the index.
|
88
|
+
"""
|
89
|
+
endpoint = "/datahub/index/components"
|
90
|
+
params = {
|
91
|
+
"tradingSymbol": trading_symbol,
|
92
|
+
"exchange": exchange
|
93
|
+
}
|
94
|
+
|
95
|
+
logger.debug("Fetching index components with params: %s", params)
|
96
|
+
response = self._make_request("GET", endpoint, params=params)
|
97
|
+
return response
|
98
|
+
|
99
|
+
def get_historical_ohlcv(
|
100
|
+
self,
|
101
|
+
instruments: List[str],
|
102
|
+
start_date: str,
|
103
|
+
end_date: str,
|
104
|
+
ohlcv: List[str]
|
105
|
+
) -> List[Dict[str, Any]]:
|
106
|
+
"""
|
107
|
+
Get historical OHLCV data for specified instruments.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
instruments (List[str]): List of instrument identifiers (e.g., ["NSE:SBIN:3045"]).
|
111
|
+
start_date (str): Start date in YYYY-MM-DD format.
|
112
|
+
end_date (str): End date in YYYY-MM-DD format.
|
113
|
+
ohlcv (List[str]): List of OHLCV fields to retrieve (open, high, low, close, volume).
|
114
|
+
|
115
|
+
Returns:
|
116
|
+
List[Dict[str, Any]]: Historical data for requested instruments.
|
117
|
+
"""
|
118
|
+
endpoint = "/datahub/historical/ohlcv"
|
119
|
+
data = {
|
120
|
+
"instruments": instruments,
|
121
|
+
"startDate": start_date,
|
122
|
+
"endDate": end_date,
|
123
|
+
"ohlcv": ohlcv
|
124
|
+
}
|
125
|
+
|
126
|
+
logger.debug("Fetching historical OHLCV with data: %s", data)
|
127
|
+
response = self._make_request("POST", endpoint, json=data)
|
128
|
+
return response
|
129
|
+
|
130
|
+
def _make_request(
|
131
|
+
self,
|
132
|
+
method: str,
|
133
|
+
endpoint: str,
|
134
|
+
params: Optional[Dict[str, str]] = None,
|
135
|
+
json: Optional[Dict[str, Any]] = None
|
136
|
+
) -> Any:
|
137
|
+
"""
|
138
|
+
Make an HTTP request to the DataHub API.
|
139
|
+
|
140
|
+
Args:
|
141
|
+
method (str): HTTP method (GET, POST, etc.)
|
142
|
+
endpoint (str): API endpoint path.
|
143
|
+
params (Optional[Dict[str, str]]): Query parameters for GET requests.
|
144
|
+
json (Optional[Dict[str, Any]]): JSON payload for POST requests.
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
Any: Parsed JSON response.
|
148
|
+
|
149
|
+
Raises:
|
150
|
+
requests.RequestException: If the request fails.
|
151
|
+
"""
|
152
|
+
url = f"{self.base_url}{endpoint}"
|
153
|
+
|
154
|
+
try:
|
155
|
+
logger.debug("%s request to %s", method, url)
|
156
|
+
response = requests.request(
|
157
|
+
method=method,
|
158
|
+
url=url,
|
159
|
+
headers=self.headers,
|
160
|
+
params=params,
|
161
|
+
json=json
|
162
|
+
)
|
163
|
+
response.raise_for_status()
|
164
|
+
return response.json()
|
165
|
+
except requests.RequestException as e:
|
166
|
+
logger.error("API request failed: %s", e, exc_info=True)
|
167
|
+
if hasattr(e.response, 'text'):
|
168
|
+
logger.error("Response content: %s", e.response.text)
|
169
|
+
raise
|
@@ -8,10 +8,6 @@ from typing import Callable, List, Optional
|
|
8
8
|
import websockets
|
9
9
|
from websockets.exceptions import ConnectionClosed
|
10
10
|
from websockets.protocol import State
|
11
|
-
from dotenv import load_dotenv
|
12
|
-
|
13
|
-
# Load environment variables from .env (if available)
|
14
|
-
load_dotenv()
|
15
11
|
|
16
12
|
# Setup module-level logger with a default handler if none exists.
|
17
13
|
logger = logging.getLogger(__name__)
|
@@ -46,8 +42,9 @@ class QuotesClient:
|
|
46
42
|
logger.setLevel(valid_levels[log_level])
|
47
43
|
|
48
44
|
self.log_level = log_level
|
49
|
-
|
50
|
-
self.
|
45
|
+
# System env vars take precedence over .env
|
46
|
+
self.base_url = base_url or os.environ.get("WZ__QUOTES_BASE_URL")
|
47
|
+
self.token = token or os.environ.get("WZ__TOKEN")
|
51
48
|
if not self.token:
|
52
49
|
raise ValueError("JWT token must be provided as an argument or in .env (WZ__TOKEN)")
|
53
50
|
if not self.base_url:
|
@@ -0,0 +1,165 @@
|
|
1
|
+
Metadata-Version: 2.2
|
2
|
+
Name: wiz_trader
|
3
|
+
Version: 0.3.0
|
4
|
+
Summary: A Python SDK for connecting to the Wizzer.
|
5
|
+
Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
6
|
+
Author: Pawan Wagh
|
7
|
+
Author-email: Pawan Wagh <pawan@wizzer.in>
|
8
|
+
License: MIT
|
9
|
+
Project-URL: Homepage, https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
10
|
+
Project-URL: Bug Tracker, https://bitbucket.org/wizzer-tech/quotes_sdk/issues
|
11
|
+
Keywords: finance,trading,sdk
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
14
|
+
Classifier: Intended Audience :: Developers
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
16
|
+
Classifier: Operating System :: OS Independent
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
18
|
+
Classifier: Topic :: Office/Business :: Financial
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
20
|
+
Requires-Python: >=3.6
|
21
|
+
Description-Content-Type: text/markdown
|
22
|
+
Requires-Dist: websockets
|
23
|
+
Requires-Dist: requests
|
24
|
+
Dynamic: author
|
25
|
+
Dynamic: home-page
|
26
|
+
Dynamic: requires-python
|
27
|
+
|
28
|
+
# WizTrader SDK
|
29
|
+
|
30
|
+
A Python SDK for connecting to the Wizzer trading platform.
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
You can install the package directly from PyPI:
|
35
|
+
|
36
|
+
```bash
|
37
|
+
pip install wiz_trader
|
38
|
+
```
|
39
|
+
|
40
|
+
## Features
|
41
|
+
|
42
|
+
- Real-time market data through WebSocket connection
|
43
|
+
- REST API for accessing market data and indices
|
44
|
+
- Automatic WebSocket reconnection with exponential backoff
|
45
|
+
- Subscribe/unsubscribe to instruments
|
46
|
+
- Customizable logging levels
|
47
|
+
|
48
|
+
## Quick Start - Quotes Client
|
49
|
+
|
50
|
+
```python
|
51
|
+
import asyncio
|
52
|
+
from wiz_trader import QuotesClient
|
53
|
+
|
54
|
+
# Callback function to process market data
|
55
|
+
def process_tick(data):
|
56
|
+
print(f"Received tick: {data}")
|
57
|
+
|
58
|
+
async def main():
|
59
|
+
# Initialize client with direct parameters
|
60
|
+
client = QuotesClient(
|
61
|
+
base_url="wss://websocket-url/quotes",
|
62
|
+
token="your-jwt-token",
|
63
|
+
log_level="info" # Options: "error", "info", "debug"
|
64
|
+
)
|
65
|
+
|
66
|
+
# Set callback
|
67
|
+
client.on_tick = process_tick
|
68
|
+
|
69
|
+
# Connect in the background
|
70
|
+
connection_task = asyncio.create_task(client.connect())
|
71
|
+
|
72
|
+
# Subscribe to instruments
|
73
|
+
await client.subscribe(["NSE:SBIN:3045"])
|
74
|
+
|
75
|
+
# Keep the connection running
|
76
|
+
try:
|
77
|
+
await asyncio.sleep(3600) # Run for 1 hour
|
78
|
+
except KeyboardInterrupt:
|
79
|
+
# Unsubscribe and close
|
80
|
+
await client.unsubscribe(["NSE:SBIN:3045"])
|
81
|
+
await client.close()
|
82
|
+
|
83
|
+
await connection_task
|
84
|
+
|
85
|
+
if __name__ == "__main__":
|
86
|
+
asyncio.run(main())
|
87
|
+
```
|
88
|
+
|
89
|
+
## Quick Start - DataHub Client
|
90
|
+
|
91
|
+
```python
|
92
|
+
from wiz_trader import WizzerClient
|
93
|
+
|
94
|
+
# Initialize client
|
95
|
+
client = WizzerClient(
|
96
|
+
base_url="https://api-url.in",
|
97
|
+
token="your-jwt-token",
|
98
|
+
log_level="info" # Options: "error", "info", "debug"
|
99
|
+
)
|
100
|
+
|
101
|
+
# Get list of indices
|
102
|
+
indices = client.get_indices(exchange="NSE")
|
103
|
+
print(indices)
|
104
|
+
|
105
|
+
# Get index components
|
106
|
+
components = client.get_index_components(
|
107
|
+
trading_symbol="NIFTY 50",
|
108
|
+
exchange="NSE"
|
109
|
+
)
|
110
|
+
print(components)
|
111
|
+
|
112
|
+
# Get historical OHLCV data
|
113
|
+
historical_data = client.get_historical_ohlcv(
|
114
|
+
instruments=["NSE:SBIN:3045"],
|
115
|
+
start_date="2024-01-01",
|
116
|
+
end_date="2024-01-31",
|
117
|
+
ohlcv=["open", "high", "low", "close", "volume"]
|
118
|
+
)
|
119
|
+
print(historical_data)
|
120
|
+
```
|
121
|
+
|
122
|
+
## Configuration
|
123
|
+
|
124
|
+
You can configure the clients in two ways:
|
125
|
+
|
126
|
+
1. **Direct parameter passing** (recommended):
|
127
|
+
```python
|
128
|
+
quotes_client = QuotesClient(
|
129
|
+
base_url="wss://websocket-url/quotes",
|
130
|
+
token="your-jwt-token",
|
131
|
+
log_level="info"
|
132
|
+
)
|
133
|
+
|
134
|
+
wizzer_client = WizzerClient(
|
135
|
+
base_url="https://api-url.in",
|
136
|
+
token="your-jwt-token",
|
137
|
+
log_level="info"
|
138
|
+
)
|
139
|
+
```
|
140
|
+
|
141
|
+
2. **System environment variables**:
|
142
|
+
- `WZ__QUOTES_BASE_URL`: WebSocket URL for the quotes server
|
143
|
+
- `WZ__API_BASE_URL`: Base URL for the Wizzer's REST API
|
144
|
+
- `WZ__TOKEN`: JWT token for authentication
|
145
|
+
|
146
|
+
```python
|
147
|
+
# The clients will automatically use the environment variables if parameters are not provided
|
148
|
+
quotes_client = QuotesClient(log_level="info")
|
149
|
+
wizzer_client = WizzerClient(log_level="info")
|
150
|
+
```
|
151
|
+
|
152
|
+
## Advanced Usage
|
153
|
+
|
154
|
+
Check the `examples/` directory for more detailed examples:
|
155
|
+
|
156
|
+
- `example_manual.py`: Demonstrates direct configuration with parameters
|
157
|
+
- `example_wizzer.py`: Demonstrates usage of the Wizzer client
|
158
|
+
|
159
|
+
## License
|
160
|
+
|
161
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
162
|
+
|
163
|
+
## Contributing
|
164
|
+
|
165
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
MANIFEST.in
|
2
|
+
README.md
|
3
|
+
pyproject.toml
|
4
|
+
setup.py
|
5
|
+
src/wiz_trader/__init__.py
|
6
|
+
src/wiz_trader.egg-info/PKG-INFO
|
7
|
+
src/wiz_trader.egg-info/SOURCES.txt
|
8
|
+
src/wiz_trader.egg-info/dependency_links.txt
|
9
|
+
src/wiz_trader.egg-info/requires.txt
|
10
|
+
src/wiz_trader.egg-info/top_level.txt
|
11
|
+
src/wiz_trader/apis/__init__.py
|
12
|
+
src/wiz_trader/apis/client.py
|
13
|
+
src/wiz_trader/quotes/__init__.py
|
14
|
+
src/wiz_trader/quotes/client.py
|
15
|
+
tests/test_apis.py
|
16
|
+
tests/test_quotes.py
|
@@ -0,0 +1 @@
|
|
1
|
+
wiz_trader
|
wiz_trader-0.1.0/MANIFEST.in
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
exclude .env
|
wiz_trader-0.1.0/PKG-INFO
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.2
|
2
|
-
Name: wiz_trader
|
3
|
-
Version: 0.1.0
|
4
|
-
Summary: A Python SDK for connecting to the Wizzer.
|
5
|
-
Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
6
|
-
Author: Pawan Wagh
|
7
|
-
Author-email: pawan@wizzer.in
|
8
|
-
Classifier: Development Status :: 3 - Alpha
|
9
|
-
Classifier: Intended Audience :: Financial and Insurance Industry
|
10
|
-
Classifier: Intended Audience :: Developers
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
12
|
-
Classifier: Operating System :: OS Independent
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
14
|
-
Classifier: Topic :: Office/Business :: Financial
|
15
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
16
|
-
Requires-Python: >=3.6
|
17
|
-
Description-Content-Type: text/markdown
|
18
|
-
Requires-Dist: websockets
|
19
|
-
Requires-Dist: python-dotenv
|
20
|
-
Dynamic: author
|
21
|
-
Dynamic: author-email
|
22
|
-
Dynamic: classifier
|
23
|
-
Dynamic: description
|
24
|
-
Dynamic: description-content-type
|
25
|
-
Dynamic: home-page
|
26
|
-
Dynamic: requires-dist
|
27
|
-
Dynamic: requires-python
|
28
|
-
Dynamic: summary
|
29
|
-
|
30
|
-
# WizTrader SDK
|
31
|
-
|
32
|
-
A Python SDK for connecting to the Wizzer.
|
33
|
-
|
34
|
-
## Installation
|
35
|
-
|
36
|
-
Install the dependencies:
|
37
|
-
```
|
38
|
-
pip install -r requirements.txt
|
39
|
-
```
|
40
|
-
|
41
|
-
## Usage Example
|
42
|
-
|
43
|
-
See `example.py` for a complete example.
|
wiz_trader-0.1.0/README.md
DELETED
wiz_trader-0.1.0/apis/client.py
DELETED
wiz_trader-0.1.0/pyproject.toml
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.2
|
2
|
-
Name: wiz_trader
|
3
|
-
Version: 0.1.0
|
4
|
-
Summary: A Python SDK for connecting to the Wizzer.
|
5
|
-
Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
|
6
|
-
Author: Pawan Wagh
|
7
|
-
Author-email: pawan@wizzer.in
|
8
|
-
Classifier: Development Status :: 3 - Alpha
|
9
|
-
Classifier: Intended Audience :: Financial and Insurance Industry
|
10
|
-
Classifier: Intended Audience :: Developers
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
12
|
-
Classifier: Operating System :: OS Independent
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
14
|
-
Classifier: Topic :: Office/Business :: Financial
|
15
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
16
|
-
Requires-Python: >=3.6
|
17
|
-
Description-Content-Type: text/markdown
|
18
|
-
Requires-Dist: websockets
|
19
|
-
Requires-Dist: python-dotenv
|
20
|
-
Dynamic: author
|
21
|
-
Dynamic: author-email
|
22
|
-
Dynamic: classifier
|
23
|
-
Dynamic: description
|
24
|
-
Dynamic: description-content-type
|
25
|
-
Dynamic: home-page
|
26
|
-
Dynamic: requires-dist
|
27
|
-
Dynamic: requires-python
|
28
|
-
Dynamic: summary
|
29
|
-
|
30
|
-
# WizTrader SDK
|
31
|
-
|
32
|
-
A Python SDK for connecting to the Wizzer.
|
33
|
-
|
34
|
-
## Installation
|
35
|
-
|
36
|
-
Install the dependencies:
|
37
|
-
```
|
38
|
-
pip install -r requirements.txt
|
39
|
-
```
|
40
|
-
|
41
|
-
## Usage Example
|
42
|
-
|
43
|
-
See `example.py` for a complete example.
|
@@ -1,15 +0,0 @@
|
|
1
|
-
MANIFEST.in
|
2
|
-
README.md
|
3
|
-
pyproject.toml
|
4
|
-
setup.py
|
5
|
-
apis/__init__.py
|
6
|
-
apis/client.py
|
7
|
-
tests/test_apis.py
|
8
|
-
tests/test_quotes.py
|
9
|
-
ticker/__init__.py
|
10
|
-
ticker/client.py
|
11
|
-
wiz_trader.egg-info/PKG-INFO
|
12
|
-
wiz_trader.egg-info/SOURCES.txt
|
13
|
-
wiz_trader.egg-info/dependency_links.txt
|
14
|
-
wiz_trader.egg-info/requires.txt
|
15
|
-
wiz_trader.egg-info/top_level.txt
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|