Advertisement
Guest User

Untitled

a guest
Sep 28th, 2016
607
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.18 KB | None | 0 0
  1. #Current error, looping through Master Control and Tradelogic self.data gets assigned another value.
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10. #This program accesses Krakenex the bitcoin exchange, analyses and trades.
  11.  
  12. #THE STORAGE OBJECT - { PAIR LIST ITERATION TRADE NUMBER TRADE QUALITY }
  13.  
  14. #MasterControl -> DataStorage CurPair to get data.
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21. #Threading
  22. #threads = []
  23. #for i in range(5):
  24. # t = threading.Thread(target=worker)
  25. # threads.append(t)
  26. # t.start()
  27.  
  28. #for i in threads():
  29. # print i
  30.  
  31.  
  32.  
  33. import json
  34. import urllib
  35. import shelve
  36. import smtplib
  37.  
  38. # private query nonce
  39. import time
  40. import pickle
  41. import hashlib
  42. import hmac
  43. import base64
  44. import connection
  45.  
  46.  
  47.  
  48.  
  49.  
  50. class API(object):
  51. """Kraken.com cryptocurrency Exchange API.
  52.  
  53. Public methods:
  54. load_key
  55. query_public
  56. query_private
  57.  
  58. """
  59. keypath = "key.txt"
  60. def __init__(self, key = '', secret = ''):
  61. """Create an object with authentication information.
  62.  
  63. Arguments:
  64. key -- key required to make queries to the API (default: '')
  65. secret -- private key used to sign API messages (default: '')
  66.  
  67. """
  68. self.key = key
  69. self.secret = secret
  70. self.uri = 'https://api.kraken.com'
  71. self.apiversion = '0'
  72. self.method = "Balance"
  73. def load_key(self, path):
  74. """Load key and secret from file.
  75.  
  76. Argument:
  77. path -- path to file (string, no default)
  78.  
  79. """
  80. f = open(path, "r")
  81. self.key = f.readline().strip()
  82. self.secret = f.readline().strip()
  83.  
  84.  
  85. def _query(self, urlpath, req = {}, conn = None, headers = {}):
  86. """Low-level query handling.
  87.  
  88. Arguments:
  89. urlpath -- API URL path sans host (string, no default)
  90. req -- additional API request parameters (default: {})
  91. conn -- kraken.Connection object (default: None)
  92. headers -- HTTPS headers (default: {})
  93.  
  94. """
  95. url = self.uri + urlpath
  96.  
  97. if conn is None:
  98. conn = connection.Connection()
  99.  
  100. ret = conn._request(url, req, headers)
  101. conn.close()
  102. return json.loads(ret)
  103.  
  104.  
  105. def query_public(self, method, req = {}, conn = None):
  106. """API queries that do not require a valid key/secret pair.
  107. "https://api.kraken.com/0/private/Balance"
  108. Arguments:
  109. method -- API method name (string, no default)
  110. req -- additional API request parameters (default: {})
  111. conn -- connection object to reuse (default: None)
  112.  
  113. """
  114. urlpath = '/' + self.apiversion + '/public/' + method
  115.  
  116. return self._query(urlpath, req, conn)
  117.  
  118.  
  119. def query_private(self, method, req={}, conn = None):
  120. """API queries that require a valid key/secret pair.
  121.  
  122. Arguments:
  123. method -- API method name (string, no default)
  124. req -- additional API request parameters (default: {})
  125. conn -- connection object to reuse (default: None)
  126.  
  127. """
  128. urlpath = '/' + self.apiversion + '/private/' + method
  129.  
  130. req['nonce'] = int(1000*time.time())
  131. postdata = urllib.urlencode(req)
  132. message = urlpath + hashlib.sha256(str(req['nonce']) +
  133. postdata).digest()
  134. signature = hmac.new(base64.b64decode(self.secret),
  135. message, hashlib.sha512)
  136. headers = {
  137. 'API-Key': self.key,
  138. 'API-Sign': base64.b64encode(signature.digest())
  139. }
  140.  
  141. return self._query(urlpath, req, conn, headers)
  142.  
  143. def close_connection(self,method = "",req={}, conn = "None"):
  144. conn.close()
  145.  
  146.  
  147. #List of keys. First pair then
  148. class shelfControl():
  149. database = None
  150. def __init__(self):
  151. self.database = shelve.open("Krakenex.db")
  152. def retreive(self, key):
  153. if self.database != None:
  154. return self.database[key]
  155.  
  156. def store(self,key, item):
  157. self.database[key] = item
  158.  
  159. def storeData(self, item):
  160. items = self.database["items"]
  161. temp = self.database[i]
  162. while i < items:
  163. self.database[i] = temp
  164. self.database[i] = self.database[i+1]
  165. temp = self.database[i+1]
  166. self.database[0] = item
  167.  
  168. #Update a List and combine.
  169. #http://stackoverflow.com/questions/30055830/pythonic-way-to-merge-two-overlapping-lists-preserving-order
  170. def update(self, key, newList):
  171. oldList = self.database[key]
  172. print oldList[0]
  173.  
  174.  
  175.  
  176. class trade():
  177. def __init__(self, pairIn = None, priceIn = None, volumeIn = None, buySellIn = None, timeIn = None, idIn = None):
  178. self.pair = pairIn
  179. self.price = priceIn
  180. self.volume = volumeIn
  181. self.buySell = buySellIn #None means NA -1 means sell, +1 means buy
  182. self.time = time
  183. self.id = idIn
  184. def __getstate__(self): return self.__dict__
  185. def __setstate__(self, d): self.__dict__.update(d)
  186.  
  187.  
  188. #This will create a trade from the Trades Public Query to KrakenEX
  189. def tradeFromTrades(pairIn, dictIn):
  190. if dictIn[3] == 's':
  191. dictIn[3] = -1
  192. elif dictIn[3] == 'b':
  193. dictIn[3] = 1
  194. newTrade = trade(pairIn, dictIn[0], dictIn[1], dictIn[3], dictIn[2],dictIn[2])
  195. return newTrade
  196.  
  197. def tradeFromOrders(pairIn, dictIn, buySell):
  198. return trade(pairIn, dictIn[0], dictIn[1], buySell, dictIn[2], dictIn[2])
  199.  
  200. class tradeList():
  201. description = None
  202. trades = []
  203. listType = 0
  204. def __getstate__(self): return self.__dict__
  205. def __setstate__(self, d): self.__dict__.update(d)
  206.  
  207. def __init__(self,pair,listTypeIn):
  208. self.description = pair
  209. self.listType = listTypeIn
  210. self.trades = []
  211. def addTrade(self,trade):
  212. self.trades.append(trade)
  213. return self.trades
  214.  
  215.  
  216. #unless I can figure out how to pickle objects I'll have to go with the middle of the road solution. The Middle of the road solution dicts.
  217. #So to get a price it would be dict[pair][age][list][trade][price] which is slow and long. Trade is also somewhat arbitrary.
  218. class DataStorage(object):
  219. data = {}
  220. shelf = None
  221. iterations = None
  222. def __init__(self):
  223. self.shelf = shelfControl()
  224. self.shelf.store("Iterations",1)
  225. self.iterations = self.shelf.retreive("Iterations")
  226. #data = self.update(400)
  227. def save():
  228. self.shelf.store(self.data)
  229. #redo
  230. def load(iteration):
  231. self.data = self.shelf.retreive("data")
  232. self.data[keyPair] = self.shelf.retreive(0)
  233. #Update all data one place.
  234. #For number of iterations saved update all of them
  235.  
  236. def update(self):
  237. #We need to decide how to do this. Simple way.
  238. print "Update"
  239.  
  240.  
  241. class getPair(object):
  242. api = API()
  243. pair = None
  244. data = {} #Might be wrong.
  245. shelf = None
  246. def __init__ (self,dataIn, pairIn = 'XXBTZCAD'):
  247. self.pair = pairIn
  248. self.data = dataIn
  249. self.assetinfo(self.pair, 60)
  250.  
  251.  
  252.  
  253. #These are supposed to provide object permenence but don't seem to
  254. def __getstate__(self): return self.__dict__
  255. def __setstate__(self, d): self.__dict__.update(d)
  256.  
  257. #Gets a Kraken Pair from the server and parses it into lists.
  258. def assetinfo(self,pair, count = 30):
  259.  
  260. #Orderbook
  261. requestOrderbook = {"pair": pair, "count" : count}
  262. ordersPending = self.api.query_public( "Depth", requestOrderbook)
  263. print "In AssetInfo"
  264. count = 0
  265. itemList = []
  266. print self.data[0]
  267. self.data[0][pair] = {}
  268. self.data[0][pair]['bids'] = {}
  269. for item in ordersPending["result"][pair]["bids"]:
  270. print item
  271. itemList.append(item[0])
  272. itemList.append(item[1])
  273. itemList.append(item[2])
  274. # FIX THIS! PAIR LIST ITERATION TRADENUMBER VALUES
  275.  
  276. self.data[0][pair]['bids'][count] = {}
  277. self.data[0][pair]['bids'][count] = itemList
  278. count += 1
  279. itemList = []
  280. self.data[0][pair]['asks'] = {}
  281. count = 0
  282. for item in ordersPending["result"][pair]["asks"]:
  283. print item
  284. itemList.append(item[0])
  285. itemList.append(item[1])
  286. itemList.append(item[2])
  287. # FIX THIS! PAIR LIST ITERATION TRADENUMBER VALUES
  288. self.data[0][pair]['asks'][count] = {}
  289. self.data[0][pair]['asks'][count] = itemList
  290. count += 1
  291. itemList = []
  292. #Past Trades
  293.  
  294. requestPastTrades = {"pair": pair}
  295. trades = self.api.query_public( "Trades", requestPastTrades)
  296. itemList = []
  297. countBuy = 0
  298. countSell = 0
  299. self.data[0][pair]['sold'] = {}
  300. self.data[0][pair]['bought'] = {}
  301. for item in trades["result"][pair]:
  302. if item[3] == 's':
  303. item[3] = -1
  304. elif item[3] == 'b':
  305. item[3] = 1
  306. # FIX THIS! PAIR LIST ITERATION TRADENUMBER VALUES
  307.  
  308. else:
  309. print "ErrorTrade"
  310. print item
  311. itemList.append(item[0])
  312. itemList.append(item[1])
  313. itemList.append(item[3])
  314. itemList.append(item[2])
  315. if item[3] == -1:
  316. self.data[0][pair]['sold'][countSell] = itemList
  317. countSell += 1
  318. elif item[3] == 1:
  319. self.data[0][pair]['bought'][countBuy] = itemList
  320. countBuy += 1
  321. else:
  322. print "Trade Error"
  323. itemList = []
  324. print "AssetInfo Finished"
  325. print len(self.data)
  326.  
  327.  
  328.  
  329. #TODO Curpair, Trade Lists, TradeList, Trade
  330.  
  331. class tradeLogic(object):
  332. shelf = None
  333. settings = {"patience" : .75, "patiencea" : .5, "patiencego" : 0, "spreadgo": .04}
  334. pairSettings = {}
  335. pairList = {}
  336. thisPair = None
  337. def __init__( self, dataIn,pairListIn = ['XXBTZCAD'] ):
  338. #Goes through list of pairs and creates CurPair items
  339. self.pairList = pairListIn
  340. self.data = dataIn
  341. for item in self.pairList:
  342. self.thisPair = item
  343. print item
  344. self.patience(self.settings,item)
  345. self.trendSpot(item)
  346. self.spread(self.settings, item)
  347. #Save relevant data
  348.  
  349. def pairList(listIn):
  350. self.pairList = listIn
  351. def trendSpot(self, pair):
  352. print "TrendSpot"
  353. #Checks for rapid update in Price via % or Low volume of orders before major price swing.
  354. #for item in self.data[0][pair].sellOrders.trades:
  355. #print item.price
  356. #print item.volume
  357.  
  358. #for item in self.data[0][pair].buyOrders.trades:
  359. # print item.price
  360. # print item.volume
  361. # print item
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369. #2nd guess. Got to get good at this!!!
  370. #for item in self.data[0][pair]['bids'][count]:
  371. # print item
  372.  
  373.  
  374.  
  375.  
  376.  
  377. #Checks if there is a big spread and sends: spread, pair, and volume at the spread
  378.  
  379. def spread(self,setting,pairs):
  380.  
  381. print "Spread"
  382. spreadInPlace = self.data[0][self.thisPair]['bids'][0][0]/self.data[0][self.thisPair]['asks'][0][0]
  383. volumeSpread = self.data[0][self.thisPair]['bids'][0][1] * self.data[0][self.thisPair]['asks'][0][1]
  384. spreadGoing = setting['spreadgo']
  385. if spreadInPlace >= spreadGoing:
  386. toSend = "Spread detected" , spreadInPlace, pairs, volumeSpread
  387. message(toSend)
  388.  
  389.  
  390. #2 up 1 down, then two down one up. Two sells one buy or two buys one sell all the time.
  391. def theThreeTrades():
  392. print "Three Trades"
  393.  
  394.  
  395. def patience(self, setting, pairs):
  396. aggression = setting["patience"]
  397. amount = setting["patiencea"]
  398. go = setting["patiencego"]
  399. #Make a list of trades starting from the daily high and low and extending 75% counting from the amount traded.
  400. #The idea for patience is to trade based on how much we're trading. So if we're trading blocks of .5 units then we trade that far into the buy or sell orders.
  401. #So go through trades starting at sold0 - soldX subtrade the volume of each from amount until it hits 0 then make the trade.
  402. x = 0
  403. while x < amount:
  404. print "Amount ", amount, "x = " , x
  405. amount += 1
  406. print amount
  407. x +=2
  408. if go:
  409. #DO TRADE
  410. print "In Go Not Trading yet"
  411. #Send Email
  412. print "No Email Either"
  413.  
  414.  
  415. def easyMoney(self, volume = 35, aggression = 100):
  416. #Get 5 bids and asks. Find lowest/highest price which has least volume between it and current price.
  417. y = {}
  418. dataStack = {}
  419. aggression2 = aggression * 2
  420. y['tradebid'] = 0
  421. y['tradeask'] = 0
  422. count = 0
  423. x = 0
  424. z = 0
  425. while x < volume:
  426. print count
  427. x += float(self.data[0][self.thisPair]['bids'][count][1])#Find a bid or ask add volume.
  428. print self.data[0][self.thisPair]['bids'][0][1]
  429. y['bid'] = self.data[0][self.thisPair]['bids'][count][0]#Price 1 for bid.
  430.  
  431. y['tradebid'] = (1 + y['tradebid'])
  432. y['diffbid'] = (y['bid'])# - firstbid)
  433.  
  434. if y['diffbid'] >= aggression2:
  435. #fire trade Size Aggression.
  436. print "We'd be trading"
  437. count += 1
  438. print "This is x", x
  439. print "Done finding trade before volume 1"
  440.  
  441. count = 0
  442. for z in 0, volume:
  443. z += float(self.data[0][self.thisPair]['asks'][count][1])#find opposite bid or ask.
  444. y['ask'] = float(self.data[0][self.thisPair]['asks'][count][0])#Price 2
  445. y['tradeask'] = (1 + y['tradeask'])
  446. y['diffask'] = (y['ask'])# + firstbidasks)
  447. # if y['diffask'] >= aggression2:
  448. # message("Trade Made")
  449.  
  450.  
  451. #make Trade (/s? Like multiple?)
  452. #Send Email
  453. print self.settings
  454.  
  455. return dataStack
  456.  
  457.  
  458. #Master Control, the central Object
  459. class MasterControl(object):
  460. #Currencies = XBT, ETH, DAO,ETC,ETH,LTC,XDG,XLM,XRP,CAD,EUR,JPY,GBP,USD
  461. pairList = [ 'XETHZCAD', 'XETHZEUR','XETHZJPY']#,'XLTCZEUR','XXBTZCAD']#'XDAOZEUR', 'XETCZEUR','XLTCZCAD','XXBTZEUR','XETHZEUR.d', 'XXBTZJPY', 'XXBTZGBP', 'XDAOXXBT', 'XETHZUSD','XLTCZUSD', 'XETCXXBT','XDAOXETH', 'XETHZGBP', 'XXBTZGBP', 'XLTCZEUR', 'XETCXETH', 'XETHZGBP', 'XLTCXXBT', 'XXLTCZJPY','XXBTZUSD', 'XETCZEUR', 'XXRPXXBT', 'XDAOZGBP','XETCZUSD', 'XDAOZUSD', 'XETHXXBT' ]
  462. ds = None
  463. data = {}
  464. data[0] = {}
  465. aPair = None
  466. def __init__(self):
  467. myapi = API()
  468. self.ds = DataStorage()
  469.  
  470. #GetStorage working. Don't worry about speed.
  471. for items in self.pairList:
  472. print "This is the curPair we're working on"
  473. print items
  474.  
  475. #This updates the data.
  476. self.data = getPair(self.data, items)
  477.  
  478.  
  479. #Logic - Load old data. Update Data in datastorage. Get new data put into dataStorage. Do calculations on data.
  480. print "Should be data Here"
  481.  
  482.  
  483. tl = tradeLogic(self.data, self.pairList)
  484. tl.easyMoney(70, 130)#Volume and aggression
  485.  
  486.  
  487. myapi = API()
  488. myapi.load_key(myapi.keypath)
  489.  
  490. #print "Private Balance"
  491. #balance = myapi.query_private("Balance")
  492. #print balance
  493.  
  494. #print "Private OpenOrders"
  495. #openorders = myapi.query_private("OpenOrders")
  496. #print openorders
  497.  
  498. #print "Private ClosedOrders"
  499. #closedorders = myapi.query_private("ClosedOrders")
  500. #print closedorders
  501.  
  502. print "Private QueryOrders"
  503. #queryorders = myapi.query_private("QueryOrders", {'trades':"True"})
  504. #print queryorders
  505.  
  506. print "Private TradeHistory"
  507. #tradeshistory = myapi.query_private("TradesHistory")
  508. #print tradeshistory
  509.  
  510. print "Private QueryTrades"
  511. #querytrades = myapi.query_private("QueryTrades")
  512. #print querytrades
  513.  
  514. print "Private OpenPositions"
  515. openpositions = myapi.query_private("OpenPositions")
  516. print openpositions
  517.  
  518. print "Private Ledgers"
  519. #ledgers = myapi.query_private("Ledgers")
  520. #print ledgers
  521.  
  522. print "Query Ledgers"
  523. #queryledgers = myapi.query_private("QueryLedgers")
  524. #print queryledgers
  525.  
  526. #tradevolume = myapi.query_private("TradeVolume")
  527. #print "TradeVolume "
  528. #print tradevolume
  529. #addorderQuery = {"pair": "XXBTZCAD", "type":"buy", "ordertype": "limit", "price": "1.0", "volume" : "0.1"}
  530. #addorder = myapi.query_private("AddOrder", addorderQuery)
  531. #print "ORDER ADDED"
  532. #print addorder
  533. #assetpairs = myapi.query_public("AssetPairs")
  534.  
  535.  
  536. #existing.append(getPair("XXBTZCAD"))
  537. #existingTL = tradeLogic()
  538. #TODO check for price changes and update lists, send email.
  539.  
  540. #LOAD, UPDATE, GET
  541. global mc
  542. mc = MasterControl()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement