forked from ejp-zz/upstox_python_bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
niftyoptions.py
143 lines (122 loc) · 5.39 KB
/
niftyoptions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from time import sleep
from datetime import date, timedelta
from upstox_api import api as upstox
from utils import BUY, SELL, get_expiry_dates, create_logger
from gannbot import GannBot
N50_SYMBOL = 'NIFTY_50'
LOT_SIZE = 75
MAX_CYCLES = 2
class GannNiftyOptions:
def __init__(self, debug=False):
self.running = False
self.cycles = 0
self.logger = create_logger(self.__class__.__name__)
self.state = []
self.pe_bot = GannBot()
self.pe_symbol = None
self.ce_bot = GannBot()
self.ce_symbol = None
def setup(self, client=None):
if 'setup complete' in self.state:
return
self.logger.debug('Creating options symbols')
tod = date.today()
exp = get_expiry_dates(tod.month)[-1]
if exp - tod < timedelta(days=6):
exp = get_expiry_dates(tod.month + 1)[-1]
nifty = client.get_instrument_by_symbol('nse_index', N50_SYMBOL)
data = client.get_live_feed(nifty, upstox.LiveFeedType.Full)
nearest_100 = int(float(data['close']) / 100) * 100
self.logger.debug('Base price for options = %d' % nearest_100)
self._create_ce_symbol(client, nearest_100, exp)
ce_inst = client.get_instrument_by_symbol('nse_fo', self.ce_symbol)
while client.subscribe(ce_inst, upstox.LiveFeedType.LTP)['success'] is not True:
sleep(1)
else:
self.logger.debug('Subscribed to %s' % self.ce_symbol)
self.logger.debug('close = %f' % ce_inst.closing_price)
pass
self._create_pe_symbol(client, nearest_100, exp)
pe_inst = client.get_instrument_by_symbol('nse_fo', self.pe_symbol)
while client.subscribe(pe_inst, upstox.LiveFeedType.LTP)['success'] is not True:
sleep(1)
else:
self.logger.debug('Subscribed to %s' % self.pe_symbol)
self.logger.debug('close = %f' % pe_inst.closing_price)
pass
self.state.append('setup complete')
self.logger.debug(self.state[-1])
def process_quote(self, quote):
sym = quote['symbol'].lower()
pe_order = None
ce_order = None
if sym == self.pe_symbol:
pe_order = self.pe_bot.process_quote(quote)
elif sym == self.ce_symbol:
ce_order = self.ce_bot.process_quote(quote)
if self.state[-1] in ('setup complete') and self.cycles < MAX_CYCLES:
if pe_order is not None and 'pe position closed' not in self.state:
self.state.append('pe ordered')
return pe_order
elif ce_order is not None and 'ce position closed' not in self.state:
self.state.append('ce ordered')
return ce_order
elif self.cycles == MAX_CYCLES:
self.state.append('finished trading')
def process_order(self, order):
sym = order['symbol'].lower()
if sym == self.pe_symbol:
self.pe_bot.process_order(order)
elif sym == self.ce_symbol:
self.ce_bot.process_order(order)
def process_trade(self, trade):
self._log_trade(trade)
sym = trade['symbol'].lower()
if sym == self.pe_symbol:
self.pe_bot.process_trade(trade)
newstate = 'pe ' + self.pe_bot.state[-1]
elif sym == self.ce_symbol:
self.ce_bot.process_trade(trade)
newstate = 'ce ' + self.pe_bot.state[-1]
if newstate != self.state[-1]:
self.state.append(newstate)
if 'position closed' in self.state[-1]:
self.cycles += 1
def get_symbols(self):
if 'setup complete' not in self.state:
return None
return (self.pe_symbol, self.ce_symbol)
def _create_pe_symbol(self, client, nearest_100, expiry):
exp = expiry
puts = []
for i in range(-400, 0, 100):
sym = 'nifty' + exp.strftime('%y%b').lower() + str(nearest_100 + i) + 'pe'
feed = client.get_live_feed(client.get_instrument_by_symbol('nse_fo', sym),
upstox.LiveFeedType.Full)
puts.append(feed)
puts_sorted = sorted(puts, key=lambda k: float(k['close']))
self.pe_symbol = puts_sorted[0]['symbol'].lower()
def _create_ce_symbol(self, client, nearest_100, expiry):
exp = expiry
calls = []
for i in range(0, 400, 100):
sym = 'nifty' + exp.strftime('%y%b').lower() + str(nearest_100 + i) + 'ce'
feed = client.get_live_feed(client.get_instrument_by_symbol('nse_fo', sym),
upstox.LiveFeedType.Full)
calls.append(feed)
calls_sorted = sorted(calls, key=lambda k: float(k['close']))
self.ce_symbol = calls_sorted[0]['symbol'].lower()
def _log_trade(self, trade_info=None):
if trade_info is None:
self.logger.error('Invalid trade info given to _log_trade()')
lots = int(int(trade_info['quantity']) / 75)
sym = trade_info['symbol'].lower()
oid = str(trade_info['order_id'])
poid = str(trade_info['parent_order_id'])
if trade_info['transaction_type'] == BUY:
self.logger.info('Purchased %d lots of %s' % (lots, sym))
else:
self.logger.info('Sold %d lots of %s' % (lots, sym))
if poid != 'NA':
self.logger.info('Parent OID - %s' % poid)
self.logger.info('Order ID - %s' % oid)