Ejemplo n.º 1
0
 def __init__(self, stratName, isLive=False):
     logging.debug("Initialising ExitTrade()")
     self.isLive = isLive
     self.stratName = stratName
     db = MongoClient("localhost", 27017)[stratName]
     self.transCol = db["transactionLogs"]
     self.currentCol = db["currentPositions"]
     self.pull = Pull()
     self.capDict = None
Ejemplo n.º 2
0
 def __init__(self, stratName, isTest):
     logging.debug("Initilising ERC20TickFade")
     with open("%s/Pipeline/resources/%s/config.yml" %
               (Settings.BASE_PATH, stratName)) as configFile:
         self.enterParams = yaml.load(configFile)["enter"]
     self.coinDict = self.enterParams["assetList"]
     self.isTest = isTest
     self.p = Pull()
     self.coolDown = True
     self.oldData = {"erc": pd.DataFrame([]), "non": pd.DataFrame([])}
Ejemplo n.º 3
0
 def __init__(self, stratName, isLive=False):
     self.stratName = stratName
     logging.debug("Initialising OpenTrade()")
     self.isLive = isLive
     self.resourcePath = "%s/Pipeline/resources/%s" % (Settings.BASE_PATH,
                                                       stratName)
     self.db = MongoClient("localhost", 27017)[stratName]
     self.EU = ExchangeUtil()
     self.P = Position(stratName)
     self.pull = Pull()
     self.capDict = None
Ejemplo n.º 4
0
def test_candles():
    BinanceData = Binance().getCandles(asset="LTCBTC",
                                       limit=5,
                                       interval=300,
                                       columns=["TS", "open"],
                                       lastReal=True)
    PullData = Pull().candles(
        exchange="Binance",
        asset="LTCBTC",
        limit=5,
        interval=300,
        columns=["TS", "open"],
        lastReal=True,
    )
    assert PullData.equals(BinanceData) and len(PullData) != 0
Ejemplo n.º 5
0
 def _initSingle(self, asset, exchange, testData=[]):
     logging.debug("Starting CheapVol._initSingle(asset=%s)" % asset)
     logging.debug("1 second sleep to avoid rate limiters")
     time.sleep(1.5 if not self.isTest else 0)
     try:
         pullData = (Pull(
             emailOnFailure=False if self.isTest else True).candles(
                 asset="%sBTC" % asset,
                 exchange=exchange,
                 limit=max(
                     self.enterParams["periodsMA"],
                     self.enterParams["periodsVolLong"],
                 ) + 1,
                 interval=self.enterParams["granularity"],
             ) if len(testData) == 0 else testData)
         priceList = list(
             pullData["close"])[-self.enterParams["periodsMA"]:]
         volList = list(
             pullData["volume"])[-self.enterParams["periodsVolLong"]:]
         if (len(priceList) == self.enterParams["periodsMA"]
                 and len(volList) == self.enterParams["periodsVolLong"]):
             self.col.insert_one({
                 "asset": asset,
                 "price": priceList,
                 "vol": volList,
                 "isLive": False,
             })
             return True
         else:
             logging.info("Not enough data for asset: %s" % asset)
     except IndexError:
         logging.warning("Failure on asset: %s" % asset)
     return False
Ejemplo n.º 6
0
 def before(self, testData=None):
     """
         Runs before CheapVol on each asset and updates the mongo collection
     """
     logging.debug("Starting CheapVol.before()")
     newPA = {}
     delistDict = {}
     # using reversed to keep exchange priority
     for exchange in reversed(self.exchangeList):
         newPA.update(
             self._getPADict(
                 exchange=exchange) if not self.isTest else testData)
         delistDict.update(Pull().getDepositStatus(
             exchange=exchange)) if not self.isTest else {}
     for assetDict in list(self.col.find()):
         assetDict["price"] = assetDict["price"][1:] + [
             newPA[assetDict["asset"]]["price"]
         ]
         assetDict["vol"] = assetDict["vol"][1:] + [
             newPA[assetDict["asset"]]["vol"]
         ]
         assetDict["isLive"] = (delistDict[assetDict["asset"]]
                                if not self.isTest else True)
         assetDict.pop("_id", None)
         self.col.find_one_and_replace({"asset": assetDict["asset"]},
                                       assetDict)
     logging.debug("Finished CheapVol.before()")
Ejemplo n.º 7
0
def before():
    CCD.create()
    col.insert_one(posDataMain)
    params = {
        "isLive": False,
        "exit": {
            "bolStd": 2,
            "granularity": 7200,
            "name": "ProfitRun",
            "maPeriods": 5,
            "closePeriods": 5,
            "stdDict": {
                "up": 1,
                "down": 0.5
            },
            "exchange": "Binance",
        },
    }
    with open("%s/%s/config.yml" % (Settings.BASE_PATH, resPath),
              "w") as configFile:
        yaml.dump(params, configFile)
    PR = ProfitRun(stratName="testExit", isTest=True)
    E = Exit(stratName="testExit", isTest=True)
    P = Pull()
    return PR, E, P
Ejemplo n.º 8
0
 def getTradesDiff(self, asset, exchange):
     logging.debug("Starting OrderBookDepth.getTradesDiff")
     vals = Pull().getTrades(
         asset=asset,
         exchange=exchange,
         limit=self.enterParams["numTrades"],
         maxTime=self.enterParams["period"],
     )
     if len(vals) != 0:
         vL = len(vals)
         meanVal = round(float(np.mean(vals["Qty"])))
         diff = round(
             sum(vals[vals["Buy/Sell"] == "b"]["Qty"])
             - sum(vals[vals["Buy/Sell"] == "s"]["Qty"])
         )
         return (
             [
                 diff - (vL / diffVal) * meanVal
                 for diffVal in self.enterParams["diffVals"]
             ]
             + [diff]
             + [
                 diff + (vL / diffVal) * meanVal
                 for diffVal in self.enterParams["diffVals"]
             ]
         )
     else:
         return -1
Ejemplo n.º 9
0
 def _getPADict(self, exchange):
     logging.debug("Starting CheapVol._getPADict()")
     startTS = int(time.time() - self.enterParams["granularity"])
     dateStart = datetime.fromtimestamp(startTS).strftime(
         "%Y-%m-%dT%H:%M:%S.000Z")
     return Pull().getPriceAction(exchange=exchange,
                                  startDate=dateStart,
                                  baseAsset="BTC")
Ejemplo n.º 10
0
 def __init__(self, stratName, isTest=False, testAssets=None):
     logging.debug("Initialising Enter()")
     self.compPath = "%s/Pipeline/resources/%s" % (Settings.BASE_PATH, stratName)
     self.stratName = stratName
     self.isTest = isTest
     with open("%s/config.yml" % self.compPath) as stratFile:
         self.config = yaml.load(stratFile)
     self.assetList = Select(stratName).assets() if not isTest else testAssets
     self.enterStrat = eval(self.config["enter"]["name"])(
         stratName=stratName, assetList=self.assetList, isTest=isTest
     )
     self.OT = (
         OpenTrade(stratName=stratName, isLive=self.config["isLive"])
         if not isTest
         else None
     )
     self.pull = Pull()
     self.col = MongoClient("localhost", 27017)[stratName]["currentPositions"]
Ejemplo n.º 11
0
 def getAssets(self):
     logging.debug("Starting AllNomics.getAssets")
     logging.debug("Exchanges analysed: %s" % self.exchangeList)
     logging.debug("Base Asset: %s" % self.baseAsset)
     assetList = []
     for exchange in self.exchangeList:
         logging.debug("Starting exchange: %s" % exchange)
         if self.baseAsset == "BTC":
             tmpListNomics = Pull().BTCAssets(exchange="Nomics",
                                              exchange_=exchange)
             tmpListEx = Pull().BTCAssets(exchange=exchange, justQuote=True)
             tmpList = list(set(tmpListNomics) & set(tmpListEx))
             addedAssets = ([
                 val.lower() for val in np.array(assetList)[:, 0]
             ] if len(assetList) != 0 else [])
             assetList += [(asset, exchange) for asset in tmpList
                           if asset.lower() not in addedAssets]
     logging.debug("Ending All.getAssets")
     logging.debug("Assetlist length: %s" % len(assetList))
     return assetList
