├── .DS_Store ├── __pycache__ ├── buy.cpython-36.pyc ├── sell.cpython-36.pyc └── fcoin.cpython-36.pyc ├── reboot.sh ├── main.py ├── buy.py ├── README.md ├── fcoin.py ├── .ipynb_checkpoints └── Untitled-checkpoint.ipynb └── Untitled.ipynb /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaurix/fcoin_python/HEAD/.DS_Store -------------------------------------------------------------------------------- /__pycache__/buy.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaurix/fcoin_python/HEAD/__pycache__/buy.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/sell.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaurix/fcoin_python/HEAD/__pycache__/sell.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/fcoin.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaurix/fcoin_python/HEAD/__pycache__/fcoin.cpython-36.pyc -------------------------------------------------------------------------------- /reboot.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | pidof main.py # 检测程序是否运行 3 | while [ $? -ne 0 ] # 判断程序上次运行是否正常结束 4 | do 5 | echo "Process exits with errors! Restarting!" 6 | python main.py #重启程序 7 | done 8 | echo "Process ends!" 9 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from fcoin import Fcoin 2 | from buy import Buy 3 | import datetime 4 | import schedule 5 | import time 6 | 7 | fcoin = Fcoin() 8 | fcoin.auth('', '') 9 | coin_buy = Buy('ftusdt',fcoin=fcoin,type='limit') 10 | 11 | def buyTask(): 12 | print("I'm working for buy and sell") 13 | coin_buy.buy() 14 | 15 | def run(): 16 | schedule.every(1).seconds.do(buyTask) 17 | while True: 18 | schedule.run_pending() 19 | 20 | 21 | if __name__ == '__main__': 22 | run() -------------------------------------------------------------------------------- /buy.py: -------------------------------------------------------------------------------- 1 | from fcoin import Fcoin 2 | import datetime 3 | import schedule 4 | import threading 5 | import time 6 | import random 7 | 8 | ''' 9 | 多线程定时器买和卖 10 | 11 | ''' 12 | 13 | class Buy(): 14 | def __init__(self,trade_pair = 'ftusdt',fcoin = None,type = 'market'): 15 | self._trade_pair = trade_pair 16 | self._fcoin = fcoin 17 | self._type = type 18 | 19 | ''' 20 | 不敢操作ft,波动太大,以后研究,只买卖eth_usdt对 21 | ''' 22 | def trunc(self,f, n): 23 | 24 | if not str(f): 25 | return '0' 26 | sarr = str(f).split('.') 27 | if len(sarr) == 2: 28 | s1, s2 = str(f).split('.') 29 | else: 30 | s1 = str(f) 31 | s2 = '0' 32 | if n == 0: 33 | return s1 34 | if n <= len(s2): 35 | return s1 + '.' + s2[:n] 36 | return s1 + '.' + s2 + '0' * (n - len(s2)) 37 | 38 | def buy(self): 39 | if not self._fcoin: 40 | return 41 | ''' 42 | 账户中的钱 43 | ''' 44 | eth_num = float(self._fcoin.get_coin_balance('ft')) * 0.99 45 | usdt_num = float(self._fcoin.get_coin_balance('usdt')) * 0.98 46 | 47 | ''' 48 | 一个eth能买多少个usdt 49 | ''' 50 | 51 | max_price = float(self._fcoin.get_coin_price_max(self._trade_pair)) 52 | min_price = float(self._fcoin.get_coin_price_min(self._trade_pair)) 53 | 54 | 55 | print('usdt num:') 56 | print(usdt_num) 57 | print('ft num:') 58 | print(eth_num) 59 | 60 | print('usdt price:') 61 | print(max_price) 62 | 63 | print('eth price') 64 | print(min_price) 65 | 66 | self._fcoin.sell(self._trade_pair,price = self.trunc(max_price,6),amount = self.trunc(random.uniform(1,200),2) , type = self._type) 67 | 68 | if min_price == 0 : 69 | buy_amount = 0 70 | else: 71 | buy_amount = usdt_num / min_price 72 | 73 | print('buy amount') 74 | print(buy_amount) 75 | self._fcoin.buy(self._trade_pair,price = self.trunc(min_price,6),amount = self.trunc(random.uniform(1,200),2) , type = self._type) 76 | 77 | ''' 78 | if float(usdt_num) > 1: 79 | self._fcoin.buy(self._trade_pair,price = usdt_price,amount = usdt_num, type = self._type) 80 | else: 81 | self._fcoin.sell(self._trade_pair,price = usdt_price,amount = eth_num, type = self._type) 82 | 83 | ''' 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 目前不需要注册开发者,只需要申请apikey 3 | apikey申请流程: 4 | 1.先注册账户 5 | 2.在设置页面,绑定GA 6 | 3.在设置页面,申请api,两个字段都必须填写,IP地址目前限制 7 | limit:限价 8 | market:市价 9 | 10 | api文档: 11 | https://developer.fcoin.com/zh.html#32c808cbe5 12 | 13 | 14 | 交易手续费: 15 | https://support.fcoin.com/hc/zh-cn/articles/360003715514-%E4%BA%A4%E6%98%93%E6%89%8B%E7%BB%AD%E8%B4%B9%E5%8F%8A%E8%AE%A2%E5%8D%95%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E 16 | 17 | 以下3个参数,需要放在headers中 18 | FC-ACCESS-KEY 19 | FC-ACCESS-SIGNATURE 20 | FC-ACCESS-TIMESTAMP 21 | 22 | websocket: 23 | def get_market_price(symbol): 24 | ws = create_connection("wss://ws.fcoin.com/api/v2/ws") 25 | ws.recv() 26 | s = "ticker.{}".format(symbol['name']) 27 | req = { 28 | 'cmd':'req', 29 | 'args':[s], 30 | 'id':'1' 31 | } 32 | ws.send(json.dumps(req)) 33 | r = json.loads(ws.recv()) 34 | ws.close() 35 | return r['data']['ticker'][0] 36 | 37 | 深度订阅,实际发送的内容是:{"cmd":"sub","args":["depth.L100.btcusdt"],"id":"1"} 38 | 39 | 获取订单列表中: 40 | 至少传symbol和state 41 | 42 | git地址: 43 | https://github.com/FCoinCommunity 44 | 45 | 46 | Post请求时一定要加json头: 47 | 'content-type': 'application/json;charset=UTF-8' 48 | 请求的body要传json格式 49 | 50 | 可以查询以提交和部分成交的数据: 51 | submitted, partial_filled, partial_canceled, filled, canceled 52 | 这些状态,可以同时传,中间用逗号隔开 53 | 54 | Post签名前的字符串: 55 | POSThttps://api.fcoin.com/v2/orders1528532934527amount=1000&price=0.192011&side=buy&symbol=ftusdt&type=limit 56 | Get签名前的字符串: 57 | GEThttps://api.fcoin.com/v2/orders?limit=20&states=submitted,partial_filled&symbol=ethusdt1528532959168 58 | 59 | 获取订单接口中before和after表示时间戳,只能有1个时间戳,limit最大支持100 60 | 61 | public是要传给服务器的,secret是用来签名的 62 | 63 | 1002 system busy 是因为下单太快了 64 | 65 | 获取行情深度接口中,只有L20,L150,full 66 | 67 | python版本的签名代码: 68 | def sort_payload(self, payload): 69 | keys = sorted(payload.keys()) 70 | result = '' 71 | for i in range(len(keys)): 72 | if i != 0: 73 | result += '&' + keys[i] + "=" + str(payload[keys[i]]) 74 | else: 75 | result += keys[i] + "=" + str(payload[keys[i]]) 76 | return result 77 | 78 | # 对请求数据进行加密编码 79 | def encrypt_data(self, HTTP_METHOD, HTTP_REQUEST_URI, TIMESTAMP, POST_BODY, secret): 80 | payload_result = '' 81 | if POST_BODY != '': 82 | payload_result = self.sort_payload(POST_BODY) 83 | data = HTTP_METHOD + HTTP_REQUEST_URI + TIMESTAMP + payload_result 84 | print(data) 85 | data_base64 = base64.b64encode(bytes(data, encoding='utf8')) 86 | # print(data_base64) 87 | data_base64_sha1 = hmac.new(bytes(secret, encoding='utf8'), data_base64, hashlib.sha1).digest() 88 | data_base64_sha1_base64 = base64.b64encode(data_base64_sha1) 89 | # print(data_base64_sha1_base64) 90 | return str(data_base64_sha1_base64, encoding='utf-8') 91 | 92 | def create_headers(self, HTTP_METHOD, HTTP_REQUEST_URI, TIMESTAMP, POST_BODY, public_key, secret_key): 93 | signature = self.encrypt_data(HTTP_METHOD, HTTP_REQUEST_URI, str(TIMESTAMP), POST_BODY, secret_key) 94 | self.headers['FC-ACCESS-KEY'] = public_key 95 | self.headers['FC-ACCESS-TIMESTAMP'] = str(TIMESTAMP) 96 | self.headers['FC-ACCESS-SIGNATURE'] = signature 97 | 98 | Php版本的签名代码: 99 | // 获取毫秒时间戳 100 | function get_millisecond() { 101 | list($t1, $t2) = explode(' ', microtime()); 102 | return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000); 103 | } 104 | //hmac_sha1算法 105 | function getSignature($str, $key) { 106 | $signature = ""; 107 | if (function_exists('hash_hmac')) { 108 | $signature = base64_encode(hash_hmac("sha1", $str, $key, true)); 109 | } else { 110 | $blocksize = 64; 111 | $hashfunc = 'sha1'; 112 | if (strlen($key) > $blocksize) { 113 | $key = pack('H*', $hashfunc($key)); 114 | } 115 | $key = str_pad($key, $blocksize, chr(0x00)); 116 | $ipad = str_repeat(chr(0x36), $blocksize); 117 | $opad = str_repeat(chr(0x5c), $blocksize); 118 | $hmac = pack( 119 | 'H*', $hashfunc( 120 | ($key ^ $opad) . pack( 121 | 'H*', $hashfunc( 122 | ($key ^ $ipad) . $str 123 | ) 124 | ) 125 | ) 126 | ); 127 | $signature = base64_encode($hmac); 128 | } 129 | return $signature; 130 | } 131 | // 组合参数 132 | function bind_param($param) { 133 | if($param){ 134 | $u = []; 135 | $sort_rank = []; 136 | foreach($param as $k=>$v) { 137 | $u[] = $k."=".urlencode($v); 138 | $sort_rank[] = ord($k); 139 | } 140 | asort($u); 141 | return implode('&', $u); 142 | }else{ 143 | return ''; 144 | } 145 | 146 | } 147 | // 生成签名 148 | function create_sig($param) { 149 | $this->access_timestamp = $this->get_millisecond(); 150 | $sign_param_1 = $this->req_method.$this->sign_url.$this->api_method.$this->access_timestamp.$this->bind_param($param); 151 | $sign_param_1 = base64_encode($sign_param_1); 152 | $signature = $this->getSignature($sign_param_1,SECRET_KEY); 153 | return $signature; 154 | } 155 | -------------------------------------------------------------------------------- /fcoin.py: -------------------------------------------------------------------------------- 1 | import hmac 2 | import hashlib 3 | import requests 4 | import sys 5 | import time 6 | import base64 7 | import json 8 | from collections import OrderedDict 9 | 10 | class Fcoin(): 11 | def __init__(self,base_url = 'https://api.fcoin.com/v2/'): 12 | self.base_url = base_url 13 | 14 | def auth(self, key, secret): 15 | self.key = bytes(key,'utf-8') 16 | self.secret = bytes(secret, 'utf-8') 17 | 18 | 19 | def public_request(self, method, api_url, **payload): 20 | """request public url""" 21 | r_url = self.base_url + api_url 22 | try: 23 | r = requests.request(method, r_url, params=payload) 24 | r.raise_for_status() 25 | except requests.exceptions.HTTPError as err: 26 | print(err) 27 | if r.status_code == 200: 28 | return r.json() 29 | 30 | def get_signed(self, sig_str): 31 | """signed params use sha512""" 32 | sig_str = base64.b64encode(sig_str) 33 | signature = base64.b64encode(hmac.new(self.secret, sig_str, digestmod=hashlib.sha1).digest()) 34 | return signature 35 | 36 | 37 | def signed_request(self, method, api_url, **payload): 38 | """request a signed url""" 39 | 40 | param='' 41 | if payload: 42 | sort_pay = sorted(payload.items()) 43 | #sort_pay.sort() 44 | for k in sort_pay: 45 | param += '&' + str(k[0]) + '=' + str(k[1]) 46 | param = param.lstrip('&') 47 | timestamp = str(int(time.time() * 1000)) 48 | full_url = self.base_url + api_url 49 | 50 | if method == 'GET': 51 | if param: 52 | full_url = full_url + '?' +param 53 | sig_str = method + full_url + timestamp 54 | elif method == 'POST': 55 | sig_str = method + full_url + timestamp + param 56 | 57 | signature = self.get_signed(bytes(sig_str, 'utf-8')) 58 | 59 | headers = { 60 | 'FC-ACCESS-KEY': self.key, 61 | 'FC-ACCESS-SIGNATURE': signature, 62 | 'FC-ACCESS-TIMESTAMP': timestamp 63 | 64 | } 65 | 66 | try: 67 | r = requests.request(method, full_url, headers = headers, json=payload) 68 | 69 | r.raise_for_status() 70 | except requests.exceptions.HTTPError as err: 71 | print(err) 72 | print(r.text) 73 | if r.status_code == 200: 74 | return r.json() 75 | 76 | 77 | def get_server_time(self): 78 | """Get server time""" 79 | return self.public_request('GET','/public/server-time')['data'] 80 | 81 | def get_currencies(self): 82 | """get all currencies""" 83 | return self.public_request('GET', '/public/currencies')['data'] 84 | 85 | def get_symbols(self): 86 | """get all symbols""" 87 | return self.public_request('GET', '/public/symbols')['data'] 88 | 89 | def get_market_ticker(self, symbol): 90 | """get market ticker""" 91 | return self.public_request('GET', 'market/ticker/{symbol}'.format(symbol=symbol)) 92 | 93 | def get_market_depth(self, level, symbol): 94 | """get market depth""" 95 | return self.public_request('GET', 'market/depth/{level}/{symbol}'.format(level=level, symbol=symbol)) 96 | 97 | ''' 98 | 选择最近20个的吧 99 | ''' 100 | def get_trades(self,symbol): 101 | """get detail trade""" 102 | return self.public_request('GET', 'market/trades/{symbol}?limit=10'.format(symbol=symbol)) 103 | 104 | # 查你账户里有多钱 105 | def get_balance(self): 106 | """get user balance""" 107 | return self.signed_request('GET', 'accounts/balance') 108 | 109 | # 查某个币种的余额是否够 110 | def get_coin_balance(self,symbol): 111 | try: 112 | coin_map = zip([coin['currency'] for coin in self.get_balance()['data']],[coin['balance'] for coin in self.get_balance()['data']]) 113 | return (dict(coin_map))[symbol] 114 | except: 115 | return 0 116 | 117 | # 查询某个币价格 118 | def get_coin_price_min(self,symbol): 119 | try: 120 | price = [coin['price'] for coin in self.get_trades(symbol)['data']] 121 | ''' 122 | 获取最低币价,接口目前只返回10个,为了快速交易 123 | ''' 124 | price = sum(price) /10 125 | return price 126 | except: 127 | return 0 128 | 129 | # 查询某个币价格,考虑中位数卖 130 | def get_coin_price_max(self,symbol): 131 | try: 132 | price = [coin['price'] for coin in self.get_trades(symbol)['data']] 133 | ''' 134 | 获取最低币价,接口目前只返回10个,为了快速交易 135 | ''' 136 | price = sum(price) / 10 137 | return price 138 | except: 139 | return 0 140 | 141 | 142 | # 查询某个币数量 143 | def get_coin_amount_max(self,symbol): 144 | try: 145 | amount = [coin['amount'] for coin in self.get_trades(symbol)['data']] 146 | ''' 147 | 获取最低币价,接口目前只返回一个 148 | ''' 149 | return min(amount) 150 | except: 151 | return 0 152 | 153 | # 查询某个币数量 154 | def get_coin_amount_min(self,symbol): 155 | try: 156 | amount = [coin['amount'] for coin in self.get_trades(symbol)['data']] 157 | ''' 158 | 获取最低币价,接口目前只返回一个 159 | ''' 160 | return min(amount) 161 | except: 162 | return 0 163 | 164 | def list_orders(self, **payload): 165 | """get orders""" 166 | return self.signed_request('GET','orders', **payload) 167 | 168 | def create_order(self, **payload): 169 | """create order""" 170 | return self.signed_request('POST','orders', **payload) 171 | 172 | ''' 173 | price是四位小数 174 | amount是两位小数 175 | ''' 176 | def buy(self,symbol,price,amount,type = 'limit'): 177 | """buy someting""" 178 | if type == 'market': 179 | return self.create_order(symbol=symbol, side='buy', amount=str(amount),type=type) 180 | return self.create_order(symbol=symbol, side='buy', price = str(price),amount=str(amount),type=type) 181 | 182 | def sell(self, symbol, price, amount,type='limit'): 183 | if type == 'market': 184 | return self.create_order(symbol=symbol, side='sell', amount=str(amount),type=type) 185 | return self.create_order(symbol=symbol, side='sell', price=str(price),amount=str(amount),type=type) 186 | 187 | def get_order(self,order_id): 188 | """get specfic order""" 189 | return self.signed_request('GET', 'orders/{order_id}'.format(order_id=order_id)) 190 | 191 | def cancel_order(self,order_id): 192 | """cancel specfic order""" 193 | return self.signed_request('POST', 'orders/{order_id}/submit-cancel'.format(order_id=order_id)) 194 | 195 | def order_result(self, order_id): 196 | """check order result""" 197 | return self.signed_request('GET', 'orders/{order_id}/match-results'.format(order_id=order_id)) 198 | def get_candle(self,resolution, symbol, **payload): 199 | """get candle data""" 200 | return self.public_request('GET', 'market/candles/{resolution}/{symbol}'.format(resolution=resolution, symbol=symbol), **payload) -------------------------------------------------------------------------------- /.ipynb_checkpoints/Untitled-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 32, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2018-06-09T11:33:47.467863Z", 9 | "start_time": "2018-06-09T11:33:46.914849Z" 10 | } 11 | }, 12 | "outputs": [], 13 | "source": [ 14 | "import hmac\n", 15 | "import hashlib\n", 16 | "import requests\n", 17 | "import sys\n", 18 | "import time\n", 19 | "import base64\n", 20 | "import json\n", 21 | "from collections import OrderedDict\n", 22 | "\n", 23 | "class Fcoin():\n", 24 | " def __init__(self,base_url = 'https://api.fcoin.com/v2/'):\n", 25 | " self.base_url = base_url\n", 26 | "\n", 27 | " def auth(self, key, secret):\n", 28 | " self.key = bytes(key,'utf-8')\n", 29 | " self.secret = bytes(secret, 'utf-8')\n", 30 | "\n", 31 | "\n", 32 | " def public_request(self, method, api_url, **payload):\n", 33 | " \"\"\"request public url\"\"\"\n", 34 | " r_url = self.base_url + api_url\n", 35 | " try:\n", 36 | " r = requests.request(method, r_url, params=payload)\n", 37 | " r.raise_for_status()\n", 38 | " except requests.exceptions.HTTPError as err:\n", 39 | " print(err)\n", 40 | " if r.status_code == 200:\n", 41 | " return r.json()\n", 42 | "\n", 43 | " def get_signed(self, sig_str):\n", 44 | " \"\"\"signed params use sha512\"\"\"\n", 45 | " sig_str = base64.b64encode(sig_str)\n", 46 | " signature = base64.b64encode(hmac.new(self.secret, sig_str, digestmod=hashlib.sha1).digest())\n", 47 | " return signature\n", 48 | "\n", 49 | "\n", 50 | " def signed_request(self, method, api_url, **payload):\n", 51 | " \"\"\"request a signed url\"\"\"\n", 52 | "\n", 53 | " param=''\n", 54 | " if payload:\n", 55 | " sort_pay = sorted(payload.items())\n", 56 | " #sort_pay.sort()\n", 57 | " for k in sort_pay:\n", 58 | " param += '&' + str(k[0]) + '=' + str(k[1])\n", 59 | " param = param.lstrip('&')\n", 60 | " timestamp = str(int(time.time() * 1000))\n", 61 | " full_url = self.base_url + api_url\n", 62 | "\n", 63 | " if method == 'GET':\n", 64 | " if param:\n", 65 | " full_url = full_url + '?' +param\n", 66 | " sig_str = method + full_url + timestamp\n", 67 | " elif method == 'POST':\n", 68 | " sig_str = method + full_url + timestamp + param\n", 69 | "\n", 70 | " signature = self.get_signed(bytes(sig_str, 'utf-8'))\n", 71 | "\n", 72 | " headers = {\n", 73 | " 'FC-ACCESS-KEY': self.key,\n", 74 | " 'FC-ACCESS-SIGNATURE': signature,\n", 75 | " 'FC-ACCESS-TIMESTAMP': timestamp\n", 76 | "\n", 77 | " }\n", 78 | "\n", 79 | " try:\n", 80 | " r = requests.request(method, full_url, headers = headers, json=payload)\n", 81 | "\n", 82 | " r.raise_for_status()\n", 83 | " except requests.exceptions.HTTPError as err:\n", 84 | " print(err)\n", 85 | " print(r.text)\n", 86 | " if r.status_code == 200:\n", 87 | " return r.json()\n", 88 | "\n", 89 | "\n", 90 | " def get_server_time(self):\n", 91 | " \"\"\"Get server time\"\"\"\n", 92 | " return self.public_request('GET','/public/server-time')['data']\n", 93 | "\n", 94 | "\n", 95 | " def get_currencies(self):\n", 96 | " \"\"\"get all currencies\"\"\"\n", 97 | " return self.public_request('GET', '/public/currencies')['data']\n", 98 | "\n", 99 | " def get_symbols(self):\n", 100 | " \"\"\"get all symbols\"\"\"\n", 101 | " return self.public_request('GET', '/public/symbols')['data']\n", 102 | "\n", 103 | " def get_market_ticker(self, symbol):\n", 104 | " \"\"\"get market ticker\"\"\"\n", 105 | " return self.public_request('GET', 'market/ticker/{symbol}'.format(symbol=symbol))\n", 106 | "\n", 107 | " def get_market_depth(self, level, symbol):\n", 108 | " \"\"\"get market depth\"\"\"\n", 109 | " return self.public_request('GET', 'market/depth/{level}/{symbol}'.format(level=level, symbol=symbol))\n", 110 | "\n", 111 | " def get_trades(self,symbol):\n", 112 | " \"\"\"get detail trade\"\"\"\n", 113 | " return self.public_request('GET', 'market/trades/{symbol}'.format(symbol=symbol))\n", 114 | "\n", 115 | " # 查你账户里有多钱\n", 116 | " def get_balance(self):\n", 117 | " \"\"\"get user balance\"\"\"\n", 118 | " return self.signed_request('GET', 'accounts/balance')\n", 119 | " \n", 120 | " # 查询某个币价格\n", 121 | " def get_coin_price(self,symbol):\n", 122 | " price = [coin['price'] for coin in self.get_trades(symbol)['data']]\n", 123 | " '''\n", 124 | " 获取最低币价,接口目前只返回一个\n", 125 | " ''' \n", 126 | " return min(price)\n", 127 | "\n", 128 | " def list_orders(self, **payload):\n", 129 | " \"\"\"get orders\"\"\"\n", 130 | " return self.signed_request('GET','orders', **payload)\n", 131 | "\n", 132 | " def create_order(self, **payload):\n", 133 | " \"\"\"create order\"\"\"\n", 134 | " return self.signed_request('POST','orders', **payload)\n", 135 | "\n", 136 | " def buy(self,symbol, price, amount):\n", 137 | " \"\"\"buy someting\"\"\"\n", 138 | " return self.create_order(symbol=symbol, side='buy', type='limit', price=str(price), amount=amount)\n", 139 | "\n", 140 | " def sell(self, symbol, price, amount):\n", 141 | " \"\"\"buy someting\"\"\"\n", 142 | " return self.create_order(symbol=symbol, side='sell', type='limit', price=str(price), amount=amount)\n", 143 | "\n", 144 | " def get_order(self,order_id):\n", 145 | " \"\"\"get specfic order\"\"\"\n", 146 | " return self.signed_request('GET', 'orders/{order_id}'.format(order_id=order_id))\n", 147 | " \n", 148 | " # 查某个币种的余额是否够\n", 149 | " def get_coin_balance(self,symbol):\n", 150 | " coin_map = zip([coin['currency'] for coin in self.get_balance()['data']],[coin['balance'] for coin in self.get_balance()['data']]) \n", 151 | " return (dict(coin_map))[symbol] \n", 152 | "\n", 153 | " def cancel_order(self,order_id):\n", 154 | " \"\"\"cancel specfic order\"\"\"\n", 155 | " return self.signed_request('POST', 'orders/{order_id}/submit-cancel'.format(order_id=order_id))\n", 156 | "\n", 157 | " def order_result(self, order_id):\n", 158 | " \"\"\"check order result\"\"\"\n", 159 | " return self.signed_request('GET', 'orders/{order_id}/match-results'.format(order_id=order_id))\n", 160 | " def get_candle(self,resolution, symbol, **payload):\n", 161 | " \"\"\"get candle data\"\"\"\n", 162 | " return self.public_request('GET', 'market/candles/{resolution}/{symbol}'.format(resolution=resolution, symbol=symbol), **payload)\n" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": null, 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 33, 175 | "metadata": { 176 | "ExecuteTime": { 177 | "end_time": "2018-06-09T11:33:49.301434Z", 178 | "start_time": "2018-06-09T11:33:49.298766Z" 179 | } 180 | }, 181 | "outputs": [], 182 | "source": [ 183 | "fcoin = Fcoin()\n", 184 | "fcoin.auth('5418eaac7f384e8ebf76246860e629f7', '85f6d51358f5467faa1199e18810a8b9')" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 9, 197 | "metadata": { 198 | "ExecuteTime": { 199 | "end_time": "2018-06-09T09:37:59.636084Z", 200 | "start_time": "2018-06-09T09:37:58.040798Z" 201 | } 202 | }, 203 | "outputs": [ 204 | { 205 | "name": "stdout", 206 | "output_type": "stream", 207 | "text": [ 208 | "I'm working for sell\n", 209 | "job2: 2018-06-09 17:37:59.634066\n" 210 | ] 211 | } 212 | ], 213 | "source": [ 214 | "# 多线程运行买和卖\n", 215 | "import datetime\n", 216 | "import schedule\n", 217 | "import threading\n", 218 | "import time\n", 219 | "\n", 220 | "def buy():\n", 221 | " print(\"I'm working for buy\")\n", 222 | " fcoin.buy('ethusdt',602.50,0.02);\n", 223 | " time.sleep(1);\n", 224 | " print(\"job1:\", datetime.datetime.now())\n", 225 | " \n", 226 | "def sell():\n", 227 | " print(\"I'm working for sell\")\n", 228 | " fcoin.sell('ethusdt',602.76,0.001)\n", 229 | " time.sleep(1)\n", 230 | " print(\"job2:\", datetime.datetime.now())\n", 231 | " \n", 232 | "def job1_task():\n", 233 | " threading.Thread(target=job1).start()\n", 234 | " \n", 235 | "def job2_task():\n", 236 | " threading.Thread(target=job2).start()" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": 36, 242 | "metadata": { 243 | "ExecuteTime": { 244 | "end_time": "2018-06-09T11:54:11.437560Z", 245 | "start_time": "2018-06-09T11:54:10.982262Z" 246 | } 247 | }, 248 | "outputs": [ 249 | { 250 | "data": { 251 | "text/plain": [ 252 | "{'data': [{'amount': 173.0,\n", 253 | " 'id': 765756000,\n", 254 | " 'price': 0.00105151,\n", 255 | " 'side': 'sell',\n", 256 | " 'ts': 1528545250727}],\n", 257 | " 'status': 0}" 258 | ] 259 | }, 260 | "execution_count": 36, 261 | "metadata": {}, 262 | "output_type": "execute_result" 263 | } 264 | ], 265 | "source": [ 266 | "fcoin.get_trades('fteth')\n" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 80, 272 | "metadata": { 273 | "ExecuteTime": { 274 | "end_time": "2018-06-09T15:08:16.021048Z", 275 | "start_time": "2018-06-09T15:08:15.295288Z" 276 | } 277 | }, 278 | "outputs": [ 279 | { 280 | "name": "stdout", 281 | "output_type": "stream", 282 | "text": [ 283 | "0.00106\n" 284 | ] 285 | } 286 | ], 287 | "source": [ 288 | "usdt_price = fcoin.get_coin_price('fteth')\n", 289 | "print(usdt_price)" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": null, 295 | "metadata": {}, 296 | "outputs": [], 297 | "source": [] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": null, 302 | "metadata": {}, 303 | "outputs": [], 304 | "source": [] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": null, 309 | "metadata": {}, 310 | "outputs": [], 311 | "source": [ 312 | "from functools import reduce\n", 313 | "def str2float(strf):\n", 314 | "def char2num(s):\n", 315 | "return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]\n", 316 | "def char2int(x, y):\n", 317 | "return 10 * x + y\n", 318 | "tstr = strf.split('.')\n", 319 | "hightre = reduce(char2int, map(char2num, tstr[0]))\n", 320 | "if len(tstr)>1:\n", 321 | "lowre = reduce(char2int, map(char2num, tstr[1]))*(0.1**len(tstr[1]))\n", 322 | "else:\n", 323 | "lowre = 0\n", 324 | "return hightre + lowre" 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": null, 330 | "metadata": {}, 331 | "outputs": [], 332 | "source": [] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": null, 337 | "metadata": {}, 338 | "outputs": [], 339 | "source": [] 340 | }, 341 | { 342 | "cell_type": "code", 343 | "execution_count": null, 344 | "metadata": {}, 345 | "outputs": [], 346 | "source": [] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": null, 351 | "metadata": {}, 352 | "outputs": [], 353 | "source": [] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": null, 358 | "metadata": {}, 359 | "outputs": [], 360 | "source": [] 361 | }, 362 | { 363 | "cell_type": "code", 364 | "execution_count": null, 365 | "metadata": {}, 366 | "outputs": [], 367 | "source": [] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": null, 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "metadata": {}, 380 | "outputs": [], 381 | "source": [] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": 59, 386 | "metadata": { 387 | "ExecuteTime": { 388 | "end_time": "2018-06-09T12:19:31.935056Z", 389 | "start_time": "2018-06-09T12:19:30.047301Z" 390 | } 391 | }, 392 | "outputs": [ 393 | { 394 | "data": { 395 | "text/plain": [ 396 | "{'data': [{'amount': 0.038,\n", 397 | " 'id': 37583668000,\n", 398 | " 'price': 601.79,\n", 399 | " 'side': 'buy',\n", 400 | " 'ts': 1528546771243}],\n", 401 | " 'status': 0}" 402 | ] 403 | }, 404 | "execution_count": 59, 405 | "metadata": {}, 406 | "output_type": "execute_result" 407 | } 408 | ], 409 | "source": [ 410 | "fcoin.get_trades('ethusdt')" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": null, 416 | "metadata": {}, 417 | "outputs": [], 418 | "source": [] 419 | }, 420 | { 421 | "cell_type": "code", 422 | "execution_count": null, 423 | "metadata": {}, 424 | "outputs": [], 425 | "source": [] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": null, 430 | "metadata": {}, 431 | "outputs": [], 432 | "source": [] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": null, 437 | "metadata": {}, 438 | "outputs": [], 439 | "source": [] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": null, 444 | "metadata": {}, 445 | "outputs": [], 446 | "source": [] 447 | }, 448 | { 449 | "cell_type": "code", 450 | "execution_count": null, 451 | "metadata": {}, 452 | "outputs": [], 453 | "source": [] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": null, 458 | "metadata": {}, 459 | "outputs": [], 460 | "source": [] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": null, 465 | "metadata": {}, 466 | "outputs": [], 467 | "source": [] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "execution_count": null, 472 | "metadata": {}, 473 | "outputs": [], 474 | "source": [] 475 | }, 476 | { 477 | "cell_type": "code", 478 | "execution_count": null, 479 | "metadata": {}, 480 | "outputs": [], 481 | "source": [] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "execution_count": null, 486 | "metadata": {}, 487 | "outputs": [], 488 | "source": [] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": null, 493 | "metadata": {}, 494 | "outputs": [], 495 | "source": [] 496 | }, 497 | { 498 | "cell_type": "code", 499 | "execution_count": null, 500 | "metadata": {}, 501 | "outputs": [], 502 | "source": [] 503 | }, 504 | { 505 | "cell_type": "code", 506 | "execution_count": null, 507 | "metadata": {}, 508 | "outputs": [], 509 | "source": [] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "execution_count": null, 514 | "metadata": {}, 515 | "outputs": [], 516 | "source": [] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": null, 521 | "metadata": {}, 522 | "outputs": [], 523 | "source": [] 524 | }, 525 | { 526 | "cell_type": "code", 527 | "execution_count": null, 528 | "metadata": {}, 529 | "outputs": [], 530 | "source": [] 531 | }, 532 | { 533 | "cell_type": "code", 534 | "execution_count": null, 535 | "metadata": {}, 536 | "outputs": [], 537 | "source": [] 538 | }, 539 | { 540 | "cell_type": "code", 541 | "execution_count": null, 542 | "metadata": {}, 543 | "outputs": [], 544 | "source": [] 545 | }, 546 | { 547 | "cell_type": "code", 548 | "execution_count": null, 549 | "metadata": {}, 550 | "outputs": [], 551 | "source": [] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": null, 556 | "metadata": {}, 557 | "outputs": [], 558 | "source": [] 559 | }, 560 | { 561 | "cell_type": "code", 562 | "execution_count": null, 563 | "metadata": {}, 564 | "outputs": [], 565 | "source": [] 566 | }, 567 | { 568 | "cell_type": "code", 569 | "execution_count": null, 570 | "metadata": {}, 571 | "outputs": [], 572 | "source": [] 573 | }, 574 | { 575 | "cell_type": "code", 576 | "execution_count": null, 577 | "metadata": {}, 578 | "outputs": [], 579 | "source": [] 580 | }, 581 | { 582 | "cell_type": "code", 583 | "execution_count": null, 584 | "metadata": {}, 585 | "outputs": [], 586 | "source": [] 587 | }, 588 | { 589 | "cell_type": "code", 590 | "execution_count": null, 591 | "metadata": {}, 592 | "outputs": [], 593 | "source": [] 594 | }, 595 | { 596 | "cell_type": "code", 597 | "execution_count": null, 598 | "metadata": {}, 599 | "outputs": [], 600 | "source": [] 601 | }, 602 | { 603 | "cell_type": "code", 604 | "execution_count": null, 605 | "metadata": {}, 606 | "outputs": [], 607 | "source": [] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": null, 612 | "metadata": {}, 613 | "outputs": [], 614 | "source": [] 615 | }, 616 | { 617 | "cell_type": "code", 618 | "execution_count": null, 619 | "metadata": {}, 620 | "outputs": [], 621 | "source": [] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": null, 626 | "metadata": {}, 627 | "outputs": [], 628 | "source": [] 629 | }, 630 | { 631 | "cell_type": "code", 632 | "execution_count": null, 633 | "metadata": {}, 634 | "outputs": [], 635 | "source": [] 636 | }, 637 | { 638 | "cell_type": "code", 639 | "execution_count": null, 640 | "metadata": {}, 641 | "outputs": [], 642 | "source": [] 643 | } 644 | ], 645 | "metadata": { 646 | "kernelspec": { 647 | "display_name": "Python 3", 648 | "language": "python", 649 | "name": "python3" 650 | }, 651 | "language_info": { 652 | "codemirror_mode": { 653 | "name": "ipython", 654 | "version": 3 655 | }, 656 | "file_extension": ".py", 657 | "mimetype": "text/x-python", 658 | "name": "python", 659 | "nbconvert_exporter": "python", 660 | "pygments_lexer": "ipython3", 661 | "version": "3.6.4" 662 | }, 663 | "toc": { 664 | "base_numbering": 1, 665 | "nav_menu": {}, 666 | "number_sections": true, 667 | "sideBar": true, 668 | "skip_h1_title": false, 669 | "title_cell": "Table of Contents", 670 | "title_sidebar": "Contents", 671 | "toc_cell": false, 672 | "toc_position": {}, 673 | "toc_section_display": true, 674 | "toc_window_display": false 675 | } 676 | }, 677 | "nbformat": 4, 678 | "nbformat_minor": 2 679 | } 680 | -------------------------------------------------------------------------------- /Untitled.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 32, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2018-06-09T11:33:47.467863Z", 9 | "start_time": "2018-06-09T11:33:46.914849Z" 10 | } 11 | }, 12 | "outputs": [], 13 | "source": [ 14 | "import hmac\n", 15 | "import hashlib\n", 16 | "import requests\n", 17 | "import sys\n", 18 | "import time\n", 19 | "import base64\n", 20 | "import json\n", 21 | "from collections import OrderedDict\n", 22 | "\n", 23 | "class Fcoin():\n", 24 | " def __init__(self,base_url = 'https://api.fcoin.com/v2/'):\n", 25 | " self.base_url = base_url\n", 26 | "\n", 27 | " def auth(self, key, secret):\n", 28 | " self.key = bytes(key,'utf-8')\n", 29 | " self.secret = bytes(secret, 'utf-8')\n", 30 | "\n", 31 | "\n", 32 | " def public_request(self, method, api_url, **payload):\n", 33 | " \"\"\"request public url\"\"\"\n", 34 | " r_url = self.base_url + api_url\n", 35 | " try:\n", 36 | " r = requests.request(method, r_url, params=payload)\n", 37 | " r.raise_for_status()\n", 38 | " except requests.exceptions.HTTPError as err:\n", 39 | " print(err)\n", 40 | " if r.status_code == 200:\n", 41 | " return r.json()\n", 42 | "\n", 43 | " def get_signed(self, sig_str):\n", 44 | " \"\"\"signed params use sha512\"\"\"\n", 45 | " sig_str = base64.b64encode(sig_str)\n", 46 | " signature = base64.b64encode(hmac.new(self.secret, sig_str, digestmod=hashlib.sha1).digest())\n", 47 | " return signature\n", 48 | "\n", 49 | "\n", 50 | " def signed_request(self, method, api_url, **payload):\n", 51 | " \"\"\"request a signed url\"\"\"\n", 52 | "\n", 53 | " param=''\n", 54 | " if payload:\n", 55 | " sort_pay = sorted(payload.items())\n", 56 | " #sort_pay.sort()\n", 57 | " for k in sort_pay:\n", 58 | " param += '&' + str(k[0]) + '=' + str(k[1])\n", 59 | " param = param.lstrip('&')\n", 60 | " timestamp = str(int(time.time() * 1000))\n", 61 | " full_url = self.base_url + api_url\n", 62 | "\n", 63 | " if method == 'GET':\n", 64 | " if param:\n", 65 | " full_url = full_url + '?' +param\n", 66 | " sig_str = method + full_url + timestamp\n", 67 | " elif method == 'POST':\n", 68 | " sig_str = method + full_url + timestamp + param\n", 69 | "\n", 70 | " signature = self.get_signed(bytes(sig_str, 'utf-8'))\n", 71 | "\n", 72 | " headers = {\n", 73 | " 'FC-ACCESS-KEY': self.key,\n", 74 | " 'FC-ACCESS-SIGNATURE': signature,\n", 75 | " 'FC-ACCESS-TIMESTAMP': timestamp\n", 76 | "\n", 77 | " }\n", 78 | "\n", 79 | " try:\n", 80 | " r = requests.request(method, full_url, headers = headers, json=payload)\n", 81 | "\n", 82 | " r.raise_for_status()\n", 83 | " except requests.exceptions.HTTPError as err:\n", 84 | " print(err)\n", 85 | " print(r.text)\n", 86 | " if r.status_code == 200:\n", 87 | " return r.json()\n", 88 | "\n", 89 | "\n", 90 | " def get_server_time(self):\n", 91 | " \"\"\"Get server time\"\"\"\n", 92 | " return self.public_request('GET','/public/server-time')['data']\n", 93 | "\n", 94 | "\n", 95 | " def get_currencies(self):\n", 96 | " \"\"\"get all currencies\"\"\"\n", 97 | " return self.public_request('GET', '/public/currencies')['data']\n", 98 | "\n", 99 | " def get_symbols(self):\n", 100 | " \"\"\"get all symbols\"\"\"\n", 101 | " return self.public_request('GET', '/public/symbols')['data']\n", 102 | "\n", 103 | " def get_market_ticker(self, symbol):\n", 104 | " \"\"\"get market ticker\"\"\"\n", 105 | " return self.public_request('GET', 'market/ticker/{symbol}'.format(symbol=symbol))\n", 106 | "\n", 107 | " def get_market_depth(self, level, symbol):\n", 108 | " \"\"\"get market depth\"\"\"\n", 109 | " return self.public_request('GET', 'market/depth/{level}/{symbol}'.format(level=level, symbol=symbol))\n", 110 | "\n", 111 | " def get_trades(self,symbol):\n", 112 | " \"\"\"get detail trade\"\"\"\n", 113 | " return self.public_request('GET', 'market/trades/{symbol}'.format(symbol=symbol))\n", 114 | "\n", 115 | " # 查你账户里有多钱\n", 116 | " def get_balance(self):\n", 117 | " \"\"\"get user balance\"\"\"\n", 118 | " return self.signed_request('GET', 'accounts/balance')\n", 119 | " \n", 120 | " # 查询某个币价格\n", 121 | " def get_coin_price(self,symbol):\n", 122 | " price = [coin['price'] for coin in self.get_trades(symbol)['data']]\n", 123 | " '''\n", 124 | " 获取最低币价,接口目前只返回一个\n", 125 | " ''' \n", 126 | " return min(price)\n", 127 | "\n", 128 | " def list_orders(self, **payload):\n", 129 | " \"\"\"get orders\"\"\"\n", 130 | " return self.signed_request('GET','orders', **payload)\n", 131 | "\n", 132 | " def create_order(self, **payload):\n", 133 | " \"\"\"create order\"\"\"\n", 134 | " return self.signed_request('POST','orders', **payload)\n", 135 | "\n", 136 | " def buy(self,symbol, price, amount):\n", 137 | " \"\"\"buy someting\"\"\"\n", 138 | " return self.create_order(symbol=symbol, side='buy', type='limit', price=str(price), amount=amount)\n", 139 | "\n", 140 | " def sell(self, symbol, price, amount):\n", 141 | " \"\"\"buy someting\"\"\"\n", 142 | " return self.create_order(symbol=symbol, side='sell', type='limit', price=str(price), amount=amount)\n", 143 | "\n", 144 | " def get_order(self,order_id):\n", 145 | " \"\"\"get specfic order\"\"\"\n", 146 | " return self.signed_request('GET', 'orders/{order_id}'.format(order_id=order_id))\n", 147 | " \n", 148 | " # 查某个币种的余额是否够\n", 149 | " def get_coin_balance(self,symbol):\n", 150 | " coin_map = zip([coin['currency'] for coin in self.get_balance()['data']],[coin['balance'] for coin in self.get_balance()['data']]) \n", 151 | " return (dict(coin_map))[symbol] \n", 152 | "\n", 153 | " def cancel_order(self,order_id):\n", 154 | " \"\"\"cancel specfic order\"\"\"\n", 155 | " return self.signed_request('POST', 'orders/{order_id}/submit-cancel'.format(order_id=order_id))\n", 156 | "\n", 157 | " def order_result(self, order_id):\n", 158 | " \"\"\"check order result\"\"\"\n", 159 | " return self.signed_request('GET', 'orders/{order_id}/match-results'.format(order_id=order_id))\n", 160 | " def get_candle(self,resolution, symbol, **payload):\n", 161 | " \"\"\"get candle data\"\"\"\n", 162 | " return self.public_request('GET', 'market/candles/{resolution}/{symbol}'.format(resolution=resolution, symbol=symbol), **payload)\n" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": null, 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 33, 175 | "metadata": { 176 | "ExecuteTime": { 177 | "end_time": "2018-06-09T11:33:49.301434Z", 178 | "start_time": "2018-06-09T11:33:49.298766Z" 179 | } 180 | }, 181 | "outputs": [], 182 | "source": [ 183 | "fcoin = Fcoin()\n", 184 | "fcoin.auth('5418eaac7f384e8ebf76246860e629f7', '85f6d51358f5467faa1199e18810a8b9')" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 9, 197 | "metadata": { 198 | "ExecuteTime": { 199 | "end_time": "2018-06-09T09:37:59.636084Z", 200 | "start_time": "2018-06-09T09:37:58.040798Z" 201 | } 202 | }, 203 | "outputs": [ 204 | { 205 | "name": "stdout", 206 | "output_type": "stream", 207 | "text": [ 208 | "I'm working for sell\n", 209 | "job2: 2018-06-09 17:37:59.634066\n" 210 | ] 211 | } 212 | ], 213 | "source": [ 214 | "# 多线程运行买和卖\n", 215 | "import datetime\n", 216 | "import schedule\n", 217 | "import threading\n", 218 | "import time\n", 219 | "\n", 220 | "def buy():\n", 221 | " print(\"I'm working for buy\")\n", 222 | " fcoin.buy('ethusdt',602.50,0.02);\n", 223 | " time.sleep(1);\n", 224 | " print(\"job1:\", datetime.datetime.now())\n", 225 | " \n", 226 | "def sell():\n", 227 | " print(\"I'm working for sell\")\n", 228 | " fcoin.sell('ethusdt',602.76,0.001)\n", 229 | " time.sleep(1)\n", 230 | " print(\"job2:\", datetime.datetime.now())\n", 231 | " \n", 232 | "def job1_task():\n", 233 | " threading.Thread(target=job1).start()\n", 234 | " \n", 235 | "def job2_task():\n", 236 | " threading.Thread(target=job2).start()" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": 36, 242 | "metadata": { 243 | "ExecuteTime": { 244 | "end_time": "2018-06-09T11:54:11.437560Z", 245 | "start_time": "2018-06-09T11:54:10.982262Z" 246 | } 247 | }, 248 | "outputs": [ 249 | { 250 | "data": { 251 | "text/plain": [ 252 | "{'data': [{'amount': 173.0,\n", 253 | " 'id': 765756000,\n", 254 | " 'price': 0.00105151,\n", 255 | " 'side': 'sell',\n", 256 | " 'ts': 1528545250727}],\n", 257 | " 'status': 0}" 258 | ] 259 | }, 260 | "execution_count": 36, 261 | "metadata": {}, 262 | "output_type": "execute_result" 263 | } 264 | ], 265 | "source": [ 266 | "fcoin.get_trades('fteth')\n" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 80, 272 | "metadata": { 273 | "ExecuteTime": { 274 | "end_time": "2018-06-09T15:08:16.021048Z", 275 | "start_time": "2018-06-09T15:08:15.295288Z" 276 | } 277 | }, 278 | "outputs": [ 279 | { 280 | "name": "stdout", 281 | "output_type": "stream", 282 | "text": [ 283 | "0.00106\n" 284 | ] 285 | } 286 | ], 287 | "source": [ 288 | "usdt_price = fcoin.get_coin_price('fteth')\n", 289 | "print(usdt_price)" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": null, 295 | "metadata": {}, 296 | "outputs": [], 297 | "source": [] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": null, 302 | "metadata": {}, 303 | "outputs": [], 304 | "source": [] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": null, 309 | "metadata": {}, 310 | "outputs": [], 311 | "source": [ 312 | "from functools import reduce\n", 313 | "def str2float(strf):\n", 314 | "def char2num(s):\n", 315 | "return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]\n", 316 | "def char2int(x, y):\n", 317 | "return 10 * x + y\n", 318 | "tstr = strf.split('.')\n", 319 | "hightre = reduce(char2int, map(char2num, tstr[0]))\n", 320 | "if len(tstr)>1:\n", 321 | "lowre = reduce(char2int, map(char2num, tstr[1]))*(0.1**len(tstr[1]))\n", 322 | "else:\n", 323 | "lowre = 0\n", 324 | "return hightre + lowre" 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": null, 330 | "metadata": {}, 331 | "outputs": [], 332 | "source": [] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": null, 337 | "metadata": {}, 338 | "outputs": [], 339 | "source": [] 340 | }, 341 | { 342 | "cell_type": "code", 343 | "execution_count": null, 344 | "metadata": {}, 345 | "outputs": [], 346 | "source": [] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": null, 351 | "metadata": {}, 352 | "outputs": [], 353 | "source": [] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": null, 358 | "metadata": {}, 359 | "outputs": [], 360 | "source": [] 361 | }, 362 | { 363 | "cell_type": "code", 364 | "execution_count": null, 365 | "metadata": {}, 366 | "outputs": [], 367 | "source": [] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": null, 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": null, 379 | "metadata": {}, 380 | "outputs": [], 381 | "source": [] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": 59, 386 | "metadata": { 387 | "ExecuteTime": { 388 | "end_time": "2018-06-09T12:19:31.935056Z", 389 | "start_time": "2018-06-09T12:19:30.047301Z" 390 | } 391 | }, 392 | "outputs": [ 393 | { 394 | "data": { 395 | "text/plain": [ 396 | "{'data': [{'amount': 0.038,\n", 397 | " 'id': 37583668000,\n", 398 | " 'price': 601.79,\n", 399 | " 'side': 'buy',\n", 400 | " 'ts': 1528546771243}],\n", 401 | " 'status': 0}" 402 | ] 403 | }, 404 | "execution_count": 59, 405 | "metadata": {}, 406 | "output_type": "execute_result" 407 | } 408 | ], 409 | "source": [ 410 | "fcoin.get_trades('ethusdt')" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": null, 416 | "metadata": {}, 417 | "outputs": [], 418 | "source": [] 419 | }, 420 | { 421 | "cell_type": "code", 422 | "execution_count": null, 423 | "metadata": {}, 424 | "outputs": [], 425 | "source": [] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": null, 430 | "metadata": {}, 431 | "outputs": [], 432 | "source": [] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": 81, 437 | "metadata": { 438 | "ExecuteTime": { 439 | "end_time": "2018-06-10T05:28:00.862985Z", 440 | "start_time": "2018-06-10T05:28:00.839037Z" 441 | } 442 | }, 443 | "outputs": [ 444 | { 445 | "ename": "SyntaxError", 446 | "evalue": "non-default argument follows default argument (, line 1)", 447 | "output_type": "error", 448 | "traceback": [ 449 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m def sell(self, symbol,type = 'limit', price, amount):\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m non-default argument follows default argument\n" 450 | ] 451 | } 452 | ], 453 | "source": [ 454 | "def sell(self, symbol,type = 'limit', price, amount):\n", 455 | " if type == 'market':\n", 456 | " return self.create_order(symbol=symbol, side='sell', type=type, amount=str(amount))\n", 457 | " return self.create_order(symbol=symbol, side='sell', type=type,price=str(price),amount=str(amount))" 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": null, 463 | "metadata": {}, 464 | "outputs": [], 465 | "source": [] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": null, 470 | "metadata": {}, 471 | "outputs": [], 472 | "source": [] 473 | }, 474 | { 475 | "cell_type": "code", 476 | "execution_count": null, 477 | "metadata": {}, 478 | "outputs": [], 479 | "source": [] 480 | }, 481 | { 482 | "cell_type": "code", 483 | "execution_count": null, 484 | "metadata": {}, 485 | "outputs": [], 486 | "source": [] 487 | }, 488 | { 489 | "cell_type": "code", 490 | "execution_count": null, 491 | "metadata": {}, 492 | "outputs": [], 493 | "source": [] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": null, 498 | "metadata": {}, 499 | "outputs": [], 500 | "source": [] 501 | }, 502 | { 503 | "cell_type": "code", 504 | "execution_count": null, 505 | "metadata": {}, 506 | "outputs": [], 507 | "source": [] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "execution_count": null, 512 | "metadata": {}, 513 | "outputs": [], 514 | "source": [] 515 | }, 516 | { 517 | "cell_type": "code", 518 | "execution_count": null, 519 | "metadata": {}, 520 | "outputs": [], 521 | "source": [] 522 | }, 523 | { 524 | "cell_type": "code", 525 | "execution_count": null, 526 | "metadata": {}, 527 | "outputs": [], 528 | "source": [] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": null, 533 | "metadata": {}, 534 | "outputs": [], 535 | "source": [] 536 | }, 537 | { 538 | "cell_type": "code", 539 | "execution_count": null, 540 | "metadata": {}, 541 | "outputs": [], 542 | "source": [] 543 | }, 544 | { 545 | "cell_type": "code", 546 | "execution_count": null, 547 | "metadata": {}, 548 | "outputs": [], 549 | "source": [] 550 | }, 551 | { 552 | "cell_type": "code", 553 | "execution_count": null, 554 | "metadata": {}, 555 | "outputs": [], 556 | "source": [] 557 | }, 558 | { 559 | "cell_type": "code", 560 | "execution_count": null, 561 | "metadata": {}, 562 | "outputs": [], 563 | "source": [] 564 | }, 565 | { 566 | "cell_type": "code", 567 | "execution_count": null, 568 | "metadata": {}, 569 | "outputs": [], 570 | "source": [] 571 | }, 572 | { 573 | "cell_type": "code", 574 | "execution_count": null, 575 | "metadata": {}, 576 | "outputs": [], 577 | "source": [] 578 | }, 579 | { 580 | "cell_type": "code", 581 | "execution_count": null, 582 | "metadata": {}, 583 | "outputs": [], 584 | "source": [] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "execution_count": null, 589 | "metadata": {}, 590 | "outputs": [], 591 | "source": [] 592 | }, 593 | { 594 | "cell_type": "code", 595 | "execution_count": null, 596 | "metadata": {}, 597 | "outputs": [], 598 | "source": [] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": null, 603 | "metadata": {}, 604 | "outputs": [], 605 | "source": [] 606 | }, 607 | { 608 | "cell_type": "code", 609 | "execution_count": null, 610 | "metadata": {}, 611 | "outputs": [], 612 | "source": [] 613 | }, 614 | { 615 | "cell_type": "code", 616 | "execution_count": null, 617 | "metadata": {}, 618 | "outputs": [], 619 | "source": [] 620 | }, 621 | { 622 | "cell_type": "code", 623 | "execution_count": null, 624 | "metadata": {}, 625 | "outputs": [], 626 | "source": [] 627 | }, 628 | { 629 | "cell_type": "code", 630 | "execution_count": null, 631 | "metadata": {}, 632 | "outputs": [], 633 | "source": [] 634 | }, 635 | { 636 | "cell_type": "code", 637 | "execution_count": null, 638 | "metadata": {}, 639 | "outputs": [], 640 | "source": [] 641 | }, 642 | { 643 | "cell_type": "code", 644 | "execution_count": null, 645 | "metadata": {}, 646 | "outputs": [], 647 | "source": [] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": null, 652 | "metadata": {}, 653 | "outputs": [], 654 | "source": [] 655 | }, 656 | { 657 | "cell_type": "code", 658 | "execution_count": null, 659 | "metadata": {}, 660 | "outputs": [], 661 | "source": [] 662 | }, 663 | { 664 | "cell_type": "code", 665 | "execution_count": null, 666 | "metadata": {}, 667 | "outputs": [], 668 | "source": [] 669 | } 670 | ], 671 | "metadata": { 672 | "kernelspec": { 673 | "display_name": "Python 3", 674 | "language": "python", 675 | "name": "python3" 676 | }, 677 | "language_info": { 678 | "codemirror_mode": { 679 | "name": "ipython", 680 | "version": 3 681 | }, 682 | "file_extension": ".py", 683 | "mimetype": "text/x-python", 684 | "name": "python", 685 | "nbconvert_exporter": "python", 686 | "pygments_lexer": "ipython3", 687 | "version": "3.6.4" 688 | }, 689 | "toc": { 690 | "base_numbering": 1, 691 | "nav_menu": {}, 692 | "number_sections": true, 693 | "sideBar": true, 694 | "skip_h1_title": false, 695 | "title_cell": "Table of Contents", 696 | "title_sidebar": "Contents", 697 | "toc_cell": false, 698 | "toc_position": {}, 699 | "toc_section_display": true, 700 | "toc_window_display": false 701 | } 702 | }, 703 | "nbformat": 4, 704 | "nbformat_minor": 2 705 | } 706 | --------------------------------------------------------------------------------