250 lines
8.5 KiB
Python

import pandas as pd
import datetime
import numpy as np
import market_trade.core.CoreTraidMath
import market_trade.core.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
class signalAgrigator:
"""
dictAgrigSignal
key - name str
value - dict
className - class
indParams - dict
signalParams - dict
batchSize - int
"""
def __init__(self,
data=pd.DataFrame(),
dictAgrigSignal={},
mode='online',
dataType='candel',
batchSize=None
):
self.createSingnalInstances(
data,
dictAgrigSignal,
dataType,
batchSize
)
self.mode=mode
def createSingnalInstances(
self,
data,
dictAgrigSignal,
dataType,
batchSize
):
ans={}
for i in dictAgrigSignal:
ans[i]=dictAgrigSignal[i]['className'](
data=data,
dataType=dataType,
batchSize=batchSize,
indParams=dictAgrigSignal[i]['indParams'],
signalParams=dictAgrigSignal[i]['signalParams'],
mode=self.mode
)
self.signalsInstances = ans
return ans
def getAns(self, data):
ans={}
if self.mode == 'online':
for i in self.signalsInstances:
ans[i]=(self.signalsInstances[i].getAns(data))
elif self.mode == 'retroFast' or self.mode == 'retro':
for i in self.signalsInstances:
self.signalsInstances[i].getAns(data)
ans[i]=self.signalsInstances[i].analizMetrics
return ans