import glob
import json
import numpy as np
from joblib import Parallel,delayed
import datetime
import time
import bollkaisekiReverse_pyx
import bollkaisekiReverse_pyx2
import pandas as pd

from statistics import mean
import warnings
warnings.filterwarnings('ignore')
import psutil
p = psutil.Process()
p.nice(psutil.IDLE_PRIORITY_CLASS)
del p
def beep(freq, dur=100):
    """
        ビープ音を鳴らす.
        @param freq 周波数
        @param dur  継続時間（ms）
    """
    import winsound
    winsound.Beep(freq, dur)



def writedata_function(writedata):
    passOfData='backtest_temp\\temp_bollkaisekiReverse_'+str(minute)+"_"+str(int(time.time()))+".json"
    while 1:
        f1 = open(passOfData, 'w')  #書き込みモードでオープン
        json.dump(writedata, f1)
        time.sleep(15)
        f1.close
        try:
            f1=open(passOfData,'r')
            temp=json.load(f1)
            f1.close
            break
        except Exception as e:
            print(e)
            time.sleep(5)

def Flags(kako,kensyouLength,startIflag):
    if startIflag:
        startI=kako
        endI=kensyouLength
    for n in range(len(FlagArray)):
        if not PassFlagArray[n]:
            if FlagArray[n]==2:deltaArray[n]=[i for i in rci_smarci if i[0]==dataArray[n][0] and i[1]==dataArray[n][1]][0]
            if FlagArray[n]==3:deltaArray[n]=sma1[[int(i[0]) for i in sma1].index(dataArray[n][0])]-sma1[[int(i[0]) for i in sma1].index(dataArray[n][1])]
            if FlagArray[n]==5:deltaArray[n]=[i for i in rcivwap if i[0]==dataArray[n][0] and i[1]==dataArray[n][1]][0]-[i for i in rcivwap if i[0]==dataArray[n][2] and i[1]==dataArray[n][3]][0]
            if FlagArray[n]==6:deltaArray[n]=bollkaisekiReverse_pyx.vixfix_lb2_long (lowdata,closedata,dataArray[n][0],dataArray[n][1],dataArray[n][2],dataArray[n][3],dataArray[n][4],np.zeros(len(closedata),dtype=np.int8))
            if FlagArray[n]==7:deltaArray[n]=bollkaisekiReverse_pyx.vixfix_lb2_short(lowdata,closedata,dataArray[n][0],dataArray[n][1],dataArray[n][2],dataArray[n][3],dataArray[n][4],np.zeros(len(closedata),dtype=np.int8))
            if FlagArray[n] in [8,9]:deltaArray[n]=  [[i,dataArray[n][1]] for i in rciBigData if i[0]==dataArray[n][0]][0]
            if FlagArray[n] in [10,11]:deltaArray[n]=[[i,dataArray[n][1]] for i in rsiBigData if i[0]==dataArray[n][0]][0]
            if FlagArray[n] in [12,13]:deltaArray[n]=[i for i in smaBigData if i[0]==dataArray[n][0]][0]-[i for i in smaBigData if i[0]==dataArray[n][1]][0]
            if FlagArray[n] in [14,15]:deltaArray[n]=[i for i in rsiBigData if i[0]==dataArray[n][0]][0]-[i for i in rsiBigData if i[0]==dataArray[n][1]][0]
            if FlagArray[n] in [16,17]:deltaArray[n]=[i for i in AO if i[0]==dataArray[n][0]][0]-[i for i in AO if i[0]==dataArray[n][1]][0]
            if FlagArray[n] in [18,19]:deltaArray[n]=[[i,dataArray[n][1]] for i in psycoDice if i[0]==dataArray[n][0]][0]
            if FlagArray[n] in [20,21]:deltaArray[n]=[[i,dataArray[n][1]] for i in madiv if i[0]==dataArray[n][0]][0]
            if FlagArray[n] in [22,23]:deltaArray[n]=[[i,dataArray[n][1]] for i in volmeandata if round(i[0])==dataArray[n][0]][0]
    """print("FLAG",FlagArray)
    print("PASS",PassFlagArray)
    print("AND ",AndFlagArray)"""
    """
    LongFlag=[[ (delta[i-1]<delta[i]<0 if _Flag in [16] else delta[i-1]>delta[i]>0 if _Flag in [17] else (delta[i]>0)\
    if not _Flag in [6,8,9,10,11,18,19,20,21] else delta[i] if _Flag in [6] else delta[0][i]<delta[1] if _Flag in  [8,20] else delta[0][i]>-delta[1] if _Flag in [9,21] else delta[0][i]<delta[1] if _Flag in [10,18] else delta[0][i]>-delta[1]+100 if _Flag in [11,19] else None) if i else AndFlag for i in (range(startI,endI) if startIflag else range(-kako-kensyouLength,-kako)) ] for _Flag,delta,PassFlag,AndFlag in zip(FlagArray,deltaArray,PassFlagArray,AndFlagArray) if not _Flag in [7,13,15] and not PassFlag]
    lenAndFlag=len([i for i in LongFlag if i[0]])
    OrLongFlag=np.array( [sum([n[i] * (not n[0]) for n in LongFlag])>0 for i in (range(endI-startI) if startIflag else range(kensyouLength))],dtype=np.int8)
    AndLongFlag=np.array([sum([n[i] for n in LongFlag if n[0]])==lenAndFlag for i in (range(endI-startI) if startIflag else range(kensyouLength))],dtype=np.int8)

    ShortFlag=[[(delta[i-1]>delta[i]>0 if _Flag in [16] else delta[i-1]<delta[i]<0 if _Flag in [17] else (delta[i]<0)\
    if not _Flag in [7,8,9,10,11,18,19,20,21] else delta[i] if _Flag in [7] else delta[0][i]>-delta[1] if _Flag in [8,20] else delta[0][i]<delta[1] if _Flag in [9,21] else delta[0][i]>-delta[1]+100 if _Flag in [10,18] else delta[0][i]<delta[1] if _Flag in [11,19] else None) if i else AndFlag for i in (range(startI,endI) if startIflag else range(-kako-kensyouLength,-kako))] for _Flag,delta,PassFlag,AndFlag in zip(FlagArray,deltaArray,PassFlagArray,AndFlagArray) if not _Flag in [6,12,14] and not PassFlag]
    lenAndFlag=len([i for i in ShortFlag if i[0]])
    OrShortFlag=np.array( [sum([n[i] * (not n[0]) for n in ShortFlag])>0 for i in (range(endI-startI) if startIflag else range(kensyouLength))],dtype=np.int8)
    AndShortFlag=np.array([sum([n[i]  for n in ShortFlag if n[0]])==lenAndFlag for i in (range(endI-startI) if startIflag else range(kensyouLength))],dtype=np.int8)
    """

    OrLongFlag=np.array([0 for i in (range(endI-startI) if startIflag else range(kensyouLength))])
    AndLongFlag=np.array([1 for i in (range(endI-startI) if startIflag else range(kensyouLength))])
    OrShortFlag=np.array([0 for i in (range(endI-startI) if startIflag else range(kensyouLength))])
    AndShortFlag=np.array([1 for i in (range(endI-startI) if startIflag else range(kensyouLength))])
    for _Flag,delta,PassFlag,AndFlag in zip(FlagArray,deltaArray,PassFlagArray,AndFlagArray):
        if not PassFlag:
            for a,i in enumerate(list(range(startI,endI) if startIflag else range(-kako-kensyouLength,-kako))):
                if _Flag in [8,20]:
                    Ltempflag=delta[0][i]<delta[1]
                    Stempflag=delta[0][i]>-delta[1]
                elif _Flag in [9,21]:
                    Ltempflag=delta[0][i]>-delta[1]
                    Stempflag=delta[0][i]<delta[1]
                elif _Flag in [10,18]:
                    Ltempflag=delta[0][i]<delta[1]
                    Stempflag=delta[0][i]>-delta[1]+100
                elif _Flag in [11,19]:
                    Ltempflag=delta[0][i]>-delta[1]+100
                    Stempflag=delta[0][i]<delta[1]
                elif _Flag in [22]:
                    Ltempflag=delta[0][i]<volumedata[i]*delta[1]
                    Stempflag=delta[0][i]<volumedata[i]*delta[1]
                elif _Flag in [23]:
                    Ltempflag=delta[0][i]>volumedata[i]*delta[1]
                    Stempflag=delta[0][i]>volumedata[i]*delta[1]
                if AndFlag:
                    if AndLongFlag[a]==1:
                        AndLongFlag[a]=Ltempflag
                    if AndShortFlag[a]==1:
                        AndShortFlag[a]=Stempflag
                else:
                    if OrLongFlag[a]==0:
                        OrLongFlag[a]=Ltempflag
                    if OrShortFlag[a]==0:
                        OrShortFlag[a]=Stempflag





    return(OrLongFlag,AndLongFlag,OrShortFlag,AndShortFlag)