Ejemplo n.º 12
0
class AccountUtil:
    def __init__(self, exchange, isTest=False):
        logging.debug("Initialising AccountUtil()")
        self.exchange = exchange
        self.isTest = isTest
        self.P = Pull()

    def _calcValue(self, accountDetails):
        logging.debug("Starting AccountUtil._calcValue")
        value = 0
        for coin in [c for c in list(accountDetails) if c != "BTC"]:
            value += accountDetails[coin] * (
                self.P.assetPrice(
                    exchange=self.exchange, asset="%sBTC" % coin, dir="sell"
                )
                if not self.isTest
                else self.isTest[coin]
            )
        return value

    def getValue(self, initCapital, isTest=False):
        logging.debug("Starting AccountValue.getValue")
        capDict = {"initialCapital": initCapital}
        accountDetails = (
            self.P.getAccount(exchange=self.exchange) if not isTest else isTest
        )
        capDict["liquidCurrent"] = round(accountDetails["BTC"], 8)
        capDict["paperCurrent"] = round(
            capDict["liquidCurrent"] + self._calcValue(accountDetails), 8
        )
        capDict["paperPnL"] = round(
            capDict["paperCurrent"] / capDict["initialCapital"], 2
        )
        capDict["percentAllocated"] = round(
            (capDict["paperCurrent"] - capDict["liquidCurrent"])
            / capDict["paperCurrent"],
            2,
        )
        return capDict
Ejemplo n.º 13
0
 def __init__(self, stratName, isTest=False):
     logging.debug("Initializing Exit()")
     with open("%s/Pipeline/resources/%s/config.yml" %
               (Settings.BASE_PATH, stratName)) as stratFile:
         self.config = yaml.load(stratFile)
     self.stratName = stratName
     self.exitStrat = (eval(self.config["exit"]["name"])(
         stratName=stratName, isTest=isTest)
                       if "statArb" not in self.config.keys() else None)
     self.col = MongoClient("localhost",
                            27017)[stratName]["currentPositions"]
     self.pull = Pull()
     self.updatePosition = UpdatePosition(stratName)
     self.exitTrade = ExitTrade(stratName, isLive=self.config["isLive"])
Ejemplo n.º 14
0
 def _isVol(self):
     """
         True if vol_1d/vol_1m < maxVolCoef
     """
     data = Pull().candles(
         exchange="Nomics",
         asset="BTC",
         interval="1h",
         columns=None,
         lastReal=None,
         limit=None,
     )
     vol = np.nanmean(data["volume"].iloc[-24:].astype(float)) / np.nanmean(
         data["volume"].astype(float))
     logging.debug("Vol: %s" % vol)
     return vol < self.enterParams["maxVolCoef"]
Ejemplo n.º 15
0
 def createAssetList(self):
     tickerData = {
         val["symbol"]: {
             "vol": float(val["quoteVolume"]),
             "tradeCount": val["count"],
             "baseVol": float(val["volume"]),
         }
         for val in Pull().getTickerStats(exchange="Binance")
         if "BTC" in val["symbol"]
     }
     coinList = []
     base = tickerData["BTCUSDT"]["baseVol"]
     for coin in [c for c in list(tickerData) if c != "BTCUSDT"]:
         if (tickerData[coin]["tradeCount"] > self.params["minTrades"]
                 and self.params["minVol"] * base < tickerData[coin]["vol"]
                 < self.params["maxVol"] * base):
             coinList.append({"asset": coin, "exchange": "Binance"})
     self.assetCol.insert_many(coinList)
Ejemplo n.º 16
0
 def run(self, asset, exchange, testData=None):
     logging.debug("Starting OrderBookDepth.run")
     tradeDiff = self.getTradesDiff(asset=asset, exchange=exchange)
     priceList = []
     if tradeDiff != -1:
         orderBook = Pull().getOrderBook(
             exchange=exchange, asset=asset, limit=self.enterParams["bookDepth"]
         )
         for tradeQty in tradeDiff:
             priceList.append(self.walkDown(orderBook, tradeQty))
         price_ = round(float(np.mean(priceList)), 8)
         pDiff = round(price_ / orderBook["bids"][0][1], 8)
         if pDiff > 1:
             logging.debug("Asset: %s, pDiff: %s" % (asset, pDiff))
         if pDiff > self.enterParams["enterPercent"]:
             return True
         else:
             return False
     else:
         logging.debug("Data is incomplete")
         return False
