-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
#BMCLI - Bitmex Api Tool | ||
|
||
~ Darkerego, 2019 - 2020 | ||
====== | ||
|
||
## About: | ||
|
||
<p> | ||
Bmcli is a python3 powered, command line API tool for interacting with the Bitmex | ||
exchange. It is intended to make manual trading easier and more profitable by | ||
automating some of the things that traders do all of the time and offering some | ||
unique features such as <i>order chasing</i> and built in trailing stop functionality | ||
which does not use on Bitmex's trailing stop feature -- this is because bimex's stop's | ||
sometimes don't execute on time or properly due to 'system overload', or whatever. | ||
</p> | ||
|
||
## Features: | ||
|
||
- Create long/short limit/market/post/etc orders | ||
- Check account balance | ||
- Get current position | ||
- AutoStop - Watch for new positions and automatically set a stop loss, and trigger | ||
a trailing stop when the price goes a user defined percentage upwards. | ||
- Trailing Stops - Custom python implementation of trailing stop functionality | ||
- Limit Order Chasing - Chase your order up or down the books, amending the price | ||
so that it is at the top of the orderbook to ensure not paying the market fee and | ||
entering a position. Optionally use `chase_failsafe` to revert to a market order | ||
if the `max chase` variable is exceeded. | ||
|
||
## Usage: | ||
|
||
<pre> | ||
l$ ./bmcli -h | ||
usage: bmcli [-h] [-b] [-p] | ||
[-o {limit,market,post,stop,stop_limit,limit_if_touched}] [-c] | ||
[-F] [-M MAX_CHASE] [-t TRAILING_STOP] | ||
[-a AUTOSTOP AUTOSTOP AUTOSTOP] [-s SYMBOL] [-q QUANTITY] | ||
|
||
optional arguments: | ||
-h, --help show this help message and exit | ||
-b, --balance Get Balance | ||
-p, --position Get Position | ||
-o {limit,market,post,stop,stop_limit,limit_if_touched}, --order {limit,market,post,stop,stop_limit,limit_if_touched} | ||
Place an order | ||
-c, --chase Limit Order Chase | ||
-F, --chase_failsafe Revert to market if max chase exceeded. | ||
-M MAX_CHASE, --max_chase MAX_CHASE | ||
Max limit chase | ||
-t TRAILING_STOP, --trailing_stop TRAILING_STOP | ||
Place a trailing stop order with this offset. | ||
-a AUTOSTOP AUTOSTOP AUTOSTOP, --auto_stop AUTOSTOP AUTOSTOP AUTOSTOP | ||
Autostop Loss, Trailing Stop. Example -a 0.015 0.03 25 | ||
(Stop loss at 15 percent +/- entry price, enable | ||
trailing stop at 30 percent +/- entry price, close | ||
position when price drops 25 dollars +/- trailing stop | ||
price.) See documentation for more details. | ||
-s SYMBOL, --symbol SYMBOL | ||
Symbol self.of instrument | ||
-q QUANTITY, --qty QUANTITY | ||
Quantity for orders placed. Use negative value to open | ||
a short position. | ||
|
||
</pre> | ||
|
||
<p> | ||
First, edit `lib/conf.py` and add your api keys. | ||
</p> | ||
|
||
###### Check Balance: | ||
|
||
<pre> | ||
$ ./bmcli -b | ||
[+] Balance: 1417332 | ||
</pre> | ||
|
||
###### Get Current position | ||
|
||
<pre> | ||
[+] Position: 2000 | ||
</pre> | ||
|
||
###### Create Order | ||
<pre> | ||
./bmcli -o limit -q 100 -s XBTUSD | ||
INFO:lib.bitmex_api_lib:quote {'symbol': 'XBTUSD', 'id': 8799047500, 'side': 'Sell', 'size': 1539179, 'price': 9525.0} | ||
Sending buy order for 100.0 at 9525.0 , order type: limit | ||
[*] ({'orderID': '9945cbf4-10af-9a14-1d28-419d25a7481b', 'clOrdID': '', 'clOrdLinkID': '', 'account': 'xxxxxx', 'symbol': 'XBTUSD', 'side': 'Buy', 'simpleOrderQty': None, 'orderQty': 100, 'price': 9525.0, 'displayQty': None, 'stopPx': None, 'pegOffsetValue': None, 'pegPriceType': '', 'currency': 'USD', 'settlCurrency': 'XBt', 'ordType': 'Limit', 'timeInForce': 'GoodTillCancel', 'execInst': '', 'contingencyType': '', 'exDestination': 'XBME', 'ordStatus': 'Filled', 'triggered': '', 'workingIndicator': False, 'ordRejReason': '', 'simpleLeavesQty': None, 'leavesQty': 0, 'simpleCumQty': None, 'cumQty': 100, 'avgPx': 9524.5, 'multiLegReportingType': 'SingleSecurity', 'text': 'bmx_api_tool', 'transactTime': datetime.datetime(2020, 5, 20, 23, 20, 33, 286000, tzinfo=tzutc()), 'timestamp': datetime.datetime(2020, 5, 20, 23, 20, 33, 286000, tzinfo=tzutc())}, <bravado.requests_client.RequestsResponseAdapter object at 0x7f29c6868550>) | ||
|
||
</pre> | ||
|
||
###### Order Chase | ||
|
||
<pre> | ||
$ ./bmcli -c -q 100 -M 1 | ||
INFO:exchange_lib.bitmex_ws:Connecting to wss://www.bitmex.com/realtime?subscribe=execution:XBTUSD,instrument:XBTUSD,order:XBTUSD,position:XBTUSD,quote:XBTUSD,trade:XBTUSD,margin | ||
INFO:exchange_lib.bitmex_ws:Authenticating with API Key. | ||
INFO:exchange_lib.bitmex_ws:Connected to WS. | ||
INFO:exchange_lib.bitmex_ws:Got all market data. Starting. | ||
Sending buy order for 100.0 at 9515 , order type: limit | ||
INFO:lib.bitmex_api_lib:Chasing buy order c2e7fee0-20af-3f5d-a7b9-c22d49de2c19, order_price: 9508.0, last_price: 9508.0, current price: 9508 max chase: 9511.0 | ||
.... trunicated | ||
INFO:lib.bitmex_api_lib:Chasing buy order c2e7fee0-20af-3f5d-a7b9-c22d49de2c19, order_price: 9508.0, last_price: 9508.0, current price: 9508 max chase: 9511.0 | ||
INFO:lib.bitmex_api_lib:Order Filled | ||
|
||
</pre> | ||
See <a href='https://asciinema.org/a/Ctn7upSmaIuhhJOXEBxBZMYoi'>Asciinema Recording</a> here. | ||
|
||
|
||
###### Trailing Stop | ||
|
||
<pre> | ||
./bmcli -t 10 | ||
[+] Initializing Trailing Stop with offset: 10.0 | ||
INFO:exchange_lib.bitmex_ws:Connecting to wss://www.bitmex.com/realtime?subscribe=execution:XBTUSD,instrument:XBTUSD,order:XBTUSD,position:XBTUSD,quote:XBTUSD,trade:XBTUSD,margin | ||
INFO:exchange_lib.bitmex_ws:Authenticating with API Key. | ||
INFO:exchange_lib.bitmex_ws:Connected to WS. | ||
INFO:exchange_lib.bitmex_ws:Got all market data. Starting. | ||
INFO:bmexlib.bitmex_api_lib:Trailing stop triggered | ||
INFO:bmexlib.bitmex_api_lib:Trailing Stop for long position of entry price: 9535.6155 triggered: offset price 9521.5 current price: [9531.5] | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9533.00000000 Updating stop loss to 9523.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9538.50000000 Updating stop loss to 9528.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9539.00000000 Updating stop loss to 9529.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9540.50000000 Updating stop loss to 9530.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9545.00000000 Updating stop loss to 9535.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9546.50000000 Updating stop loss to 9536.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9547.00000000 Updating stop loss to 9537.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9550.00000000 Updating stop loss to 9540.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9560.50000000 Updating stop loss to 9550.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9562.00000000 Updating stop loss to 9552.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9567.00000000 Updating stop loss to 9557.00000000 | ||
Sending sell order for -2100 at 9553.5 , order type: market | ||
INFO:bmexlib.bitmex_api_lib:Sell triggered | Price: 9553.50000000 | Stop loss: 9557.00000000 | ||
|
||
</pre> | ||
<p> | ||
|
||
See <a href='https://asciinema.org/a/RUySuh40ObfavX7qxw8yafRSP'>Asciinema Recording</a> here. | ||
</p> | ||
###### AutoStop | ||
<pre> | ||
$ ./bmcli -a 0.001 0.005 10 | ||
[i] AutoStop: Stop Loss 0.01, Enable Trailing Stop: 0.005, Trail Offset: 10.0 | ||
INFO:exchange_lib.bitmex_ws:Connecting to wss://www.bitmex.com/realtime?subscribe=execution:XBTUSD,instrument:XBTUSD,order:XBTUSD,position:XBTUSD,quote:XBTUSD,trade:XBTUSD,margin | ||
INFO:exchange_lib.bitmex_ws:Authenticating with API Key. | ||
INFO:exchange_lib.bitmex_ws:Connected to WS. | ||
INFO:exchange_lib.bitmex_ws:Got all market data. Starting. | ||
INFO:bmexlib.bitmex_api_lib:Time: 2020-05-20 20:45:33, Position: 500, Entry Price: 9535.5, Current Price: 9537.5 | ||
INFO:bmexlib.bitmex_api_lib:Stop Loss Price: 9492.3, Trailing Stop Enable: 9549.54 | ||
INFO:bmexlib.bitmex_api_lib:Trailing stop triggered | ||
INFO:bmexlib.bitmex_api_lib:Trailing Stop for long position of entry price: 9535.5 triggered: offset price 9521.5 current price: [9531.5] | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9533.00000000 Updating stop loss to 9523.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9538.50000000 Updating stop loss to 9528.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9539.00000000 Updating stop loss to 9529.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9540.50000000 Updating stop loss to 9530.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9545.00000000 Updating stop loss to 9535.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9546.50000000 Updating stop loss to 9536.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9547.00000000 Updating stop loss to 9537.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9550.00000000 Updating stop loss to 9540.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9560.50000000 Updating stop loss to 9550.50000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9562.00000000 Updating stop loss to 9552.00000000 | ||
INFO:bmexlib.bitmex_api_lib:New high observed: 9567.00000000 Updating stop loss to 9557.00000000 | ||
Sending sell order for -2100 at 9553.5 , order type: market | ||
INFO:bmexlib.bitmex_api_lib:Sell triggered | Price: 9553.50000000 | Stop loss: 9557.00000000 | ||
|
||
</pre> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
BitMex API TOOL -- Python3 powered CLI tool to make manual bitmex trading easier. | ||
Features include: get account balance and position, create a new order, | ||
""" | ||
import argparse | ||
from lib.bitmex_api_lib import BitmexApiTool | ||
from lib.conf import * | ||
from colorama import Fore, Style, init | ||
|
||
init(autoreset=True) | ||
|
||
|
||
class ColorPrint: | ||
""" | ||
Colorized Output Class | ||
""" | ||
|
||
def red(self, data): | ||
print(Fore.RED + Style.BRIGHT + '[!] ' + Style.RESET_ALL + str(data)) | ||
|
||
def green(self, data): | ||
print(Fore.GREEN + Style.BRIGHT + '[+] ' + Style.RESET_ALL + str(data)) | ||
|
||
def yellow(self, data): | ||
print(Fore.YELLOW + Style.BRIGHT + '[i] ' + Style.RESET_ALL + str(data)) | ||
|
||
def blue(self, data): | ||
print(Fore.BLUE + Style.BRIGHT + '[+] ' + Style.RESET_ALL + str(data)) | ||
|
||
def cyan(self, data): | ||
print(Fore.CYAN + Style.BRIGHT + '[*] ' + Style.RESET_ALL + str(data)) | ||
|
||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-b', '--balance', dest='balance', action='store_true', help='Get Balance') | ||
parser.add_argument('-p', '--position', dest='position', action='store_true', help='Get Position') | ||
parser.add_argument('-o', '--order', dest='new_order', help='Place an order', type=str, choices=['limit', | ||
'market', | ||
'post', 'stop', | ||
'stop_limit', | ||
'limit_if_touched']) | ||
# TODO: better/more options for creating orders | ||
parser.add_argument('-c', '--chase', dest='chase', action='store_true', help='Limit Order Chase') | ||
parser.add_argument('-F', '--chase_failsafe', action='store_true', dest='failsafe', | ||
help='Revert to market if max chase exceeded.') | ||
parser.add_argument('-M', '--max_chase', dest='max_chase', default='3.0', type=float, help='Max limit chase') | ||
parser.add_argument('-t', '--trailing_stop', dest='trailing_stop', type=float, nargs=1, | ||
help='Place a trailing stop order with this offset.') | ||
parser.add_argument('-a', '--auto_stop', dest='autostop', action='store', type=float, nargs=3, | ||
help='Autostop Loss, Trailing Stop. Example -a 0.015 0.03 25 (Stop loss at 15 percent +/- ' | ||
'entry price, enable trailing stop at 30 percent +/- entry price, close position ' | ||
'when price drops 25 dollars +/- trailing stop price.) See documentation for more ' | ||
'details.') | ||
parser.add_argument('-s', '--symbol', dest='symbol', help='Symbol self.of instrument', default='XBTUSD') | ||
parser.add_argument('-q', '--qty', dest='quantity', type=float, help='Quantity for orders placed. ' | ||
'Use negative value to open a short position.') | ||
|
||
args = parser.parse_args() | ||
|
||
balance = args.balance | ||
position = args.position | ||
new_order = args.new_order | ||
chase = args.chase | ||
failsafe = args.failsafe | ||
max_chase = args.max_chase | ||
trailing_stop_order = args.trailing_stop | ||
autostop = args.autostop | ||
symbol = args.symbol | ||
quantity = args.quantity | ||
cp = ColorPrint() | ||
if balance: | ||
api = BitmexApiTool(symbol=symbol, api_key=api_key, api_secret=api_secret, test_net=testnet, require_ws=False) | ||
bal = api.get_balance() | ||
if bal == 0: | ||
cp.red('Zero balance available!') | ||
else: | ||
cp.green(f'Balance: {bal}') | ||
if position: | ||
api = BitmexApiTool(symbol=symbol, api_key=api_key, api_secret=api_secret, test_net=testnet, require_ws=False) | ||
pos = api.get_position() | ||
if pos == 0: | ||
cp.red(f'No position for {symbol}') | ||
exit(0) | ||
pos_qty = pos['openingQty'] + pos['execQty'] | ||
cp.green(f'Position: {pos_qty}') | ||
if new_order: | ||
api = BitmexApiTool(symbol=symbol, api_key=api_key, api_secret=api_secret, test_net=testnet, require_ws=False) | ||
cp.cyan(api.send_order(oq=quantity, ot=args.new_order)) | ||
if chase: | ||
api = BitmexApiTool(symbol=symbol, api_key=api_key, api_secret=api_secret, test_net=testnet, require_ws=True) | ||
api.limit_chase(oq=quantity, max_chase=max_chase, failsafe=failsafe, double_check=False) | ||
if trailing_stop_order: | ||
offset = float(trailing_stop_order[0]) | ||
cp.green(f'Initializing Trailing Stop with offset: {offset}') | ||
api = BitmexApiTool(symbol=symbol, api_key=api_key, api_secret=api_secret, test_net=testnet, require_ws=True) | ||
api.trailing_stop(offset=offset) | ||
if autostop: | ||
stop_loss = autostop[0] | ||
enable_ts = autostop[1] | ||
trail_offset = autostop[2] | ||
cp.yellow(f'AutoStop: Stop Loss {stop_loss}, Enable Trailing Stop: {enable_ts}, Trail Offset: {trail_offset}') | ||
api = BitmexApiTool(symbol=symbol, api_key=api_key, api_secret=api_secret, test_net=testnet, require_ws=True) | ||
api.auto_stop(stop_loss=stop_loss, enable_trailing_stop=enable_ts, trail_offset=trail_offset) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |