AI4Finance-Foundation / FinRL-Meta

FinRL­-Meta: Dynamic datasets and market environments for FinRL.
https://ai4finance.org
MIT License
1.2k stars 560 forks source link

TypeError: 'CryptoEnv' object is not callable #216

Open Daiiszuki opened 1 year ago

Daiiszuki commented 1 year ago

I tried a re-implementation of the multicrypto trading notebook and got TypeError: 'CryptoEnv' object is not callable, as was the case in the notebook.

Are there any workarounds/solutions yet?

Environment: Google colab.

Below is my output:


binance successfully connected
Using cached file ./cache/BTCUSDT_ETHUSDT_XRPUSDT_ADAUSDT_binance_2021-09-01_2021-09-02_5m.pickle
tech_indicator_list:  ['macd', 'rsi', 'cci', 'dx']
indicator:  macd
indicator:  rsi
indicator:  cci
indicator:  dx
Succesfully add technical indicators
Successfully transformed into array
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
[<ipython-input-25-5a7deccf64a2>](https://localhost:8080/#) in <module>
     36           break_step=5e4,
     37           startingCapital = 1e4,
---> 38           if_vix = False
     39           )
     40 

1 frames
[/FinRL-Meta/agents/elegantrl_models.py](https://localhost:8080/#) in get_model(self, model_name, model_kwargs)
     51             "if_train": True,
     52         }
---> 53         env = self.env(config=env_config)
     54         env.env_num = 1
     55         agent = MODELS[model_name]

TypeError: 'CryptoTradingEnv' object is not callable

Please let me know if you need any additional information

Daiiszuki commented 1 year ago

Any potential work arounds/recommendations for cryptocurrency portfolio allocation?

This is a somewhat urgent matter and would appreciate a quick response

Thank you in advance.

mhdmyz commented 1 year ago

How do you set your environment?

Athe-kunal commented 1 year ago

I guess you can use this @Daiiszuki https://github.com/AI4Finance-Foundation/FinRL-Meta/blob/master/tutorials/1-Introduction/FinRL_PortfolioAllocation_NeurIPS_2020.ipynb for portfolio allocation

Daiiszuki commented 1 year ago

@mhdmyz my environment is as follows;


import numpy as np
import math

class CryptoTradingEnv:

    def __init__(self, env_config , lookBack = 1, startingCapital = 1e4, buyFee = 1e-3, sellFee = 1e-3, gamma = 0.99, **kwargs):

      self.lookBack =lookBack
      self.totalAssetsStart = startingCapital
      self.startCash = startingCapital 
      self.buyFee = buyFee
      self.sellFee = sellFee
      self.maxCrypto = 1
      self.gamma = gamma
      self.pricesArr = env_config['pricesArr']
      self.indicatorArr = env_config['indicatorArr']

      self.numOfCryptos = self.pricesArr.shape[1]
      self.maximumSteps = self.pricesArr.shape[0] - lookBack - 1 

      self.currentTime = lookBack - 1
      self.currentCash = startingCapital 
      self.currentPrice = self.pricesArr[self.currentTime]
      self.currentIndicator = self.indicatorArr[self.currentTime]
      self.cryptosInStock = np.zeros(self.numOfCryptos,dtype = np.float32)

      self.assetsAtHand = self.currentCash +(self.cryptosInStock * self.pricesArr[self.currentTime]).sum() 
      self.periodReturn = 0.0
      self.gammaReturn = 0.0

      self.actionNormalizerGenerator()

      self.envName = 'CryptoTradingEnv'
      self.stateDimension = 1 + (self.pricesArr.shape[1] + self.indicatorArr.shape[1])*lookBack
      self.actionDimension = self.pricesArr.shape[1]
      self.if_discrete = False
      self.targetReturns = 10 

    def actionNormalizerGenerator(self):

      normalisedActionVec = []
      zeroIndexPrice = self.pricesArr[0]

      for assetPrice in zeroIndexPrice:
        normItem = math.floor(math.log(assetPrice, 10))
        normalisedActionVec.append( 1/ ((10) ** normItem ))

      normalisedActionVec = np.asarray(normalisedActionVec) * 10000
      self.normalisedActionVec = np.asarray(normalisedActionVec)

    def resetEnv():
      self.currentTime = lookBack - 1
      self.currentCash = self.startingCapital 
      self.currentPrice = self.pricesArr[self.currentTime]
      self.currentIndicator = self.indicatorArr[self.currentTime]
      self.cryptosInStock = np.zeros(self.numOfCryptos,dtype = np.float32)
      self.assetsAtHand = self.currentCash +(self.cryptosInStock * self.priceArr[self.currentTime]).sum() 
      stateVar = self.generateState()

      return stateVar

    def performStep(self, actions) -> (np.ndarray, float, bool, None):
      self.currentTime += 1
      priceVar = self.pricesArr[self.currentTime] 

      for index in range(actionDimension):
        normalisationVecAtIndex = self.normalisedActionVec[index]
        actions[index] = actions[index] * normalisationVecAtIndex

      for ind in np.where(actions < 0 )[0]:
        if priceVar[ind] > 0:
          sellAmount = min(self.cryptosInStock, -actions[ind] )
          self.cryptosInStock[ind] -= sellAmount
          self.currentCash += priceArr[ind] * sellAmount * (1 - self.sellFee)

      for ind in np.where(actions > 0 )[0]:
        if priceVar[ind] > 0:
          buyAmount = min(self.currentCash // priceArr[ind], actions[ind] )
          self.cryptosInStock[ind] += buyAmount
          self.currentCash -= priceArr[ind] * buyAmount * (1 + self.buyFee) 
      ifComplete = self.currentTime == self.max_step
      stateVar = self.generateState()
      futureReturn = self.currentCash + (self.cryptosInStock * self.pricesArr[self.currentTime]).sum()
      rewardVar = (futureReturn - self.assetsAtHand) * 2 ** -16
      self.assetsAthand = futureReturn
      self.gammaReturn =  self.gamma * self.gammaReturn + rewardVar
      self.returnsCumulative = self.assetsAtHand / self.startCash

      if ifComplete:
        reward = self.gammaReturn
        self.episodicReturn = self.assetsAtHand/ self.startCash

      return stateVar, rewardVar, ifComplete, None  

    def generateState(self):
      stateObj = np.hstack((self.currentCash * 2 ** -18, self.cryptosInStock * 2** -3))
      for l in range(self.lookBack):
        indicatorItor = self.indicatorArr[self.time-l]
        normalisedIdicatorArr = indicatorItor * 2 ** -15
        stateObj = ((stateObj, normalisedIdicatorArr)).astype(np.float32)

      return stateObj

    def closeFunc(self):
      pass
Daiiszuki commented 1 year ago

I guess you can use this @Daiiszuki https://github.com/AI4Finance-Foundation/FinRL-Meta/blob/master/tutorials/1-Introduction/FinRL_PortfolioAllocation_NeurIPS_2020.ipynb for portfolio allocation

How can this be adapted to crypto. The yahoodownloader seems to be quite limited