Skip to content

Commit

Permalink
orderbook price for dividend scanner
Browse files Browse the repository at this point in the history
  • Loading branch information
holohup committed Aug 21, 2023
1 parent b270231 commit 35a6f88
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ Although you might see more Bot commands in the source code, here's the list of
- **/nuke [ticker] [sum]** - places stop orders for the ticker, splitting sum into four: current price, 99% of current price, 95% of current price and 93% of current price, like in Art Cashin's formula
- **/stash** and **/restore** - stashes active stop orders to the database and restores them. Needed in case you urgently need to cancel everything and don't want to loose your precious stop orders parameters. The commands clean up before saving or restoring stops, only one stash is available.
- **/scan (rate)** - scans all the pairs of stock-future and future-future (available for trading) and returns the most profitable ones (the profit is normalized to yearly %, is counted upon the required margin to do the trade). Due to the message limits doesn't return more then 70 top profitable pairs. Rate is an optional parameter (the default rate is currently 7.5%).
- **/dscan (number of results)** - scans the market for the amount of dividends in the nearest 3 futures (stock-future and future-future pairs). Returns the pair tickers, dividend amount in the current prices, yield %, time till future expiration (maximum wait time), wheather the pair is available for trade in TCS and current spread buying price. To calculate the price, the orderbook data is used if it's trading time, otherwise the last trade prices.
- **/tasks** - returns the list of currently running tasks.

## Plans for the future
Expand Down
17 changes: 10 additions & 7 deletions bot/scanner/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class DividendSpread(NamedTuple):
days_till_expiration: int
yld: float
can_trade: bool
buy_price: float


class DivSpread(NamedTuple):
Expand Down Expand Up @@ -386,8 +387,9 @@ async def get_api_response(instrument: str):


class DividendScanner:
def __init__(self) -> None:
def __init__(self, result_limit=50) -> None:
self._ir = float(CURRENT_INTEREST_RATE)
self._result_limit = result_limit

async def scan_spreads(self):
await self._load_instruments()
Expand Down Expand Up @@ -424,17 +426,18 @@ async def scan_spreads(self):
days_till_expiration,
round(float(norm_delta / sell_price) * 100, 2),
can_trade=spread.can_trade,
buy_price=float(buy_price - sell_price * spread.ratio),
)
)
ordered = sorted(result, key=lambda s: s.yld, reverse=True)
spreads = [
f'{s.stock_ticker} - {s.future_ticker}: {s.dividend} RUB, {s.yld}%'
f', {s.days_till_expiration} days, {s.can_trade}'
f', {s.days_till_expiration} days, {s.can_trade},'
f' price: {s.buy_price}'
for s in ordered
if s.yld >= PERCENT_THRESHOLD
]
print(len(spreads))
return '\n'.join(spreads[:70])
return '\n'.join(spreads[: self._result_limit])

async def _load_instruments(self) -> None:
shares = await get_api_response('shares')
Expand Down Expand Up @@ -550,16 +553,16 @@ async def _update_from_orderbooks(self, uids_to_update):
)
result[uid] = OrderBook(
bid=quotation_to_decimal(ob.bids[0].price),
ask=quotation_to_decimal(ob.asks[0].price)
ask=quotation_to_decimal(ob.asks[0].price),
)
self._orderbooks.update(result)


async def dividend_scan(command, args):
return await DividendScanner().scan_spreads()
return await DividendScanner(int(args)).scan_spreads()


if __name__ == '__main__':
import asyncio

print(asyncio.run(dividend_scan(1, 1)))
print(asyncio.run(dividend_scan(1, 50)))

0 comments on commit 35a6f88

Please sign in to comment.