Пример #1
0
def run(debug):

    base = "BTC"
    base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60 * 24 * 30 * 2  #60*24*30*4
    interval = 60
    #dtend = datetime.datetime.strptime('2018-05-02 15:00', '%Y-%m-%d %H:%M')
    dtend = datetime.datetime.strptime('2018-05-24 17:00', '%Y-%m-%d %H:%M')

    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)
    #inp = json.load(open('misc/json_BTCUSDT_60min.json'))
    uncertainty_margin = 0.001

    def sig(prev_len, prevPrice, price):
        multiplier = (2 / float(1 + prev_len))
        v = price * multiplier + prevPrice * (1 - multiplier)
        return v

    def normalize(arr):
        a = arr[:]
        mi = min(a)
        ma = max(a)
        if (ma - mi) == 0: return [0.0]
        for i, v in enumerate(a):
            a[i] = (a[i] - mi) / (ma - mi)
        return a

    def work(_1, _2, _3, _4, _5, _6):
        portfolio = {}
        dtit = dtstart

        traceA = core.createNewScatterTrace("traceA", "y")
        traceA['prev_len'] = _1
        traceB = core.createNewScatterTrace("traceB", "y")
        traceB['prev_len'] = _2

        traceC = core.createNewScatterTrace("W&L", "y2")

        usage = {
            'canBuy': True,
            'canSell': False,
            'buyPrice': None,
            'sellPrice': None,
            'prevPrice': None,
            'win': 0,
            'loss': 0,
        }
        bucket = []
        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                price = (o + c + l + h) / 4  # ok
                #price = c         # ok
                #price = o + (c-o)*random.randint(0,10)/10 # ok
                #price = random.uniform(o, c) if c > o else random.uniform(c, o)
                #price = random.uniform(l, h)  # reality

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)

                pA = sig(
                    traceA['prev_len'],
                    np.average(traceA['y'][-_3:]) if len(traceA['y']) > 0 else
                    (o + c) / 2, (o + c) / 2)
                pB = sig(
                    traceB['prev_len'],
                    np.average(traceB['y'][-_3:]) if len(traceB['y']) > 0 else
                    (o + c) / 2, (o + c) / 2)
                core.addToScatterTrace(traceA, dtit, pA)
                core.addToScatterTrace(traceB, dtit, pB)

                bucket.append(pA)  # dummy

                def buyF():
                    if np.average(traceB['y'][-_4:]) > traceB['y'][-1]:
                        return False
                    if traceB['y'][-2] > traceA['y'][-2] and traceB['y'][
                            -1] < traceA['y'][-1]:
                        return True
                    if traceB['y'][-1] > traceB['y'][-2]:
                        return True

                def sellF():
                    if price > usage['buyPrice'] * _5 and not buyF():
                        usage['win'] += 1
                        return True
                    if price < usage['buyPrice'] * _6:
                        usage['loss'] += 1
                        return True

                if len(bucket) > 2:
                    if usage['canBuy'] and buyF():
                        core.portfolioBuy(portfolio, dtit, price,
                                          uncertainty_margin)
                        usage['canSell'] = True
                        usage['canBuy'] = False
                        usage['buyPrice'] = price
                    elif usage['canSell'] and sellF():
                        core.portfolioSell(portfolio, dtit, price,
                                           uncertainty_margin)
                        usage['canSell'] = False
                        usage['canBuy'] = True
                        usage['sellPrice'] = price

                    core.addToScatterTrace(traceC, dtit, (1 + usage['win']) /
                                           (1 + usage['loss']))

                usage['prevPrice'] = price

            dtit += datetime.timedelta(minutes=interval)

        for i, v in enumerate(
                traceB['y']):  # beautify (replacing 0's by None )
            if v == 0:
                traceB['y'][i] = None

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [
            traceA,
            traceB,
            traceC,
        ])

    if debug == 0:  # computing ROI
        A = 2
        B = 15
        C = 5
        D = 10
        E = 1.02
        F = 0.97
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(A, B, C, D, E, F)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    elif debug == 1:  # brute-force searching for optimal parameters (A,B,C,D)
        dct = {}
        for A in range(1, 30):
            for B in range(2, 30):
                for C in range(1, 10):
                    for D in range(5, 15):
                        for E in [1 + x / 100 for x in range(0, 10)]:
                            for F in [0.90 + x / 100 for x in range(0, 10)]:
                                if (B <= A): continue
                                avgs = []
                                for x in range(20):
                                    (proc, portfolio,
                                     traces) = work(A, B, C, D, E, F)
                                    #print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
                                    avgs.append(proc['_']['ROI%'])

                                print("%f %f %f %f %f %f" % (A, B, C, D, E, F))
                                print("avg ROI%: " +
                                      str(sum(avgs) / len(avgs)))
                                std = np.std(avgs)
                                print("std ROI%: " + str(std))

                                if not str(sum(avgs) / len(avgs)) in dct:
                                    dct[str(
                                        sum(avgs) / len(avgs)
                                    )] = str(A) + "_" + str(B) + "_" + str(
                                        C) + "_" + str(D) + "_" + str(
                                            E) + "_" + str(F)
        print("--------")
        print(base)
        print("--------")
        print(json.dumps(dct))
        print("--------")
        print(base)

    else:  # computing and plotting out
        A = 2
        B = 15
        C = 5
        D = 10
        E = 1.02
        F = 0.97
        (proc, portfolio, traces) = work(A, B, C, D, E, F)
        print("ROI: (%i, %i) %f" % (A, B, proc['_']['ROI%']))
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #2
0
def run(debug):

    # this strategy works best at 1hr intervals
    # 1. the idea is based on calculating the slope of the current price (which is a random price at interval 't') against the previous close price.
    # 2. it also makes sure a buy occurs when the current price is higher than the previous one
    # 3.

    base = "BTC"
    #base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60 * 24 * 30 * 4  #60*24*30*4
    interval = 120
    dtend = datetime.datetime.strptime('2018-04-15 00:00', '%Y-%m-%d %H:%M')
    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)
    uncertainty_margin = 0.001

    def EMA(_arr, size, iterations=2):  # simplified version
        multiplier = (2 / float(1 + size))

        arr = _arr[:]  # slice/copy it
        for j in range(iterations):
            ema = [arr[0]]
            for i in range(1, len(arr)):
                v = (arr[i] * multiplier) + (ema[i - 1] * (1 - multiplier))
                ema.append(v)
            arr = ema[:]

        return arr

    def sig(prev_len, prevs, price, num):
        x = price - np.average(prevs[-prev_len:])
        u = EMA(prevs[-prev_len:], prev_len, 1)
        z = np.average(u)
        x = (-1 if x < 0 else 1) * math.log(abs(z / prev_len))
        x = (-num if x < 0 else num)
        return x

    def sig2(prev_len, prevs, price):
        u = EMA(prevs, prev_len, 1)
        z = u[-1]
        return z

    def isDownTrend(arr):
        if len(arr) < 10: return True
        arr = arr[:]
        j = int(len(arr) / 3)
        first = np.average(arr[:j])
        mid = np.average(arr[j:j * 2])
        last = np.average(arr[-j:])

        if first > mid or mid > last:
            return True
        return False

    def work():
        portfolio = {}
        dtit = dtstart
        prevs = []
        canBuy = True
        canSell = False

        traceA = core.createNewScatterTrace("traceA", "y2")
        traceA['prev_len'] = 10

        traceB = core.createNewScatterTrace("traceB", "y")
        traceB[
            'prev_len'] = 12  # make sure it's large enough ( >= 12) for isDownTrend formula

        upduration_A = 0
        downduration_A = 0

        prevBuyPrice = 0

        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                price = (o + c) / 2  # ok
                # price = c         # ok
                #price = o + (c-o)*random.randint(0,10)/10 # ok
                # price = random.uniform(o, c) if c > o else random.uniform(c, o)
                # price = random.uniform(l, h)  # much worse than [open, close]

                buyprice = price
                sellprice = price

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)
                if len(prevs) > 0:
                    core.addToScatterTrace(
                        traceA, dtit, sig(traceA['prev_len'], prevs, price, 1))
                    core.addToScatterTrace(
                        traceB, dtit, sig2(traceB['prev_len'], prevs, price))

                    if len(traceA['y']) > 1:
                        if traceA['y'][-1] > 0 and traceA['y'][
                                -2] > 0:  # A up -> up
                            upduration_A += 1
                        if traceA['y'][-1] < 0 and traceA['y'][
                                -2] > 0:  # A up -> down
                            upduration_A = 0
                        if traceA['y'][-1] < 0 and traceA['y'][
                                -2] < 0:  # A down -> down
                            downduration_A += 1
                        if traceA['y'][-1] > 0 and traceA['y'][
                                -2] < 0:  # A down -> up
                            downduration_A = 0

                        if canBuy and isDownTrend(
                                traceB['y'][-traceB['prev_len']:]) == False:
                            if traceA['y'][-1] > 0 and traceA['y'][
                                    -2] < 0:  # B down -> up

                                core.portfolioBuy(portfolio, dtit, buyprice,
                                                  uncertainty_margin)
                                prevBuyPrice = buyprice
                                canSell = True
                                canBuy = False
                        elif canSell:
                            if traceA['y'][-1] < 0 and traceA['y'][
                                    -2] > 0:  # B up -> down
                                core.portfolioSell(portfolio, dtit, sellprice,
                                                   uncertainty_margin)
                                canSell = False
                                canBuy = True

                else:
                    core.addToScatterTrace(traceA, dtit,
                                           0)  # use 0 instead of None
                    core.addToScatterTrace(traceB, dtit,
                                           0)  # use 0 instead of None

                prevs.append(price)

            # else:
            #     print("missing: " + str(idx))

            dtit += datetime.timedelta(minutes=interval)

        # beautify (replacing 0's by None )
        for i, v in enumerate(traceB['y']):
            if v == 0:
                traceB['y'][i] = None

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [traceA, traceB])

    if debug == 0:
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work()
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    else:
        (proc, portfolio, traces) = work()
        print("ROI: %f" % proc['_']['ROI%'])
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #3
0
def run(debug):

    base = "BTC"
    base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60*24*30*2 #60*24*30*4
    interval = 60
    dtend = datetime.datetime.strptime('2018-05-02 15:00', '%Y-%m-%d %H:%M')
    #dtend = datetime.datetime.strptime('2018-05-17 12:00', '%Y-%m-%d %H:%M')
    #dtend = datetime.datetime.strptime('2018-06-02 12:00', '%Y-%m-%d %H:%M')
    dtend = datetime.datetime.strptime('2018-07-26 10:00', '%Y-%m-%d %H:%M')

    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote, historymins, dtend)
    preds = core.getPredictions_v1('binance', interval, base, quote, historymins, dtend)
    #preds = json.load(open('misc/preds1.json'))

    uncertainty_margin = 0.001

    def work(_1, _2, _3, _4):
        portfolio = {}
        dtit = dtstart
        canBuy = True
        canSell = False

        traceA = core.createNewScatterTrace("traceA", "y")
        traceB = core.createNewScatterTrace("traceB", "y")
        
        buyPrice = None
        prevC = None
        prevCavg = None
        bucket=[]
        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                #price = (o+c+l+h)/4   # ok
                #price = (o+c)/2   # ok
                #price = c         # ok
                #price = o + (c-o)*random.randint(0,10)/10 # ok
                #price = random.uniform(o, c) if c > o else random.uniform(c, o) 
                price = random.uniform(l, h)  # reality

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)
                
                shouldBuy=False
                if idx in preds:
                    x1,y1=list(preds[idx].items())[0]
                    x2,y2=list(preds[idx].items())[1]
                    _2 = 1.002
                    if ((y2['open']+y2['high']+y2['low']+y2['close'])/4) > ((y1['open']+y1['high']+y1['low']+y1['close'])/4)*_2:
                    	shouldBuy=True


                #if canBuy and (prevCavg < 0 and pCavg > 0) and pE > 0:
                if canBuy and shouldBuy :
                        core.portfolioBuy(portfolio, dtit, price, uncertainty_margin)
                        canSell = True
                        canBuy = False
                        buyPrice = price
                elif canSell and (price > buyPrice*_3 or price < buyPrice*_4):
                        core.portfolioSell(portfolio, dtit, price, uncertainty_margin)
                        canSell = False
                        canBuy = True

            dtit += datetime.timedelta(minutes=interval)

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [ traceA,  traceB ])


    if debug == 0: # computing ROI
        A = 2
        B = 15
        C = 1.03
        D = 0.95
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(A, B, C, D)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs)/len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))
    
    elif debug == 1: # brute-force searching for optimal parameters (A,B,C,D)
        dct = {}
        for A in range(1, 30):
            for B in range(2, 30):
                if (B <= A): continue
                for C in [1+x/100 for x in range(0, 10)]:
                    for D in [0.90+x/100 for x in range(0, 10)]:
                        avgs = []
                        for x in range(20):
                            (proc, portfolio, traces) = work(A,B,C,D)
                            #print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
                            avgs.append(proc['_']['ROI%'])

                        print("%f %f %f %f" % (A,B,C,D))
                        print("avg ROI%: " + str(sum(avgs)/len(avgs)))
                        std = np.std(avgs)
                        print("std ROI%: " + str(std))

                        if not str(sum(avgs)/len(avgs)) in dct:
                            dct [ str(sum(avgs)/len(avgs)) ] = str(A)+"_"+str(B)+"_"+str(C)+"_"+str(D)
        print("--------")
        print(base)
        print("--------")
        print(json.dumps(dct))
        print("--------")
        print(base)
    
    else: # computing and plotting out
        A = 2
        B = 15
        C = 1.03
        D = 0.95
        (proc, portfolio, traces) = work(A, B, C, D)
        print("ROI: (%i, %i %f %f) %f" % (A,B,C,D, proc['_']['ROI%']))
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #4
0
def run(debug):

    base = "BTC"
    base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60 * 24 * 30 * 1  #60*24*30*4
    interval = 60
    dtend = datetime.datetime.strptime('2018-04-26 15:00', '%Y-%m-%d %H:%M')
    # dtend = datetime.datetime.strptime('2018-05-17 12:00', '%Y-%m-%d %H:%M')
    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)
    #inp = json.load(open('misc/json_BTCUSDT_60min.json'))
    uncertainty_margin = 0.001

    def sig(prev_len, prevPrice, price):
        multiplier = (2 / float(1 + prev_len))
        v = price * multiplier + prevPrice * (1 - multiplier)
        return v

    def normalize(arr):
        a = arr[:]
        mi = min(a)
        ma = max(a)
        if (ma - mi) == 0: return [0.0]
        for i, v in enumerate(a):
            a[i] = (a[i] - mi) / (ma - mi)
        return a

    def work(_1, _2, _3):
        portfolio = {}
        dtit = dtstart

        traceD = core.createNewScatterTrace("traceD", "y2")

        usage = {
            'canBuy': True,
            'canSell': False,
            'buyPrice': None,
            'sellPrice': None,
            'prevPrice': None,
        }
        bucket = []
        bucketstd = []
        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                price = (o + c + l + h) / 4  # ok
                #price = c         # ok
                #price = o + (c-o)*random.randint(0,10)/10 # ok
                #price = random.uniform(o, c) if c > o else random.uniform(c, o)
                price = random.uniform(l, h)  # reality

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)

                def buyF():
                    if len(traceD['y']) < 2:
                        return False
                    if traceD['y'][-2] == 1 and traceD['y'][-1] == -1:
                        return True
                    #if traceD['y'][-1] == 1 and traceD['y'][-2] == -1:
                    #    return True
                def sellF():
                    if price > usage['buyPrice'] * _1:
                        return True
                    if price < usage['buyPrice'] * _2:
                        return True

                if len(bucket) > 2:
                    pD = np.average(bucket[-_3:])
                    pD = 1 if pD > 1 else -1
                    core.addToScatterTrace(traceD, dtit, pD)

                    if usage['canBuy'] and buyF():
                        core.portfolioBuy(portfolio, dtit, price,
                                          uncertainty_margin)
                        usage['canSell'] = True
                        usage['canBuy'] = False
                        usage['buyPrice'] = price
                    elif usage['canSell'] and sellF():
                        core.portfolioSell(portfolio, dtit, price,
                                           uncertainty_margin)
                        usage['canSell'] = False
                        usage['canBuy'] = True
                        usage['sellPrice'] = price
                        usage['countSinceSell'] = 0

                if usage['prevPrice'] != None:
                    bucket.append(price / usage['prevPrice'])

                usage['prevPrice'] = price

            dtit += datetime.timedelta(minutes=interval)

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [traceD])

    if debug == 0:  # computing ROI
        A = 1.03
        B = 0.96
        C = 16
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(A, B, C)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    elif debug == 1:  # brute-force searching for optimal parameters (A,B,C,D)
        dct = {}
        for A in [1 + x / 100 for x in range(1, 6)]:
            for B in [0.95 + x / 100 for x in range(0, 5)]:
                for C in range(1, 20):
                    avgs = []
                    for x in range(20):
                        (proc, portfolio, traces) = work(A, B, C)
                        #print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
                        avgs.append(proc['_']['ROI%'])

                    print("%f %f %f" % (A, B, C))
                    print("avg ROI%: " + str(sum(avgs) / len(avgs)))
                    std = np.std(avgs)
                    print("std ROI%: " + str(std))

                    if not str(sum(avgs) / len(avgs)) in dct:
                        dct[str(
                            sum(avgs) /
                            len(avgs))] = str(A) + "_" + str(B) + "_" + str(C)
        print("--------")
        print(base)
        print("--------")
        print(json.dumps(dct))
        print("--------")
        print(base)

    else:  # computing and plotting out
        # A = 1.02
        # B = 0.98
        # C = 9
        A = 1.03
        B = 0.97
        C = 16
        (proc, portfolio, traces) = work(A, B, C)
        print("ROI: (%f %f %i) %f" % (A, B, C, proc['_']['ROI%']))
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #5
0
def run(debug):

    base = "BTC"
    #base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60 * 24 * 30 * 1  #60*24*30*4
    interval = 60
    dtend = datetime.datetime.strptime('2018-04-15 00:00', '%Y-%m-%d %H:%M')
    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)
    uncertainty_margin = 0.001

    def sig(prev_len, prevY, prevs, price):
        if len(prevY) == 0: return price
        multiplier = (2 / float(1 + prev_len))
        v = price * multiplier + prevY[-1] * (1 - multiplier)
        return v

    def work(_1, _2):
        portfolio = {}
        dtit = dtstart
        prevs = []
        canBuy = True
        canSell = False

        traceA = core.createNewScatterTrace("traceA", "y")
        traceA['prev_len'] = _1

        traceB = core.createNewScatterTrace("traceB", "y")
        traceB['prev_len'] = _2

        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                #price = (o+c)/2   # ok
                # price = c         # ok
                price = o + (c - o) * random.randint(0, 10) / 10  # ok
                #price = random.uniform(o, c) if c > o else random.uniform(c, o)
                # price = random.uniform(l, h)  # much worse than [open, close]

                buyprice = price
                sellprice = price

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)

                core.addToScatterTrace(
                    traceA, dtit,
                    sig(traceA['prev_len'], traceA['y'], prevs, price))
                core.addToScatterTrace(
                    traceB, dtit,
                    sig(traceB['prev_len'], traceB['y'], prevs, price))

                if len(traceA['y']) > 1:

                    if canBuy and (traceA['y'][-2] < traceB['y'][-2]
                                   and traceA['y'][-1] > traceB['y'][-1]):
                        core.portfolioBuy(portfolio, dtit, buyprice,
                                          uncertainty_margin)
                        canSell = True
                        canBuy = False
                    elif canSell and (traceA['y'][-2] > traceB['y'][-2]
                                      and traceA['y'][-1] < traceB['y'][-1]):
                        core.portfolioSell(portfolio, dtit, sellprice,
                                           uncertainty_margin)
                        canSell = False
                        canBuy = True

                prevs.append(price)
            dtit += datetime.timedelta(minutes=interval)

        # beautify (replacing 0's by None )
        for i, v in enumerate(traceB['y']):
            if v == 0:
                traceB['y'][i] = None

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [traceA, traceB])

    if debug == 0:  # computing ROI
        A = 1
        B = 2
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(A, B)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    elif debug == 1:  # brute-force searching for optimal parameters (A & B)
        arr = []
        for A in range(1, 30):
            for B in range(2, 30):
                if (B <= A): continue
                rois = []
                for x in range(5):
                    (proc, portfolio, traces) = work(A, B)
                    rois.append(proc['_']['ROI%'])
                arr.append({"ROI": np.average(rois), "A": A, "B": B})
                print("ROI: %i %i %f" % (A, B, np.average(rois)))
        print(sorted(arr, key=lambda x: x['ROI']))

    else:  # computing and plotting out
        A = 8
        B = 23
        (proc, portfolio, traces) = work(A, B)
        print("ROI: (%i, %i) %f" % (A, B, proc['_']['ROI%']))
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #6
0
def run(debug):

    # this strategy works best at 1hr intervals
    # 1. the idea is based on calculating the slope of the current price (which is a random price at interval 't') against the previous close price.
    # 2. it also makes sure a buy occurs when the current price is higher than the previous one
    # 3. 

    base = "BTC"
    base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60*24*30*3 #60*24*30*4
    dtend = datetime.datetime.strptime('2018-04-18 00:00', '%Y-%m-%d %H:%M')
    dtstart = dtend - datetime.timedelta(minutes=historymins)
    interval = 60
    inp = core.getPriceExchange_v1('binance', interval, base, quote, historymins, dtend)
    uncertainty_margin = 0.001
    slope_pct_threshold = 0.3

    def work(dtstart, dtend):
        portfolio = {}
        prevPrice = None
        slopes = []
        dtit = dtstart
        while dtit < dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                # let price be any random value in range [open, close]
                # price = random.uniform(o, c) if c > o else random.uniform(c, o) 
                # price = random.uniform(l, h)  # much worse than [open, close]
                # let the price be any random value in range [open ; (close-open)*x ] where x is in range [0.0 ; 1.0]
                price = o + (c-o)*random.randint(0,10)/10
                # this strategy seems to stop working when we use range [low, high]
                # however in reality there is a chance the system takes near-low/high values, as a result the ROI will be low or even negative.
                buyprice = price 
                sellprice = price

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)
                if prevPrice != None:
                    slope_pct = round((price-prevPrice)/prevPrice*100,2)
                    slopes.append(slope_pct)
                    if price > prevPrice:
                        slopes.append( slope_pct )
                        avgS = sum(slopes)/len(slopes)
                        if avgS > slope_pct_threshold : # len(slopes) > 1 and
                            # buy
                            core.portfolioBuy(portfolio, dtit, buyprice, uncertainty_margin)
                    else:
                        if len(slopes) > 0:
                            # sell
                            core.portfolioSell(portfolio, dtit, sellprice, uncertainty_margin)
                        slopes = []

                prevPrice = c

            dtit += datetime.timedelta(minutes=interval)
            
        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio)

    if debug == 0:
        avgs = []
        for x in range(100):
            (proc, portfolio) = work(dtstart, dtend)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs)/len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))
    
    else:
        (proc, portfolio) = work(dtstart, dtend)
        print("ROI: %f" % proc['_']['ROI%'])
        core.portfolioToChart_OHLC(portfolio)
Пример #7
0
def run(debug):

    base = "BTC"
    base = "ETH"
    base = "LTC"

    quote = "USDT"
    historymins = 60 * 24 * 30 * 3  #60*24*30*4
    interval = 60
    dtend = datetime.datetime.strptime('2018-05-02 15:00', '%Y-%m-%d %H:%M')
    dtend = datetime.datetime.strptime('2018-05-17 12:00', '%Y-%m-%d %H:%M')

    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)

    uncertainty_margin = 0.001

    def sig(prev_len, prevY, price):
        if len(prevY) == 0: return price
        multiplier = (2 / float(1 + prev_len))
        v = price * multiplier + prevY[-1] * (1 - multiplier)
        return v

    def normalize(arr):
        a = arr[:]
        mi = min(a)
        ma = max(a)
        if (ma - mi) == 0: return [0.0]
        for i, v in enumerate(a):
            a[i] = (a[i] - mi) / (ma - mi)
        return a

    def work(_1, _2, _3, _4):
        portfolio = {}
        dtit = dtstart
        canBuy = True
        canSell = False

        traceA = core.createNewScatterTrace("traceA", "y")
        traceA['prev_len'] = _1

        traceB = core.createNewScatterTrace("traceB", "y")
        traceB['prev_len'] = _2

        traceC = core.createNewScatterTrace("traceC", "y2")
        traceD = core.createNewScatterTrace("traceD", "y2")

        buyPrice = None
        prevC = None
        prevCavg = None
        bucket = []
        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                #price = (o+c+l+h)/4   # ok
                #price = (o+c)/2   # ok
                #price = c         # ok
                #price = o + (c-o)*random.randint(0,10)/10 # ok
                #price = random.uniform(o, c) if c > o else random.uniform(c, o)
                price = random.uniform(l, h)  # reality

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)

                pA = sig(traceA['prev_len'], traceA['y'], o)
                pB = sig(traceB['prev_len'], traceB['y'], c)
                pC = pA - pB
                pC = sig(3, [prevC if prevC != None else pC], pC)
                bucket.append(pC)
                pCavg = np.average(bucket[-10:])

                core.addToScatterTrace(traceA, dtit, pA)
                core.addToScatterTrace(traceB, dtit, pB)
                core.addToScatterTrace(traceC, dtit, pC)
                core.addToScatterTrace(traceD, dtit, pCavg)

                if len(bucket) > 2:

                    if canBuy and (prevCavg < 0 and pCavg > 0):
                        core.portfolioBuy(portfolio, dtit, price,
                                          uncertainty_margin)
                        canSell = True
                        canBuy = False
                        buyPrice = price
                    elif canSell and (price > buyPrice * _3
                                      or price < buyPrice * _4):
                        core.portfolioSell(portfolio, dtit, price,
                                           uncertainty_margin)
                        canSell = False
                        canBuy = True
                prevC = pC
                prevCavg = pCavg

            dtit += datetime.timedelta(minutes=interval)

        for i, v in enumerate(
                traceB['y']):  # beautify (replacing 0's by None )
            if v == 0:
                traceB['y'][i] = None

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [traceA, traceB, traceC, traceD])

    if debug == 0:  # computing ROI
        A = 2
        B = 15
        C = 1.03
        D = 0.97
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(A, B, C, D)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    elif debug == 1:  # brute-force searching for optimal parameters (A,B,C,D)
        dct = {}
        for A in range(1, 30):
            for B in range(2, 30):
                if (B <= A): continue
                for C in [1 + x / 100 for x in range(0, 10)]:
                    for D in [0.90 + x / 100 for x in range(0, 10)]:
                        avgs = []
                        for x in range(20):
                            (proc, portfolio, traces) = work(A, B, C, D)
                            #print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
                            avgs.append(proc['_']['ROI%'])

                        print("%f %f %f %f" % (A, B, C, D))
                        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
                        std = np.std(avgs)
                        print("std ROI%: " + str(std))

                        if not str(sum(avgs) / len(avgs)) in dct:
                            dct[str(sum(avgs) / len(avgs))] = str(
                                A) + "_" + str(B) + "_" + str(C) + "_" + str(D)
        print("--------")
        print(base)
        print("--------")
        print(json.dumps(dct))
        print("--------")
        print(base)

    else:  # computing and plotting out
        A = 2
        B = 15
        C = 1.03
        D = 0.97
        (proc, portfolio, traces) = work(A, B, C, D)
        print("ROI: (%i, %i %f %f) %f" % (A, B, C, D, proc['_']['ROI%']))
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #8
0
def run(debug):

    base = "BTC"
    base = "ETH"
    base = "LTC"

    quote = "USDT"
    historymins = 60 * 6  #60*24*1 #60*24*30*1 #60*24*30*4
    interval = 1  #60
    #dtend = datetime.datetime.strptime('2018-05-02 15:00', '%Y-%m-%d %H:%M')
    dtend = datetime.datetime.strptime('2018-05-24 12:30', '%Y-%m-%d %H:%M')

    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)
    #inp = json.load(open('misc/json_BTCUSDT_60min.json'))
    #uncertainty_margin = 0.001
    uncertainty_margin = 0.0005  # slippage

    if debug == 0:  # computing ROI
        A = 2
        B = 1.007
        C = 0.993
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(dtstart, dtend, inp, interval,
                                             uncertainty_margin, A, B, C)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    elif debug == 1:  # brute-force searching for optimal parameters (A,B,C,D)
        dct = {}
        for A in range(2, 10):
            for B in [1 + x / 1000 for x in range(3, 10)]:
                for C in [0.99 + x / 1000 for x in range(3, 10)]:
                    #if (B <= A): continue
                    avgs = []
                    for x in range(1):
                        (proc, portfolio,
                         traces) = work(dtstart, dtend, inp, interval,
                                        uncertainty_margin, A, B, C)
                        #print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
                        avgs.append(proc['_']['ROI%'])

                    if sum(avgs) / len(avgs) < 0: continue  # skip negatives

                    print("%f %f %f %f %f %f" % (A, B, C, D, E, F))
                    print("avg ROI%: " + str(sum(avgs) / len(avgs)))
                    std = np.std(avgs)
                    #print("std ROI%: " + str(std))

                    if not str(sum(avgs) / len(avgs)) in dct:
                        dct[str(
                            sum(avgs) /
                            len(avgs))] = str(A) + "_" + str(B) + "_" + str(C)

        print("--------")
        print(base)
        print("--------")
        print(json.dumps(dct))
        print("--------")
        print(base)

    else:  # computing and plotting out
        shapes = [
            {
                'type': 'line',
                'xref': 'x',
                'yref': 'y2',
                'x0': datetime.datetime.strftime(dtstart, '%Y-%m-%dT%H:%M'),
                'x1': datetime.datetime.strftime(dtend, '%Y-%m-%dT%H:%M'),
                'y0': 50,
                'y1': 50,
                'line': {
                    'color': 'gray',
                    'width': 3,
                    'dash': 'dash'
                },
            },
            {
                'type': 'line',
                'xref': 'x',
                'yref': 'y2',
                'x0': datetime.datetime.strftime(dtstart, '%Y-%m-%dT%H:%M'),
                'x1': datetime.datetime.strftime(dtend, '%Y-%m-%dT%H:%M'),
                'y0': 70,
                'y1': 70,
                'line': {
                    'color': 'gray',
                    'width': 2,
                },
            },
            {
                'type': 'line',
                'xref': 'x',
                'yref': 'y2',
                'x0': datetime.datetime.strftime(dtstart, '%Y-%m-%dT%H:%M'),
                'x1': datetime.datetime.strftime(dtend, '%Y-%m-%dT%H:%M'),
                'y0': 30,
                'y1': 30,
                'line': {
                    'color': 'gray',
                    'width': 2,
                },
            },
        ]
        A = 7
        B = 1.002
        C = 0.991
        (proc, portfolio, traces) = work(dtstart, dtend, inp, interval,
                                         uncertainty_margin, A, B, C)
        print("ROI: (%i, %i) %f" % (A, B, proc['_']['ROI%']))
        core.portfolioToChart_OHLC(portfolio, traces, shapes=shapes)
Пример #9
0
def run(debug):

    base = "BTC"
    base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60 * 24 * 30 * 2  #60*24*30*4
    interval = 30
    dtend = datetime.datetime.strptime('2018-05-28 23:00', '%Y-%m-%d %H:%M')
    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)
    # inp = json.load(open("./LTC_60m.json"))
    uncertainty_margin = 0.001

    def EMAsingle(size, prevY, price):
        if len(prevY) == 0: return price
        multiplier = (2 / float(1 + size))
        v = price * multiplier + prevY[-1] * (1 - multiplier)
        return v

    def finalizeTrace(trace):
        # beautify (replacing 0's by None )
        for i, v in enumerate(trace['y']):
            if v == 0:
                trace['y'][i] = None

    def sigA(y, z, price, hp_arrL, hp_arrEL):
        z.append(price)
        L = hp_arrL
        avg = np.average(z[-L:])
        std = np.std(z[-L:]) * 2
        out = avg + std
        out = EMAsingle(hp_arrEL, y, out)
        return out

    def sigC(y, z, price, hp_arrL, hp_arrEL):
        z.append(price)
        L = hp_arrL
        avg = np.average(z[-L:])
        std = np.std(z[-L:]) * 2
        out = avg - std
        out = EMAsingle(hp_arrEL, y, out)
        return out

    def work():
        portfolio = {}
        dtit = dtstart
        canBuy = True
        canSell = False

        traceA = core.createNewScatterTrace("traceA", "y")
        traceC = core.createNewScatterTrace("traceC", "y")

        hp_arrL = 35
        hp_arrEL = 4

        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                volume = inp[idx]['volume']
                trades = inp[idx]['trades']
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                price = random.randint(
                    int(l), int(h)) if int(h) > int(l) else random.randint(
                        int(h), int(l)
                    )  # still "okay" but much worse than [open, close]

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)

                pA = sigA(traceA['y'], traceA['z'], price, hp_arrL, hp_arrEL)
                pC = sigC(traceC['y'], traceA['z'], price, hp_arrL, hp_arrEL)
                core.addToScatterTrace(traceA, dtit, pA)
                core.addToScatterTrace(traceC, dtit, pC)

                #if canBuy and (pC >= o and pC <= c):
                if canBuy and (pC >= l and pC <= h):
                    core.portfolioBuy(portfolio, dtit, price,
                                      uncertainty_margin)
                    canSell = True
                    canBuy = False
                #elif canSell and (pA >= c and pA <= o):
                elif canSell and (pA >= l and pA <= h):
                    core.portfolioSell(portfolio, dtit, price,
                                       uncertainty_margin)
                    canSell = False
                    canBuy = True

            dtit += datetime.timedelta(minutes=interval)

        finalizeTrace(traceA)
        finalizeTrace(traceC)

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [traceA, traceC])

    if debug == 0:
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work()
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    else:
        (proc, portfolio, traces) = work()
        print("ROI: %f" % proc['_']['ROI%'])
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #10
0
def run(debug):

    base = "BTC"
    base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60 * 24 * 2  #60*24*30*4
    interval = 1
    dtend = datetime.datetime.strptime('2018-05-01 12:00', '%Y-%m-%d %H:%M')
    dtend = datetime.datetime.strptime('2018-05-30 12:00', '%Y-%m-%d %H:%M')
    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote,
                                   historymins, dtend)
    # inp = json.load(open("./LTC_60m.json"))
    uncertainty_margin = 0.001

    def EMAsingle(size, prevY, price):
        if len(prevY) == 0: return price
        multiplier = (2 / float(1 + size))
        v = price * multiplier + prevY[-1] * (1 - multiplier)
        return v

    def sigA(y, z, price, hp_arrL, hp_arrEL):
        z.append(price)
        L = hp_arrL
        avg = np.average(z[-L:])
        std = np.std(z[-L:]) * 2
        out = avg + std
        out = EMAsingle(hp_arrEL, y, out)
        return out

    def sigC(y, z, price, hp_arrL, hp_arrEL):
        z.append(price)
        L = hp_arrL
        avg = np.average(z[-L:])
        std = np.std(z[-L:]) * 2
        out = avg - std
        out = EMAsingle(hp_arrEL, y, out)
        return out

    def work(_1, _2):
        portfolio = {}
        dtit = dtstart
        canBuy = True
        canSell = False

        traceA = core.createNewScatterTrace("traceA", "y")

        traceC = core.createNewScatterTrace("traceC", "y3")

        traceD = core.createNewScatterTrace("traceD", "y3")
        traceE = core.createNewScatterTrace("traceE", "y3")
        traceF = core.createNewScatterTrace("traceF", "y3")

        hp_arrL = 35
        hp_arrEL = 4

        usage = {
            'canBuy': True,
            'canSell': False,
            'buyPrice': None,
            'prevPrice': None
        }

        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                volume = inp[idx]['volume']
                trades = inp[idx]['trades']
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']

                price = (o + c + l + h) / 4  # ok
                #price = (o+c)/2
                #price = c         # ok
                #price = o + (c-o)*random.randint(0,10)/10 # ok
                #price = random.uniform(o, c) if c > o else random.uniform(c, o)
                #price = random.uniform(l, h)  # reality

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)

                core.addToScatterTrace(traceC, dtit, (c - o))
                core.addToScatterTrace(
                    traceD, dtit,
                    np.std(traceC['y'][-16:]) * 2 +
                    np.average([abs(x) for x in traceC['y'][-16:]]))

                def buyF():
                    if len(traceD['y']) < 2: return False
                    if traceC['y'][-2] < traceD['y'][-2] and traceC['y'][
                            -1] > traceD['y'][-1]:
                        return True

                def sellF():
                    if price > usage['buyPrice'] * _1:  #and not buyF():
                        return True
                    if price < usage['buyPrice'] * _2:
                        return True

                if usage['canBuy'] and buyF():
                    core.portfolioBuy(portfolio, dtit, price,
                                      uncertainty_margin)
                    usage['canSell'] = True
                    usage['canBuy'] = False
                    usage['buyPrice'] = price
                elif usage['canSell'] and sellF():
                    core.portfolioSell(portfolio, dtit, price,
                                       uncertainty_margin)
                    usage['canSell'] = False
                    usage['canBuy'] = True
                    usage['sellPrice'] = price

                usage['prevPrice'] = price

            dtit += datetime.timedelta(minutes=interval)

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [
            traceA,
            traceC,
            traceD,
            traceE,
            traceF,
        ])

    if debug == 0:
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(1.03, 0.96)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs) / len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    elif debug == 1:  # brute-force searching for optimal parameters (A,B,C,D)
        dct = {}

        for A in [1 + x / 100 for x in range(1, 10)]:
            for B in [0.90 + x / 100 for x in range(1, 10)]:
                avgs = []
                #for x in range(100):
                for x in range(1):
                    (proc, portfolio, traces) = work(A, B)
                    avgs.append(proc['_']['ROI%'])

                print("%f %f" % (A, B))
                print("avg ROI%: " + str(sum(avgs) / len(avgs)))
                std = np.std(avgs)
                print("std ROI%: " + str(std))

                if not str(sum(avgs) / len(avgs)) in dct:
                    dct[str(sum(avgs) / len(avgs))] = str(A) + "_" + str(B)
        print("--------")
        print(base)
        print("--------")
        print(json.dumps(dct))
        print("--------")
        print(base)

    else:
        (proc, portfolio, traces) = work(1.02, 0.98)
        print("ROI: %f" % proc['_']['ROI%'])
        core.portfolioToChart_OHLC(portfolio, traces)