Ejemplo n.º 17
0
 def getAssets(self):
     logging.debug("Starting All.getAssets")
     logging.debug("Exchanges analysed: %s" % self.exchangeList)
     logging.debug("Base Asset: %s" % self.baseAsset)
     assetList = []
     for exchange in self.exchangeList:
         logging.debug("Starting exchange: %s" % exchange)
         if self.baseAsset == "BTC":
             tmpList = Pull().BTCAssets(exchange=exchange)
             addedAssets = (
                 [val.lower() for val in np.array(assetList)[:, 0]]
                 if len(assetList) != 0
                 else []
             )
             assetList += [
                 (asset, exchange)
                 for asset in tmpList
                 if asset.lower() not in addedAssets
             ]
     logging.debug("Ending All.getAssets")
     return assetList
Ejemplo n.º 18
0
class ERC20TickFade:
    """
        Buy ETHUSD, Sell BTCUSD when erc20tick > enterVal

        Config Requirements:
            - enterVal
            - assetList = {
                'erc20': [],
                'non': []
            }
            - maxVolCoef
    """
    def __init__(self, stratName, isTest):
        logging.debug("Initilising ERC20TickFade")
        with open("%s/Pipeline/resources/%s/config.yml" %
                  (Settings.BASE_PATH, stratName)) as configFile:
            self.enterParams = yaml.load(configFile)["enter"]
        self.coinDict = self.enterParams["assetList"]
        self.isTest = isTest
        self.p = Pull()
        self.coolDown = True
        self.oldData = {"erc": pd.DataFrame([]), "non": pd.DataFrame([])}

    def _getTick(self, type):
        logging.debug("Starting ERC20TickArb._getTick()")
        newPrices = self.p.getPriceList(coinList=self.coinDict[type])
        logging.debug("Pulled new prices for type: %s" % type)
        if len(self.oldData[type]) != 0:
            logging.debug("Calculating tick value")
            tick = sum([
                1 if val > 0 else -1 if val < 0 else 0
                for val in list(newPrices["price"] -
                                self.oldData[type]["price"])
            ])
            logging.debug("Ending ERC20TickArb._getTick()")
            logging.debug("Tick Val: %s" % tick)
            return tick
        else:
            logging.debug("Creating old data")
            self.oldData[type] = newPrices
            logging.debug("Ending ERC20TickArb._getTick()")
            return 0

    def _isVol(self):
        """
            True if vol_1d/vol_1m < maxVolCoef
        """
        data = Pull().candles(
            exchange="Nomics",
            asset="BTC",
            interval="1h",
            columns=None,
            lastReal=None,
            limit=None,
        )
        vol = np.nanmean(data["volume"].iloc[-24:].astype(float)) / np.nanmean(
            data["volume"].astype(float))
        logging.debug("Vol: %s" % vol)
        return vol < self.enterParams["maxVolCoef"]

    def run(self):
        logging.debug("Starting ERC20TickFade.run()")
        logging.debug("IsCoolDown: %s" % self.coolDown)
        if self._isVol() and not self.coolDown:
            tickSum = self._getTick(type="erc") - self._getTick(type="non")
            if tickSum > self.enterParams["enterVal"]:
                self.coolDown = True
                return 1
            elif tickSum < -self.enterParams["enterVal"]:
                self.coolDown = True
                return -1
            else:
                return 0
        else:
            logging.debug("Creating oldData")
            self.coolDown = False
            _ = self._getTick(type="erc")
            _ = self._getTick(type="non")
Ejemplo n.º 19
0
 def __init__(self, exchange, isTest=False):
     logging.debug("Initialising AccountUtil()")
     self.exchange = exchange
     self.isTest = isTest
     self.P = Pull()
