Esempio n. 1
0
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)
Esempio n. 2
0
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)