# Python APIs for SAS Online Alpha Trade Web Platform
# MAJOR CHANGES : NEW VERSION 1.0.0
## API endpoints are changed to match the new ones, bugs expected
1. Removed check for enabled exchanges, you can now download or search symbols from MCX as well if it is not enabled
2. TOTP SECRET or TOTP both can be given as argument while creating AlphaTrade object (if it is 6 digits it will conside TOTP else TOTP SECRET)
3. Added new search function to search scrips which will return json for found scrips, you need to process it further
4. More functions to come.
5. Check whether streaming websocket is working or not
6. The `examples` folder is removed and examples are renamed and kept in root directory for ease of development
# STEPS to work
1. Clone the repo locally - `git clone https://github.com/algo2t/alphatrade.git`
2. Create a virtualenv - `python -m pip install virtualenv` and then `python -m virtualenv venv` and activate the `venv` environment.
3. Install dev-requirement.txt - `python -m pip install -r dev-requirements.txt` - this is to ensure `setuptools==57.5.0` is installed. There is a bug with `protlib`, target is to get reed of `protlib` in future
4. Install requirement.txt - `python -m pip install -r requirement.txt`
5. Create the `config.py` file in root of cloned repo with `login_id`, `password` and `TOTP` SECRET, you can add the `access_token.txt` if you want to use existing `access_token`.
6. Try the examples `python zlogin_example.py`, `python zexample_sas_login.py`, `python zhistorical_data.py` and `python zstreaming_data.py`
7. Expecting issues with the streaming data !!! :P
# NOTE:: This is Unofficial python module, don't ask SAS support team for help, use it AS-IS
The Python APIs for communicating with the SAS Online Alpha Trade Web Platform.
Alpha Trade Python library provides an easy to use python wrapper over the HTTPS APIs.
The HTTP calls have been converted to methods and JSON responses are wrapped into Python-compatible objects.
Websocket connections are handled automatically within the library.
This work is completely based on Python SDK / APIs for [AliceBlueOnline](https://github.com/krishnavelu/alice_blue.git).
Thanks to [krishnavelu](https://github.com/krishnavelu/).
- **Author: [algo2t](https://github.com/algo2t/)**
- **Github Repository: [alphatrade](https://github.com/algo2t/alphatrade.git)**
## Installation
This module is installed via pip:
```
pip install git+https://github.com/algo2t/alphatrade.git
```
It can also be installed from [pypi](https://pypi.org/project/alphatrade/0.1.2/)
```
pip install alphatrade
```
To force upgrade existing installations:
```
pip uninstall alphatrade
pip --no-cache-dir install --upgrade alphatrade
```
### Prerequisites
Python 3.x
Also, you need the following modules:
- `protlib`
- `websocket_client`
- `requests`
- `pandas`
The modules can also be installed using `pip`
## Examples - Start Here - Important
Please clone this repository and check the examples folder to get started.
Check [here](https://algo2t.github.io/alphatrade/#working-with-examples)
## Getting started with API
### Overview
There is only one class in the whole library: `AlphaTrade`. When the `AlphaTrade` object is created an access token from the SAS Online alpha trade server is stored in text file `access_token.txt` in the same directory. An access token is valid for 24 hours. See the examples folder with `config.py` file to see how to store your credentials.
With an access token, you can instantiate an AlphaTrade object again. Ideally you only need to create an access_token once every day.
### REST Documentation
The original REST API that this SDK is based on is available online.
[Alice Blue API REST documentation](http://antplus.aliceblueonline.com/#introduction)
## Using the API
### Logging
The whole library is equipped with python‘s `logging` module for debugging. If more debug information is needed, enable logging using the following code.
```python
import logging
logging.basicConfig(level=logging.DEBUG)
```
### Get an access token
1. Import alphatrade
```python
from alphatrade import *
```
2. Create `config.py` file
Always keep credentials in a separate file
```python
login_id = "XXXXX"
password = "XXXXXXXX"
Totp = 'XXXXXXXXXXXXXXXX'
try:
access_token = open('access_token.txt', 'r').read().rstrip()
except Exception as e:
print('Exception occurred :: {}'.format(e))
access_token = None
```
3. Import the config
```python
import config
```
### Create AlphaTrade Object
1. Create `AlphaTrade` object with your `login_id`, `password`, `TOTP` / `TOTP_SECRET` and/or `access_token`.
Use `config` object to get `login_id`, `password`, `TOTP` and `access_token`.
```python
from alphatrade import AlphaTrade
import config
import pyotp
Totp = config.Totp
pin = pyotp.TOTP(Totp).now()
totp = f"{int(pin):06d}" if len(pin) <=5 else pin
sas = AlphaTrade(login_id=config.login_id, password=config.password, twofa=totp, access_token=config.access_token)
```
```python
## filename config.py
login_id = "RR24XX"
password = "SuperSecretPassword!!!"
TOTP_SECRET = 'YOURTOTPSECRETEXTERNALAUTH'
try:
access_token = open('access_token.txt', 'r').read().rstrip()
except Exception as e:
print(f'Exception occurred :: {e}')
access_token = None
```
```python
from alphatrade import AlphaTrade
import config
import pyotp
sas = AlphaTrade(login_id=config.login_id, password=config.password, twofa=config.TOTP_SECRET, access_token=config.access_token)
```
2. You can run commands here to check your connectivity
```python
print(sas.get_balance()) # get balance / margin limits
print(sas.get_profile()) # get profile
print(sas.get_daywise_positions()) # get daywise positions
print(sas.get_netwise_positions()) # get netwise positions
print(sas.get_holding_positions()) # get holding positions
```
### Get master contracts
Getting master contracts allow you to search for instruments by symbol name and place orders.
Master contracts are stored as an OrderedDict by token number and by symbol name. Whenever you get a trade update, order update, or quote update, the library will check if master contracts are loaded. If they are, it will attach the instrument object directly to the update. By default all master contracts of all enabled exchanges in your personal profile will be downloaded. i.e. If your profile contains the following as enabled exchanges `['NSE', 'BSE', 'CDS', 'MCX', NFO']` all contract notes of all exchanges will be downloaded by default. If you feel it takes too much time to download all exchange, or if you don‘t need all exchanges to be downloaded, you can specify which exchange to download contract notes while creating the AlphaTrade object.
```python
sas = AlphaTrade(login_id=config.login_id, password=config.password, twofa=totp, access_token=config.access_token, master_contracts_to_download=['NSE', 'BSE'])
```
This will reduce a few milliseconds in object creation time of AlphaTrade object.
### Get tradable instruments
Symbols can be retrieved in multiple ways. Once you have the master contract loaded for an exchange, you can get an instrument in many ways.
Get a single instrument by it‘s name:
```python
tatasteel_nse_eq = sas.get_instrument_by_symbol('NSE', 'TATASTEEL')
reliance_nse_eq = sas.get_instrument_by_symbol('NSE', 'RELIANCE')
ongc_bse_eq = sas.get_instrument_by_symbol('BSE', 'ONGC')
india_vix_nse_index = sas.get_instrument_by_symbol('NSE', 'India VIX')
sensex_nse_index = sas.get_instrument_by_symbol('BSE', 'SENSEX')
```
Get a single instrument by it‘s token number (generally useful only for BSE Equities):
```python
ongc_bse_eq = sas.get_instrument_by_token('BSE', 500312)
reliance_bse_eq = sas.get_instrument_by_token('BSE', 500325)
acc_nse_eq = sas.get_instrument_by_token('NSE', 22)
```
Get FNO instruments easily by mentioning expiry, strike & call or put.
```python
bn_fut = sas.get_instrument_for_fno(symbol = 'BANKNIFTY', expiry_date=datetime.date(2019, 6, 27), is_fut=True, strike=None, is_call = False)
bn_call = sas.get_instrument_for_fno(symbol = 'BANKNIFTY', expiry_date=datetime.date(2019, 6, 27), is_fut=False, strike=30000, is_call = True)
bn_put = sas.get_instrument_for_fno(symbol = 'BANKNIFTY', expiry_date=datetime.date(2019, 6, 27), is_fut=False, strike=30000, is_call = False)
```
### Search for symbols
Search for multiple instruments by matching the name. This works case insensitive and returns all instrument which has the name in its symbol.
```python
all_sensex_scrips = sas.search_instruments('BSE', 'sEnSeX')
print(all_sensex_scrips)
```
The above code results multiple symbol which has ‘sensex’ in its symbol.
```
[Instrument(exchange='BSE', token=1, symbol='SENSEX', name='SENSEX', expiry=None, lot_size=None), Instrument(exchange='BSE', token=540154, symbol='IDFSENSEXE B', name='IDFC Mutual Fund', expiry=None, lot_size=None), Instrument(exchange='BSE', token=532985, symbol='KTKSENSEX B', name='KOTAK MAHINDRA MUTUAL FUND', expiry=None, lot_size=None), Instrument(exchange='BSE', token=538683, symbol='NETFSENSEX B', name='NIPPON INDIA ETF SENSEX', expiry=None, lot_size=None), Instrument(exchange='BSE', token=535276, symbol='SBISENSEX B', name='SBI MUTUAL FUND - SBI ETF SENS', expiry=None, lot_size=None)]
```
Search for multiple instruments by matching multiple names
```python
multiple_underlying = ['BANKNIFTY','NIFTY','INFY','BHEL']
all_scripts = sas.search_instruments('NFO', multiple_underlying)
```
#### Instrument object
Instruments are represented by instrument objects. These are named-tuples that are created while getting the master contracts. They are used when placing an order and searching for an instrument. The structure of an instrument tuple is as follows:
```python
Instrument = namedtuple('Instrument', ['exchange', 'token', 'symbol',
'name', 'expiry', 'lot_size'])
```
All instruments have the fields mentioned above. Wherever a field is not applicable for an instrument (for example, equity instruments don‘t have strike prices), that value will be `None`
### Quote update
Once you have master contracts loaded, you can easily subscribe to quote updates.
#### Four types of feed data are available
You can subscribe any one type of quote update for a given scrip. Using the `LiveFeedType` enum, you can specify what type of live feed you need.
- `LiveFeedType.MARKET_DATA`
- `LiveFeedType.COMPACT`
- `LiveFeedType.SNAPQUOTE`
- `LiveFeedType.FULL_SNAPQUOTE`
Please refer to the original documentation [here](http://antplus.aliceblueonline.com/#marketdata) for more details of different types of quote update.
#### Subscribe to a live feed
```python
sas.subscribe(sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), LiveFeedType.MARKET_DATA)
sas.subscribe(sas.get_instrument_by_symbol('BSE', 'RELIANCE'), LiveFeedType.COMPACT)
```
Subscribe to multiple instruments in a single call. Give an array of instruments to be subscribed.
```python
sas.subscribe([sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), sas.get_instrument_by_symbol('NSE', 'ACC')], LiveFeedType.MARKET_DATA)
```
Note: There is a limit of 250 scrips that can be subscribed on total. Beyond this point the server may disconnect web-socket connection.
Start getting live feed via socket
```python
socket_opened = False
def event_handler_quote_update(message):
print(f"quote update {message}")
def open_callback():
global socket_opened
socket_opened = True
sas.start_websocket(subscribe_callback=event_handler_quote_update,
socket_open_callback=open_callback,
run_in_background=True)
while(socket_opened==False):
pass
sas.subscribe(sas.get_instrument_by_symbol('NSE', 'ONGC'), LiveFeedType.MARKET_DATA)
sleep(10)
```
#### Unsubscribe to a live feed
Unsubscribe to an existing live feed
```python
sas.unsubscribe(sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), LiveFeedType.MARKET_DATA)
sas.unsubscribe(sas.get_instrument_by_symbol('BSE', 'RELIANCE'), LiveFeedType.COMPACT)
```
Unsubscribe to multiple instruments in a single call. Give an array of instruments to be unsubscribed.
```python
sas.unsubscribe([sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), sas.get_instrument_by_symbol('NSE', 'ACC')], LiveFeedType.MARKET_DATA)
```
#### Get All Subscribed Symbols
```python
sas.get_all_subscriptions() # All
```
### Market Status messages & Exchange messages.
Subscribe to market status messages
```python
sas.subscribe_market_status_messages()
```
Getting market status messages.
```python
print(sas.get_market_status_messages())
```
Example result of `get_market_status_messages()`
```
[{'exchange': 'NSE', 'length_of_market_type': 6, 'market_type': b'NORMAL', 'length_of_status': 31, 'status': b'The Closing Session has closed.'}, {'exchange': 'NFO', 'length_of_market_type': 6, 'market_type': b'NORMAL', 'length_of_status': 45, 'status': b'The Normal market has closed for 22 MAY 2020.'}, {'exchange': 'CDS', 'length_of_market_type': 6, 'market_type': b'NORMAL', 'length_of_status': 45, 'status': b'The Normal market has closed for 22 MAY 2020.'}, {'exchange': 'BSE', 'length_of_market_type': 13, 'market_type': b'OTHER SESSION', 'length_of_status': 0, 'status': b''}]
```
Note: As per `alice blue` [documentation](http://antplus.aliceblueonline.com/#market-status) all market status messages should be having a timestamp. But in actual the server doesn‘t send timestamp, so the library is unable to get timestamp for now.
Subscribe to exchange messages
```python
sas.subscribe_exchange_messages()
```
Getting market status messages.
```python
print(sas.get_exchange_messages())
```
Example result of `get_exchange_messages()`
```
[{'exchange': 'NSE', 'length': 32, 'message': b'DS : Bulk upload can be started.', 'exchange_time_stamp': 1590148595}, {'exchange': 'NFO', 'length': 200, 'message': b'MARKET WIDE LIMIT FOR VEDL IS 183919959. OPEN POSITIONS IN VEDL HAVE REACHED 84 PERCENT OF THE MARKET WIDE LIMIT. ', 'exchange_time_stamp': 1590146132}, {'exchange': 'CDS', 'length': 54, 'message': b'DS : Regular segment Bhav copy broadcast successfully.', 'exchange_time_stamp': 1590148932}, {'exchange': 'MCX', 'length': 7, 'message': b'.......', 'exchange_time_stamp': 1590196159}]
```
#### Market Status messages & Exchange messages through callbacks
```python
socket_opened = False
def market_status_messages(message):
print(f"market status messages {message}")
def exchange_messages(message):
print(f"exchange messages {message}")
def open_callback():
global socket_opened
socket_opened = True
sas.start_websocket(market_status_messages_callback=market_status_messages,
exchange_messages_callback=exchange_messages,
socket_open_callback=open_callback,
run_in_background=True)
while(socket_opened==False):
pass
sas.subscribe_market_status_messages()
sas.subscribe_exchange_messages()
sleep(10)
```
### Place an order
Place limit, market, SL, SL-M, AMO, BO, CO orders
```python
print (sas.get_profile())
# TransactionType.Buy, OrderType.Market, ProductType.Delivery
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.Market,
product_type = ProductType.Delivery,
price = 0.0,
trigger_price = None,
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.Market, ProductType.Intraday
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.Market,
product_type = ProductType.Intraday,
price = 0.0,
trigger_price = None,
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.Market, ProductType.CoverOrder
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.Market,
product_type = ProductType.CoverOrder,
price = 0.0,
trigger_price = 7.5, # trigger_price Here the trigger_price is taken as stop loss (provide stop loss in actual amount)
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.Limit, ProductType.BracketOrder
# OCO Order can't be of type market
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.Limit,
product_type = ProductType.BracketOrder,
price = 8.0,
trigger_price = None,
stop_loss = 6.0,
square_off = 10.0,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.Limit, ProductType.Intraday
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%5%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.Limit,
product_type = ProductType.Intraday,
price = 8.0,
trigger_price = None,
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.Limit, ProductType.CoverOrder
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%6%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.Limit,
product_type = ProductType.CoverOrder,
price = 7.0,
trigger_price = 6.5, # trigger_price Here the trigger_price is taken as stop loss (provide stop loss in actual amount)
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
###############################
# TransactionType.Buy, OrderType.StopLossMarket, ProductType.Delivery
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%7%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.StopLossMarket,
product_type = ProductType.Delivery,
price = 0.0,
trigger_price = 8.0,
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.StopLossMarket, ProductType.Intraday
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%8%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.StopLossMarket,
product_type = ProductType.Intraday,
price = 0.0,
trigger_price = 8.0,
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.StopLossMarket, ProductType.CoverOrder
# CO order is of type Limit and And Market Only
# TransactionType.Buy, OrderType.StopLossMarket, ProductType.BO
# BO order is of type Limit and And Market Only
###################################
# TransactionType.Buy, OrderType.StopLossLimit, ProductType.Delivery
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%9%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.StopLossMarket,
product_type = ProductType.Delivery,
price = 8.0,
trigger_price = 8.0,
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.StopLossLimit, ProductType.Intraday
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%10%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.StopLossLimit,
product_type = ProductType.Intraday,
price = 8.0,
trigger_price = 8.0,
stop_loss = None,
square_off = None,
trailing_sl = None,
is_amo = False)
)
# TransactionType.Buy, OrderType.StopLossLimit, ProductType.CoverOrder
# CO order is of type Limit and And Market Only
# TransactionType.Buy, OrderType.StopLossLimit, ProductType.BracketOrder
print ("%%%%%%%%%%%%%%%%%%%%%%%%%%%%11%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print(
sas.place_order(transaction_type = TransactionType.Buy,
instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),
quantity = 1,
order_type = OrderType.StopLossLimit,
product_type = ProductType.BracketOrder,
price = 8.0,
trigger_price = 8.0,
stop_loss = 1.0,
square_off = 1.0,
trailing_sl = 20,
is_amo = False)
)
```
### Place basket order
Basket order is used to buy or sell group of securities simultaneously.
```python
order1 = { "instrument" : sas.get_instrument_by_symbol('NSE', 'INFY'),
"order_type" : OrderType.Market,
"quantity" : 1,
"transaction_type" : TransactionType.Buy,
"product_type" : ProductType.Delivery}
order2 = { "instrument" : sas.get_instrument_by_symbol('NSE', 'SBIN'),
"order_type" : OrderType.Limit,
"quantity" : 2,
"price" : 280.0,
"transaction_type" : TransactionType.Sell,
"product_type" : ProductType.Intraday}
order = [order1, order2]
print(sas.place_basket_order(orders))
```
### Cancel an order
```python
sas.cancel_order('170713000075481') #Cancel an open order
```
### Getting order history and trade details
#### Get order history of a particular order
```python
print(sas.get_order_history('170713000075481'))
```
#### Get order history of all orders.
```python
print(sas.get_order_history())
```
#### Get trade book
```python
print(sas.get_trade_book())
```
#### Get historical candles data
This will provide historical data but **not for current day**.
This returns a `pandas` `DataFrame` object which be used with `pandas_ta` to get various indicators values.
```python
from datetime import datetime
print(sas.get_historical_candles('MCX', 'NATURALGAS NOV FUT', datetime(2020, 10, 19), datetime.now() ,interval=30))
```
Output
```console
Instrument(exchange='MCX', token=224365, symbol='NATURALGAS NOV FUT', name='', expiry=datetime.date(2020, 11, 24), lot_size=None)
open high low close volume
date
2020-10-19 09:00:00+05:30 238.9 239.2 238.4 239.0 373
2020-10-19 09:30:00+05:30 239.0 239.0 238.4 238.6 210
2020-10-19 10:00:00+05:30 238.7 238.7 238.1 238.1 213
2020-10-19 10:30:00+05:30 238.0 238.4 238.0 238.1 116
2020-10-19 11:00:00+05:30 238.1 238.2 238.0 238.0 69
... ... ... ... ... ...
2020-10-23 21:00:00+05:30 237.5 238.1 237.3 237.6 331
2020-10-23 21:30:00+05:30 237.6 238.5 237.6 237.9 754
2020-10-23 22:00:00+05:30 237.9 238.1 237.2 237.9 518
2020-10-23 22:30:00+05:30 237.9 238.7 237.7 238.1 897
2020-10-23 23:00:00+05:30 238.2 238.3 236.3 236.5 1906
```
Better way to get historical data, first get the latest version from github
`python -m pip install git+https://github.com/algo2t/alphatrade.git`
```python
from datetime import datetime
india_vix_nse_index = sas.get_instrument_by_symbol('NSE', 'India VIX')
print(sas.get_historical_candles(india_vix_nse_index.exchange, india_vix_nse_index.symbol, datetime(2020, 10, 19), datetime.now() ,interval=30))
```
#### Get intraday candles data
This will give candles data for **current day only**.
This returns a `pandas` `DataFrame` object which be used with `pandas_ta` to get various indicators values.
```python
print(sas.get_intraday_candles('MCX', 'NATURALGAS NOV FUT', interval=15))
```
Better way to get intraday data, first get the latest version from github
`python -m pip install git+https://github.com/algo2t/alphatrade.git`
```python
from datetime import datetime
nifty_bank_nse_index = sas.get_instrument_by_symbol('NSE', 'Nifty Bank')
print(sas.get_intraday_candles(nifty_bank_nse_index.exchange, nifty_bank_nse_index.symbol, datetime(2020, 10, 19), datetime.now(), interval=10))
```
### Order properties as enums
Order properties such as TransactionType, OrderType, and others have been safely classified as enums so you don‘t have to write them out as strings
#### TransactionType
Transaction types indicate whether you want to buy or sell. Valid transaction types are of the following:
- `TransactionType.Buy` - buy
- `TransactionType.Sell` - sell
#### OrderType
Order type specifies the type of order you want to send. Valid order types include:
- `OrderType.Market` - Place the order with a market price
- `OrderType.Limit` - Place the order with a limit price (limit price parameter is mandatory)
- `OrderType.StopLossLimit` - Place as a stop loss limit order
- `OrderType.StopLossMarket` - Place as a stop loss market order
#### ProductType
Product types indicate the complexity of the order you want to place. Valid product types are:
- `ProductType.Intraday` - Intraday order that will get squared off before market close
- `ProductType.Delivery` - Delivery order that will be held with you after market close
- `ProductType.CoverOrder` - Cover order
- `ProductType.BracketOrder` - One cancels other order. Also known as bracket order
## Working with examples
[Here](https://github.com/algo2t/alphatrade), examples directory there are 3 files `zlogin_example.py`, `zstreaming_data.py` and `stop.txt`
### Steps
- Clone the repository to your local machine `git clone https://github.com/algo2t/alphatrade.git`
- Copy the examples directory to any location where you want to write your code
- Install the `alphatrade` module using `pip` => `python -m pip install https://github.com/algo2t/alphatrade.git`
- Open the examples directory in your favorite editor, in our case it is [VSCodium](https://vscodium.com/)
- Open the `zlogin_example.py` file in the editor
- Now, create `config.py` file as per instructions given below and in the above file
- Provide correct login credentials like login_id, password and 16 digit totp code (find below qr code)
- This is generally set from the homepage of alpha web trading platform [here](https://alpha.sasonline.in/)
- Click on `FORGET PASSWORD?` => Select `Reset 2FA` radio button. ![image](https://raw.githubusercontent.com/algo2t/alphatrade/main/snaps/forget_password.png)
- Enter the CLIENT ID (LOGIN_ID), EMAIL ID and PAN NUMBER, click on `RESET` button. ![image](https://raw.githubusercontent.com/algo2t/alphatrade/main/snaps/reset_two_fa.png)
- Click on `BACK TO LOGIN` and enter `CLIENT ID` and `PASSWORD`, click on `SECURED SIGN-IN`
- Set same answers for 5 questions and click on `SUBMIT` button. ![image](https://raw.githubusercontent.com/algo2t/alphatrade/main/snaps/set_answers.png)
`config.py`
```python
login_id = "XXXXX"
password = "XXXXXXXX"
Totp = 'XXXXXXXXXXXXXXXX'
try:
access_token = open('access_token.txt', 'r').read().rstrip()
except Exception as e:
print('Exception occurred :: {}'.format(e))
access_token = None
```
## Example strategy using alpha trade API
[Here](https://github.com/algo2t/alphatrade/blob/main/zstreaming_data.py) is an example moving average strategy using alpha trade web API.
This strategy generates a buy signal when 5-EMA > 20-EMA (golden cross) or a sell signal when 5-EMA < 20-EMA (death cross).
## Example for getting historical and intraday candles data
[Here](https://github.com/algo2t/alphatrade/blob/main/zhistorical_data.py) is an example for getting historical data using alpha trade web API.
For historical candles data `start_time` and `end_time` must be provided in format as shown below.
It can also be provided as `timedelta`. Check the script `zhistorical_data.py` in examples.
```python
from datetime import datetime, timedelta
start_time = datetime(2020, 10, 19, 9, 15, 0)
end_time = datetime(2020, 10, 21, 16, 59, 0)
df = sas.get_historical_candles('MCX', 'NATURALGAS OCT FUT', start_time, end_time, 5)
print(df)
end_time = start_time + timedelta(days=5)
df = sas.get_historical_candles('MCX', 'NATURALGAS NOV FUT', start_time, end_time, 15)
print(df)
```
For intraday or today‘s / current day‘s candles data.
```python
df = sas.get_intraday_candles('MCX', 'NATURALGAS OCT FUT')
print(df)
df = sas.get_intraday_candles('MCX', 'NATURALGAS NOV FUT', 15)
print(df)
```
## Read this before creating an issue
Before creating an issue in this library, please follow the following steps.
1. Search the problem you are facing is already asked by someone else. There might be some issues already there, either solved/unsolved related to your problem. Go to [issues](https://github.com/algo2t/alphatrade/issues) page, use `is:issue` as filter and search your problem. ![image](https://user-images.githubusercontent.com/38440742/85207058-376ee400-b2f4-11ea-91ad-c8fd8a682a12.png)
2. If you feel your problem is not asked by anyone or no issues are related to your problem, then create a new issue.
3. Describe your problem in detail while creating the issue. If you don‘t have time to detail/describe the problem you are facing, assume that I also won‘t be having time to respond to your problem.
4. Post a sample code of the problem you are facing. If I copy paste the code directly from issue, I should be able to reproduce the problem you are facing.
5. Before posting the sample code, test your sample code yourself once. Only sample code should be tested, no other addition should be there while you are testing.
6. Have some print() function calls to display the values of some variables related to your problem.
7. Post the results of print() functions also in the issue.
8. Use the insert code feature of github to inset code and print outputs, so that the code is displayed neat. ![image](https://user-images.githubusercontent.com/38440742/85207234-4dc96f80-b2f5-11ea-990c-df013dd69cf2.png)
Raw data
{
"_id": null,
"home_page": "https://github.com/algo2t/alphatrade",
"name": "alphatrade",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "alphatrade,alpha-trade,sasonline,python,sdk,trading,stock markets",
"author": "Algo 2 Trade",
"author_email": "help@algo2.trade",
"download_url": "https://files.pythonhosted.org/packages/83/3f/a37a6250f385e2d13f12a8351b35613cfbbe28a395af203d21894371fc36/alphatrade-1.0.0.tar.gz",
"platform": null,
"description": "# Python APIs for SAS Online Alpha Trade Web Platform\n\n# MAJOR CHANGES : NEW VERSION 1.0.0\n\n## API endpoints are changed to match the new ones, bugs expected\n\n1. Removed check for enabled exchanges, you can now download or search symbols from MCX as well if it is not enabled\n2. TOTP SECRET or TOTP both can be given as argument while creating AlphaTrade object (if it is 6 digits it will conside TOTP else TOTP SECRET)\n3. Added new search function to search scrips which will return json for found scrips, you need to process it further\n4. More functions to come.\n5. Check whether streaming websocket is working or not\n6. The `examples` folder is removed and examples are renamed and kept in root directory for ease of development\n\n# STEPS to work\n\n1. Clone the repo locally - `git clone https://github.com/algo2t/alphatrade.git` \n2. Create a virtualenv - `python -m pip install virtualenv` and then `python -m virtualenv venv` and activate the `venv` environment.\n3. Install dev-requirement.txt - `python -m pip install -r dev-requirements.txt` - this is to ensure `setuptools==57.5.0` is installed. There is a bug with `protlib`, target is to get reed of `protlib` in future\n4. Install requirement.txt - `python -m pip install -r requirement.txt`\n5. Create the `config.py` file in root of cloned repo with `login_id`, `password` and `TOTP` SECRET, you can add the `access_token.txt` if you want to use existing `access_token`.\n6. Try the examples `python zlogin_example.py`, `python zexample_sas_login.py`, `python zhistorical_data.py` and `python zstreaming_data.py`\n7. Expecting issues with the streaming data !!! :P\n\n\n# NOTE:: This is Unofficial python module, don't ask SAS support team for help, use it AS-IS\n\nThe Python APIs for communicating with the SAS Online Alpha Trade Web Platform.\n\nAlpha Trade Python library provides an easy to use python wrapper over the HTTPS APIs.\n\nThe HTTP calls have been converted to methods and JSON responses are wrapped into Python-compatible objects.\n\nWebsocket connections are handled automatically within the library.\n\nThis work is completely based on Python SDK / APIs for [AliceBlueOnline](https://github.com/krishnavelu/alice_blue.git). \nThanks to [krishnavelu](https://github.com/krishnavelu/). \n\n- **Author: [algo2t](https://github.com/algo2t/)**\n- **Github Repository: [alphatrade](https://github.com/algo2t/alphatrade.git)**\n\n## Installation\n\nThis module is installed via pip:\n\n```\npip install git+https://github.com/algo2t/alphatrade.git\n```\n\nIt can also be installed from [pypi](https://pypi.org/project/alphatrade/0.1.2/) \n\n```\npip install alphatrade\n```\n\nTo force upgrade existing installations:\n\n```\npip uninstall alphatrade\npip --no-cache-dir install --upgrade alphatrade\n```\n\n### Prerequisites\n\nPython 3.x\n\nAlso, you need the following modules:\n\n- `protlib`\n- `websocket_client`\n- `requests`\n- `pandas`\n\nThe modules can also be installed using `pip`\n\n## Examples - Start Here - Important \n\nPlease clone this repository and check the examples folder to get started. \nCheck [here](https://algo2t.github.io/alphatrade/#working-with-examples)\n\n## Getting started with API\n\n### Overview\n\nThere is only one class in the whole library: `AlphaTrade`. When the `AlphaTrade` object is created an access token from the SAS Online alpha trade server is stored in text file `access_token.txt` in the same directory. An access token is valid for 24 hours. See the examples folder with `config.py` file to see how to store your credentials.\nWith an access token, you can instantiate an AlphaTrade object again. Ideally you only need to create an access_token once every day.\n\n### REST Documentation\n\nThe original REST API that this SDK is based on is available online.\n[Alice Blue API REST documentation](http://antplus.aliceblueonline.com/#introduction)\n\n## Using the API\n\n### Logging\n\nThe whole library is equipped with python\u2018s `logging` module for debugging. If more debug information is needed, enable logging using the following code.\n\n```python\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\n```\n\n### Get an access token\n\n1. Import alphatrade\n\n```python\nfrom alphatrade import *\n```\n\n2. Create `config.py` file \nAlways keep credentials in a separate file\n```python\nlogin_id = \"XXXXX\"\npassword = \"XXXXXXXX\"\nTotp = 'XXXXXXXXXXXXXXXX'\n\ntry:\n access_token = open('access_token.txt', 'r').read().rstrip()\nexcept Exception as e:\n print('Exception occurred :: {}'.format(e))\n access_token = None\n```\n\n3. Import the config\n```python\nimport config\n```\n\n### Create AlphaTrade Object\n\n1. Create `AlphaTrade` object with your `login_id`, `password`, `TOTP` / `TOTP_SECRET` and/or `access_token`.\n\nUse `config` object to get `login_id`, `password`, `TOTP` and `access_token`. \n\n```python\nfrom alphatrade import AlphaTrade\nimport config\nimport pyotp\nTotp = config.Totp\npin = pyotp.TOTP(Totp).now()\ntotp = f\"{int(pin):06d}\" if len(pin) <=5 else pin \nsas = AlphaTrade(login_id=config.login_id, password=config.password, twofa=totp, access_token=config.access_token)\n\n```\n\n```python\n## filename config.py\n\nlogin_id = \"RR24XX\"\npassword = \"SuperSecretPassword!!!\"\nTOTP_SECRET = 'YOURTOTPSECRETEXTERNALAUTH'\n\ntry:\n access_token = open('access_token.txt', 'r').read().rstrip()\nexcept Exception as e:\n print(f'Exception occurred :: {e}')\n access_token = None\n\n```\n\n\n```python\nfrom alphatrade import AlphaTrade\nimport config\nimport pyotp\nsas = AlphaTrade(login_id=config.login_id, password=config.password, twofa=config.TOTP_SECRET, access_token=config.access_token)\n\n```\n\n\n2. You can run commands here to check your connectivity\n\n```python\nprint(sas.get_balance()) # get balance / margin limits\nprint(sas.get_profile()) # get profile\nprint(sas.get_daywise_positions()) # get daywise positions\nprint(sas.get_netwise_positions()) # get netwise positions\nprint(sas.get_holding_positions()) # get holding positions\n```\n\n### Get master contracts\n\nGetting master contracts allow you to search for instruments by symbol name and place orders.\nMaster contracts are stored as an OrderedDict by token number and by symbol name. Whenever you get a trade update, order update, or quote update, the library will check if master contracts are loaded. If they are, it will attach the instrument object directly to the update. By default all master contracts of all enabled exchanges in your personal profile will be downloaded. i.e. If your profile contains the following as enabled exchanges `['NSE', 'BSE', 'CDS', 'MCX', NFO']` all contract notes of all exchanges will be downloaded by default. If you feel it takes too much time to download all exchange, or if you don\u2018t need all exchanges to be downloaded, you can specify which exchange to download contract notes while creating the AlphaTrade object.\n\n```python\nsas = AlphaTrade(login_id=config.login_id, password=config.password, twofa=totp, access_token=config.access_token, master_contracts_to_download=['NSE', 'BSE'])\n```\n\nThis will reduce a few milliseconds in object creation time of AlphaTrade object.\n\n### Get tradable instruments\n\nSymbols can be retrieved in multiple ways. Once you have the master contract loaded for an exchange, you can get an instrument in many ways.\n\nGet a single instrument by it\u2018s name:\n\n```python\ntatasteel_nse_eq = sas.get_instrument_by_symbol('NSE', 'TATASTEEL')\nreliance_nse_eq = sas.get_instrument_by_symbol('NSE', 'RELIANCE')\nongc_bse_eq = sas.get_instrument_by_symbol('BSE', 'ONGC')\nindia_vix_nse_index = sas.get_instrument_by_symbol('NSE', 'India VIX')\nsensex_nse_index = sas.get_instrument_by_symbol('BSE', 'SENSEX')\n```\n\nGet a single instrument by it\u2018s token number (generally useful only for BSE Equities):\n\n```python\nongc_bse_eq = sas.get_instrument_by_token('BSE', 500312)\nreliance_bse_eq = sas.get_instrument_by_token('BSE', 500325)\nacc_nse_eq = sas.get_instrument_by_token('NSE', 22)\n```\n\nGet FNO instruments easily by mentioning expiry, strike & call or put.\n\n```python\nbn_fut = sas.get_instrument_for_fno(symbol = 'BANKNIFTY', expiry_date=datetime.date(2019, 6, 27), is_fut=True, strike=None, is_call = False)\nbn_call = sas.get_instrument_for_fno(symbol = 'BANKNIFTY', expiry_date=datetime.date(2019, 6, 27), is_fut=False, strike=30000, is_call = True)\nbn_put = sas.get_instrument_for_fno(symbol = 'BANKNIFTY', expiry_date=datetime.date(2019, 6, 27), is_fut=False, strike=30000, is_call = False)\n```\n\n### Search for symbols\n\nSearch for multiple instruments by matching the name. This works case insensitive and returns all instrument which has the name in its symbol.\n\n```python\nall_sensex_scrips = sas.search_instruments('BSE', 'sEnSeX')\nprint(all_sensex_scrips)\n```\n\nThe above code results multiple symbol which has \u2018sensex\u2019 in its symbol.\n\n```\n[Instrument(exchange='BSE', token=1, symbol='SENSEX', name='SENSEX', expiry=None, lot_size=None), Instrument(exchange='BSE', token=540154, symbol='IDFSENSEXE B', name='IDFC Mutual Fund', expiry=None, lot_size=None), Instrument(exchange='BSE', token=532985, symbol='KTKSENSEX B', name='KOTAK MAHINDRA MUTUAL FUND', expiry=None, lot_size=None), Instrument(exchange='BSE', token=538683, symbol='NETFSENSEX B', name='NIPPON INDIA ETF SENSEX', expiry=None, lot_size=None), Instrument(exchange='BSE', token=535276, symbol='SBISENSEX B', name='SBI MUTUAL FUND - SBI ETF SENS', expiry=None, lot_size=None)]\n```\n\nSearch for multiple instruments by matching multiple names\n\n```python\nmultiple_underlying = ['BANKNIFTY','NIFTY','INFY','BHEL']\nall_scripts = sas.search_instruments('NFO', multiple_underlying)\n```\n\n#### Instrument object\n\nInstruments are represented by instrument objects. These are named-tuples that are created while getting the master contracts. They are used when placing an order and searching for an instrument. The structure of an instrument tuple is as follows:\n\n```python\nInstrument = namedtuple('Instrument', ['exchange', 'token', 'symbol',\n 'name', 'expiry', 'lot_size'])\n```\n\nAll instruments have the fields mentioned above. Wherever a field is not applicable for an instrument (for example, equity instruments don\u2018t have strike prices), that value will be `None`\n\n### Quote update\n\nOnce you have master contracts loaded, you can easily subscribe to quote updates.\n\n#### Four types of feed data are available\n\nYou can subscribe any one type of quote update for a given scrip. Using the `LiveFeedType` enum, you can specify what type of live feed you need.\n\n- `LiveFeedType.MARKET_DATA`\n- `LiveFeedType.COMPACT`\n- `LiveFeedType.SNAPQUOTE`\n- `LiveFeedType.FULL_SNAPQUOTE`\n\nPlease refer to the original documentation [here](http://antplus.aliceblueonline.com/#marketdata) for more details of different types of quote update.\n\n#### Subscribe to a live feed\n\n```python\nsas.subscribe(sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), LiveFeedType.MARKET_DATA)\nsas.subscribe(sas.get_instrument_by_symbol('BSE', 'RELIANCE'), LiveFeedType.COMPACT)\n```\n\nSubscribe to multiple instruments in a single call. Give an array of instruments to be subscribed.\n\n```python\nsas.subscribe([sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), sas.get_instrument_by_symbol('NSE', 'ACC')], LiveFeedType.MARKET_DATA)\n```\n\nNote: There is a limit of 250 scrips that can be subscribed on total. Beyond this point the server may disconnect web-socket connection.\n\nStart getting live feed via socket\n\n```python\nsocket_opened = False\ndef event_handler_quote_update(message):\n print(f\"quote update {message}\")\n\ndef open_callback():\n global socket_opened\n socket_opened = True\n\nsas.start_websocket(subscribe_callback=event_handler_quote_update,\n socket_open_callback=open_callback,\n run_in_background=True)\nwhile(socket_opened==False):\n pass\nsas.subscribe(sas.get_instrument_by_symbol('NSE', 'ONGC'), LiveFeedType.MARKET_DATA)\nsleep(10)\n```\n\n#### Unsubscribe to a live feed\n\nUnsubscribe to an existing live feed\n\n```python\nsas.unsubscribe(sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), LiveFeedType.MARKET_DATA)\nsas.unsubscribe(sas.get_instrument_by_symbol('BSE', 'RELIANCE'), LiveFeedType.COMPACT)\n```\n\nUnsubscribe to multiple instruments in a single call. Give an array of instruments to be unsubscribed.\n\n```python\nsas.unsubscribe([sas.get_instrument_by_symbol('NSE', 'TATASTEEL'), sas.get_instrument_by_symbol('NSE', 'ACC')], LiveFeedType.MARKET_DATA)\n```\n\n#### Get All Subscribed Symbols\n\n```python\nsas.get_all_subscriptions() # All\n```\n\n### Market Status messages & Exchange messages.\n\nSubscribe to market status messages\n\n```python\nsas.subscribe_market_status_messages()\n```\n\nGetting market status messages.\n\n```python\nprint(sas.get_market_status_messages())\n```\n\nExample result of `get_market_status_messages()`\n\n```\n[{'exchange': 'NSE', 'length_of_market_type': 6, 'market_type': b'NORMAL', 'length_of_status': 31, 'status': b'The Closing Session has closed.'}, {'exchange': 'NFO', 'length_of_market_type': 6, 'market_type': b'NORMAL', 'length_of_status': 45, 'status': b'The Normal market has closed for 22 MAY 2020.'}, {'exchange': 'CDS', 'length_of_market_type': 6, 'market_type': b'NORMAL', 'length_of_status': 45, 'status': b'The Normal market has closed for 22 MAY 2020.'}, {'exchange': 'BSE', 'length_of_market_type': 13, 'market_type': b'OTHER SESSION', 'length_of_status': 0, 'status': b''}]\n```\n\nNote: As per `alice blue` [documentation](http://antplus.aliceblueonline.com/#market-status) all market status messages should be having a timestamp. But in actual the server doesn\u2018t send timestamp, so the library is unable to get timestamp for now.\n\nSubscribe to exchange messages\n\n```python\nsas.subscribe_exchange_messages()\n```\n\nGetting market status messages.\n\n```python\nprint(sas.get_exchange_messages())\n```\n\nExample result of `get_exchange_messages()`\n\n```\n[{'exchange': 'NSE', 'length': 32, 'message': b'DS : Bulk upload can be started.', 'exchange_time_stamp': 1590148595}, {'exchange': 'NFO', 'length': 200, 'message': b'MARKET WIDE LIMIT FOR VEDL IS 183919959. OPEN POSITIONS IN VEDL HAVE REACHED 84 PERCENT OF THE MARKET WIDE LIMIT. ', 'exchange_time_stamp': 1590146132}, {'exchange': 'CDS', 'length': 54, 'message': b'DS : Regular segment Bhav copy broadcast successfully.', 'exchange_time_stamp': 1590148932}, {'exchange': 'MCX', 'length': 7, 'message': b'.......', 'exchange_time_stamp': 1590196159}]\n```\n\n#### Market Status messages & Exchange messages through callbacks\n\n```python\nsocket_opened = False\ndef market_status_messages(message):\n print(f\"market status messages {message}\")\n\ndef exchange_messages(message):\n print(f\"exchange messages {message}\")\n\ndef open_callback():\n global socket_opened\n socket_opened = True\n\nsas.start_websocket(market_status_messages_callback=market_status_messages,\n\t\t\t\t\t exchange_messages_callback=exchange_messages,\n socket_open_callback=open_callback,\n run_in_background=True)\nwhile(socket_opened==False):\n pass\nsas.subscribe_market_status_messages()\nsas.subscribe_exchange_messages()\nsleep(10)\n```\n\n### Place an order\n\nPlace limit, market, SL, SL-M, AMO, BO, CO orders\n\n```python\nprint (sas.get_profile())\n\n# TransactionType.Buy, OrderType.Market, ProductType.Delivery\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.Market,\n product_type = ProductType.Delivery,\n price = 0.0,\n trigger_price = None,\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n )\n\n# TransactionType.Buy, OrderType.Market, ProductType.Intraday\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.Market,\n product_type = ProductType.Intraday,\n price = 0.0,\n trigger_price = None,\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n# TransactionType.Buy, OrderType.Market, ProductType.CoverOrder\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.Market,\n product_type = ProductType.CoverOrder,\n price = 0.0,\n trigger_price = 7.5, # trigger_price Here the trigger_price is taken as stop loss (provide stop loss in actual amount)\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n\n# TransactionType.Buy, OrderType.Limit, ProductType.BracketOrder\n# OCO Order can't be of type market\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%4%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.Limit,\n product_type = ProductType.BracketOrder,\n price = 8.0,\n trigger_price = None,\n stop_loss = 6.0,\n square_off = 10.0,\n trailing_sl = None,\n is_amo = False)\n)\n\n# TransactionType.Buy, OrderType.Limit, ProductType.Intraday\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%5%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.Limit,\n product_type = ProductType.Intraday,\n price = 8.0,\n trigger_price = None,\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n\n# TransactionType.Buy, OrderType.Limit, ProductType.CoverOrder\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%6%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.Limit,\n product_type = ProductType.CoverOrder,\n price = 7.0,\n trigger_price = 6.5, # trigger_price Here the trigger_price is taken as stop loss (provide stop loss in actual amount)\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n###############################\n\n# TransactionType.Buy, OrderType.StopLossMarket, ProductType.Delivery\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%7%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.StopLossMarket,\n product_type = ProductType.Delivery,\n price = 0.0,\n trigger_price = 8.0,\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n\n# TransactionType.Buy, OrderType.StopLossMarket, ProductType.Intraday\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%8%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.StopLossMarket,\n product_type = ProductType.Intraday,\n price = 0.0,\n trigger_price = 8.0,\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n\n\n# TransactionType.Buy, OrderType.StopLossMarket, ProductType.CoverOrder\n# CO order is of type Limit and And Market Only\n\n# TransactionType.Buy, OrderType.StopLossMarket, ProductType.BO\n# BO order is of type Limit and And Market Only\n\n###################################\n\n# TransactionType.Buy, OrderType.StopLossLimit, ProductType.Delivery\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%9%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.StopLossMarket,\n product_type = ProductType.Delivery,\n price = 8.0,\n trigger_price = 8.0,\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n\n# TransactionType.Buy, OrderType.StopLossLimit, ProductType.Intraday\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%10%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.StopLossLimit,\n product_type = ProductType.Intraday,\n price = 8.0,\n trigger_price = 8.0,\n stop_loss = None,\n square_off = None,\n trailing_sl = None,\n is_amo = False)\n)\n\n\n\n# TransactionType.Buy, OrderType.StopLossLimit, ProductType.CoverOrder\n# CO order is of type Limit and And Market Only\n\n\n# TransactionType.Buy, OrderType.StopLossLimit, ProductType.BracketOrder\n\nprint (\"%%%%%%%%%%%%%%%%%%%%%%%%%%%%11%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\")\nprint(\n sas.place_order(transaction_type = TransactionType.Buy,\n instrument = sas.get_instrument_by_symbol('NSE', 'INFY'),\n quantity = 1,\n order_type = OrderType.StopLossLimit,\n product_type = ProductType.BracketOrder,\n price = 8.0,\n trigger_price = 8.0,\n stop_loss = 1.0,\n square_off = 1.0,\n trailing_sl = 20,\n is_amo = False)\n)\n```\n\n### Place basket order\n\nBasket order is used to buy or sell group of securities simultaneously.\n\n```python\norder1 = { \"instrument\" : sas.get_instrument_by_symbol('NSE', 'INFY'),\n \"order_type\" : OrderType.Market,\n \"quantity\" : 1,\n \"transaction_type\" : TransactionType.Buy,\n \"product_type\" : ProductType.Delivery}\norder2 = { \"instrument\" : sas.get_instrument_by_symbol('NSE', 'SBIN'),\n \"order_type\" : OrderType.Limit,\n \"quantity\" : 2,\n \"price\" : 280.0,\n \"transaction_type\" : TransactionType.Sell,\n \"product_type\" : ProductType.Intraday}\norder = [order1, order2]\nprint(sas.place_basket_order(orders))\n```\n\n### Cancel an order\n\n```python\nsas.cancel_order('170713000075481') #Cancel an open order\n```\n\n### Getting order history and trade details\n\n#### Get order history of a particular order\n\n```python\nprint(sas.get_order_history('170713000075481'))\n```\n\n#### Get order history of all orders.\n\n```python\nprint(sas.get_order_history())\n```\n\n#### Get trade book\n\n```python\nprint(sas.get_trade_book())\n```\n\n#### Get historical candles data\n\nThis will provide historical data but **not for current day**. \nThis returns a `pandas` `DataFrame` object which be used with `pandas_ta` to get various indicators values. \n\n```python\nfrom datetime import datetime\nprint(sas.get_historical_candles('MCX', 'NATURALGAS NOV FUT', datetime(2020, 10, 19), datetime.now() ,interval=30))\n```\n\nOutput \n\n```console\nInstrument(exchange='MCX', token=224365, symbol='NATURALGAS NOV FUT', name='', expiry=datetime.date(2020, 11, 24), lot_size=None)\n open high low close volume\ndate\n2020-10-19 09:00:00+05:30 238.9 239.2 238.4 239.0 373\n2020-10-19 09:30:00+05:30 239.0 239.0 238.4 238.6 210\n2020-10-19 10:00:00+05:30 238.7 238.7 238.1 238.1 213\n2020-10-19 10:30:00+05:30 238.0 238.4 238.0 238.1 116\n2020-10-19 11:00:00+05:30 238.1 238.2 238.0 238.0 69\n... ... ... ... ... ...\n2020-10-23 21:00:00+05:30 237.5 238.1 237.3 237.6 331\n2020-10-23 21:30:00+05:30 237.6 238.5 237.6 237.9 754\n2020-10-23 22:00:00+05:30 237.9 238.1 237.2 237.9 518\n2020-10-23 22:30:00+05:30 237.9 238.7 237.7 238.1 897\n2020-10-23 23:00:00+05:30 238.2 238.3 236.3 236.5 1906\n\n```\n\nBetter way to get historical data, first get the latest version from github \n\n`python -m pip install git+https://github.com/algo2t/alphatrade.git`\n\n```python\nfrom datetime import datetime\nindia_vix_nse_index = sas.get_instrument_by_symbol('NSE', 'India VIX')\nprint(sas.get_historical_candles(india_vix_nse_index.exchange, india_vix_nse_index.symbol, datetime(2020, 10, 19), datetime.now() ,interval=30))\n```\n\n\n#### Get intraday candles data\n\nThis will give candles data for **current day only**. \nThis returns a `pandas` `DataFrame` object which be used with `pandas_ta` to get various indicators values. \n\n```python\nprint(sas.get_intraday_candles('MCX', 'NATURALGAS NOV FUT', interval=15))\n```\n\nBetter way to get intraday data, first get the latest version from github \n\n`python -m pip install git+https://github.com/algo2t/alphatrade.git`\n\n```python\nfrom datetime import datetime\nnifty_bank_nse_index = sas.get_instrument_by_symbol('NSE', 'Nifty Bank')\nprint(sas.get_intraday_candles(nifty_bank_nse_index.exchange, nifty_bank_nse_index.symbol, datetime(2020, 10, 19), datetime.now(), interval=10))\n```\n\n### Order properties as enums\n\nOrder properties such as TransactionType, OrderType, and others have been safely classified as enums so you don\u2018t have to write them out as strings\n\n#### TransactionType\n\nTransaction types indicate whether you want to buy or sell. Valid transaction types are of the following:\n\n- `TransactionType.Buy` - buy\n- `TransactionType.Sell` - sell\n\n#### OrderType\n\nOrder type specifies the type of order you want to send. Valid order types include:\n\n- `OrderType.Market` - Place the order with a market price\n- `OrderType.Limit` - Place the order with a limit price (limit price parameter is mandatory)\n- `OrderType.StopLossLimit` - Place as a stop loss limit order\n- `OrderType.StopLossMarket` - Place as a stop loss market order\n\n#### ProductType\n\nProduct types indicate the complexity of the order you want to place. Valid product types are:\n\n- `ProductType.Intraday` - Intraday order that will get squared off before market close\n- `ProductType.Delivery` - Delivery order that will be held with you after market close\n- `ProductType.CoverOrder` - Cover order\n- `ProductType.BracketOrder` - One cancels other order. Also known as bracket order\n\n## Working with examples\n\n[Here](https://github.com/algo2t/alphatrade), examples directory there are 3 files `zlogin_example.py`, `zstreaming_data.py` and `stop.txt`\n\n### Steps\n\n- Clone the repository to your local machine `git clone https://github.com/algo2t/alphatrade.git`\n- Copy the examples directory to any location where you want to write your code\n- Install the `alphatrade` module using `pip` => `python -m pip install https://github.com/algo2t/alphatrade.git`\n- Open the examples directory in your favorite editor, in our case it is [VSCodium](https://vscodium.com/)\n- Open the `zlogin_example.py` file in the editor\n- Now, create `config.py` file as per instructions given below and in the above file\n- Provide correct login credentials like login_id, password and 16 digit totp code (find below qr code)\n- This is generally set from the homepage of alpha web trading platform [here](https://alpha.sasonline.in/)\n- Click on `FORGET PASSWORD?` => Select `Reset 2FA` radio button. ![image](https://raw.githubusercontent.com/algo2t/alphatrade/main/snaps/forget_password.png)\n- Enter the CLIENT ID (LOGIN_ID), EMAIL ID and PAN NUMBER, click on `RESET` button. ![image](https://raw.githubusercontent.com/algo2t/alphatrade/main/snaps/reset_two_fa.png)\n- Click on `BACK TO LOGIN` and enter `CLIENT ID` and `PASSWORD`, click on `SECURED SIGN-IN`\n- Set same answers for 5 questions and click on `SUBMIT` button. ![image](https://raw.githubusercontent.com/algo2t/alphatrade/main/snaps/set_answers.png)\n\n`config.py`\n```python\nlogin_id = \"XXXXX\"\npassword = \"XXXXXXXX\"\nTotp = 'XXXXXXXXXXXXXXXX'\n\ntry:\n access_token = open('access_token.txt', 'r').read().rstrip()\nexcept Exception as e:\n print('Exception occurred :: {}'.format(e))\n access_token = None\n```\n\n## Example strategy using alpha trade API\n\n[Here](https://github.com/algo2t/alphatrade/blob/main/zstreaming_data.py) is an example moving average strategy using alpha trade web API.\nThis strategy generates a buy signal when 5-EMA > 20-EMA (golden cross) or a sell signal when 5-EMA < 20-EMA (death cross).\n\n## Example for getting historical and intraday candles data\n\n[Here](https://github.com/algo2t/alphatrade/blob/main/zhistorical_data.py) is an example for getting historical data using alpha trade web API.\n\nFor historical candles data `start_time` and `end_time` must be provided in format as shown below.\nIt can also be provided as `timedelta`. Check the script `zhistorical_data.py` in examples.\n\n```python\nfrom datetime import datetime, timedelta\nstart_time = datetime(2020, 10, 19, 9, 15, 0)\nend_time = datetime(2020, 10, 21, 16, 59, 0)\n\ndf = sas.get_historical_candles('MCX', 'NATURALGAS OCT FUT', start_time, end_time, 5)\nprint(df)\nend_time = start_time + timedelta(days=5)\ndf = sas.get_historical_candles('MCX', 'NATURALGAS NOV FUT', start_time, end_time, 15)\nprint(df)\n```\n\nFor intraday or today\u2018s / current day\u2018s candles data. \n\n```python\ndf = sas.get_intraday_candles('MCX', 'NATURALGAS OCT FUT')\nprint(df)\ndf = sas.get_intraday_candles('MCX', 'NATURALGAS NOV FUT', 15)\nprint(df)\n```\n\n\n## Read this before creating an issue\n\nBefore creating an issue in this library, please follow the following steps.\n\n1. Search the problem you are facing is already asked by someone else. There might be some issues already there, either solved/unsolved related to your problem. Go to [issues](https://github.com/algo2t/alphatrade/issues) page, use `is:issue` as filter and search your problem. ![image](https://user-images.githubusercontent.com/38440742/85207058-376ee400-b2f4-11ea-91ad-c8fd8a682a12.png)\n2. If you feel your problem is not asked by anyone or no issues are related to your problem, then create a new issue.\n3. Describe your problem in detail while creating the issue. If you don\u2018t have time to detail/describe the problem you are facing, assume that I also won\u2018t be having time to respond to your problem.\n4. Post a sample code of the problem you are facing. If I copy paste the code directly from issue, I should be able to reproduce the problem you are facing.\n5. Before posting the sample code, test your sample code yourself once. Only sample code should be tested, no other addition should be there while you are testing.\n6. Have some print() function calls to display the values of some variables related to your problem.\n7. Post the results of print() functions also in the issue.\n8. Use the insert code feature of github to inset code and print outputs, so that the code is displayed neat. ![image](https://user-images.githubusercontent.com/38440742/85207234-4dc96f80-b2f5-11ea-990c-df013dd69cf2.png)\n\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Python APIs for SAS Online Alpha Trade Web Platform",
"version": "1.0.0",
"project_urls": {
"Homepage": "https://github.com/algo2t/alphatrade"
},
"split_keywords": [
"alphatrade",
"alpha-trade",
"sasonline",
"python",
"sdk",
"trading",
"stock markets"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9267e92186f210ce98befc3d76eb40a505c6d225fd0b8466152af7275638c2a0",
"md5": "ee32a104ca4294a1f8dcc8a1e429f0c8",
"sha256": "1053e20a3a7c3fdd05fddd93e1484983a21d2c2f336bf7567c1bea0176058171"
},
"downloads": -1,
"filename": "alphatrade-1.0.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "ee32a104ca4294a1f8dcc8a1e429f0c8",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.7",
"size": 22172,
"upload_time": "2023-07-17T19:19:03",
"upload_time_iso_8601": "2023-07-17T19:19:03.971484Z",
"url": "https://files.pythonhosted.org/packages/92/67/e92186f210ce98befc3d76eb40a505c6d225fd0b8466152af7275638c2a0/alphatrade-1.0.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "833fa37a6250f385e2d13f12a8351b35613cfbbe28a395af203d21894371fc36",
"md5": "9cecab3fc32add9293aa63fbf4aa08b4",
"sha256": "b8adf1f7f8d3f430e440b43021820970fc6401d47576d2e9092fbb97d6ee91e7"
},
"downloads": -1,
"filename": "alphatrade-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "9cecab3fc32add9293aa63fbf4aa08b4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 37506,
"upload_time": "2023-07-17T19:19:05",
"upload_time_iso_8601": "2023-07-17T19:19:05.340588Z",
"url": "https://files.pythonhosted.org/packages/83/3f/a37a6250f385e2d13f12a8351b35613cfbbe28a395af203d21894371fc36/alphatrade-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-07-17 19:19:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "algo2t",
"github_project": "alphatrade",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "alphatrade"
}