Ejemplo n.º 20
0
class Enter:
    def __init__(self, stratName, isTest=False, testAssets=None):
        logging.debug("Initialising Enter()")
        self.compPath = "%s/Pipeline/resources/%s" % (Settings.BASE_PATH, stratName)
        self.stratName = stratName
        self.isTest = isTest
        with open("%s/config.yml" % self.compPath) as stratFile:
            self.config = yaml.load(stratFile)
        self.assetList = Select(stratName).assets() if not isTest else testAssets
        self.enterStrat = eval(self.config["enter"]["name"])(
            stratName=stratName, assetList=self.assetList, isTest=isTest
        )
        self.OT = (
            OpenTrade(stratName=stratName, isLive=self.config["isLive"])
            if not isTest
            else None
        )
        self.pull = Pull()
        self.col = MongoClient("localhost", 27017)[stratName]["currentPositions"]

    def run(self):
        try:
            logging.info("Starting Enter.run: %s" % datetime.now())
            startTime = time.time()
            openList = []
            currentPositions = [
                val["assetName"] for val in list(self.col.find({}, {"assetName": 1}))
            ]
            self.OT.initRun() if not self.isTest else None
            self.enterStrat.before() if not self.isTest else None
            for asset, exchange in [
                val
                for val in self.assetList
                if "%sBTC" % val[0] not in currentPositions
            ]:
                logging.debug("Starting asset: %s" % asset)
                if self.enterStrat.run(asset):
                    logging.info("Entering trade: %s" % asset)
                    openPrice = (
                        self.pull.assetPrice(
                            exchange=exchange, asset="%sBTC" % asset, dir="buy"
                        )
                        if not self.isTest
                        else 1
                    )
                    if openPrice != -1:
                        openList.append(asset)
                        self.OT.open(
                            assetVals=("%sBTC" % asset, exchange, openPrice)
                        ) if not self.isTest else None
            self.OT.updateBooks() if not self.isTest else None
            logging.info(
                "Ending Enter run. Took: %s seconds" % round(time.time() - startTime)
            )
            logging.info("%s assets analysed" % len(self.assetList))
            logging.info(
                "Entering trades: \n %s" % openList
                if len(openList) != 0
                else "0 trades entered"
            )
            return openList if self.isTest else None
        except Exception as e:
            EmailUtil(strat=self.stratName).errorExit(
                file=self.stratName,
                funct="Enter.run()",
                message=f"Error message: {e}, \n Asset: {asset}",
            )
            raise Exception
Ejemplo n.º 21
0
def before():
    P = Pull()
    CCD.create()
    posDataInit = {
        "assetName": "ADABTC",
        "openPrice": 0.0000158,
        "currentPrice": 9,
        "periods": 0,
        "positionSize": 0.4995,
        "paperSize": 0.4995,
        "TSOpen": 1534711395,
        "exchange": "Binance",
    }
    posDataMain = {
        "assetName": "ETHBTC",
        "openPrice": 0.0000158,
        "currentPrice": 10,
        "periods": 0,
        "hitPrice": 11,
        "positionSize": 0.4995,
        "paperSize": 0.4995,
        "TSOpen": 1534711395,
        "sellPrice": 9,
        "exchange": "Binance",
    }
    posDataPeriods = {
        "assetName": "LTCBTC",
        "openPrice": 0.0000158,
        "currentPrice": 0.0000158,
        "periods": 6,
        "sellPrice": 9,
        "positionSize": 0.4995,
        "paperSize": 0.4995,
        "TSOpen": 1534711395,
        "hitPrice": 11,
        "exchange": "Binance",
    }
    updatePosData = pd.DataFrame(data=[[10], [9], [8], [11], [7]],
                                 columns=["close"])
    col.insert_many([posDataMain, posDataInit, posDataPeriods])
    params = {
        "exit": {
            "bolStd": 2,
            "granularity": 7200,
            "name": "ProfitRun",
            "maPeriods": 5,
            "closePeriods": 5,
            "stdDict": {
                "up": 1,
                "down": 0.5
            },
        }
    }
    with open("%s/%s/config.yml" % (Settings.BASE_PATH, resPath),
              "w") as configFile:
        yaml.dump(params, configFile)
    PR = ProfitRun("testProfitRun", isTest=True)
    return (
        PR,
        P,
        {
            "main": posDataMain,
            "init": posDataInit,
            "periods": posDataPeriods
        },
        updatePosData,
    )
