class AsyncTradingManager(AsyncTaskManager): def __init__(self, dbReference, connection, authData, logger): super().__init__(dbReference, connection, logger) self.positionCache = {} from .Constants import NOT_SET self.symbol, self.quantity, self.riskParams = (NOT_SET, ) * 3 from gdax import AuthenticatedClient self.gdaxAuthClient = AuthenticatedClient(*authData) def getCacheSize(self): return len(list(self.positionCache.keys())) def validPosLimitCheck(self): return bool(self.positionCache.size() <= self.riskParams['posLimit']) async def createOrders(self, stratVerdict): #read entryOrder, validEntryVerdict = 0, (stratVerdict == 1) if (validEntryVerdict and self.validPosLimitCheck()): from .Order import Order entryOrder = Order('ENTRY', 'B', self.symbol, self.quantity) orderLog = "Created Order for: " + str( self.symbol) + " at size: " + str(self.quantity) self.logger.addEvent('trading', orderLog) await asyncio.sleep(0) return entryOrder async def verifyAndEnterPosition(self, entryOrder, currentCapital, spotPrice): #read newPosition, validEntryConditions = None, (entryOrder is not None and currentCapital > 0) if validEntryConditions: fundToleranceAvailible = currentCapital * self.riskParams[ 'tolerance'] > self.quantity if (fundToleranceAvailible and self.validPosLimitCheck()): response = dict( self.gdaxAuthClient.buy(product_id=self.symbol, type='market', funds=self.quantity)) orderID = response['id'] time.sleep(1) orderStatus = dict(self.gdaxAuthClient.get_order(orderID)) if (orderStatus['status'] != 'done'): timedOut = 'TIMED_OUT' self.gdaxAuthClient.cancel_order(orderID) entryOrder.setErrorCode(timedOut) orderTimeOut = 'Order: ' + str(orderID) + ' ' + timedOut self.logger.addEvent('trading', orderTimeOut) else: noErrors = 'NO_ERRORS' entryOrder.setOrderID(orderID) entryOrder.setErrorCode(noErrors) orderFillTime = orderStatus['done_at'] entryValue = float(response['executed_value']) orderData = (entryOrder.direction, self.symbol, self.quantity, entryValue, orderFillTime) ### CREATE POSITION OBJECT FROM ORDERDATA AND ADD TO POSTION CACHE from .Position import Position newPosition = Position(orderID, *orderData) self.positionCache.update({orderID: newPosition}) positionEntered = noErrors + ', Entered Position: ' + str( orderID) self.logger.addEvent('trading', positionEntered) else: noFunds = "CAPITAL_TOLERANCE_EXCEEDED" entryOrder.setErrorCode(noFunds) self.logger.addEvent('trading', noFunds) await asyncio.sleep(0) return ([entryOrder], newPosition) async def exitValidPositions(self, stratVerdict): #read validExitConditions = stratVerdict == -1 and self.getCacheSize() > 0 completedPositions, exitOrders = [None], [None] if validExitConditions: self.logger.addEvent('strategy', 'POSITION EXIT CONDITIONS VALID') sellResponses, completedPositions, exitOrders, response = [], [], [], None self.gdaxAuthClient.cancel_all(product=self.symbol) from .Position import Position from .Order import Order for p in self.positionCache.values(): from .Constants import GDAX_FUNDS_ERROR while (response == GDAX_FUNDS_ERROR or response == None): response = dict( self.gdaxAuthClient.sell(product_id=self.symbol, type='market', funds=self.quantity)) if (response == GDAX_FUNDS_ERROR): self.logger.addEvent( 'trading', 'INVALID_SELL_RESPONSE: GDAX_FUNDS_ERROR') pArgs = (p['entID'], p['direction'], p['ticker'], p['quantity'], p['entryPrice'], p['entryTime']) completedPosition = Position(*pArgs) completedPosition.setExitID(response['id']) completedPositions.append(completedPosition) sellResponses.append(response) exitOrder = Order('EXIT', 'S', self.symbol, self.quantity) exitOrder.setErrorCode("NO_ERRORS") exitOrder.setOrderID(response['id']) exitOrders.append(exitOrder) response = None for posit, response in zip(completedPositions, sellResponses): exitedPos = "Exited Position:" + posit.exID self.logger.addEvent('trading', exitedPos) try: orderStatus = dict( self.gdaxAuthClient.get_order(posit.exID)) orderExitTime = orderStatus['done_at'] posit.setExitParams(float(response['executed_value']), orderExitTime) except BaseException as e: self.logger.addEvent( 'trading', ('GDAX_AUTHCLIENT_GETORDER_ERROR: ' + str(e))) self.positionCache.clear() await asyncio.sleep(0) return (exitOrders, completedPositions)
class AsyncTradingManager(AsyncTaskManager): def __init__(self, dbReference, connection, authData, logger): super().__init__(dbReference, connection, logger) from gdax import AuthenticatedClient self.pCacheRef = self.dbReference.table('PositionCache') self.RiskStatsRef = self.dbReference.table('RiskStats') self.CapitalStatsRef = self.dbReference.table('CapitalStats') self.gdaxAuthClient = AuthenticatedClient(*authData) from .Constants import NOT_SET self.symbol, self.quantity, self.tolerance, self.poslimit = ( NOT_SET, ) * 4 from .Utilities import getObjectDict self.getObjectDict = getObjectDict def validPosLimitCheck(self): return bool( (len(self.pullTableContents(self.pCacheRef)) + 1) <= self.poslimit) async def createOrders(self, stratVerdict): #read entryOrder = None validEntryVerdict = stratVerdict == 1 if (validEntryVerdict and self.validPosLimitCheck()): from .Order import Order entryOrder = Order('ENT', 'B', self.symbol, self.quantity) orderLog = "Created Order for: " + str( self.symbol) + " at size: " + str(self.quantity) self.logger.addEvent('trading', orderLog) await asyncio.sleep(0) return entryOrder async def verifyAndEnterPosition(self, entryOrder, capitalStats, spotPrice): #read newPosition, currentCapital = None, capitalStats['capital'] validEntryConditions = entryOrder is not None and currentCapital > 0 if (validEntryConditions and self.validPosLimitCheck()): fundToleranceAvailible = currentCapital * self.tolerance > self.quantity #check db for viable kelly criterion values, max draw, etc. (not done) if (fundToleranceAvailible): response = dict( self.gdaxAuthClient.buy(product_id=self.symbol, type='market', funds=self.quantity)) orderID = response['id'] time.sleep(1) orderStatus = dict(self.gdaxAuthClient.get_order(orderID)) if (orderStatus['status'] != 'done'): timedOut = 'TIMED_OUT' self.gdaxAuthClient.cancel_order(orderID) entryOrder.setErrorCode(timedOut) orderTimeOut = 'Order: ' + str(orderID) + ' ' + timedOut self.logger.addEvent('trading', orderTimeOut) else: noErrors = 'NO_ERRORS' entryOrder.setOrderID(orderID) entryOrder.setErrorCode(noErrors) orderFillTime = orderStatus['done_at'] entryValue = float(response['executed_value']) orderData = (entryOrder.direction, self.symbol, self.quantity, entryValue, orderFillTime) from .Position import Position newPosition = Position(orderID, *orderData) positionEntered = noErrors + ', Entered Position: ' + str( orderID) self.logger.addEvent('trading', positionEntered) else: noFunds = "CAPITAL_TOLERANCE_EXCEEDED" entryOrder.setErrorCode(noFunds) self.logger.addEvent('trading', noFunds) await asyncio.sleep(0) return ([entryOrder], newPosition) async def exitValidPositions(self, stratVerdict): #read positionCache = self.pullTableContents(self.pCacheRef) validExitConditions = stratVerdict == -1 and positionCache != [] completedPositions, exitOrders = [None], [None] if (validExitConditions): sellResponses, completedPositions, exitOrders, response = [], [], [], None self.gdaxAuthClient.cancel_all(product=self.symbol) from .Position import Position from .Order import Order for p in positionCache: from .Constants import GDAX_FUNDS_ERROR while (response == GDAX_FUNDS_ERROR or response == None): response = dict( self.gdaxAuthClient.sell(product_id=self.symbol, type='market', funds=self.quantity)) if (response == GDAX_FUNDS_ERROR): self.logger.addEvent( 'trading', 'INVALID_SELL_RESPONSE: GDAX_FUNDS_ERROR') pArgs = (p['entID'], p['direction'], p['ticker'], p['quantity'], p['entryPrice'], p['entryTime']) completedPosition = Position(*pArgs) completedPosition.setExitID(response['id']) completedPositions.append(completedPosition) sellResponses.append(response) exitOrder = Order('EX', 'S', self.symbol, self.quantity) exitOrder.setErrorCode("NO_ERRORS") exitOrder.setOrderID(response['id']) exitOrders.append(exitOrder) response = None time.sleep(1) for posit, response in zip(completedPositions, sellResponses): exitedPos = "Exited Position:" + posit.exID self.logger.addEvent('trading', exitedPos) try: orderStatus = dict( self.gdaxAuthClient.get_order(posit.exID)) orderExitTime = orderStatus['done_at'] posit.setExitParams(float(response['executed_value']), orderExitTime) except BaseException as e: self.logger.addEvent( 'trading', ('GDAX_AUTHCLIENT_GETORDER_ERROR: ' + str(e))) self.pCacheRef.delete().run(self.connection) await asyncio.sleep(0) return (exitOrders, completedPositions) async def addToPositionCache(self, position): #write if (position is not None): pDict = self.getObjectDict(position) self.pCacheRef.insert(pDict).run(self.connection) await asyncio.sleep(0)