Пример #11
0
def run(debug):

    # this strategy works best at 1hr intervals
    # 1. the idea is based on calculating the slope of the current price (which is a random price at interval 't') against the previous close price.
    # 2. it also makes sure a buy occurs when the current price is higher than the previous one
    # 3. 

    base = "BTC"
    #base = "ETH"
    #base = "LTC"

    quote = "USDT"
    historymins = 60*24*30*2 #60*24*30*4
    interval = 30
    dtend = datetime.datetime.strptime('2018-05-01 12:00', '%Y-%m-%d %H:%M')
    dtend = datetime.datetime.strptime('2018-05-26 12:00', '%Y-%m-%d %H:%M')
    dtstart = dtend - datetime.timedelta(minutes=historymins)
    inp = core.getPriceExchange_v1('binance', interval, base, quote, historymins, dtend)
    # inp = json.load(open("./LTC_60m.json"))
    uncertainty_margin = 0.001


    def EMAsingle(size, prevY, price):
        if len(prevY) == 0: return price
        multiplier = (2 / float(1 + size))
        v = price*multiplier + prevY[-1]*(1-multiplier)
        return v

    def sigA(y, z, price, hp_arrL, hp_arrEL):
        z.append(price)
        L = hp_arrL
        avg = np.average(z[-L:])
        std = np.std(z[-L:]) * 2
        out = avg + std
        out = EMAsingle(hp_arrEL, y, out)
        return out

    def sigC(y, z, price, hp_arrL, hp_arrEL):
        z.append(price)
        L = hp_arrL
        avg = np.average(z[-L:])
        std = np.std(z[-L:]) * 2
        out = avg - std
        out = EMAsingle(hp_arrEL, y, out)
        return out
    
    def work(_1, _2):
        portfolio = {}
        dtit = dtstart
        canBuy = True
        canSell = False

        traceA = core.createNewScatterTrace("traceA" ,"y")
        traceC = core.createNewScatterTrace("traceC" ,"y2", 'markers')
        traceD = core.createNewScatterTrace("traceD" ,"y2", 'markers')
        traceE = core.createNewScatterTrace("traceE" ,"y3")

        hp_arrL = 35
        hp_arrEL = 4

        usage = {
            'canBuy': True,
            'canSell': False,

            'buyPrice': None,
            'timeHeld': 0,
        }

        while dtit <= dtend:
            idx = datetime.datetime.strftime(dtit, '%Y-%m-%dT%H:%M')
            if idx in inp:
                volume = inp[idx]['volume']
                trades = inp[idx]['trades']
                c = inp[idx]['close']
                o = inp[idx]['open']
                l = inp[idx]['low']
                h = inp[idx]['high']


                #price = (o+c+l+h)/4   # ok
                price = (o+c)/2
                #price = c         # ok
                #price = o + (c-o)*random.randint(0,10)/10 # ok
                #price = random.uniform(o, c) if c > o else random.uniform(c, o) 
                #price = random.uniform(l, h)  # reality

                core.portfolioPriceEntry(portfolio, dtit, price, o, c, l, h)
            
                
                core.addToScatterTrace(traceA, dtit, (o+h+l+c)/4)
                pC = 1-1/(1+(price/np.average(traceA['y'][-24:])))
                core.addToScatterTrace(traceC, dtit, pC)

                core.addToScatterTrace(traceD, dtit, np.average(traceC['y'][-24:]))

                if len(traceD['y']) > 8:
                    pD = 1 if np.average(traceD['y'][-8:-4]) > np.average(traceD['y'][-4:-2]) and np.average(traceD['y'][-4:-2]) < np.average(traceD['y'][-2:]) else 0
                    #pD = 1 if traceD['y'][-1] > traceD['y'][-3] and traceD['y'][-2] < traceD['y'][-3] and traceD['y'][-2] < traceD['y'][-1] else 0
                    core.addToScatterTrace(traceE, dtit, pD )

                def buyF():
                    if len(traceE['y']) < 2: return False
                    
                    if traceE['y'][-2] == 0 and traceE['y'][-1]==1:
                        return True
                def sellF():
                    if traceD['y'][-1] < .5 and usage['timeHeld'] > 5:
                        return True

                    if price > usage['buyPrice']*_1: #and not buyF():
                        return True 
                    if price < usage['buyPrice']*_2:
                        return True

                if usage['canBuy'] and buyF():
                        core.portfolioBuy(portfolio, dtit, price, uncertainty_margin)
                        usage['canSell'] = True
                        usage['canBuy'] = False
                        usage['timeHeld'] = 0
                        usage['buyPrice'] = price
                elif usage['canSell'] and sellF():
                        core.portfolioSell(portfolio, dtit, price, uncertainty_margin)
                        usage['canSell'] = False
                        usage['canBuy'] = True
                        usage['timeHeld'] = 0
                        usage['sellPrice'] = price

                usage['timeHeld']+=1

                
            dtit += datetime.timedelta(minutes=interval)

        proc = core.processPortfolio(portfolio, 1)
        return (proc, portfolio, [traceA, traceC, traceD, traceE, ])


    if debug == 0:
        avgs = []
        for x in range(100):
            (proc, portfolio, traces) = work(1.03, 0.96)
            print("%s ROI \t %f" % (str(x), proc['_']['ROI%']))
            avgs.append(proc['_']['ROI%'])

        print("avg ROI%: " + str(sum(avgs)/len(avgs)))
        std = np.std(avgs)
        print("std ROI%: " + str(std))

    elif debug == 1: # brute-force searching for optimal parameters (A,B,C,D)
        dct = {}

        for A in [1+x/100 for x in range(1, 10)]:
            for B in [0.90+x/100 for x in range(1, 10)]:
                avgs = []
                for x in range(20):
                    (proc, portfolio, traces) = work(A,B)
                    avgs.append(proc['_']['ROI%'])

                print("%f %f" % (A,B))
                print("avg ROI%: " + str(sum(avgs)/len(avgs)))
                std = np.std(avgs)
                print("std ROI%: " + str(std))

                if not str(sum(avgs)/len(avgs)) in dct:
                    dct [ str(sum(avgs)/len(avgs)) ] = str(A)+"_"+str(B)
        print("--------")
        print(base)
        print("--------")
        print(json.dumps(dct))
        print("--------")
        print(base)
    
    else:
        shapes = [
            {
                'type': 'line',
                'xref': 'x',
                'yref': 'y2',
                'x0': datetime.datetime.strftime(dtstart, '%Y-%m-%dT%H:%M'),
                'x1': datetime.datetime.strftime(dtend, '%Y-%m-%dT%H:%M'),
                'y0': .50,
                'y1': .50,
                'line': {
                    'color': 'gray',
                    'width': 3,
                    'dash': 'dash'
                },
            },
        ]

        (proc, portfolio, traces) = work(1.02, 0.97)
        print("ROI: %f" % proc['_']['ROI%'])
        core.portfolioToChart_OHLC(portfolio, traces, shapes=shapes)