Ejemplo n.º 22
0
class OpenTrade:
    def __init__(self, stratName, isLive=False):
        self.stratName = stratName
        logging.debug("Initialising OpenTrade()")
        self.isLive = isLive
        self.resourcePath = "%s/Pipeline/resources/%s" % (Settings.BASE_PATH,
                                                          stratName)
        self.db = MongoClient("localhost", 27017)[stratName]
        self.EU = ExchangeUtil()
        self.P = Position(stratName)
        self.pull = Pull()
        self.capDict = None

    def initRun(self):
        with open("%s/capital.yml" % self.resourcePath) as capFile:
            self.capDict = yaml.load(capFile)

    def _getPrice(self, fills):
        return round(
            sum([float(val["price"]) * float(val["qty"])
                 for val in fills]) / sum([float(val["qty"])
                                           for val in fills]),
            8,
        )

    def open(self, assetVals):
        logging.debug("Starting OpenTrade.open")
        # assetVals = (name, exchange, price)
        capAllocated = self.P.getSize(asset=assetVals[0])
        posSize = capAllocated * (1 - self.EU.fees(exchange=assetVals[1]))
        if not self.isLive:
            openDict = {
                "assetName": assetVals[0],
                "openPrice": assetVals[2],
                "currentPrice": assetVals[2],
                "periods": 0,
                "positionSize": posSize,
                "paperSize": posSize,
                "TSOpen": round(time.time()),
                "exchange": assetVals[1],
            }
        else:
            try:
                quantity = round(capAllocated / assetVals[2], 2)
                orderDict = self.pull.makeTrade(
                    exchange=assetVals[1],
                    asset=assetVals[0],
                    quantity=np.floor(quantity),
                    dir="BUY",
                )
                buyPrice = self._getPrice(orderDict["fills"])
                openDict = {
                    "assetName": assetVals[0],
                    "openPrice": buyPrice,
                    "currentPrice": buyPrice,
                    "periods": 0,
                    "positionSize": float(orderDict["cummulativeQuoteQty"]),
                    "posSizeBase": float(orderDict["executedQty"]),
                    "TSOpen": round(time.time()),
                    "exchange": assetVals[1],
                    "clientOrderId": orderDict["clientOrderId"],
                }
            except KeyError as e:
                EmailUtil(strat=self.stratName).errorExit(
                    file=self.stratName, funct="Enter.runNorm()", message=e)
                logging.error("orderDict: %s" % orderDict)
                raise Exception(
                    "Failed with error message: %s and assetVals: %s" %
                    (e, assetVals))
        self.db["currentPositions"].insert_one(openDict)
        self.capDict["paperCurrent"] -= round(
            capAllocated - openDict["positionSize"], 6)
        self.capDict["liquidCurrent"] -= capAllocated

    def updateBooks(self):
        logging.debug("Starting OpenTrade.updateBooks()")
        if not self.isLive:
            self.capDict["percentAllocated"] = round(
                1 -
                self.capDict["liquidCurrent"] / self.capDict["paperCurrent"],
                3)
            self.capDict["paperPnL"] = round(
                self.capDict["paperCurrent"] / self.capDict["initialCapital"],
                3)
        else:
            # **TODO hard coding 'Binance' as whole capDict system will need to change to capListDict when adding multiple
            self.capDict = AccountUtil(exchange="Binance").getValue(
                initCapital=self.capDict["initialCapital"])
        with open("%s/capital.yml" % self.resourcePath, "w") as capFile:
            yaml.dump(self.capDict, capFile)
