#!/usr/bin/env python
# coding: utf-8

# In[1]:


import pandas as pd
import datetime
import numpy as np
import random
from signals import * #потом удалить


# In[2]:


class trandeVoter():

    def __init__(self,name):
       
        self.name = name # просто имя
        self.trandeValuesList = ['up','none','down'] #словарь трегдов
        self.matrixAmounts = None # матрица сумм
        self.keysMatrixAmounts = None #ключи матрицы сумм, техническое поле
        self.matrixProbability = None # матрица вероятностей
        
    
    #функция которая создает df с заданным набором колонок и индексов. индексы - уникальные соотношения 
    def createDFbyNames(self, namesIndex, namesColoms,defaultValue=0.0):
        df = pd.DataFrame(dict.fromkeys(namesColoms, [defaultValue]*pow(3,len(namesIndex))),
                          index=pd.MultiIndex.from_product([self.trandeValuesList]*len(namesIndex), names=namesIndex)
                            #,columns=namesColoms
                        )
        return(df)
    
    #создание матрицы сумм с дефолтным значением
    def createMatrixAmounts(self,namesIndex: list) -> pd.DataFrame():
        self.matrixAmounts = self.createDFbyNames(namesIndex,self.trandeValuesList,0)
        self.keysMatrixAmounts = self.matrixAmounts.to_dict('tight')['index_names']
        self.createMatrixProbability(namesIndex)
        return(self.matrixAmounts)
    
    #создание матрицы вероятностей с дефолтным значением
    def createMatrixProbability(self,namesIndex: list) -> pd.DataFrame():
        self.matrixProbability = self.createDFbyNames(namesIndex,self.trandeValuesList)
        return(self.matrixProbability)
    
    #установка значений в матрицы сумм. signalDecisions - значения индикаторов key:value; trande - реальное значение
    def setDecisionBySignals(self,signalDecisions: dict,trande: str) -> None:
        buff=[]
        for i in self.keysMatrixAmounts:
            buff.append(signalDecisions[i])
        self.matrixAmounts.loc[tuple(buff),trande] += 1
        
    #заполнение матрицы вероятностей вычисляемыми значениями из матрицы сумм
    def generateMatrixProbability(self) -> None:
        for i in range(self.matrixAmounts.shape[0]):
            rowSum=sum(self.matrixAmounts.iloc[i])
            self.matrixProbability.iloc[i]['up'] = (self.matrixAmounts.iloc[i]['up'] / rowSum)
            self.matrixProbability.iloc[i]['none'] = self.matrixAmounts.iloc[i]['none'] / rowSum
            self.matrixProbability.iloc[i]['down'] = self.matrixAmounts.iloc[i]['down'] / rowSum

    #получение рещения из матрицы вероятностей по заданным значениям сигналов
    def getDecisionBySignals(self,signalDecisions: dict) -> dict:
        ans = {}
        spliceSearch =self.matrixProbability.xs(tuple(signalDecisions.values()),
                                                       level=list(signalDecisions.keys())
                                                      ) 
        ans['probability'] = spliceSearch.to_dict('records')[0]
        ans['trande'] = spliceSearch.iloc[0].idxmax()
        return ans
    
    #получение матриц вероятностей и суммы в видей словарей
    def getMatrixDict(self) -> dict:
        ans={}
        ans['amounts'] = self.matrixAmounts.to_dict('tight')
        ans['probability'] = self.matrixProbability.to_dict('tight')
        return ans
    
    #установка матриц вероятностей и суммы в видей словарей
    def setMatrixDict(self,matrixDict: dict) -> dict:
        if matrixDict['amounts'] != None:
            self.matrixAmounts = pd.DataFrame.from_dict(y['amounts'], orient='tight')
        if matrixDict['probability'] != None:
            self.matrixProbability = pd.DataFrame.from_dict(y['probability'], orient='tight') 


# In[3]:


reqSig={
    'BB1':{
        'className':signal_BB,
        'indParams':{'MeanType':'SMA','window':15,'valueType':'close','kDev':2.5},
        'signalParams':{'source':'close','target':'close'},
        'batchSize':15
    },
    'BB2':{
        'className':signal_BB,
        'indParams':{'MeanType':'SMA','window':15,'valueType':'close','kDev':2.5},
        'signalParams':{'source':'close','target':'close'},
        'batchSize':20
    }
}



# In[4]:


reqDS={'BB1':'up','BB2':'none'}


# In[7]:


reqCreate=list(reqSig.keys())
reqCreate


# In[8]:


t=trandeVoter('piu')
o=t.createMatrixAmounts(['BB1', 'BB2'])
o


# In[9]:


for i in range(100000):
    t.setDecisionBySignals({'BB1':random.choice(['up','down','none']),
                            'BB2':random.choice(['up','down','none'])},
                           random.choice(['up','down','none']))
    


# In[10]:


t.matrixAmounts


# In[11]:


t.generateMatrixProbability()


# In[577]:


t.matrixProbability


# In[14]:


t.setMatrixDict(y)


# In[15]:


t.getDecisionBySignals(reqDS)


# In[ ]:





# In[ ]:





# In[13]:


y = t.getMatrixDict()
y


# In[16]:


ddf = pd.DataFrame.from_dict(y['amounts'], orient='tight')
ddf


# In[ ]:





# In[ ]:





# In[ ]:





# In[ ]:





# In[17]:


t.matrixProbability.iloc[0]['up'] = (t.matrixProbability.iloc[0]['up'] / (sum(t.matrixProbability.iloc[0])))
t.matrixProbability


# In[ ]:





# In[ ]:





# In[ ]:





# In[18]:


t.matrixProbability['trandе']


# In[19]:


random.choice(['up','down','none'])


# In[20]:


t.setDecisionBySignals(reqDS,'up')


# In[21]:


#t.matrixAmounts.at(bbb,'up')
    
t.matrixAmounts.iloc[0]


# In[22]:


for i in t.matrixAmounts.iloc[0]:
    print (i)


# In[23]:


(t.matrixAmounts.iloc[0]).idxmax()


# In[24]:


t.matrixAmounts


# In[ ]:





# In[25]:


o.xs(('up','down'), level=['BB1','BB2'])['up'].iloc[0]

#oldValue = o.xs(('up','down'), level=['BB1','BB2'])['up']

#o=o.replace(oldValue,oldValue.iloc[0]+1) 
#o.xs(('up','down'), level=['BB1','BB2'])


# In[26]:


o.xs(('up','down'), level=['BB1','BB2'], drop_level=False)#.iloc[0].loc['up']=2#.at['up']=4


# In[27]:


o.xs(('up','down'), level=['BB1','BB2']).iloc[0].at['up']


# In[28]:


o.loc['up'].loc['down']


# In[29]:


bbb=tuple(['up','down'])
bbb


# In[30]:


o.loc[bbb,]


# In[31]:


o.at[bbb, 'up']+=1
o


# In[32]:


o.loc[bbb]


# In[33]:


dict(zip(['a','b','c'], [1,2,3]))


# In[ ]:




