new files for indicators and signals

This commit is contained in:
Mark 2022-08-13 16:13:13 +03:00
parent 3525d05a11
commit 20f8b1a682
2 changed files with 353 additions and 0 deletions

View File

@ -0,0 +1,159 @@
import pandas as pd
import datetime
import numpy as np
import market_trade.core.CoreTraidMath as CoreTraidMath
import market_trade.core.CoreDraw as CoreDraw
class coreIndicator():
def __init__(self,
data=pd.DataFrame(),
options={},
showMode='None',
):
'''
showMode = None/Ind/PartOf
'''
self.data=data
self.showMode=showMode
self.options=options
self.overlayInd=None #True/False
self.ans=None
self.figDict=None
def getAns(self,data=None):
if type(data)!=type(None):
self.data=data
self.ans=self.getCalculate()
if self.showMode=='Ind' or self.showMode=='PartOf':
self.figDict=self.getFigDict()
if self.showMode=='Ind':
self.getFig()
return self.ans
def getFig(self,row=1):
CoreDraw.coreDraw(self.figDict,True)
def getCalculate(self):
return "Error"
def getFigDict(self):
return "Error"
class indicatorAgrigator():
'''
Тема чисто для отладки
jj=indicatorAgrigator().runAll([o1,o2],df_candle[:30])
#jj.createIndFromList([o1,o2])
#jj.calculateInd(df_candle[:30])
'''
def __init__(self):
self.indList=None
self.data=None
def createInd(self,classDict):
return classDict['name'](
options=classDict['params'],
showMode=classDict['showMode']
)
def createIndFromList(self,indList):
self.indList=indList
ans=[]
for i in self.indList:
ans.append(self.createInd(i))
self.indList=ans
return ans
def calculateInd(self,data):
self.data=data
for i in self.indList:
#i.getAns(data)
i.data=self.data
i.ans=i.getCalculate()
i.figDict=i.getFigDict()
#i.getFig()
def agrigateFig(self):
req=[[]]
for i in self.indList:
if i.overlayInd==True:
req[0].append(i)
else:
req.append([i])
CoreDraw.agrigateFig(req,True)
def runAll(self,indList,df,needDraw=False):
self.createIndFromList(indList)
self.calculateInd(df)
if needDraw:
self.agrigateFig()
class ind_BB(coreIndicator):
def getCalculate(self):
self.overlayInd=True
ans={}
opMA={'dataType':'ohcl',
'action':'findMean',
'actionOptions':{
'MeanType':self.options['MeanType'],
'valueType':self.options['valueType'],
'window':self.options['window']
}
}
ans['BB']=CoreTraidMath.CoreMath(self.data,opMA).ans
opSTD={'dataType':'ohcl',
'action':'findSTD',
'actionOptions':{'valueType':self.options['valueType'],'window':self.options['window']}
}
ans['STD']=CoreTraidMath.CoreMath(self.data,opSTD).ans
ans['pSTD']=ans['BB']+ans['STD']*self.options['kDev']
ans['mSTD']=ans['BB']-ans['STD']*self.options['kDev']
ans['x']=np.array(self.data['date'][self.options['window']-1:].to_list())
return ans
def getFigDict(self,row=1):
req=[]
req.append({
'vtype':'Scatter',
'df':pd.DataFrame(
{'value':self.ans['BB'],'date':self.ans['x']}) ,
'row':row,
'col':1,
'name':'BB'
})
req.append({
'vtype':'Scatter',
'df':pd.DataFrame(
{'value':self.ans['pSTD'],'date':self.ans['x']}) ,
'row':row,
'col':1,
'name':'pSTD'
})
req.append({
'vtype':'Scatter',
'df':pd.DataFrame(
{'value':self.ans['mSTD'],'date':self.ans['x']}) ,
'row':row,
'col':1,
'name':'mSTD'
})
return req
class ind_OCHL(coreIndicator):
def getCalculate(self):
self.overlayInd=True
def getFigDict(self,row=1):
req=[]
req.append({
'vtype':'OCHL',
'df':self.data,
'row':1,
'col':1,
'name':'OHCL'
})
return req

View File

@ -0,0 +1,194 @@
import pandas as pd
import datetime
import numpy as np
import market_trade.core.CoreTraidMath as CoreTraidMath
import market_trade.core.CoreDraw as CoreDraw
from tqdm import tqdm
from market_trade.core.indicators import *
class coreSignalTrande():
def __init__(self,
data=pd.DataFrame(),
dataType='candel',
mode='online',
batchSize=None,
indParams=None,
signalParams=None,
# needFig=False,
# showOnlyIndex=False,
# drawFig=False,
# equalityGap=0
):
self.data = data.reset_index(drop=True)
self.onlineData = data.reset_index(drop=True)
self.dataType = dataType
self.mode = mode
self.ans = None
self.softAnalizList = np.asarray([])
self.hardAnalizList = np.asarray([])
self.analizMetrics = {}
self.indParams = indParams
self.signalParams = signalParams
self.batchSize = batchSize
# self.needFig=needFig
# self.showOnlyIndex=showOnlyIndex
# self.drawFig=drawFig
# self.equalityGap=equalityGap
# Роутер получения ответа
def getAns(self, data):
# ans='Error: unknown Mode!'
ans = None
print("Start processing...")
if self.mode == 'online':
ans = self.getOnlineAns(data.reset_index(drop=True))
elif self.mode == 'retro':
ans = self.getRetroAns(data)
elif self.mode == 'retroFast':
ans = self.getRetroFastAns(data)
print("Processing DONE!")
return ans
# Ретро режим, где расширяется окно добавлением новых элементов
def getRetroAns(self, data):
ans = np.asarray([])
for i in tqdm(range(self.batchSize, len(data) - 1)):
# self.onlineData=self.data[0:i]
window_data = data[0:i]
window_data.reset_index(drop=True)
ans = np.append(ans, (self.getOnlineAns(window_data)))
self.ans = ans
self.getAnaliz()
self.getMetrix()
return ans
# Ретро режим, где двигается окно
def getRetroFastAns(self, data):
# print('d - ',data)
ans = np.asarray([])
for i in tqdm(range(len(data) - 1 - self.batchSize)):
# self.onlineData=self.data[i:i+self.batchSize]
window_data = data[i:i + self.batchSize]
# print('win - ',window_data)
window_data.reset_index(drop=True)
# print('win - ',window_data)
ans = np.append(ans, (self.getOnlineAns(window_data)))
self.ans = ans
self.getAnaliz()
self.getMetrix()
return ans
# Метод, который будет переопределять каждый дочерний класс
def getOnlineAns(self):
return 'Error'
def getAnaliz(self):
print("Start analiz...")
for i in (range(len(self.ans))):
sourceValue = self.data[self.signalParams['source']][i + self.batchSize]
targetValue = self.data[self.signalParams['target']][i + self.batchSize + 1]
if (targetValue) > sourceValue:
if self.ans[i] == 1:
self.softAnalizList = np.append(self.softAnalizList, 1)
self.hardAnalizList = np.append(self.hardAnalizList, 1)
elif self.ans[i] == -1:
self.softAnalizList = np.append(self.softAnalizList, -1)
self.hardAnalizList = np.append(self.hardAnalizList, -1)
else:
self.softAnalizList = np.append(self.softAnalizList, 0)
self.hardAnalizList = np.append(self.hardAnalizList, -1)
elif (targetValue) < sourceValue:
if self.ans[i] == 1:
self.softAnalizList = np.append(self.softAnalizList, -1)
self.hardAnalizList = np.append(self.hardAnalizList, -1)
elif self.ans[i] == -1:
self.softAnalizList = np.append(self.softAnalizList, 1)
self.hardAnalizList = np.append(self.hardAnalizList, 1)
else:
self.softAnalizList = np.append(self.softAnalizList, 0)
self.hardAnalizList = np.append(self.hardAnalizList, -1)
else:
if self.ans[i] == 1:
self.softAnalizList = np.append(self.softAnalizList, -1)
self.hardAnalizList = np.append(self.hardAnalizList, -1)
elif self.ans[i] == -1:
self.softAnalizList = np.append(self.softAnalizList, -1)
self.hardAnalizList = np.append(self.hardAnalizList, -1)
else:
self.softAnalizList = np.append(self.softAnalizList, 0)
self.hardAnalizList = np.append(self.hardAnalizList, 1)
print("Analiz DONE!")
return 0
def getMeteixDict(self, d):
'''
1 - (сбывшиеся + несбывшиеся) \ (сбывшиеся + несбывшиеся +0)
2 - (сбывшиеся - несбывшиеся) \ (сбывшиеся + несбывшиеся +0)
'''
return {
'1': (d['1'] + d['-1']) / (d['1'] + d['-1'] + d['0']),
'2': (d['1'] - d['-1']) / (d['1'] + d['-1'] + d['0']),
}
def getMetrix(self):
softAnalizCount = {'-1': 0, '0': 0, '1': 0}
hardAnalizCount = {'-1': 0, '0': 0, '1': 0}
for i in range(len(self.softAnalizList)):
softAnalizCount[str(int(self.softAnalizList[i]))] += 1
hardAnalizCount[str(int(self.hardAnalizList[i]))] += 1
self.analizMetrics = {'softAnaliz': self.getMeteixDict(softAnalizCount),
'hardAnaliz': self.getMeteixDict(hardAnalizCount)
}
class signal_BB(coreSignalTrande):
def __init__(self,
data=pd.DataFrame(),
dataType='candel',
mode='online',
batchSize=None,
indParams=None,
signalParams=None,
):
super().__init__(
data=data,
dataType=dataType,
mode=mode,
batchSize=batchSize,
indParams=indParams,
signalParams=signalParams,
)
if self.indParams == None:
indParams = {'MeanType': 'SMA', 'window': 15, 'valueType': 'low', 'kDev': 2}
else:
indParams = self.indParams
self.BB = ind_BB(
data=data,
options=indParams,
)
def getOnlineAns(self, data):
ans = 0
# print(data)
self.BB.getAns(data)
# print(BB)
lastValue = data[self.signalParams['source']].to_list()[-1]
if lastValue > self.BB.ans['pSTD'][-1]:
ans = -1
elif lastValue < self.BB.ans['mSTD'][-1]:
ans = +1
else:
ans = 0
return ans