Ejemplo n.º 23
0
class ExitTrade:
    def __init__(self, stratName, isLive=False):
        logging.debug("Initialising ExitTrade()")
        self.isLive = isLive
        self.stratName = stratName
        db = MongoClient("localhost", 27017)[stratName]
        self.transCol = db["transactionLogs"]
        self.currentCol = db["currentPositions"]
        self.pull = Pull()
        self.capDict = None

    def initBooks(self):
        logging.debug("Starting ExitTrade.initBooks")
        with open(
            "%s/Pipeline/resources/%s/capital.yml"
            % (Settings.BASE_PATH, self.stratName)
        ) as capFile:
            self.capDict = yaml.load(capFile)
        logging.debug("Ending ExitTrade.initBooks")

    def _getPrice(self, fills):
        return round(
            sum([float(val["price"]) * float(val["qty"]) for val in fills])
            / sum([float(val["qty"]) for val in fills]),
            8,
        )

    def exit(self, positionDict, currentPrice):
        logging.debug("Starting ExitTrade.exit")
        fees = ExchangeUtil().fees(exchange=positionDict["exchange"])
        dir = positionDict["dir"] if "dir" in positionDict.keys() else "buy"
        leverage = positionDict["leverage"] if "leverage" in positionDict.keys() else 1
        exitPositionSize = (
            round(
                (currentPrice / float(positionDict["openPrice"]))
                * float(positionDict["positionSize"])
                * (1 - fees),
                6,
            )
            if dir == "buy"
            else round(
                (float(positionDict["openPrice"] / currentPrice))
                * float(positionDict["positionSize"])
                * (1 - fees),
                6,
            )
        )
        logging.debug(
            "Removing val from db.currentPosition & inserting into db.tranactionLog"
        )
        self.currentCol.delete_one({"assetName": positionDict["assetName"]})
        if not self.isLive:
            realPnL = (exitPositionSize - positionDict["positionSize"]) * leverage
            exitDict = {
                "assetName": positionDict["assetName"],
                "openPrice": round(float(positionDict["openPrice"]), 8),
                "closePrice": round(currentPrice, 8),
                "percentPnL": round(currentPrice / positionDict["openPrice"] - 1, 6),
                "TSOpen": positionDict["TSOpen"],
                "TSClose": round(time.time()),
                "periods": positionDict["periods"] + 1,
                "positionSize": positionDict["positionSize"],
                "realPnL": round(realPnL, 8),
            }
        else:
            orderDict = self.pull.makeTrade(
                exchange=positionDict["exchange"],
                asset=positionDict["assetName"],
                quantity=positionDict["posSizeBase"],
                dir="SELL",
            )
            realPnL = float(orderDict["cummulativeQuoteQty"]) - float(
                positionDict["positionSize"]
            )
            closePrice = self._getPrice(orderDict["fills"])
            exitDict = {
                "assetName": positionDict["assetName"],
                "openPrice": round(positionDict["openPrice"], 8),
                "hitPrice": round(positionDict["hitPrice"], 8),
                "sellPrice": round(positionDict["sellPrice"], 8),
                "closePrice": closePrice,
                "percentPnL": round(closePrice / positionDict["openPrice"] - 1, 6),
                "TSOpen": positionDict["TSOpen"],
                "TSClose": round(time.time()),
                "periods": positionDict["periods"] + 1,
                "positionSize": positionDict["positionSize"],
                "realPnL": round(realPnL, 8),
            }
        self.transCol.insert_one(exitDict)
        self.capDict["liquidCurrent"] += exitPositionSize
        logging.debug("Ending ExitTrade.run")

    def paperValue(self):
        logging.debug("Starting ExitTrade.paperValue")
        return sum([val["paperSize"] for val in list(self.currentCol.find())])

    def closeOutBooks(self):
        logging.debug("Starting ExitTrade.closeOutBooks")
        if not self.isLive:
            self.capDict["paperCurrent"] = round(
                self.capDict["liquidCurrent"] + self.paperValue(), 4
            )
            self.capDict["percentAllocated"] = round(
                1 - self.capDict["liquidCurrent"] / self.capDict["paperCurrent"], 3
            )
            self.capDict["paperPnL"] = round(
                self.capDict["paperCurrent"] / self.capDict["initialCapital"], 3
            )
            self.capDict["liquidCurrent"] = round(self.capDict["liquidCurrent"], 4)
        else:
            # **TODO hard coding 'Binance' as whole capDict system will need to change to capListDict when adding multiple
            self.capDict = AccountUtil(exchange="Binance").getValue(
                initCapital=self.capDict["initialCapital"]
            )
        with open(
            "%s/Pipeline/resources/%s/capital.yml"
            % (Settings.BASE_PATH, self.stratName),
            "w",
        ) as capFile:
            yaml.dump(self.capDict, capFile)
        logging.debug("Ending ExitTrade.closeOutBooks")