├── okex ├── okexapi │ ├── okexapi │ │ ├── __init__.py │ │ ├── HttpMD5Util.py │ │ ├── SpotAPI.py │ │ └── FutureAPI.py │ ├── setup.py │ └── apitest.py ├── IDEA ├── git_update.sh ├── killall.sh ├── run.sh ├── watcher │ ├── runner.sh │ ├── watcher.json │ └── my_watcher.py ├── strategy │ ├── future │ │ ├── config │ │ │ ├── 3kline.json │ │ │ ├── ma.json │ │ │ ├── ma_beta.json │ │ │ └── grid.json │ │ ├── base.py │ │ ├── 3kline.py │ │ ├── ma.py │ │ ├── ma_beta.py │ │ └── grid.py │ └── spot │ │ ├── config │ │ └── ma.json │ │ ├── test.py │ │ ├── base.py │ │ └── ma.py ├── runner.py └── loss_control │ └── atr │ ├── config.json │ └── atr.py ├── .gitignore └── README.md /okex/okexapi/okexapi/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /okex/IDEA: -------------------------------------------------------------------------------- 1 | 1. ma_beta, 均线交叉时反方向单不平,止损50%,只开新单;如,持有多单,止损50%(or more),遇死叉不平,只开空单 2 | -------------------------------------------------------------------------------- /okex/git_update.sh: -------------------------------------------------------------------------------- 1 | git add -A 2 | git commit -m 'update' 3 | git push origin master 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | dist 3 | build 4 | .DS_Store 5 | log 6 | log/* 7 | *.log 8 | *.out 9 | *.swp 10 | 11 | 12 | -------------------------------------------------------------------------------- /okex/killall.sh: -------------------------------------------------------------------------------- 1 | pid=$(ps -ef | grep python3 | grep -v grep | awk '{print $2}') 2 | 3 | for i in $pid 4 | do 5 | kill $i 6 | done 7 | -------------------------------------------------------------------------------- /okex/run.sh: -------------------------------------------------------------------------------- 1 | nohup python3 runner.py strategy/future/ma_beta.py strategy/future/config/ma_beta.json > log/future.log & 2 | nohup python3 runner.py strategy/spot/ma.py strategy/spot/config/ma.json > log/spot.log & 3 | -------------------------------------------------------------------------------- /okex/watcher/runner.sh: -------------------------------------------------------------------------------- 1 | function check(){ 2 | count=`ps -ef | grep my_watcher | grep -v 'grep' | wc -l` 3 | 4 | if [ 0 == $count ];then 5 | python3 my_watcher.py 6 | fi 7 | } 8 | 9 | while true 10 | do 11 | check 12 | done 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # okex auto trading 2 | 3 | ## intro 4 | * Implemented okex trading API in okex/okexapi 5 | * To use these API, you need to install it first: pip install okex/okexapi 6 | * Some simple trading strategies 7 | 8 | # WARNING 9 | This is just a toy, USE IT AT YOUR OWN RISK! 10 | 11 | -------------------------------------------------------------------------------- /okex/strategy/future/config/3kline.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key":"xxx", 3 | "secret_key":"xxx", 4 | "url":"www.okb.com", 5 | "coin":"eos_usd", 6 | "contract_type":"this_week", 7 | "kline_size":"3min", 8 | "kline_num":20, 9 | "open_ratio":0.15, 10 | "bbo":1, 11 | "leverage":20, 12 | "hold_for":10 13 | } 14 | -------------------------------------------------------------------------------- /okex/watcher/watcher.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key":"xxx", 3 | "secret_key":"xxx", 4 | "url":"www.okb.com", 5 | "coin":"eos_usd", 6 | "contract_type":"this_week", 7 | "kline_size":"15min", 8 | "kline_num":200, 9 | "amount_ratio":0.25, 10 | "bbo":1, 11 | "leverage":20, 12 | "lower":4.85, 13 | "upper":4.95 14 | } 15 | -------------------------------------------------------------------------------- /okex/strategy/spot/config/ma.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key":"xxx", 3 | "secret_key":"xxx", 4 | "url":"www.okb.com", 5 | "symbol":"eth_usdt", 6 | "kline_size":"15min", 7 | "kline_num":100, 8 | "amount_ratio":0.4, 9 | "bbo":1, 10 | "slow":20, 11 | "fast":5, 12 | "interval":5, 13 | "band_width":0.05, 14 | "least_amount":0.01 15 | } 16 | -------------------------------------------------------------------------------- /okex/okexapi/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup(name = 'okexapi', 4 | version = '18.9.4', 5 | description = 'okex future trading api', 6 | url = 'https://github.com/C790266922/okex.git', 7 | author = 'Cyan', 8 | author_email = 'ccyanxyz@gmail.com', 9 | licence = 'MIT', 10 | packages = ['okexapi'], 11 | zip_safe = False) 12 | -------------------------------------------------------------------------------- /okex/runner.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import json 4 | import logging 5 | import sys 6 | 7 | strategy = sys.argv[1] 8 | config = sys.argv[2] 9 | 10 | if __name__ == '__main__': 11 | while os.system('python3 ' + strategy + ' ' + config): 12 | time.sleep(3) 13 | try: 14 | print('RESTARTNG...') 15 | except KeyboardInterrupt: 16 | exit() 17 | -------------------------------------------------------------------------------- /okex/strategy/future/config/ma.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key":"xxx", 3 | "secret_key":"xxx", 4 | "url":"www.okb.com", 5 | "coin":"eos_usd", 6 | "contract_type":"this_week", 7 | "kline_size":"15min", 8 | "kline_num":200, 9 | "amount_ratio":0.15, 10 | "bbo":1, 11 | "leverage":20, 12 | "slow":20, 13 | "fast":5, 14 | "interval":15, 15 | "stop_loss":-20 16 | } 17 | -------------------------------------------------------------------------------- /okex/loss_control/atr/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key":"6d1f9dc9-95f2-4595-a9c0-20bd344a5154", 3 | "secret_key":"C275C775AA323969F1CB936216735126", 4 | "url":"www.okb.com", 5 | "coin":"eos_usd", 6 | "contract_type":"this_week", 7 | "kline_size":"15min", 8 | "kline_num":200, 9 | "open_ratio":0.25, 10 | "bbo":1, 11 | "leverage":20, 12 | "slow_ma":60, 13 | "fast_ma":5 14 | } 15 | -------------------------------------------------------------------------------- /okex/strategy/future/config/ma_beta.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key":"xxx", 3 | "secret_key":"xxx", 4 | "url":"www.okb.com", 5 | "coin":"eth_usdt", 6 | "contract_type":"quarter", 7 | "kline_size":"15min", 8 | "kline_num":200, 9 | "amount_ratio":0.9, 10 | "bbo":1, 11 | "leverage":20, 12 | "slow":20, 13 | "fast":5, 14 | "interval":5, 15 | "stop_loss":-50, 16 | "band_width":0.05 17 | } 18 | -------------------------------------------------------------------------------- /okex/strategy/future/config/grid.json: -------------------------------------------------------------------------------- 1 | { 2 | "api_key":"xxx", 3 | "secret_key":"xxx", 4 | "url":"www.okb.com", 5 | "coin":"eos_usd", 6 | "contract_type":"this_week", 7 | "kline_size":"15min", 8 | "kline_num":200, 9 | "bbo":0, 10 | "leverage":20, 11 | "grid_size":1, 12 | "amount":15, 13 | "times_atr":0.7, 14 | "interval":15, 15 | "clear_interval":120, 16 | "amount_ratio":0.3, 17 | "fast_kline":5, 18 | "slow_kline":20, 19 | "gap":0.020, 20 | "use_gap":true, 21 | "stop_win":10, 22 | "stop_loss":-40 23 | } 24 | -------------------------------------------------------------------------------- /okex/strategy/spot/test.py: -------------------------------------------------------------------------------- 1 | from base import * 2 | import json 3 | 4 | f = open('./config/ma.json', 'r') 5 | config = json.load(f) 6 | 7 | api_key = config['api_key'] 8 | secret_key = config['secret_key'] 9 | symbol = config['symbol'] 10 | url = config['url'] 11 | kline_size = config['kline_size'] 12 | 13 | logger = get_logger() 14 | 15 | b = Base(api_key, secret_key, url, logger) 16 | 17 | # print(b.get_kline(symbol, kline_size = kline_size, kline_num = 5)) 18 | eth = b.get_available('eth') 19 | print(eth) 20 | # print(b.spot.sell('eth_usdt', 230, eth, 1)) 21 | 22 | usdt = b.get_available('usdt') 23 | print(usdt) 24 | print(b.spot.buy('eth_usdt', 211, usdt, 1)) 25 | 26 | -------------------------------------------------------------------------------- /okex/okexapi/okexapi/HttpMD5Util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import http.client 4 | import urllib 5 | import json 6 | import hashlib 7 | import time 8 | 9 | def buildMySign(params,secretKey): 10 | sign = '' 11 | for key in sorted(params.keys()): 12 | sign += key + '=' + str(params[key]) +'&' 13 | data = sign+'secret_key='+secretKey 14 | return hashlib.md5(data.encode("utf8")).hexdigest().upper() 15 | 16 | def httpGet(url,resource,params=''): 17 | conn = http.client.HTTPSConnection(url, timeout=10) 18 | conn.request("GET",resource + '?' + params) 19 | response = conn.getresponse() 20 | data = response.read().decode('utf-8') 21 | return json.loads(data) 22 | 23 | def httpPost(url,resource,params): 24 | headers = { 25 | "Content-type" : "application/x-www-form-urlencoded", 26 | } 27 | conn = http.client.HTTPSConnection(url, timeout=10) 28 | temp_params = urllib.parse.urlencode(params) 29 | conn.request("POST", resource, temp_params, headers) 30 | response = conn.getresponse() 31 | data = response.read().decode('utf-8') 32 | params.clear() 33 | conn.close() 34 | return json.loads(data) 35 | 36 | -------------------------------------------------------------------------------- /okex/okexapi/apitest.py: -------------------------------------------------------------------------------- 1 | from okexapi.FutureAPI import Future 2 | import json 3 | import time 4 | 5 | f = open('../config.json', 'r') 6 | config = json.load(f) 7 | 8 | url = config['url'] 9 | api_key = config['api_key'] 10 | secret_key = config['secret_key'] 11 | 12 | future = Future(url, api_key, secret_key) 13 | 14 | coin = config['coin'] 15 | contract_type = config['contract_type'] 16 | bbo = config['bbo'] 17 | amount = 1 18 | price = 1 19 | leverage = 20 20 | 21 | # get position 22 | position = future.get_position(coin, contract_type) 23 | print(position) 24 | 25 | orders = future.future_orderinfo(coin, contract_type, -1, 1, 1, 50) 26 | print(orders) 27 | 28 | ''' 29 | # open long 30 | ret = future.open_long(coin, contract_type, price, 100000000, leverage, bbo) 31 | print(ret) 32 | position = future.get_position(coin, contract_type) 33 | print(position) 34 | time.sleep(5) 35 | 36 | # close long 37 | ret = future.close_long(coin, contract_type, price, amount, leverage, bbo) 38 | print(ret) 39 | position = future.get_position(coin, contract_type) 40 | print(position) 41 | time.sleep(5) 42 | 43 | # open short 44 | ret = future.open_short(coin, contract_type, price, amount, leverage, bbo) 45 | print(ret) 46 | position = future.get_position(coin, contract_type) 47 | print(position) 48 | time.sleep(5) 49 | 50 | # close short 51 | ret = future.close_short(coin, contract_type, price, amount, leverage, bbo) 52 | print(ret) 53 | position = future.get_position(coin, contract_type) 54 | print(position) 55 | ''' 56 | -------------------------------------------------------------------------------- /okex/loss_control/atr/atr.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import time 3 | import json 4 | import talib as tb 5 | import logging 6 | from okexapi.FutureAPI import Future 7 | 8 | 9 | logging.basicConfig( 10 | # filename = './atr_loss_control.log', 11 | level = logging.INFO, 12 | format = '[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s', 13 | datefmt = '%Y-%m-%d %H:%M:%S', 14 | filemode = 'a' 15 | ) 16 | logger = logging.getLogger('controler') 17 | 18 | f = open('config.json', 'r') 19 | config = json.load(f) 20 | 21 | url = config['url'] 22 | api_key = config['api_key'] 23 | secret_key = config['secret_key'] 24 | 25 | future = Future(url, api_key, secret_key, logger) 26 | 27 | coin = config['coin'] 28 | contract_type = config['contract_type'] 29 | kline_size = config['kline_size'] 30 | kline_num = config['kline_num'] 31 | 32 | while True: 33 | 34 | kline = future.future_kline(coin, contract_type, kline_size, kline_num) 35 | high = [kline[i][2] for i in range(kline_num)] 36 | low = [kline[i][3] for i in range(kline_num)] 37 | close = [kline[i][4] for i in range(kline_num)] 38 | 39 | high = np.array(high) 40 | low = np.array(low) 41 | close = np.array(close) 42 | 43 | atr = tb.ATR(high, low, close, timeperiod = 14) 44 | 45 | last = close[-1] 46 | 47 | logger.info('last: ' + str(last) + ', atr[-1]: ' + str(atr[-1])) 48 | logger.info('3atr: ' + str(3 * atr[-1])) 49 | logger.info('+3atr: ' + str(last + 3 * atr[-1]) + ', -3atr: ' + str(last - 3 * atr[-1])) 50 | 51 | 52 | time.sleep(3) 53 | 54 | -------------------------------------------------------------------------------- /okex/strategy/spot/base.py: -------------------------------------------------------------------------------- 1 | from okexapi.SpotAPI import Spot 2 | import talib as tb 3 | import numpy as np 4 | import logging 5 | 6 | 7 | class Base: 8 | 9 | def __init__(self, api_key, secret_key, url, logger = None): 10 | self.__api_key = api_key 11 | self.__secret_key = secret_key 12 | self.url = url 13 | if logger: 14 | self.logger = logger 15 | else: 16 | self.logger = logging.getLogger('tradebot') 17 | 18 | self.spot = Spot(url, api_key, secret_key, logger) 19 | 20 | def get_kline(self, symbol, kline_size, kline_num = None, since = None): 21 | kline = self.spot.spot_kline(symbol, kline_size, kline_num) 22 | 23 | return kline 24 | 25 | def get_available(self, coin): 26 | userinfo = self.spot.userinfo() 27 | coin_avail = userinfo['info']['funds']['free'][coin] 28 | 29 | return float(coin_avail) 30 | 31 | def get_order_info(self, symbol, order_id): 32 | ret = self.spot.order_info(symbol, order_id) 33 | return ret 34 | 35 | def get_last(self, symbol): 36 | kline = self.get_kline(symbol, '1min', 1) 37 | return kline[-1][4] 38 | 39 | def clear_pending_orders(self, symbol): 40 | order_id = -1 # get unfilled or partially filled orders 41 | orders = self.get_order_info(symbol, order_id)['orders'] 42 | for order in orders: 43 | id = order['order_id'] 44 | self.spot.cancel_order(symbol, id) 45 | 46 | def get_logger(): 47 | logging.basicConfig( 48 | # filename = './log/' + log_filename + str(time.strftime('%m-%d %H:%M:%S')), 49 | level = logging.INFO, 50 | format = '[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s', 51 | datefmt = '%Y-%m-%d %H:%M:%S', 52 | filemode = 'a' 53 | ) 54 | return logging.getLogger('tradebot') 55 | -------------------------------------------------------------------------------- /okex/strategy/future/base.py: -------------------------------------------------------------------------------- 1 | from okexapi.FutureAPI import Future 2 | import talib as tb 3 | import numpy as np 4 | import logging 5 | 6 | 7 | class Base: 8 | 9 | def __init__(self, api_key, secret_key, url, logger = None): 10 | self.__api_key = api_key 11 | self.__secret_key = secret_key 12 | self.url = url 13 | if logger: 14 | self.logger = logger 15 | else: 16 | self.logger = logging.getLogger('tradebot') 17 | 18 | self.future = Future(url, api_key, secret_key, logger) 19 | 20 | def get_kline(self, symbol, contract_type, kline_size, kline_num): 21 | kline = self.future.future_kline(symbol, contract_type, kline_size, kline_num) 22 | 23 | return kline 24 | 25 | def get_position(self, symbol, contract_type): 26 | long_amount, long_profit, short_amount, short_profit = self.future.get_position(symbol, contract_type) 27 | return long_amount, long_profit, short_amount, short_profit 28 | 29 | def get_available(self, symbol): 30 | ret = self.future.future_userinfo_4fix()['info'][symbol[:3]] 31 | # print(ret) 32 | avail = 0 33 | for item in ret['contracts']: 34 | if item['contract_type'] == 'quarter': 35 | avail = item['available'] 36 | # print(self.future.future_userinfo_4fix()['info'][symbol[:3]]) 37 | return avail 38 | 39 | def clear_pending_orders(self, symbol, contract_type): 40 | order_id = -1 # get orders with specific status 41 | status = 1 # unfilled orders, 2: filled orders 42 | page = 1 43 | page_len = 50 # max 50 44 | orders = self.future.future_orderinfo(symbol, contract_type, order_id, status, page, page_len) 45 | for order in orders: 46 | id = order['order_id'] 47 | self.future.future_cancel(symbol, contract_type, id) 48 | 49 | def get_logger(): 50 | logging.basicConfig( 51 | # filename = './log/' + log_filename + str(time.strftime('%m-%d %H:%M:%S')), 52 | level = logging.INFO, 53 | format = '[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s', 54 | datefmt = '%Y-%m-%d %H:%M:%S', 55 | filemode = 'a' 56 | ) 57 | return logging.getLogger('tradebot') 58 | -------------------------------------------------------------------------------- /okex/strategy/future/3kline.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import time 4 | import arrow 5 | from talib import SMA 6 | import json 7 | import logging 8 | from okexapi.FutureAPI import Future 9 | from base import * 10 | 11 | class 3kline(Base): 12 | 13 | def __init__(self, 14 | api_key, 15 | secret_key, 16 | url, 17 | kline_size, 18 | kline_num) 19 | # TODO: rewrite 20 | 21 | 22 | def get_amount(): 23 | coin_available = future.future_userinfo_4fix()['info'][coin[:3]]['contracts'][0]['available'] 24 | return int(leverage * amount_ratio * coin_available) 25 | 26 | def three_up(opens, closes): 27 | if opens[-4] <= closes[-4] and opens[-3] <= closes[-3] and opens[-2] <= closes[-2]: 28 | return True 29 | else: 30 | return False 31 | 32 | def three_down(opens, closes): 33 | if opens[-4] >= closes[-4] and opens[-3] >= closes[-3] and opens[-2] >= closes[-2]: 34 | return True 35 | else: 36 | return False 37 | 38 | while True: 39 | kline = future.future_kline(coin, contract_type, kline_size, kline_num) 40 | last_closes = [kline[i][4] for i in range(kline_num)] 41 | last_opens = [kline[i][1] for i in range(kline_num)] 42 | 43 | long_amount, long_profit, short_amount, short_profit = future.get_position(coin, contract_type) 44 | logger.info('position: long_amount = %s, long_profit = %s, short_amount = %s, short_profit = %s' % (long_amount, long_profit, short_amount, short_profit)) 45 | 46 | coin_available = future.future_userinfo_4fix()['info'][coin[:3]]['contracts'][0]['available'] 47 | logger.info('coin_available = ' + str(coin_available)) 48 | 49 | last = kline[-1][4] 50 | 51 | if three_up(last_opens, last_closes) and long_amount < 1: 52 | logger.info('Three up.') 53 | if short_amount > 0: 54 | logger.info('close short, amount: %d' % short_amount) 55 | future.close_short(coin, contract_type, last, short_amount, leverage, bbo) 56 | amount = get_amount() 57 | future.open_long(coin, contract_type, last, amount, leverage, bbo) 58 | logger.info('open long, amount: %d' % amount) 59 | elif three_down(last_opens, last_closes) and short_amount < 1: 60 | logger.info('Three down.') 61 | if long_amount > 0: 62 | logger.info('close long, amount: %d' % long_amount) 63 | future.close_long(coin, contract_type, last, long_amount, leverage, bbo) 64 | amount = get_amount() 65 | future.open_short(coin, contract_type, last, amount, leverage, bbo) 66 | logger.info('open short, amount: %d' % amount) 67 | else: 68 | logger.info('no trading signal.') 69 | 70 | time.sleep(15) 71 | 72 | 73 | 74 | if __name__ == '__main__': 75 | config_path = sys.argv[1] 76 | 77 | f = open('config.json', encoding = 'utf-8') 78 | config = json.load(f) 79 | 80 | #初始化apikey,secretkey,url 81 | apikey = config['api_key'] 82 | secretkey = config['secret_key'] 83 | okcoinRESTURL = config['url'] 84 | 85 | 86 | #期货API 87 | future = Future(okcoinRESTURL, apikey, secretkey, logger) 88 | 89 | coin = config['coin'] 90 | contract_type = config['contract_type'] 91 | kline_size = config['kline_size'] 92 | kline_num = config['kline_num'] 93 | amount_ratio = config['open_ratio'] 94 | 95 | bbo = config['bbo'] 96 | leverage = config['leverage'] 97 | hold_for = config['hold_for'] 98 | 99 | 100 | -------------------------------------------------------------------------------- /okex/strategy/spot/ma.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import time 4 | import arrow 5 | from talib import SMA 6 | import json 7 | import logging 8 | from okexapi.FutureAPI import Future 9 | from base import * 10 | 11 | 12 | class Ma(Base): 13 | 14 | def __init__(self, 15 | api_key, 16 | secret_key, 17 | url, 18 | symbol, 19 | kline_size, # kline size, 15min 20 | kline_num, # number of klines to get 21 | amount_ratio, # percentage of available coins 22 | bbo, # 1: market price, 0: use given price 23 | fast, # fast kline period, 5 24 | slow, # slow kline period, 20 25 | interval, 26 | band_width, 27 | least_amount, 28 | logger = None): 29 | 30 | super(Ma, self).__init__(api_key, secret_key, url, logger) 31 | self.symbol = symbol 32 | idx = symbol.index('_') 33 | self.coin = symbol[:idx] 34 | self.currency = symbol[idx + 1:] 35 | self.kline_size = kline_size 36 | self.kline_num = kline_num 37 | self.amount_ratio = amount_ratio 38 | self.bbo = bbo 39 | self.fast = fast 40 | self.slow = slow 41 | self.interval = interval 42 | self.band_width = band_width 43 | self.least_amount = least_amount 44 | 45 | 46 | def get_amount(self, coin): 47 | 48 | return self.get_available(coin) 49 | 50 | def ma_cross(self, fast_ma, slow_ma): 51 | # stable version 52 | if fast_ma[-3] < slow_ma[-3] and fast_ma[-2] >= slow_ma[-2]: 53 | return 'gold' 54 | elif fast_ma[-3] > slow_ma[-3] and fast_ma[-2] <= slow_ma[-2]: 55 | return 'dead' 56 | else: 57 | return 'nothing' 58 | 59 | def run_forever(self): 60 | 61 | while True: 62 | usdt_available = round(self.get_available('usdt'), 2) - 0.05 63 | coin_available = round(self.get_available(self.coin) - 0.001, 3) 64 | 65 | self.logger.info('position: usdt = %s, %s = %s' % (usdt_available, self.coin, coin_available)) 66 | 67 | kline = self.get_kline(self.symbol, self.kline_size, self.kline_num) 68 | 69 | close = np.array([float(kline[i][4]) for i in range(self.kline_num)]) 70 | 71 | fast_ma = tb.SMA(close, int(self.fast)) 72 | slow_ma = tb.SMA(close, int(self.slow)) 73 | slow_upper = slow_ma + self.band_width 74 | slow_lower = slow_ma - self.band_width 75 | self.logger.info('fast_ma:' + str(fast_ma[-1]) + ', slow_ma:' + str(slow_ma[-1])) 76 | 77 | last = float(kline[-1][4]) 78 | self.logger.info('last: ' + str(last)) 79 | 80 | cross_with_upper = self.ma_cross(fast_ma, slow_upper) 81 | cross_with_slow = self.ma_cross(fast_ma, slow_ma) 82 | self.logger.info('cross_with_upper:' + cross_with_upper + ', cross_with_slow:' + cross_with_slow) 83 | 84 | 85 | if cross_with_upper == 'gold' and coin_available < self.least_amount: 86 | self.logger.info('golden cross with upper bond') 87 | amount = usdt_available 88 | if amount < 1: 89 | continue 90 | self.spot.buy(self.symbol, last, amount, self.bbo) 91 | self.logger.info('buy at: %f, amount: %f' % (last, amount)) 92 | 93 | if cross_with_slow == 'dead' and coin_available > self.least_amount: 94 | self.logger.info('dead cross with slow ma') 95 | self.spot.sell(self.symbol, last, coin_available, self.bbo) 96 | self.logger.info('sell at: %f, amount: %f' % (last, coin_available)) 97 | 98 | time.sleep(self.interval) 99 | 100 | 101 | if __name__ == '__main__': 102 | 103 | config_path = sys.argv[1] 104 | 105 | f = open(config_path, encoding = 'utf-8') 106 | config = json.load(f) 107 | 108 | api_key = config['api_key'] 109 | secret_key = config['secret_key'] 110 | url = config['url'] 111 | 112 | symbol = config['symbol'] 113 | kline_size = config['kline_size'] 114 | kline_num = config['kline_num'] 115 | amount_ratio = config['amount_ratio'] 116 | slow = config['slow'] 117 | fast = config['fast'] 118 | interval = config['interval'] 119 | 120 | bbo = config['bbo'] 121 | band_width = config['band_width'] 122 | least_amount = config['least_amount'] 123 | 124 | logger = get_logger() 125 | 126 | ma_bot = Ma(api_key, 127 | secret_key, 128 | url, 129 | symbol, 130 | kline_size, 131 | kline_num, 132 | amount_ratio, 133 | bbo, 134 | fast, 135 | slow, 136 | interval, 137 | band_width, 138 | least_amount, 139 | logger = logger) 140 | 141 | 142 | ma_bot.run_forever() 143 | 144 | 145 | -------------------------------------------------------------------------------- /okex/watcher/my_watcher.py: -------------------------------------------------------------------------------- 1 | from okexapi.FutureAPI import Future 2 | import talib as tb 3 | import numpy as np 4 | import logging 5 | import json 6 | import os 7 | import sys 8 | import time 9 | import re 10 | import _thread 11 | 12 | 13 | class Watcher: 14 | 15 | def __init__(self, api_key, secret_key, url, symbol, contract_type, leverage, kline_size, kline_num, logger = None): 16 | self.__api_key = api_key 17 | self.__secret_key = secret_key 18 | self.url = url 19 | self.symbol = symbol 20 | self.contract_type = contract_type 21 | self.leverage = leverage 22 | self.kline_size = kline_size 23 | self.kline_num = kline_num 24 | 25 | if logger: 26 | self.logger = logger 27 | else: 28 | self.logger = logging.getLogger('tradebot') 29 | 30 | self.future = Future(url, api_key, secret_key, logger) 31 | 32 | def get_kline(self): 33 | kline = self.future.future_kline(self.symbol, self.contract_type, self.kline_size, self.kline_num) 34 | 35 | return kline 36 | 37 | def get_position(self): 38 | long_amount, long_profit, short_amount, short_profit = self.future.get_position(self.symbol, self.contract_type) 39 | return long_amount, long_profit, short_amount, short_profit 40 | 41 | def get_available(self): 42 | coin_avail = self.future.future_userinfo_4fix()['info'][self.symbol[:3]]['contracts'][0]['available'] 43 | return coin_avail 44 | 45 | def get_last(self): 46 | kline = self.get_kline() 47 | return kline[-1][4] 48 | 49 | def open_long(self, price, amount, bbo): 50 | ret = self.future.open_long(self.symbol, self.contract_type, price, amount, self.leverage, bbo) 51 | return ret 52 | 53 | def close_long(self, price, amount, bbo): 54 | ret = self.future.close_long(self.symbol, self.contract_type, price, amount, self.leverage, bbo) 55 | return ret 56 | 57 | def open_short(self, price, amount, bbo): 58 | ret = self.future.open_short(self.symbol, self.contract_type, price, amount, self.leverage, bbo) 59 | return ret 60 | 61 | def close_short(self, price, amount, bbo): 62 | ret = self.future.close_short(self.symbol, self.contract_type, price, amount, self.leverage, bbo) 63 | 64 | def watch_forever(self, upper, lower): 65 | 66 | while True: 67 | last = watcher.get_last() 68 | if last >= upper: 69 | cmd = "osascript -e 'display notification \"" + 'last price: ' + str(last) + ' > upper: ' + str(upper) + "\" with title \"okex\" ' " 70 | 71 | os.system(cmd) 72 | 73 | if last <= lower: 74 | cmd = "osascript -e 'display notification \"" + 'last price: ' + str(last) + ' < lower: ' + str(lower) + "\" with title \"okex\" ' " 75 | 76 | os.system(cmd) 77 | 78 | self.logger.info('last = ' + str(last)) 79 | 80 | time.sleep(15) 81 | 82 | def control(self, nothing): 83 | 84 | amount_matcher = re.compile('\d{1, 10}') 85 | 86 | while True: 87 | 88 | cmd = input('~>') 89 | 90 | bbo = 1 91 | price = self.get_last() 92 | amount = int(amount_matcher.findall(cmd)[0]) 93 | 94 | if 'open long' in cmd: 95 | self.open_long(price, amount, bbo) 96 | elif 'close long' in cmd: 97 | self.close_long(price, amount, bbo) 98 | elif 'open short' in cmd: 99 | self.open_short(price, amount, bbo) 100 | elif 'close short' in cmd: 101 | self.close_short(price, amount, bbo) 102 | else: 103 | print('wrong command.') 104 | 105 | 106 | def get_logger(): 107 | logging.basicConfig( 108 | # filename = './log/' + log_filename + str(time.strftime('%m-%d %H:%M:%S')), 109 | level = logging.INFO, 110 | format = '[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s', 111 | datefmt = '%Y-%m-%d %H:%M:%S', 112 | filemode = 'a' 113 | ) 114 | return logging.getLogger('tradebot') 115 | 116 | if __name__ == '__main__': 117 | 118 | config_path = './watcher.json' 119 | f = open(config_path, 'r') 120 | config = json.load(f) 121 | 122 | api_key = config['api_key'] 123 | secret_key = config['secret_key'] 124 | url = config['url'] 125 | symbol = config['coin'] 126 | contract_type = config['contract_type'] 127 | kline_size = config['kline_size'] 128 | kline_num = config['kline_num'] 129 | leverage = config['leverage'] 130 | 131 | upper = config['upper'] 132 | lower = config['lower'] 133 | 134 | logger = get_logger() 135 | watcher = Watcher(api_key, secret_key, url, symbol, contract_type, leverage, kline_size, kline_num, logger) 136 | 137 | # upper = float(input('~> upper limit:')) 138 | # lower = float(input('~> lower limit:')) 139 | # lower = float(sys.argv[1]) 140 | # upper = float(sys.argv[2]) 141 | 142 | watcher.watch_forever(upper, lower) 143 | ''' 144 | _thread.start_new_thread(watcher.watch_forever, (upper, lower)) 145 | _thread.start_new_thread(watcher.control, ('nothing', )) 146 | ''' 147 | -------------------------------------------------------------------------------- /okex/okexapi/okexapi/SpotAPI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from .HttpMD5Util import buildMySign,httpGet,httpPost 4 | import logging 5 | 6 | class Spot: 7 | 8 | def __init__(self, url, apikey, secretkey, logger = None): 9 | self.__url = url 10 | self.__apikey = apikey 11 | self.__secretkey = secretkey 12 | if logger: 13 | self.logger = logger 14 | else: 15 | self.logger = logging.getLogger('tradebot') 16 | 17 | #获取OKCOIN现货行情信息 18 | def ticker(self,symbol = ''): 19 | TICKER_RESOURCE = "/api/v1/ticker.do" 20 | params='' 21 | if symbol: 22 | params = 'symbol=%(symbol)s' %{'symbol':symbol} 23 | return httpGet(self.__url,TICKER_RESOURCE,params) 24 | 25 | #获取OKCOIN现货市场深度信息 26 | def depth(self,symbol = ''): 27 | DEPTH_RESOURCE = "/api/v1/depth.do" 28 | params='' 29 | if symbol: 30 | params = 'symbol=%(symbol)s' %{'symbol':symbol} 31 | return httpGet(self.__url,DEPTH_RESOURCE,params) 32 | 33 | #获取OKCOIN现货历史交易信息 34 | def trades(self,symbol = ''): 35 | TRADES_RESOURCE = "/api/v1/trades.do" 36 | params='' 37 | if symbol: 38 | params = 'symbol=%(symbol)s' %{'symbol':symbol} 39 | return httpGet(self.__url,TRADES_RESOURCE,params) 40 | 41 | # get kline 42 | def spot_kline(self, symbol, type_, size = None, since = None): 43 | KLINE_RESOURCE = "/api/v1/kline.do" 44 | params = 'symbol=' + symbol + '&type=' + type_ 45 | if size: 46 | params += '&size=' + str(size) 47 | if since: 48 | params += '&since=' + str(since) 49 | return httpGet(self.__url, KLINE_RESOURCE, params) 50 | 51 | 52 | 53 | #获取用户现货账户信息 54 | def userinfo(self): 55 | USERINFO_RESOURCE = "/api/v1/userinfo.do" 56 | params ={} 57 | params['api_key'] = self.__apikey 58 | params['sign'] = buildMySign(params,self.__secretkey) 59 | return httpPost(self.__url,USERINFO_RESOURCE,params) 60 | 61 | #现货交易 62 | def trade(self, symbol, trade_type, price, amount): 63 | TRADE_RESOURCE = "/api/v1/trade.do" 64 | params = { 65 | 'api_key':self.__apikey, 66 | 'symbol':symbol, 67 | 'type':trade_type 68 | } 69 | if price: 70 | params['price'] = str(price) 71 | if amount: 72 | params['amount'] = str(amount) 73 | 74 | params['sign'] = buildMySign(params,self.__secretkey) 75 | return httpPost(self.__url,TRADE_RESOURCE,params) 76 | 77 | #现货批量下单 78 | def batch_trade(self,symbol,tradeType,orders_data): 79 | BATCH_TRADE_RESOURCE = "/api/v1/batch_trade.do" 80 | params = { 81 | 'api_key':self.__apikey, 82 | 'symbol':symbol, 83 | 'type':tradeType, 84 | 'orders_data':orders_data 85 | } 86 | params['sign'] = buildMySign(params,self.__secretkey) 87 | return httpPost(self.__url,BATCH_TRADE_RESOURCE,params) 88 | 89 | #现货取消订单 90 | def cancel_order(self, symbol, orderId): 91 | CANCEL_ORDER_RESOURCE = "/api/v1/cancel_order.do" 92 | params = { 93 | 'api_key':self.__apikey, 94 | 'symbol':symbol, 95 | 'order_id':orderId 96 | } 97 | params['sign'] = buildMySign(params,self.__secretkey) 98 | return httpPost(self.__url,CANCEL_ORDER_RESOURCE,params) 99 | 100 | #现货订单信息查询 101 | def order_info(self,symbol,orderId): 102 | ORDER_INFO_RESOURCE = "/api/v1/order_info.do" 103 | params = { 104 | 'api_key':self.__apikey, 105 | 'symbol':symbol, 106 | 'order_id':orderId 107 | } 108 | params['sign'] = buildMySign(params,self.__secretkey) 109 | return httpPost(self.__url,ORDER_INFO_RESOURCE,params) 110 | 111 | #现货批量订单信息查询 112 | def orders_info(self,symbol,orderId,tradeType): 113 | ORDERS_INFO_RESOURCE = "/api/v1/orders_info.do" 114 | params = { 115 | 'api_key':self.__apikey, 116 | 'symbol':symbol, 117 | 'order_id':orderId, 118 | 'type':tradeType 119 | } 120 | params['sign'] = buildMySign(params,self.__secretkey) 121 | return httpPost(self.__url,ORDERS_INFO_RESOURCE,params) 122 | 123 | #现货获得历史订单信息 124 | def order_history(self,symbol,status,currentPage,pageLength): 125 | ORDER_HISTORY_RESOURCE = "/api/v1/order_history.do" 126 | params = { 127 | 'api_key':self.__apikey, 128 | 'symbol':symbol, 129 | 'status':status, 130 | 'current_page':currentPage, 131 | 'page_length':pageLength 132 | } 133 | params['sign'] = buildMySign(params,self.__secretkey) 134 | return httpPost(self.__url,ORDER_HISTORY_RESOURCE,params) 135 | 136 | 137 | def buy(self, symbol, price, amount, bbo = 0): 138 | trade_type = 'buy' 139 | if bbo == 1: 140 | # 市价买单传price作为买入金额 141 | trade_type = 'buy_market' 142 | ret = self.trade(symbol, trade_type, price = amount, amount = None) 143 | elif bbo == 0: 144 | trade_type = 'buy' 145 | ret = self.trade(symbol, trade_type, price = price, amount = None) 146 | 147 | try: 148 | if ret['result'] == True: 149 | return ret['order_id'] 150 | else: 151 | self.logger.error('buy order failed.') 152 | self.logger.error(str(ret)) 153 | return '' 154 | except: 155 | self.logger.error(str(ret)) 156 | return '' 157 | 158 | def sell(self, symbol, price, amount, bbo = 0): 159 | trade_type = 'sell' 160 | if bbo == 1: 161 | # 市价卖单不传price 162 | trade_type = 'sell_market' 163 | ret = self.trade(symbol, trade_type, price = None, amount = amount) 164 | elif bbo == 0: 165 | trade_type = 'sell' 166 | ret = self.trade(symbol, trade_type, price = price, amount = None) 167 | 168 | try: 169 | if ret['result'] == True: 170 | return ret['order_id'] 171 | else: 172 | self.logger.error('sell order failed.') 173 | self.logger.error(str(ret)) 174 | return '' 175 | except: 176 | self.logger.error(str(ret)) 177 | return '' 178 | -------------------------------------------------------------------------------- /okex/strategy/future/ma.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import time 4 | import arrow 5 | from talib import SMA 6 | import json 7 | import logging 8 | from okexapi.FutureAPI import Future 9 | from base import * 10 | 11 | 12 | class Ma(Base): 13 | 14 | def __init__(self, 15 | api_key, 16 | secret_key, 17 | url, 18 | coin, 19 | contract_type, 20 | kline_size, # kline size, 15min 21 | kline_num, # number of klines to get 22 | amount_ratio, # percentage of available coins 23 | bbo, # 1: market price, 0: use given price 24 | leverage, # leverage, 10 or 20 25 | fast, # fast kline period, 5 26 | slow, # slow kline period, 20 27 | interval, 28 | stop_loss, 29 | logger = None): 30 | 31 | super(Ma, self).__init__(api_key, secret_key, url, logger) 32 | self.coin = coin 33 | self.contract_type = contract_type 34 | self.kline_size = kline_size 35 | self.kline_num = kline_num 36 | self.amount_ratio = amount_ratio 37 | self.bbo = bbo 38 | self.leverage = leverage 39 | self.fast = fast 40 | self.slow = slow 41 | self.interval = interval 42 | self.stop_loss = stop_loss 43 | 44 | 45 | def get_amount(self): 46 | coin_available = self.get_available(self.coin) 47 | 48 | return int(self.leverage * amount_ratio * coin_available) 49 | 50 | def ma_cross(self): 51 | kline = self.get_kline(self.coin, self.contract_type, self.kline_size, self.kline_num) 52 | close = np.array([kline[i][4] for i in range(self.kline_num)]) 53 | 54 | fast_ma = tb.SMA(close, self.fast) 55 | slow_ma = tb.SMA(close, self.slow) 56 | 57 | ''' 58 | # stable version 59 | if fast_ma[-3] < slow_ma[-3] and fast_ma[-2] >= slow_ma[-2]: 60 | return 'gold' 61 | elif fast_ma[-3] > slow_ma[-3] and fast_ma[-2] <= slow_ma[-2]: 62 | return 'dead' 63 | else: 64 | return 'nothing' 65 | ''' 66 | 67 | # unstable version 68 | if fast_ma[-2] < slow_ma[-2] and fast_ma[-1] >= slow_ma[-1]: 69 | return 'gold' 70 | elif fast_ma[-2] > slow_ma[-2] and fast_ma[-1] <= slow_ma[-1]: 71 | return 'dead' 72 | else: 73 | return 'nothing' 74 | 75 | 76 | def get_last(self): 77 | kline = self.get_kline(self.coin, self.contract_type, self.kline_size, 1) 78 | return kline[0][4] 79 | 80 | def update_stop_loss(self, stop_loss, current_profit): 81 | if current_profit < 10: 82 | return stop_loss 83 | elif current_profit >= 10 and current_profit < 60: 84 | if current_profit * 0.5 > stop_loss: 85 | return current_profit * 0.5 86 | else: 87 | return stop_loss 88 | elif current_profit >= 60 and current_profit < 100: 89 | if current_profit * 0.6 > stop_loss: 90 | return current_profit * 0.6 91 | else: 92 | return stop_loss 93 | elif current_profit >= 100 and current_profit < 150: 94 | if current_profit * 0.7 > stop_loss: 95 | return current_profit * 0.7 96 | else: 97 | return stop_loss 98 | else: 99 | if current_profit * 0.8 > stop_loss: 100 | return current_profit * 0.8 101 | else: 102 | return stop_loss 103 | 104 | def run_forever(self): 105 | stop_loss = self.stop_loss 106 | 107 | while True: 108 | long_amount, long_profit, short_amount, short_profit = self.get_position(self.coin, self.contract_type) 109 | logger.info('position: long_amount = %s, long_profit = %s, short_amount = %s, short_profit = %s' % (long_amount, long_profit, short_amount, short_profit)) 110 | 111 | coin_available = self.get_available(self.coin) 112 | logger.info('coin_available = ' + str(coin_available)) 113 | 114 | last = self.get_last() 115 | 116 | current_profit = 0 117 | if long_amount > 0: 118 | current_profit = long_profit 119 | if short_amount > 0: 120 | current_profit = short_profit 121 | if current_profit == 0: 122 | stop_loss = self.stop_loss 123 | stop_loss = self.update_stop_loss(stop_loss, current_profit) 124 | 125 | self.logger.info('stop_loss: ' + str(stop_loss)) 126 | 127 | if long_profit < stop_loss and long_amount > 0: 128 | self.future.close_long(self.coin, self.contract_type, last, long_amount, self.leverage, self.bbo) 129 | stop_loss = self.stop_loss 130 | self.logger.info('close long at: ' + str(last) + ', amount: ' + str(long_amount)) 131 | 132 | if short_profit < stop_loss and short_amount > 0: 133 | self.future.close_short(self.coin, self.contract_type, last, short_amount, self.leverage, self.bbo) 134 | stop_loss = self.stop_loss 135 | self.logger.info('close short at: ' + str(last) + ', amount: ' + str(short_amount)) 136 | 137 | 138 | cross = self.ma_cross() 139 | if cross == 'gold' and long_amount < 10: 140 | logger.info('golden cross.') 141 | if short_amount > 0: 142 | logger.info('close short at: %f, amount: %d' % (last, short_amount)) 143 | stop_loss = self.stop_loss 144 | self.future.close_short(self.coin, self.contract_type, last, short_amount, self.leverage, self.bbo) 145 | amount = self.get_amount() 146 | self.future.open_long(self.coin, self.contract_type, last, amount, self.leverage, self.bbo) 147 | logger.info('open long at: %f, amount: %d' % (last, amount)) 148 | elif cross == 'dead' and short_amount < 10: 149 | logger.info('dead cross.') 150 | if long_amount > 0: 151 | logger.info('close long at: %f, amount: %d' % (last, long_amount)) 152 | stop_loss = self.stop_loss 153 | self.future.close_long(self.coin, self.contract_type, last, long_amount, self.leverage, self.bbo) 154 | amount = self.get_amount() 155 | self.future.open_short(self.coin, self.contract_type, last, amount, self.leverage, self.bbo) 156 | logger.info('open short at: %f, amount: %d' % (last, amount)) 157 | else: 158 | logger.info('No trading signal.') 159 | 160 | time.sleep(self.interval) 161 | 162 | 163 | if __name__ == '__main__': 164 | 165 | config_path = sys.argv[1] 166 | 167 | f = open(config_path, encoding = 'utf-8') 168 | config = json.load(f) 169 | 170 | api_key = config['api_key'] 171 | secret_key = config['secret_key'] 172 | url = config['url'] 173 | 174 | coin = config['coin'] 175 | contract_type = config['contract_type'] 176 | kline_size = config['kline_size'] 177 | kline_num = config['kline_num'] 178 | amount_ratio = config['amount_ratio'] 179 | slow = config['slow'] 180 | fast = config['fast'] 181 | interval = config['interval'] 182 | 183 | bbo = config['bbo'] 184 | leverage = config['leverage'] 185 | stop_loss = config['stop_loss'] 186 | 187 | logger = get_logger() 188 | 189 | ma_bot = Ma(api_key, 190 | secret_key, 191 | url, 192 | coin, 193 | contract_type, 194 | kline_size, 195 | kline_num, 196 | amount_ratio, 197 | bbo, 198 | leverage, 199 | fast, 200 | slow, 201 | interval, 202 | stop_loss, 203 | logger = logger) 204 | 205 | ma_bot.run_forever() 206 | 207 | 208 | -------------------------------------------------------------------------------- /okex/strategy/future/ma_beta.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import time 4 | import arrow 5 | from talib import SMA 6 | import json 7 | import logging 8 | from okexapi.FutureAPI import Future 9 | from base import * 10 | 11 | 12 | class Ma(Base): 13 | 14 | def __init__(self, 15 | api_key, 16 | secret_key, 17 | url, 18 | coin, 19 | contract_type, 20 | kline_size, # kline size, 15min 21 | kline_num, # number of klines to get 22 | amount_ratio, # percentage of available coins 23 | bbo, # 1: market price, 0: use given price 24 | leverage, # leverage, 10 or 20 25 | fast, # fast kline period, 5 26 | slow, # slow kline period, 20 27 | interval, 28 | stop_loss, 29 | band_width, 30 | logger = None): 31 | 32 | super(Ma, self).__init__(api_key, secret_key, url, logger) 33 | self.coin = coin 34 | self.contract_type = contract_type 35 | self.kline_size = kline_size 36 | self.kline_num = kline_num 37 | self.amount_ratio = amount_ratio 38 | self.bbo = bbo 39 | self.leverage = leverage 40 | self.fast = fast 41 | self.slow = slow 42 | self.interval = interval 43 | self.stop_loss = stop_loss 44 | self.band_width = band_width 45 | 46 | 47 | def get_amount(self): 48 | coin_available = self.get_available(self.coin) 49 | price = self.get_last() 50 | total = coin_available * price * self.leverage / 10 51 | return int(amount_ratio * total - 1) 52 | 53 | def ma_cross(self, fast_ma, slow_ma): 54 | # stable version 55 | if fast_ma[-3] < slow_ma[-3] and fast_ma[-2] >= slow_ma[-2]: 56 | return 'gold' 57 | elif fast_ma[-3] > slow_ma[-3] and fast_ma[-2] <= slow_ma[-2]: 58 | return 'dead' 59 | else: 60 | return 'nothing' 61 | 62 | 63 | def get_last(self): 64 | kline = self.get_kline(self.coin, self.contract_type, self.kline_size, 1) 65 | return kline[0][4] 66 | 67 | def update_stop_loss(self, stop_loss, current_profit): 68 | ''' 69 | if current_profit < 10: 70 | return stop_loss 71 | elif current_profit >= 10 and current_profit < 60: 72 | if current_profit * 0.5 > stop_loss: 73 | return current_profit * 0.5 74 | else: 75 | return stop_loss 76 | elif current_profit >= 60 and current_profit < 100: 77 | if current_profit * 0.6 > stop_loss: 78 | return current_profit * 0.6 79 | else: 80 | return stop_loss 81 | elif current_profit >= 100 and current_profit < 150: 82 | if current_profit * 0.7 > stop_loss: 83 | return current_profit * 0.7 84 | else: 85 | return stop_loss 86 | else: 87 | if current_profit * 0.8 > stop_loss: 88 | return current_profit * 0.8 89 | else: 90 | return stop_loss 91 | ''' 92 | if current_profit > 100: 93 | if current_profit * 0.7 > stop_loss: 94 | return current_profit * 0.7 95 | else: 96 | return stop_loss 97 | elif current_profit >= 40: 98 | if current_profit * 0.5 > stop_loss: 99 | return current_profit * 0.5 100 | else: 101 | return stop_loss 102 | elif current_profit >= 20 and current_profit < 40: 103 | if stop_loss > 0: 104 | return stop_loss 105 | else: 106 | return 7 107 | else: 108 | return stop_loss 109 | 110 | def run_forever(self): 111 | stop_loss = self.stop_loss 112 | 113 | while True: 114 | long_amount, long_profit, short_amount, short_profit = self.get_position(self.coin, self.contract_type) 115 | self.logger.info('position: long_amount = %s, long_profit = %s, short_amount = %s, short_profit = %s' % (long_amount, long_profit, short_amount, short_profit)) 116 | 117 | coin_available = self.get_available(self.coin) 118 | self.logger.info('coin_available = ' + str(coin_available)) 119 | 120 | kline = self.get_kline(self.coin, self.contract_type, self.kline_size, self.kline_num) 121 | close = np.array([kline[i][4] for i in range(self.kline_num)]) 122 | 123 | fast_ma = tb.SMA(close, self.fast) 124 | slow_ma = tb.SMA(close, self.slow) 125 | slow_upper = slow_ma + self.band_width 126 | slow_lower = slow_ma - self.band_width 127 | 128 | last = kline[-1][4] 129 | self.logger.info('last: ' + str(last)) 130 | 131 | current_profit = 0 132 | if long_amount > 0: 133 | current_profit = long_profit 134 | if short_amount > 0: 135 | current_profit = short_profit 136 | if current_profit == 0: 137 | stop_loss = self.stop_loss 138 | stop_loss = self.update_stop_loss(stop_loss, current_profit) 139 | 140 | self.logger.info('stop_loss: ' + str(stop_loss)) 141 | 142 | if long_profit < stop_loss and long_amount > 0: 143 | self.future.close_long(self.coin, self.contract_type, last, long_amount, self.leverage, self.bbo) 144 | stop_loss = self.stop_loss 145 | self.logger.info('close long at: ' + str(last) + ', amount: ' + str(long_amount)) 146 | 147 | if short_profit < stop_loss and short_amount > 0: 148 | self.future.close_short(self.coin, self.contract_type, last, short_amount, self.leverage, self.bbo) 149 | stop_loss = self.stop_loss 150 | self.logger.info('close short at: ' + str(last) + ', amount: ' + str(short_amount)) 151 | 152 | 153 | cross_with_upper = self.ma_cross(fast_ma, slow_upper) 154 | cross_with_lower = self.ma_cross(fast_ma, slow_lower) 155 | cross_with_slow = self.ma_cross(fast_ma, slow_ma) 156 | 157 | if cross_with_upper == 'gold' and long_amount < 10: 158 | self.logger.info('golden cross with upper bond') 159 | amount = self.get_amount() 160 | self.future.open_long(self.coin, self.contract_type, last, amount, self.leverage, self.bbo) 161 | self.logger.info('open long at: %f, amount: %d' % (last, amount)) 162 | 163 | if cross_with_slow == 'dead' and long_amount > 0: 164 | self.logger.info('dead cross with slow ma') 165 | self.future.close_long(self.coin, self.contract_type, last, long_amount, self.leverage, self.bbo) 166 | self.logger.info('close long at: %f, amount: %d' % (last, long_amount)) 167 | 168 | if cross_with_lower == 'dead' and short_amount < 10: 169 | self.logger.info('dead cross with lower bond') 170 | amount = self.get_amount() 171 | self.future.open_short(self.coin, self.contract_type, last, amount, self.leverage, self.bbo) 172 | self.logger.info('open short at: %f, amount: %d' % (last, amount)) 173 | 174 | if cross_with_slow == 'gold' and short_amount > 0: 175 | self.logger.info('gold cross with slow ma') 176 | self.future.close_short(self.coin, self.contract_type, last, short_amount, self.leverage, self.bbo) 177 | self.logger.info('close short at: %f, amount: %d' % (last, short_amount)) 178 | 179 | time.sleep(self.interval) 180 | 181 | 182 | if __name__ == '__main__': 183 | 184 | config_path = sys.argv[1] 185 | 186 | f = open(config_path, encoding = 'utf-8') 187 | config = json.load(f) 188 | 189 | api_key = config['api_key'] 190 | secret_key = config['secret_key'] 191 | url = config['url'] 192 | 193 | coin = config['coin'] 194 | contract_type = config['contract_type'] 195 | kline_size = config['kline_size'] 196 | kline_num = config['kline_num'] 197 | amount_ratio = config['amount_ratio'] 198 | slow = config['slow'] 199 | fast = config['fast'] 200 | interval = config['interval'] 201 | 202 | bbo = config['bbo'] 203 | leverage = config['leverage'] 204 | stop_loss = config['stop_loss'] 205 | band_width = config['band_width'] 206 | 207 | logger = get_logger() 208 | 209 | ma_bot = Ma(api_key, 210 | secret_key, 211 | url, 212 | coin, 213 | contract_type, 214 | kline_size, 215 | kline_num, 216 | amount_ratio, 217 | bbo, 218 | leverage, 219 | fast, 220 | slow, 221 | interval, 222 | stop_loss, 223 | band_width, 224 | logger = logger) 225 | 226 | ma_bot.run_forever() 227 | 228 | 229 | -------------------------------------------------------------------------------- /okex/okexapi/okexapi/FutureAPI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from .HttpMD5Util import buildMySign,httpGet,httpPost 4 | import logging 5 | import logging.config 6 | 7 | class Future: 8 | 9 | def __init__(self, url, apikey, secretkey, logger = None): 10 | self.__url = url 11 | self.__apikey = apikey 12 | self.__secretkey = secretkey 13 | if logger: 14 | self.logger = logger 15 | else: 16 | self.logger = logging.getLogger('tradebot') 17 | 18 | #OKCOIN期货行情信息 19 | def future_ticker(self, symbol, contractType): 20 | FUTURE_TICKER_RESOURCE = "/api/v1/future_ticker.do" 21 | params = '' 22 | if symbol: 23 | params += '&symbol=' + symbol if params else 'symbol=' +symbol 24 | if contractType: 25 | params += '&contract_type=' + contractType if params else 'contract_type=' +symbol 26 | return httpGet(self.__url,FUTURE_TICKER_RESOURCE,params) 27 | 28 | #OKCOIN期货k线信息 29 | def future_kline(self,symbol,contractType, kline_size, kline_num): 30 | FUTURE_KLINE_RESOURCE = "/api/v1/future_kline.do" 31 | params = '' 32 | if symbol: 33 | params += '&symbol=' + symbol if params else 'symbol=' +symbol 34 | if contractType: 35 | params += '&contract_type=' + contractType if params else 'contract_type=' +symbol 36 | if kline_size: 37 | params += '&type=' + str(kline_size) if params else 'type=' + str(kline_size) 38 | if kline_num: 39 | params += '&size=' + str(kline_num) if params else 'size=' + str(kline_num) 40 | return httpGet(self.__url,FUTURE_KLINE_RESOURCE,params) 41 | 42 | #期货持仓数量 43 | def future_hold_amount(self,symbol,contractType): 44 | FUTURE_HOLD_AMOUNT = "/api/v1/future_hold_amount.do" 45 | params = '' 46 | if symbol: 47 | params += '&symbol=' + symbol if params else 'symbol=' +symbol 48 | if contractType: 49 | params += '&contract_type=' + contractType if params else 'contract_type=' +symbol 50 | return httpGet(self.__url,FUTURE_HOLD_AMOUNT,params) 51 | 52 | #OKCoin期货市场深度信息 53 | def future_depth(self,symbol,contractType,size): 54 | FUTURE_DEPTH_RESOURCE = "/api/v1/future_depth.do" 55 | params = '' 56 | if symbol: 57 | params += '&symbol=' + symbol if params else 'symbol=' +symbol 58 | if contractType: 59 | params += '&contract_type=' + contractType if params else 'contract_type=' +symbol 60 | if size: 61 | params += '&size=' + size if params else 'size=' + size 62 | return httpGet(self.__url,FUTURE_DEPTH_RESOURCE,params) 63 | 64 | #OKCoin期货交易记录信息 65 | def future_trades(self,symbol,contractType): 66 | FUTURE_TRADES_RESOURCE = "/api/v1/future_trades.do" 67 | params = '' 68 | if symbol: 69 | params += '&symbol=' + symbol if params else 'symbol=' +symbol 70 | if contractType: 71 | params += '&contract_type=' + contractType if params else 'contract_type=' +symbol 72 | return httpGet(self.__url,FUTURE_TRADES_RESOURCE,params) 73 | 74 | #OKCoin期货指数 75 | def future_index(self,symbol): 76 | FUTURE_INDEX = "/api/v1/future_index.do" 77 | params='' 78 | if symbol: 79 | params = 'symbol=' +symbol 80 | return httpGet(self.__url,FUTURE_INDEX,params) 81 | 82 | #获取美元人民币汇率 83 | def exchange_rate(self): 84 | EXCHANGE_RATE = "/api/v1/exchange_rate.do" 85 | return httpGet(self.__url,EXCHANGE_RATE,'') 86 | 87 | #获取预估交割价 88 | def future_estimated_price(self,symbol): 89 | FUTURE_ESTIMATED_PRICE = "/api/v1/future_estimated_price.do" 90 | params='' 91 | if symbol: 92 | params = 'symbol=' +symbol 93 | return httpGet(self.__url,FUTURE_ESTIMATED_PRICE,params) 94 | 95 | #期货全仓账户信息 96 | def future_userinfo(self): 97 | FUTURE_USERINFO = "/api/v1/future_userinfo.do?" 98 | params ={} 99 | params['api_key'] = self.__apikey 100 | params['sign'] = buildMySign(params,self.__secretkey) 101 | return httpPost(self.__url,FUTURE_USERINFO,params) 102 | 103 | #期货全仓持仓信息 104 | def future_position(self,symbol,contractType): 105 | FUTURE_POSITION = "/api/v1/future_position.do?" 106 | params = { 107 | 'api_key':self.__apikey, 108 | 'symbol':symbol, 109 | 'contract_type':contractType 110 | } 111 | params['sign'] = buildMySign(params,self.__secretkey) 112 | return httpPost(self.__url,FUTURE_POSITION,params) 113 | 114 | #期货下单 115 | def future_trade(self,symbol,contractType,price='',amount='',tradeType='',matchPrice='',leverRate=''): 116 | FUTURE_TRADE = "/api/v1/future_trade.do?" 117 | params = { 118 | 'api_key':self.__apikey, 119 | 'symbol':symbol, 120 | 'contract_type':contractType, 121 | 'amount':amount, 122 | 'type':tradeType, 123 | 'match_price':matchPrice, 124 | 'lever_rate':leverRate 125 | } 126 | if price: 127 | params['price'] = price 128 | params['sign'] = buildMySign(params,self.__secretkey) 129 | return httpPost(self.__url,FUTURE_TRADE,params) 130 | 131 | #期货批量下单 132 | def future_batchTrade(self,symbol,contractType,orders_data,leverRate): 133 | FUTURE_BATCH_TRADE = "/api/v1/future_batch_trade.do?" 134 | params = { 135 | 'api_key':self.__apikey, 136 | 'symbol':symbol, 137 | 'contract_type':contractType, 138 | 'orders_data':orders_data, 139 | 'lever_rate':leverRate 140 | } 141 | params['sign'] = buildMySign(params,self.__secretkey) 142 | return httpPost(self.__url,FUTURE_BATCH_TRADE,params) 143 | 144 | #期货取消订单 145 | def future_cancel(self,symbol,contractType,orderId): 146 | FUTURE_CANCEL = "/api/v1/future_cancel.do?" 147 | params = { 148 | 'api_key':self.__apikey, 149 | 'symbol':symbol, 150 | 'contract_type':contractType, 151 | 'order_id':orderId 152 | } 153 | params['sign'] = buildMySign(params,self.__secretkey) 154 | return httpPost(self.__url,FUTURE_CANCEL,params) 155 | 156 | #期货获取订单信息 157 | def future_orderinfo(self,symbol,contractType,orderId,status,currentPage,pageLength): 158 | FUTURE_ORDERINFO = "/api/v1/future_order_info.do?" 159 | params = { 160 | 'api_key':self.__apikey, 161 | 'symbol':symbol, 162 | 'contract_type':contractType, 163 | 'order_id':orderId, 164 | 'status':status, 165 | 'current_page':currentPage, 166 | 'page_length':pageLength 167 | } 168 | params['sign'] = buildMySign(params,self.__secretkey) 169 | ret = httpPost(self.__url,FUTURE_ORDERINFO,params) 170 | if ret['result'] == True: 171 | return ret['orders'] 172 | else: 173 | self.logger.info('get order info failed, error code: ' + str(ret['error_code'])) 174 | return list() 175 | 176 | #期货逐仓账户信息 177 | def future_userinfo_4fix(self): 178 | FUTURE_INFO_4FIX = "/api/v1/future_userinfo_4fix.do?" 179 | params = {'api_key':self.__apikey} 180 | params['sign'] = buildMySign(params,self.__secretkey) 181 | return httpPost(self.__url,FUTURE_INFO_4FIX,params) 182 | 183 | #期货逐仓持仓信息 184 | def future_position_4fix(self,symbol,contractType,type1): 185 | FUTURE_POSITION_4FIX = "/api/v1/future_position_4fix.do?" 186 | params = { 187 | 'api_key':self.__apikey, 188 | 'symbol':symbol, 189 | 'contract_type':contractType, 190 | 'type':type1 191 | } 192 | params['sign'] = buildMySign(params,self.__secretkey) 193 | return httpPost(self.__url,FUTURE_POSITION_4FIX,params) 194 | 195 | # trade api 196 | def get_position(self, coin, contract_type): 197 | position = self.future_position_4fix(coin, contract_type, 1) 198 | if len(position['holding']) > 0: 199 | long_amount = int(position['holding'][0]['buy_available']) 200 | long_profit = float(position['holding'][0]['buy_profit_lossratio']) 201 | short_amount = int(position['holding'][0]['sell_available']) 202 | short_profit = float(position['holding'][0]['sell_profit_lossratio']) 203 | return [long_amount, long_profit, short_amount, short_profit] 204 | else: 205 | return [0, 0, 0, 0] 206 | 207 | def open_long(self, coin, contract_type, price, amount, leverage, bbo = 1): 208 | ret = self.future_trade(coin, contract_type, price, amount, 1, bbo, leverage) 209 | if ret['result'] == True: 210 | return ret['order_id'] 211 | else: 212 | self.logger.info('open long failed, error code: ' + str(ret['error_code'])) 213 | return '' 214 | 215 | def close_long(self, coin, contract_type, price, amount, leverage, bbo = 1): 216 | ret = self.future_trade(coin, contract_type, price, amount, 3, bbo, leverage) 217 | if ret['result'] == True: 218 | return ret['order_id'] 219 | else: 220 | self.logger.info('close long failed, error code: ' + str(ret['error_code'])) 221 | return '' 222 | 223 | def open_short(self, coin, contract_type, price, amount, leverage, bbo = 1): 224 | ret = self.future_trade(coin, contract_type, price, amount, 2, bbo, leverage) 225 | if ret['result'] == True: 226 | return ret['order_id'] 227 | else: 228 | self.logger.info('open short failed, error code: ' + str(ret['error_code'])) 229 | return '' 230 | 231 | def close_short(self, coin, contract_type, price, amount, leverage, bbo = 1): 232 | ret = self.future_trade(coin, contract_type, price, amount, 4, bbo, leverage) 233 | if ret['result'] == True: 234 | return ret['order_id'] 235 | else: 236 | self.logger.info('close short failed, error_code: ' + str(ret['error_code'])) 237 | return '' 238 | -------------------------------------------------------------------------------- /okex/strategy/future/grid.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | import time 4 | import arrow 5 | import talib as tb 6 | import json 7 | import logging 8 | from okexapi.FutureAPI import Future 9 | from base import * 10 | 11 | class Grid(Base): 12 | def __init__(self, 13 | apikey, 14 | secretkey, 15 | url, 16 | coin, # symbol, 'eos_usdt' 17 | contract_type, # 'this_week', 'next_week', 'quarter' 18 | kline_size, # 15min 19 | kline_num, # number of klines to get 20 | bbo, # 0, 1, if market order or not 21 | leverage, # future leverage 22 | amount, # amount for each order 23 | times_atr, # coefficient, calculate gap 24 | grid_size, # how many orders on each side 25 | interval, # time interval to refresh, 15s 26 | clear_interval, # coef, how long to clear unfilled orders 27 | amount_ratio, # percentage of available coin 28 | fast, # fast kline, 5 29 | slow, # slow kline, 20 30 | gap, # grid gap, fixed 31 | use_gap, # if True, use fixed gap, not ATR 32 | stop_win, # loss control 33 | stop_loss, # loss control 34 | logger = None): 35 | 36 | super(Grid, self).__init__(apikey, secretkey, url, logger) 37 | 38 | self.coin = coin 39 | self.contract_type = contract_type 40 | self.kline_size = kline_size 41 | self.kline_num = kline_num 42 | self.bbo = bbo 43 | self.leverage = leverage 44 | self.interval = interval 45 | self.amount = amount 46 | self.times_atr = times_atr 47 | self.gap = gap 48 | self.use_gap = use_gap 49 | self.grid_size = grid_size 50 | self.amount_ratio = amount_ratio 51 | self.fast = fast 52 | self.slow = slow 53 | if logger: 54 | self.logger = logger 55 | else: 56 | self.logger = logging.getLogger('dual mode reaper') 57 | 58 | self.init = True 59 | self.clear_interval = clear_interval 60 | 61 | self.open_longs = [] 62 | self.open_shorts = [] 63 | 64 | self.stop_win = stop_win 65 | self.stop_loss = stop_loss 66 | 67 | def get_last_atr(self): 68 | kline = self.get_kline(self.coin, self.contract_type, self.kline_size, self.kline_num) 69 | high = [kline[i][2] for i in range(kline_num)] 70 | low = [kline[i][3] for i in range(kline_num)] 71 | close = [kline[i][4] for i in range(kline_num)] 72 | high = np.array(high) 73 | low = np.array(low) 74 | close = np.array(close) 75 | 76 | atr = tb.ATR(high, low, close, timeperiod = 14) 77 | return close[-1], atr[-1] 78 | 79 | def init_orders(self, last, atr): 80 | for i in range(self.grid_size): 81 | if self.use_gap: 82 | long_price = last - (i + 1) * self.gap 83 | short_price = last + (i + 1) * self.gap 84 | else: 85 | long_price = last - (i + 1) * self.times_atr * atr 86 | short_price = last + (i + 1) * self.times_atr * atr 87 | 88 | ret = self.future.open_long(self.coin, self.contract_type, long_price, self.amount, self.leverage, bbo = 0) 89 | self.open_longs.append(ret) 90 | 91 | ret = self.future.open_short(self.coin, self.contract_type, short_price, self.amount, self.leverage, bbo = 0) 92 | self.open_shorts.append(ret) 93 | 94 | self.logger.info('init: long_order_at: ' + str(round(long_price, 3)) + ', short_order_at: ' + str(round(short_price, 3))) 95 | # avoid high frequency calls to website API 96 | time.sleep(1) 97 | 98 | def kline_cross(self): 99 | kline = self.get_kline(self.coin, self.contract_type, self.kline_size, self.kline_num) 100 | close = [kline[i][4] for i in range(self.kline_num)] 101 | close = np.array(close) 102 | 103 | fast_kline = tb.SMA(close, self.fast) 104 | slow_kline = tb.SMA(close, self.slow) 105 | if fast_kline[-2] < slow_kline[-2] and fast_kline[-1] > slow_kline[-1]: 106 | return 'gold' 107 | elif fast_kline[-2] > slow_kline[-2] and fast_kline[-1] < slow_kline[-1]: 108 | return 'dead' 109 | else: 110 | return 'nothing' 111 | 112 | def clear_orders(self): 113 | for order in self.open_longs: 114 | self.future.future_cancel(self.coin, self.contract_type, order) 115 | for order in self.open_shorts: 116 | self.future.future_cancel(self.coin, self.contract_type, order) 117 | 118 | def run_forever(self): 119 | counter = 1 120 | max_long_profit = 0 121 | max_short_profit = 0 122 | long_stop_loss = False 123 | short_stop_loss = False 124 | while True: 125 | # first clear all pending orders 126 | if counter == 1: 127 | self.clear_pending_orders(self.coin, self.contract_type) 128 | 129 | # get last, atr 130 | last, atr = self.get_last_atr() 131 | 132 | # get position 133 | long_amount, long_profit, short_amount, short_profit = self.get_position(self.coin, self.contract_type) 134 | self.logger.info('position: long_amount = %s, long_profit = %s, short_amount = %s, short_profit = %s' % (long_amount, long_profit, short_amount, short_profit)) 135 | 136 | # get available coin amount 137 | coin_available = self.get_available(self.coin) 138 | self.logger.info('coin_available = ' + str(coin_available)) 139 | self.logger.info('last = ' + str(last)) 140 | 141 | # init orders 142 | if counter == 1: 143 | self.init_orders(last, atr) 144 | 145 | # adjust orders 146 | #self.adjust_open_orders(last, atr) 147 | #self.adjust_close_orders(last, atr, long_amount, short_amount) 148 | 149 | # process long position 150 | stop_win = 10 151 | stop_loss = -40 152 | 153 | if long_profit < stop_loss: 154 | long_stop_loss = True 155 | if short_profit < stop_loss: 156 | short_stop_loss = True 157 | 158 | if long_amount > 0 and self.init: 159 | stop_win -= (long_amount / self.amount - 1) * 1 160 | if long_profit >= stop_win and not short_stop_loss: 161 | ret = self.future.close_long(self.coin, self.contract_type, last, long_amount, self.leverage, bbo = 1) 162 | # if stop loss, stop grid, open short 163 | if long_profit < stop_loss: 164 | # long stop loss and open short 165 | ret = self.future.close_long(self.coin, self.contract_type, last, long_amount, self.leverage, bbo = 1) 166 | amount = self.amount_ratio * self.leverage * self.get_available() 167 | ret = self.future.open_short(self.coin, self.contract_type, last, amount, self.leverage, bbo = 0) 168 | self.init = False 169 | long_stop_loss = False 170 | 171 | 172 | # process short position 173 | stop_win = self.stop_win 174 | stop_loss = self.stop_loss 175 | if short_amount > 0 and self.init: 176 | stop_win -= (short_amount / self.amount - 1) * 1 177 | if short_profit >= stop_win and not long_stop_loss: 178 | ret = self.future.close_short(self.coin, self.contract_type, last, short_amount, self.leverage, bbo = 1) 179 | # if stop loss, stop grid, open long 180 | if short_profit < stop_loss: 181 | # short stop loss and open long 182 | ret = self.future.close_short(self.coin, self.contract_type, last, short_amount, self.leverage, bbo = 1) 183 | amount = self.amount_ratio * self.leverage * self.get_available() 184 | ret = self.future.open_long(self.coin, self.contract_type, last, amount, self.leverage, bbo = 1) 185 | self.init = False 186 | short_stop_loss = False 187 | 188 | # one way up or down 189 | if self.init == False: 190 | if long_amount > 0: 191 | # if dead cross, close long, back to grid mode 192 | if self.kline_cross() == 'dead': 193 | self.future.close_long(self.coin, self.contract_type, last, long_amount, self.leverage, bbo = 1) 194 | self.init = True 195 | 196 | if short_amount > 0: 197 | # if golden cross, close short, back to grid mode 198 | if self.kline_cross() == 'gold': 199 | self.future.close_short(self.coin, self.contract_type, last, short_amount, self.leverage, bbo = 1) 200 | self.init = True 201 | 202 | if counter % self.clear_interval == 0 and self.init: 203 | self.clear_orders() 204 | self.init_orders() 205 | 206 | counter += 1 207 | time.sleep(self.interval) 208 | 209 | 210 | if __name__ == '__main__': 211 | 212 | config_path = sys.argv[1] 213 | 214 | f = open(config_path, encoding = 'utf-8') 215 | config = json.load(f) 216 | 217 | apikey = config['api_key'] 218 | secretkey = config['secret_key'] 219 | url = config['url'] 220 | 221 | coin = config['coin'] 222 | contract_type = config['contract_type'] 223 | kline_size = config['kline_size'] 224 | kline_num = config['kline_num'] 225 | 226 | bbo = config['bbo'] 227 | leverage = config['leverage'] 228 | 229 | amount = config['amount'] 230 | times_atr = config['times_atr'] 231 | grid_size = config['grid_size'] 232 | clear_interval = config['clear_interval'] 233 | amount_ratio = config['amount_ratio'] 234 | fast = config['fast_kline'] 235 | slow = config['slow_kline'] 236 | gap = config['gap'] 237 | use_gap = config['use_gap'] 238 | 239 | interval = config['interval'] 240 | stop_win = config['stop_win'] 241 | stop_loss = config['stop_loss'] 242 | 243 | logger = get_logger() 244 | 245 | dual_mode_reaper = Grid(apikey, 246 | secretkey, 247 | url, 248 | coin, 249 | contract_type, 250 | kline_size, 251 | kline_num, 252 | bbo, 253 | leverage, 254 | amount, 255 | times_atr, 256 | grid_size, 257 | interval, 258 | clear_interval, 259 | amount_ratio, 260 | fast, 261 | slow, 262 | gap, 263 | use_gap, 264 | stop_win, 265 | stop_loss, 266 | logger = logger) 267 | 268 | dual_mode_reaper.run_forever() 269 | --------------------------------------------------------------------------------