if __name__ == '__main__':

    CheckFlag=1
    #SettedcloseoneList=[0.1*i for i in range(1,2)]
    SettedcloseoneList=[0.025]
    closestopRatioOneList=[0.025]
    SettedcloseoneList=[float(i) for i in SettedcloseoneList]
    closestopRatioOneList=[float(i) for i in closestopRatioOneList]
    timeClose=12000

    st=time.time()
    symbol="XBTUSD"
    if symbol in ["XBTUSD","ETHUSD"]:
        _pass="ohlcs\\"+symbol+".json"
        f=open(_pass,'r')
        stockdataMoto=json.load(f)
        f.close
        stockdataMoto=[[i["timestamp"],i["high"],i["low"],i["close"],i["volume"],0] for i in stockdataMoto if i["high"] or i["low"] or i["close"]]
    else:
        filenames=glob.glob("ohlcs/*")
        filenames=sorted([i for i in filenames if symbol in i and not "USD" in i and len(i)==17])
        stockdatazenbu=[]
        for s in filenames:
            f=open(s,'r')
            stocktemp=json.load(f)
            f.close
            stockdatazenbu.append(stocktemp)
        stockdatazenbu=sorted(stockdatazenbu,key=lambda x:x[0]["timestamp"])
        stockdataMoto=[]
        timestamplst=set()
        symbolEndFlagtemp=[]
        for i,stocktemp in enumerate(stockdatazenbu):
            for i in stocktemp:
                if i["timestamp"] not in timestamplst:
                    if i==len(stockdatazenbu)-1 or i==len(stockdatazenbu)-2 or i==0 or i==1:
                        flag=1
                    else:
                        flag=0
                    stockdataMoto.append([i["timestamp"],i["high"],i["low"],i["close"],i["volume"],flag])
                    timestamplst.add(i["timestamp"])


    maxThread=6
    minute=1
    leverage=3
    feelist=np.zeros(4,dtype=np.float)

    if symbol in ["XBTUSD","ETHUSD"]:
        feelist[0]=-0.0005
        feelist[1]= 0.0005
        feelist[2]= 0.0015
        feelist[3]= 0.00075
    else:
        feelist[0]=-0.0005*2
        feelist[1]= 0.0015
        feelist[2]= 0.005
        feelist[3]= 0.0025

    """
    feelist[0]=0
    feelist[1]=0
    feelist[2]=0
    feelist[3]=0
    """
    kaisekiLength=50000
    kensyouLength=2500
    kensyouBigLength=len(stockdataMoto)//minute


    LimitFlag=0
    Limit_gosa=0.6
    T_sum,F_sum=0,0
    Setted_Accurateper=7
    DotenFlag=1
    prd_start,prd_per,prd_count=10,3,1
    bbl_start,bbl_per,bbl_count=10,5,1
    mult_start,mult_per,mult_count=0,0.2,1
    lb_start,lb_per,lb_count=20,5,1
    ph_start,ph_per,ph_count=0.05,0.1,1
    pl_start,pl_per,pl_count=0.01,0.1,1

    rsi_time_start,rsi_time_per,rsi_time_count=3,1,100
    rci_time_start,rci_time_per,rci_time_count=3,1,30
    volspanst,volspanper,volspanend=3,1,50
    volmeanPerArray=np.array([0.2*i for i in range(1,20)],dtype=float)

    psycoDicestart,psycoDicecount=3,50
    madivstart,madivcount=3,5
    FlagArrayList=[[8,9,10,11,19]]
    AcuuratePerList=[2.5]
    kaisekiLengthList=[50000]

    closestopRatioList=np.array([i*0.1 for i in range(1,4)],dtype=np.float)
    kensyouLengthDiv=40
    kaisekiLength=max(kaisekiLengthList)
    kensyouLength=max(kaisekiLengthList)//kensyouLengthDiv


    zenbutime=100
    #print(len(stockdataMoto)//minute - max(kaisekiLengthList)*1.2)
    zenbutime=int(min(zenbutime,(len(stockdataMoto)//minute - kaisekiLength*1.2)//kensyouLength))


    """print("zenbutime:",zenbutime)
    if not zenbutime:
        print("zenbutime000000")
        exit()"""
    st=time.time()
    stockdata=stockdataMoto[len(stockdataMoto)-(1+kensyouLength * (zenbutime+1)+ kaisekiLength)*minute: ]




    length=len(stockdata)
    length_=int((length-minute)/minute)
    closedata=np.zeros(length_,dtype=np.float)
    highdata=np.zeros(length_,dtype=np.float)
    lowdata=np.zeros(length_,dtype=np.float)
    volumedata=np.zeros(length_,dtype=np.float)
    symbolEndFlag=np.zeros(length_,dtype=np.int8)


    for i in range(length_):
        closedata[i]=stockdata[i*minute][3]
        highdata[i]=max([stockdata[i*minute-x][1] for x in range(minute)])
        lowdata[i]=min([stockdata[i*minute-x][2] for x in range(minute)])
        volumedata[i]=sum([stockdata[i*minute-x][4] for x in range(minute)])
        symbolEndFlag[i]=sum([stockdata[max(i*minute-x-minute,0)][5] for x in range(minute)])

    volmeandata=np.array([pd.rolling_mean(volumedata,span,1) for span in range(volspanst,volspanend,volspanper)],dtype=np.float)
    for i,a in enumerate([i for i in range(volspanst,volspanend,volspanper)]):
        volmeandata[i][0]=a
    #print("stockdata作成:",time.time()-st)
    st=time.time()
    HLdata=highdata+lowdata
    psycoDice=[2 if closedata[i]-closedata[i-1]>0 else 1 if closedata[i]-closedata[i-1]==0 else 0 for i in range(len(closedata))]
    psycoDice=np.array([[span if not i else sum(psycoDice[max(i-span+1,0):i+1])*100/(2*span) for i in range(len(closedata))] for span in range(psycoDicestart,psycoDicecount)],dtype=np.float)
    #print("psycoDice作成",time.time()-st)
    madiv=np.array([[span if not i  else (closedata[i]-mean(closedata[max(i-span+1,0):i+1]))/closedata[i] for i in range(len(closedata))] for span in range(madivstart,madivcount)],dtype=np.float)
    AO=np.array([[span if not i else data for i,data in enumerate(pd.rolling_mean(HLdata,span,1))] for span in range(2,50,2)],dtype=np.float)
    #print("madiv,AO作成:",time.time()-st)


    spantime_array=[i+8 for i in range(100)]
    multArray=np.array([0.001*(i-20) for i in range(40)],dtype=np.double)
    Tempvwap=closedata*volumedata

    smaBigData=np.array([[span if not i else data for i,data in enumerate(pd.rolling_mean(closedata,span,1))] for span in range(5,75,2)],dtype=np.float)
    #print("smaBigData作成:",time.time()-st)
    rsiBigData=np.empty((rsi_time_count,len(closedata)),dtype= np.float32)
    rsitimearray=np.empty(rsi_time_count,dtype= np.int)
    bollkaisekiReverse_pyx.rsi_list_get(closedata,[i for i in range(rsi_time_start,rsi_time_count,rsi_time_per)],rsiBigData)
    #print("rsi_list作成:",time.time()-st)
    #print([i for i in FlagArrayList if 8 in i or 9 in i])
    if not  [i for i in FlagArrayList if 8 in i or 9 in i]:rci_time_count=5
    #print(rci_time_count)
    rci_time_count=5
    rciBigData=np.array([bollkaisekiReverse_pyx._get_rci(closedata,rcispan) for rcispan in range(rci_time_start,rci_time_count,rci_time_per)],dtype=np.float32)
    #print("rciBigData作成:",time.time()-st)
    vwap=[[pd.rolling_sum(Tempvwap,span,1)/pd.rolling_sum(volumedata,span,1),span] for span in range(2,3,3)]
    for i in vwap:
        i[0][0]=i[1]
    vwap=np.array([i[0] for i in vwap],dtype=np.float)
    _rcivwap=[[[[bollkaisekiReverse_pyx._get_rci(vwapone,rcispan),rcispan] for rcispan in range(2,3,3)],vwapone[0]] for vwapone in vwap]
    #print(_rcivwap[0][0][0][0])
    for i in _rcivwap:
        for m in i[0]:
            m[0][0]=i[1]
            m[0][1]=m[1]
    rcivwap=[]
    for i in _rcivwap:
        for m in i[0]:
            rcivwap+=[m[0]]
    del(_rcivwap)
    rcivwap=np.array(rcivwap,dtype=np.float)
    #print("rcivwap:",time.time()-st)

    closePerArray=np.array([0.001*(i) for i in range(3,60)],dtype=np.double)
    stopPerArray=np.array([0.001*(i) for i in range(25)],dtype=np.double)



    _upprice=  [[pd.rolling_max(highdata,span,1),span] for span in range(2,3)]
    _downprice=[[pd.rolling_min(lowdata,span,1),span] for span in range(2,3)]
    _Largeupprice=  [[pd.rolling_max(highdata,span,1),span] for span in range(200,201,2)]
    _Largedownprice=[[pd.rolling_min(lowdata,span,1),span] for span in range(200,201,2)]
    for i in _upprice:
        i[0][0]=i[1]
    for i in _downprice:
        i[0][0]=i[1]
    for i in _Largeupprice:
        i[0][0]=i[1]
    for i in _Largedownprice:
        i[0][0]=i[1]
    _upprice  =np.array([i[0] for i in _upprice],dtype=np.float)
    _downprice=np.array([i[0] for i in _downprice],dtype=np.float)
    _Largeupprice  =np.array([i[0] for i in _Largeupprice],dtype=np.float)
    _Largedownprice=np.array([i[0] for i in _Largedownprice],dtype=np.float)

    _rci_smarci=[[bollkaisekiReverse_pyx._get_rci(closedata,rcispan),rcispan] for rcispan in range(2,5)]
    _rci_smarci=[[[i[0]-pd.rolling_mean(i[0],smaspan,1),i[1],smaspan] for smaspan in range(2,100,5)] for i in _rci_smarci]
    for i in _rci_smarci:
        for m in i:
            m[0][0]=m[1]
            m[0][1]=m[2]
    _rci_smarci=[[m[0] for m in i] for i in _rci_smarci]
    rci_smarci=[]
    for i in _rci_smarci:
        for m in i:
            rci_smarci+=[m]
    del(_rci_smarci)
    rci_smarci=np.array(rci_smarci,dtype=np.float)
    sma1=[[pd.rolling_mean(closedata,smaspan,1),smaspan] for smaspan in (list(range(2,100))+list(range(100,1500,10)))]
    for i in sma1:
        i[0][0]=i[1]
    sma1=np.array([i[0] for i in sma1],dtype=np.float)
    vixbigdataUpper=Parallel(n_jobs=maxThread)([delayed(bollkaisekiReverse_pyx.vix_low_memory_long )(lowdata,closedata,prd_start+prd_per*x,[bbl_start,bbl_per,bbl_count],[mult_start,mult_per,mult_count],[lb_start,lb_per,lb_count],[ph_start,ph_per,ph_count]) for x in range(prd_count)])
    vixbigdataUpper=[np.array([i[0] for i in vixbigdataUpper],dtype=np.int8),np.array([i[1] for i in vixbigdataUpper],dtype=np.float),np.array([i[2] for i in vixbigdataUpper],dtype=np.int8),np.array([i[3] for i in vixbigdataUpper],dtype=np.float)]
    vixbigdataLower=Parallel(n_jobs=maxThread)([delayed(bollkaisekiReverse_pyx.vix_low_memory_short)(lowdata,closedata,prd_start+prd_per*x,[bbl_start,bbl_per,bbl_count],[mult_start,mult_per,mult_count],[lb_start,lb_per,lb_count],[pl_start,pl_per,pl_count]) for x in range(prd_count)])
    vixbigdataLower=[np.array([i[0] for i in vixbigdataLower],dtype=np.int8),np.array([i[1] for i in vixbigdataLower],dtype=np.float),np.array([i[2] for i in vixbigdataLower],dtype=np.int8),np.array([i[3] for i in vixbigdataLower],dtype=np.float)]


    for FlagArray,kaisekiLength,AcuuratePer,Settedcloseone,closestopRatioOne in [[FlagArray,kaisekiLength,AcuuratePer,Settedcloseone,closestopRatioOne] for FlagArray in FlagArrayList for kaisekiLength in kaisekiLengthList for AcuuratePer in AcuuratePerList for Settedcloseone in SettedcloseoneList for closestopRatioOne in closestopRatioOneList]:
        zenbu_writedata=[]
        kensyouLength=kaisekiLength//kensyouLengthDiv
        for kako in [1+i*kensyouLength for i in range(0,zenbutime)]:
            multone=0
            Largemultone=0
            estspan=2
            Largeestspan=200

            PassFlagArray=[1 for i in FlagArray]
            deltaArray=[0 for i in FlagArray]
            dataArray=[0 for i in FlagArray]
            AndFlagArray=[0 for i in FlagArray]

            roop=0
            recorded_score=0
            bestscore=0
            count=0
            closeone=Settedcloseone

            startI=length_ + (-kaisekiLength-kensyouLength-kako)
            endI=  length_ + (-kensyouLength-kako)
            checkFlag=0
            preodds=0
            OrLongFlag=np.zeros(length_,dtype=np.int8)
            AndLongFlag=np.zeros(length_,dtype=np.int8)
            OrShortFlag=np.zeros(length_,dtype=np.int8)
            AndShortFlag=np.zeros(length_,dtype=np.int8)
            closeper=Settedcloseone
            Now_closestopRatio=closestopRatioOne
            while bestscore>recorded_score or roop==0:
                recorded_score=bestscore

                for IndexFlag in range(len(FlagArray)+2):
                    if IndexFlag in range(len(FlagArray)):
                        Flag=FlagArray[IndexFlag]
                        a=[PassFlagArray[i] for i in range(IndexFlag) if FlagArray[i]==Flag and PassFlagArray[i]]
                        if a:
                            if a[-1]:continue
                        PassFlagArray[IndexFlag]=2
                    else:
                        if (IndexFlag+1)-len(FlagArray)==1:
                            Flag=1
                        if (IndexFlag+1)-len(FlagArray)==2:
                            Flag=-2
                    st=time.time()
                    """OrLongFlag=np.zeros(length_,dtype=np.int8)
                    AndLongFlag=np.zeros(length_,dtype=np.int8)
                    OrShortFlag=np.zeros(length_,dtype=np.int8)
                    AndShortFlag=np.zeros(length_,dtype=np.int8)"""
                    OrLongFlag_T,AndLongFlag_T,OrShortFlag_T,AndShortFlag_T=Flags(startI,endI,startIflag=True)
                    OrLongFlag[startI:endI]=OrLongFlag_T
                    AndLongFlag[startI:endI]=AndLongFlag_T
                    OrShortFlag[startI:endI]=OrShortFlag_T
                    AndShortFlag[startI:endI]=AndShortFlag_T
                    if Flag==1:
                        pass
                        """bestscore,closeone,T,F,Rediv=bollkaisekiReverse_pyx2.rciTestTrail(timeClose,Now_closestopRatio,closeper,madiv,psycoDice,DotenFlag,closestopRatioList,Limit_gosa,AO,smaBigData,rsiBigData,rciBigData,vixbigdataUpper,vixbigdataLower,            rcivwap,       Largemultone,       multone,          multArray,    Largeestspan,           _Largeupprice,           _Largedownprice,        AndLongFlag,        OrLongFlag,        AndShortFlag,        OrShortFlag,            sma1,            sma1,            rci_smarci,            _upprice,            _downprice,          highdata,          lowdata,          closedata,     Flag,          closePerArray,          stopPerArray,                 feelist,      leverage,    estspan,maxThread,    startI,endI,     checkFlag,     LimitFlag,     AcuuratePer)
                        print(bestscore,"closeone=",closeone,Rediv)
                        closeper[startI:endI]=np.full(endI-startI,closeone)"""
                    elif Flag==-2:
                        pass
                        """closestopRatioOne,bestscore,T,F,Rediv=bollkaisekiReverse_pyx2.rciTestTrail(timeClose,Now_closestopRatio,closeper,madiv,psycoDice,DotenFlag,closestopRatioList,Limit_gosa,AO,smaBigData,rsiBigData,rciBigData,vixbigdataUpper,vixbigdataLower,            rcivwap,       Largemultone,       multone,          multArray,    Largeestspan,           _Largeupprice,           _Largedownprice,        AndLongFlag,        OrLongFlag,        AndShortFlag,        OrShortFlag,            sma1,            sma1,            rci_smarci,            _upprice,            _downprice,          highdata,          lowdata,          closedata,     Flag,          closePerArray,          stopPerArray,                 feelist,      leverage,    estspan,maxThread,    startI,endI,     checkFlag,     LimitFlag,     AcuuratePer)
                        print(bestscore,"closestopRatioOne=",closestopRatioOne,Rediv)
                        Now_closestopRatio[startI:endI]=np.full(endI-startI,closestopRatioOne)"""
                    else:
                        bestscore,PassFlagArray[IndexFlag],AndFlagArray[IndexFlag],dataArray[IndexFlag],T,F,Rediv=bollkaisekiReverse_pyx2.rciTestTrail(volumedata,volmeanPerArray,volmeandata,symbolEndFlag,timeClose,Now_closestopRatio,closeper,madiv,psycoDice,DotenFlag,closestopRatioList,Limit_gosa,AO,smaBigData,rsiBigData,rciBigData,vixbigdataUpper,vixbigdataLower,            rcivwap,       Largemultone,       multone,          multArray,    Largeestspan,           _Largeupprice,           _Largedownprice,        AndLongFlag,        OrLongFlag,        AndShortFlag,        OrShortFlag,            sma1,            sma1,            rci_smarci,            _upprice,            _downprice,          highdata,          lowdata,          closedata,     Flag,          closePerArray,          stopPerArray,                 feelist,      leverage,    estspan,maxThread,    startI,endI,     checkFlag,     LimitFlag,     AcuuratePer)
                        #print("Rediv=",Rediv,sum(T),sum(F),dataArray[IndexFlag],roop,Flag,PassFlagArray[IndexFlag],AndFlagArray[IndexFlag],"closestopRatioOne=",closestopRatioOne)
                    try:
                        odds=sum(T)/(sum(F))
                        """
                        print(T[0],T[1])
                        print(F[0],F[1])

                        print("odds=",odds)"""


                    except:
                        odds=100


                roop+=1
                if not odds:break
                if odds>=AcuuratePer>preodds:
                    preodds=odds
                    roop=0
                    recorded_score=0
            writedata={"closestopRatioOne":closestopRatioOne,"score":[sum(T),sum(F)],"odds":odds,"leverage":leverage,"minute":minute,"length":[kaisekiLength,kensyouLength,kako],"PassFlag":PassFlagArray,"AndFlag":AndFlagArray,"closeone":closeone,"Largemultone":Largemultone,"Largeestspan":Largeestspan,"multone":multone,"estspan":estspan,"dataArray":dataArray,"FlagArray":FlagArray,"PassFlagArray":PassFlagArray}
            zenbu_writedata.append(writedata)
        startI=200
        endI=length_

        OrLongFlag=np.zeros(length_,dtype=np.int8)
        AndLongFlag=np.zeros(length_,dtype=np.int8)
        OrShortFlag=np.zeros(length_,dtype=np.int8)
        AndShortFlag=np.zeros(length_,dtype=np.int8)

        Flag=-1
        T_sum=0
        F_sum=0
        for w,writedata in enumerate(zenbu_writedata):
            kaisekiLength=writedata["length"][0]
            kensyouLength=writedata["length"][1]
            kako         =writedata["length"][2]
            dataArray    =writedata["dataArray"]
            PassFlagArray=writedata["PassFlag"]
            AndFlagArray=writedata["AndFlag"]
            """print(FlagArray)
            print(dataArray)
            print(PassFlagArray)"""
            #print(AndFlagArray)
            OrLongFlag_T,AndLongFlag_T,OrShortFlag_T,AndShortFlag_T=Flags(kako,kensyouLength,startIflag=False)
            #print(-kensyouLength-kako,-kako)
            OrLongFlag[-kensyouLength-kako:-kako]=OrLongFlag_T
            AndLongFlag[-kensyouLength-kako:-kako]=AndLongFlag_T
            OrShortFlag[-kensyouLength-kako:-kako]=OrShortFlag_T
            AndShortFlag[-kensyouLength-kako:-kako]=AndShortFlag_T

            startI=max(200,length_-kensyouLength-kako)
            endI=length_-kako
            bestscore,T,F,Rediv=bollkaisekiReverse_pyx2.rciTestTrail(volumedata,volmeanPerArray,volmeandata,symbolEndFlag,timeClose,Now_closestopRatio,closeper,madiv,psycoDice,DotenFlag,closestopRatioList,Limit_gosa,AO,smaBigData,rsiBigData,rciBigData,vixbigdataUpper,vixbigdataLower,            rcivwap,       Largemultone,       multone,          multArray,    Largeestspan,           _Largeupprice,           _Largedownprice,        AndLongFlag,        OrLongFlag,        AndShortFlag,        OrShortFlag,            sma1,            sma1,            rci_smarci,            _upprice,            _downprice,          highdata,          lowdata,          closedata,     Flag,          closePerArray,          stopPerArray,                 feelist,      leverage,    estspan,maxThread,    startI,endI,     checkFlag,     LimitFlag,     0)
            try:
                odds=sum(T)/(sum(F))
            except:
                if sum(T):
                    odds=100
                else:
                    odds="None"

            T_sum+=sum(T)
            F_sum+=sum(F)

            #print("bestscore",bestscore,"T",sum(T),"F",sum(F),"odds",odds)
        try:
            odds=T_sum/F_sum
        except:
            odds="None"
        Rediv=odds
        print(T_sum,F_sum,"odds=",odds,"bunbetu")
        log={"bunbetu":True,"trailflag":True,"timeClose":timeClose,"bestscore":bestscore,"T":T_sum,"F":F_sum,"Rediv":Rediv,"odds":odds,"AcuuratePer":AcuuratePer,"FlagArray":FlagArray,"DotenFlag":DotenFlag,"LimitFlag":LimitFlag,"minute":minute,"kaisekiLength":kaisekiLength,"kensyouLength":kensyouLength,"zenbutime":zenbutime,"symbol":symbol,"closestopRatioOne":closestopRatioOne,"Settedcloseone":Settedcloseone,"feelist":[i for i in feelist]}
        filename="backtest_data\\"+str(int(time.time()))+"Big19.json"
        f = open(filename, 'w')  #書き込みモードでオープン
        json.dump(log, f)

        print(log)
        print("====================")
        startI=200
        endI=length_
        bestscore,T,F,Rediv=bollkaisekiReverse_pyx2.rciTestTrail(volumedata,volmeanPerArray,volmeandata,symbolEndFlag,timeClose,Now_closestopRatio,closeper,madiv,psycoDice,DotenFlag,closestopRatioList,Limit_gosa,AO,smaBigData,rsiBigData,rciBigData,vixbigdataUpper,vixbigdataLower,            rcivwap,       Largemultone,       multone,          multArray,    Largeestspan,           _Largeupprice,           _Largedownprice,        AndLongFlag,        OrLongFlag,        AndShortFlag,        OrShortFlag,            sma1,            sma1,            rci_smarci,            _upprice,            _downprice,          highdata,          lowdata,          closedata,     Flag,          closePerArray,          stopPerArray,                 feelist,      leverage,    estspan,maxThread,    startI,endI,     checkFlag,     LimitFlag,     0)
        try:
            print(T[0],T[1])
            print(F[0],F[1])
            odds=sum(T)/(sum(F))
            print("odds=",odds)
        except:
            odds="None"
        print("AcuuratePer",AcuuratePer)
        print("FlagArray",FlagArray)
        print("DotenFlag",DotenFlag)
        print("LimitFlag",LimitFlag)
        print("minute",minute)
        print("zenbutime:",zenbutime)
        print(symbol)

        print(kaisekiLength)
        print(kensyouLength)


        log={"bunbetu":False,"trailflag":True,"timeClose":timeClose,"bestscore":bestscore,"T":sum(T),"F":sum(F),"Rediv":Rediv,"odds":odds,"AcuuratePer":AcuuratePer,"FlagArray":FlagArray,"DotenFlag":DotenFlag,"LimitFlag":LimitFlag,"minute":minute,"kaisekiLength":kaisekiLength,"kensyouLength":kensyouLength,"zenbutime":zenbutime,"symbol":symbol,"closestopRatioOne":closestopRatioOne,"Settedcloseone":Settedcloseone,"feelist":[i for i in feelist]}
        filename="backtest_data\\"+str(int(time.time()))+"Big19.json"
        f = open(filename, 'w')  #書き込みモードでオープン
        json.dump(log, f)

        print(log)
        print("====================")
print("end")
while 1:
    beep(2000, 500)
    time.sleep(10)


### FIXED CODE ###

#from collections import *
#from itertools import *
#from bisect import *
from heapq import *
#import copy
#N=int(input())
#X,Y=map(int,input().split())
#S=list(map(int,input().split()))
#S=[list(map(int,input().split())) for i in range(N)]

N,M=map(int,input().split())
A=sorted(list(map(int,input().split())),reverse=True)
"""
lst=[]
for i in range(N):
    for m in range(N):
        lst.append(A[i]+A[m])
lst=sorted(lst,reverse=True)
#print(sum(lst[:M]))
print(lst)
"""
ng=-1
ok=max(A)*2+1
while ok>ng+1:
    mid=(ok+ng)//2
    K=0
    idx=0
    for i in range(N-1,-1,-1):
        X=mid-A[i]
        while idx<N and A[idx]>=X:
            idx+=1
        K+=idx
    if K>M:
        ng=mid
    else:
        ok=mid
idx=0
lst=[0 for i in range(N)]
for i in range(N-1,-1,-1):
    X=ng-A[i]
    while idx<N and A[idx]>=X:
        idx+=1
    lst[i]=idx*2
value=0
for a,i in zip(A,lst):
    value+=a*i
value-=ng*(sum(lst)//2-M)
print(value)