def handle_bar(
    counter,  # a counter for number of minute bars that have already been tested
    time,  # current time in string format such as "2018-07-30 00:30:00"
    data,  # data for current minute bar (in format 2)
    init_cash,  # your initial cash, a constant
    transaction,  # transaction ratio, a constant
    cash_balance,  # your cash balance at current minute
    crypto_balance,  # your crpyto currency balance at current minute
    total_balance,  # your total balance at current minute
    position_current,  # your position for 4 crypto currencies at this minute
    memory  # a class, containing the information you saved so far
):
    # Here you should explain the idea of your strategy briefly in the form of Python comment.
    # You can also attach facility files such as text & image & table in your team folder to illustrate your idea

    # The idea of my strategy:
    # Logistic regression with label = rising/falling signal.

    # Pattern for long signal:
    # When the predicted signal is rising, we long 1 BTC at the next bar; otherwise we short 1 BTC at the next bar.

    # Pattern for short signal:
    # When the predicted probability of rising is low (i.e., lower than 0.45), we short 1 BTC at the next bar.

    # No controlling of the position is conducted in this strategy.

    # Get position of last minute
    position_new = position_current

    # Generate OHLC data for every 30 minutes
    if (counter == 0):
        #memory.data_save = np.zeros((bar_length, 5))#, dtype=np.float64)
        memory.data_save = pd.DataFrame(
            columns=['close', 'high', 'low', 'open', 'volume'])

    if ((counter + 1) % bar_length == 0):
        memory.data_save.loc[bar_length - 1] = data[asset_index, ]
        bar = generate_bar(memory.data_save)  # pandas dataframe
        bar_X = bar[['open', 'close']]

        prob_pred = model.predict_proba(bar_X)[:, 1]
        if (prob_pred > 0.55): position_new[asset_index] += 1
        if (prob_pred < 0.45): position_new[asset_index] -= 1
    else:
        memory.data_save.loc[(counter + 1) % bar_length -
                             1] = data[asset_index, ]  #####

    # End of strategy
    return position_new, memory
    def load_training(self, filename, num=-1):
        data = {}
        for asset in range(4):
            data[asset] = []
        data_format1_path = data_format1_dir + filename
        data_format2_path = data_format2_dir + filename.replace(
            'format1', 'format2')
        format1 = h5py.File(data_format1_path, mode='r')
        format2 = h5py.File(data_format2_path, mode='r')
        #assets = list(format1.keys())
        keys = list(format2.keys())
        data_load = num if num != -1 else len(keys)

        for i in tqdm(range(data_load)):
            for asset in range(4):

                if len(data[asset]) == self.bar_length:
                    data_cur_min = format2[keys[i]][:]
                    data[asset].append(data_cur_min[asset, ])
                    segment = generate_bar(data[asset])
                    #print(segment)
                    self.training_set[asset]['x'].append(
                        segment[0:self.bar_length])
                    #tmp = []
                    '''
                    for k in range(len(segment[bar_length//2:bar_length])):
                        if segment[i] < segment[bar_length//2+i]:
                            tmp.append(2)
                    '''
                    def norm(x):
                        if x[0] > 0.05:
                            return 2
                        elif x[0] >= -0.05:
                            return 1
                        else:
                            return 0

                    self.training_set[asset]['y'].append(
                        norm(segment[self.bar_length]))
                    data[asset].pop(0)
                else:
                    data_cur_min = format2[keys[i]][:]
                    data[asset].append(data_cur_min[asset, ])

        self.data_size = len(self.training_set[asset]['y']) - self.pred_num
def handle_bar(counter,  # a counter for number of minute bars that have already been tested
               time,  # current time in string format such as "2018-07-30 00:30:00"
               data,  # data for current minute bar (in format 2)
               init_cash,  # your initial cash, a constant
               transaction,  # transaction ratio, a constant
               cash_balance,  # your cash balance at current minute
               crypto_balance,  # your crpyto currency balance at current minute
               total_balance,  # your total balance at current minute
               position_current,  # your position for 4 crypto currencies at this minute
               memory  # a class, containing the information you saved so far
               ):
    # Here you should explain the idea of your strategy briefly in the form of Python comment.
    # You can also attach facility files such as text & image & table in your team folder to illustrate your idea

    # The idea of my strategy:
    # Single alpha factor model for investment on BTC

    # The position of BTC is set by an alpha factor "(100*mean/CLOSE)*np.log(mean/1*std)"

    # When the operation on position will cause that the cash_balance is lower than 10000, this operation will be stop

    # Get position of last minute
    position_new = cp.deepcopy(position_current)
    # Generate OHLC data for every 30 minutes
    if (counter == 0):
        #memory.data_save = np.zeros((bar_length, 5))#, dtype=np.float64)
        memory.data_save = pd.DataFrame(columns = ['close', 'high', 'low', 'open', 'volume'])

    if ((counter + 1) % bar_length == 0):
        memory.data_save.loc[bar_length - 1] = data[asset_index,:5]
        bar = generate_bar(memory.data_save) # pandas dataframe
        #print(bar)
        aveopen=bar['ave_open']
        aveclose=bar['ave_close']
        avehigh=bar['ave_high']
        avelow=bar['ave_low']
        avemean=bar['ave_mean']
        avestd=bar['ave_std']
        avemed=bar['ave_med']
        if (avelow[0]>(avemean[0]-1.5*avestd[0])  and 
            avehigh[0] < (avemean[0]+1.5*avestd[0]) and
            (aveopen[0]+avelow[0])>1.9*avemean[0] and
            (aveclose[0]+avehigh[0])<2.1*avemean[0] and
            aveclose[0]<aveopen[0]
            ):
            print('small_drop')
            position_new[asset_index]=max(-(90*avemean[0]/aveclose[0])*np.log(avemean[0]/1*avestd[0]),-8)
        #if  (LOW[0]<mean[0]-2*std[0]  and 
        #     HIGH[0] > mean[0]+2*std[0] and
        #     HIGH[0]-CLOSE[0]<std[0]):
        elif(avelow[0]>(avemean[0]-1.5*avestd[0])  and 
            avehigh[0] < (avemean[0]+1.5*avestd[0]) and
            (aveopen[0]+avehigh[0])<2.1*avemean[0] and
            (aveclose[0]+avelow[0])>1.9*avemean[0] and
            aveclose[0]>aveopen[0]
            ):
            print('small_rise')
            position_new[asset_index]=min((90*avemean[0]/aveclose[0])*np.log(avemean[0]/1*avestd[0]),8) # Use an alpha factor "log(high/low)" to control the position of BTC
            
        elif(avelow[0]<(avemean[0]-2*avestd[0])  and 
            avehigh[0] > (avemean[0]+2*avestd[0]) and
            (aveopen[0]+aveclose[0])<2*avemed[0] and
            #(aveopen[0]+avelow[0])<1.9*avemean[0] and
            #(aveclose[0]+avehigh[0])>2.1*avemean[0] and
            aveclose[0]<aveopen[0]
             ):
            print('large_drop')
            position_new[asset_index]=max(-(90*avemean[0]/aveclose[0])*np.log(avemean[0]/1*avestd[0]),-8)
            
        elif(avelow[0]<(avemean[0]-2*avestd[0])  and 
            avehigh[0] > (avemean[0]+2*avestd[0]) and
            (aveopen[0]+aveclose[0])>2*avemed[0]  and
            #(aveopen[0]+avehigh[0])>1.9*avemean[0] and
            #(aveclose[0]+avelow[0])<2.1*avemean[0] and
            aveclose[0]>aveopen[0]
            ):
            print('large_rise')
            position_new[asset_index]=min((90*avemean[0]/aveclose[0])*np.log(avemean[0]/1*avestd[0]),8)

            
            
        

            
        
        #position_new[asset_index]=-9
        position_change = position_new - position_current
        mask = np.abs(position_change) > .25*data[:,4]
        position_change[mask] = (.25*data[:,4]*np.sign(position_change))[mask]
        position_new = position_current + position_change
        average_price = np.mean(data[:, :4], axis=1)
        transaction_cost = np.sum(np.abs(position_change)*average_price*transaction)
        crypto_balance = np.sum(np.abs(position_new*average_price))
        cash_new=total_balance-crypto_balance-transaction_cost
        #print(position_new)
    #print(cash_new)
        if (cash_new<10000):
            position_new[asset_index]=np.sign(position_current[asset_index])*(abs(position_current[asset_index])/2) # When the operation on position will cause that the cash_balance is lower than 10000, this operation will be stop
            #print(position_new-position_new)
  
    else:
        memory.data_save.loc[(counter + 1) % bar_length - 1] = data[asset_index,:5]#####
    

    # End of strategy
    return position_new, memory
예제 #4
0
def handle_bar(
    counter,  # a counter for number of minute bars that have already been tested
    time,  # current time in string format such as "2018-07-30 00:30:00"
    data,  # data for current minute bar (in format 2)
    init_cash,  # your initial cash, a constant
    transaction,  # transaction ratio, a constant
    cash_balance,  # your cash balance at current minute
    crypto_balance,  # your crpyto currency balance at current minute
    total_balance,  # your total balance at current minute
    position_current,  # your position for 4 crypto currencies at this minute
    memory  # a class, containing the information you saved so far
):
    # Here you should explain the idea of your strategy briefly in the form of Python comment.
    # You can also attach facility files such as text & image & table in your team folder to illustrate your idea

    # The idea of my strategy:
    # Logistic regression with label = rising/falling signal.

    # Pattern for long signal:
    # for rising/falling prediction, long/short one unit of & according to the confidence to calculate the goal price, once it reachs sell the crypto.

    global deal_unit
    global piror
    global piror_weight
    global period
    global failed_count
    global decision_count
    global is_reverse
    global use_model

    # Get position of last minute
    position_new = position_current

    average_price_for_all_assets = np.mean(data[:, :4], axis=1)
    if counter == 0:
        memory.data_save = dict()
        memory.deal_save = list()

    # for each asset do the predict and make deal.
    for asset_index in range(4):

        # if counter > 60 * 24 * 5 and total_balance > 105000:
        # if total_balance > 105000:
        #     position_new[asset_index] = 0
        #     continue

        average_price = average_price_for_all_assets[asset_index]
        fluctuate_volumn = fluctuate_volumn_for_each_crypto[asset_index]
        deal_unit = deal_unit_for_each_crypto[asset_index]
        # Generate OHLC data for every 30 minutes
        if (counter == 0):
            # memory.data_save = np.zeros((bar_length, 5))#, dtype=np.float64)
            memory.data_save[asset_index] = pd.DataFrame(
                columns=['close', 'high', 'low', 'open', 'volume'])
            # to support define outlier deals.
            memory.open_price = average_price
            memory.period_highest = dict()
            memory.period_lowest = dict()

        # check if any deal can sell in usual time.
        if len(memory.deal_save) > 0:
            for deal in memory.deal_save:
                if deal.asset_index != asset_index: continue
                if deal.is_dirty_deal and not deal.has_dropped:
                    deal.drop_price = average_price
                    deal.has_dropped = True
                if deal.has_selled or deal.has_dropped: continue
                if not deal.has_brought:
                    # update record
                    deal.deal_time = counter
                    deal.price = average_price
                    deal.goal_price += deal.price
                    deal.has_brought = True
                    deal.has_selled = False
                else:
                    # process deal, see if could sell.
                    if deal.deal_type == 'long' and average_price >= deal.goal_price:
                        # sell long
                        if not check_balance_warning(
                                cash_balance, crypto_balance, total_balance,
                                cash_balance_lower_limit, deal):
                            position_new[asset_index] -= 1 * deal_unit
                            deal.sell_time = counter
                            deal.has_selled = True
                    if deal.deal_type == 'short' and average_price <= deal.goal_price:
                        # sell long
                        if not check_balance_warning(
                                cash_balance, crypto_balance, total_balance,
                                cash_balance_lower_limit, deal):
                            position_new[asset_index] += 1 * deal_unit
                            deal.sell_time = counter
                            deal.has_selled = True

        # predict in period
        if ((counter + 1) % period == 0):
            if check_balance_warning(cash_balance, crypto_balance,
                                     total_balance, cash_balance_lower_limit):
                continue
            memory.data_save[asset_index].loc[period - 1] = data[asset_index, ]

            # wether use a model to predict.
            if use_model:
                # use the model to predict
                bar = generate_bar(
                    memory.data_save[asset_index])  # pandas dataframe
                bar_X = bar[['open', 'close']]

                prob_pred = model.predict_proba(bar_X)[:, 1][0]
                # prob_pred = -1 # random.random()
                is_up = prob_pred > 0.51
                is_down = prob_pred < 0.49
            else:
                # don't use model. judge trend based on the average price of last period & current price.
                hist_avg_price = get_history_avg_price(
                    memory.data_save[asset_index].drop('volume', axis=1),
                    period)
                curr_avg_price = get_current_avg_price(data[asset_index, ][:4])

                prob_pred = 1
                is_up = hist_avg_price < curr_avg_price
                is_down = hist_avg_price > curr_avg_price

            if decision_count > 150 and (
                    failed_count *
                    1.0) / decision_count > 0.7 and not is_reverse:
                is_reverse = True

            if is_reverse:
                is_up = not is_up
                is_down = not is_down

            make_deal = is_up or is_down
            confidence = prob_pred
            deal_type = 'none'

            if is_up:
                deal_type = 'long'
                position_new[asset_index] += 1 * deal_unit
            elif is_down:
                deal_type = 'short'
                position_new[asset_index] -= 1 * deal_unit

            if make_deal:
                decision_count += 1
                # store deal
                deal_price = 0  # unknown yet, for now just a assumed price in this minute
                # TODO should also consider transaction fee.
                goal_price = deal_price + (1 if deal_type == 'long' else -1
                                           ) * (piror_weight * piror +
                                                confidence) * fluctuate_volumn
                # deal = Deal_record(base_time='2018-08-01 00:00:00')
                deal = Deal_record(base_time='2018-10-07 00:00:00')
                deal.prob_pred = prob_pred
                deal.asset_index = asset_index
                deal.goal_price = goal_price
                deal.deal_type = deal_type
                deal.has_selled = False
                deal.has_brought = False
                memory.deal_save.append(deal)

            if len(memory.deal_save) > 0:
                for deal in memory.deal_save:
                    if not deal.has_brought: continue
                    if deal.has_selled: continue
                    if deal.is_hold_till_end: continue
                    if deal.is_dirty_deal: continue
                    if (deal.deal_time) % period == 0:
                        failed_count += 1
                        # deal.is_dirty_deal = True
                        a_index = deal.asset_index
                        # open_price_of_asset = memory.open_price[a_index]
                        if piror > 0:  # piror is the price will go up in final.
                            # TODO deal with outliers.
                            # if (deal.price < open_price_of_asset or (deal.price + pow((1 + piror), 2) * fluctuate_volumn) > open_price_of_index):
                            if deal.deal_type == 'long':
                                # hold till end and keep finding chance to sell
                                deal.is_hold_till_end = True
                            elif deal.deal_type == 'short':
                                # sell directly to stop loss
                                position_new[a_index] += 1 * deal_unit
                                deal.is_dirty_deal = True
                                pass

                        if piror < 0:  # piror is the price will go down in final.
                            # TODO deal with outliers.
                            # if (deal.price > open_price_of_asset or (deal.price + pow((1 + piror), 2) * fluctuate_volumn > open_price_of_index):
                            if deal.deal_type == 'long':
                                # sell directly to stop loss
                                position_new[a_index] -= 1 * deal_unit
                                deal.is_dirty_deal = True
                                pass
                            elif deal.deal_type == 'short':
                                # hold till end and keep finding chance to sell
                                deal.is_hold_till_end = True

        else:
            memory.data_save[asset_index].loc[(counter + 1) % period -
                                              1] = data[asset_index, ]  #####

    # End of strategy
    return position_new, memory
예제 #5
0
AU = format1['AU.SHF']
AU_min = AU[:100]
AU_15min = pd.concat([
    AU[:600].open.resample('15min').first(),
    AU[:600].high.resample('15min').max(),
    AU[:600].low.resample('15min').min(),
    AU[:600].close.resample('15min').last(),
    AU[:600].volume.resample('15min').sum()
],
                     axis=1).dropna()

plot_candles(AU_min, volume_bars=True, title='AU 1-min Candle Chart')
plot_candles(AU_15min, volume_bars=True, title='AU First 15-min Candle Chart')

# Function test of bar combination, white soider pattern and black craw pattern
from auxiliary import generate_bar, white_soider, black_craw

# Bar combination test
print('Combine first 15min data into one bar:')
print(generate_bar(min_data[:15]))

# White soider pattern test
print('\nTest is 15-30min and 0-15min form white soider:')
print(
    white_soider(generate_bar(min_data[15:30]),
                 generate_bar(min_data[:15]))[1])

# Black craw pattern test
print('\nTest is 15-30min and 0-15min form black craw:')
print(
    black_craw(generate_bar(min_data[15:30]), generate_bar(min_data[:15]))[1])
예제 #6
0
def handle_bar(
    counter,  # a counter for number of minute bars that have already been tested
    time,  # current time in string format such as "2018-07-30 00:30:00"
    data,  # data for current minute bar (in format 2)
    init_cash,  # your initial cash, a constant
    transaction,  # transaction ratio, a constant
    cash_balance,  # your cash balance at current minute
    crypto_balance,  # your crpyto currency balance at current minute
    total_balance,  # your total balance at current minute
    position_current,  # your position for 4 crypto currencies at this minute
    memory  # a class, containing the information you saved so far
):
    # Here you should explain the idea of your strategy briefly in the form of Python comment.
    # You can also attach facility files such as text & image & table in your team folder to illustrate your idea

    # The idea of my strategy:
    # Logistic regression with label = rising/falling signal.

    # Pattern for long signal:
    # for rising/falling prediction, long/short one unit of & according to the confidence to calculate the goal price, once it reachs sell the crypto.

    # TODO: embeded utility functions

    def get_income_rate(position, cryp_balance, current_price, transaction):
        return_balance = position * current_price
        transaction_cost = position * current_price * transaction
        return_rate = (abs(cryp_balance - return_balance) -
                       transaction_cost) / cryp_balance
        return return_rate

    def get_confidence():
        pass

    # memory init
    if counter == 0:
        # data_save only saves data in the latest decision period (1 hour)
        memory.data_save = dict.fromkeys(ASSETS,
                                         pd.DataFrame(columns=ORIGIN_FEATURES))
        memory.old_data = dict.fromkeys(
            ASSETS)  # bakck up of data_save after one period
        memory.deal_save = dict.fromkeys(ASSETS, [])
        memory.turning_price = dict.fromkeys(ASSETS, 0)
        memory.invested_balance = dict.fromkeys(
            ASSETS, 0)  # total money spent on the cryptos
        memory.last_prediction = 0

        memory.is_satisfied = False  # If True, stop to make deal
        memory.models_cof = [1 for i in range(4)]  # confidence for each model
        memory.use_model = [True for i in range(4)
                            ]  # use model or not (this is for ensembled model)

        memory.success_count = dict.fromkeys(ASSETS, 0)

        memory.hourly_rf = pd.DataFrame(columns=[
            'rate_BCH', 'dVolume_BCH', 'rate_BTC', 'dVolume_BTC', 'rate_ETH',
            'dVolume_ETH', 'rate_LTC', 'dVolume_LTC'
        ])
        memory.hourly_var = pd.DataFrame(columns=['BCH', 'BTC', 'ETH', 'LTC'])

    # data preprocess & record update
    position_new = position_current
    average_prices = np.mean(data[:, :4],
                             axis=1)  # average price for all assets

    VAR = [0.5, 0.5, 0.5, 0.5]  # Prediction for var model
    RF = [0.5, 0.5, 0.5, 0.5]  # Prediction for Random Forest
    LR = [0.5, 0.5, 0.5, 0.5]  # Prediction for Logistic regression

    if total_balance >= init_cash * (1 + EXPECT_RETURN_RATE):
        memory.is_satisfied = True
    else:
        memory.is_satisfied = False

    # for each asset do the predict and make deal.
    for asset_index in range(4):

        # when achieving target income, stop making deals
        # TODO: OR when is_satisfied is true & next prediction is opposite result, clean position for more income
        if memory.is_satisfied:
            position_new[asset_index] = 0
            continue

        asset_name = ASSETS[asset_index]
        # fluctuate_volumn = FLUCTUATE_VOLUMNS[asset_index]
        deal_unit = DEAL_UNITS[asset_index]
        average_price = average_prices[asset_index]

        memory.data_save[asset_name].loc[counter] = data[asset_index, ]

        # predict in DECISION_PERIOD
        if ((counter + 1) % DECISION_PERIOD == 0):

            # Risk Ananlysis
            if check_balance_warning(cash_balance, crypto_balance,
                                     total_balance, CASH_BALANCE_LOWER_LIMIT):
                continue

            # Model Evaluation
            if len(memory.deal_save[asset_name]) > 0:
                last_deal = memory.deal_save[asset_name][-1]
            else:
                last_deal = None
            # if decision_count > 150 and (failed_count*1.0) / decision_count > 0.7 and not is_reverse:
            if last_deal and int(
                    memory.data_save[asset_name].iloc[-DECISION_PERIOD]['open']
                    / memory.data_save[asset_name].iloc[-1]['close']
            ) == last_deal.prediction:
                memory.success_count[asset_name] += 1
            else:
                memory.models_cof[
                    asset_index] -= 0.01  # TODO better strategy needed
            if ((counter + 1) % (DECISION_PERIOD * 24 * 2) == 0):
                decision_count = int((counter + 1) / DECISION_PERIOD)
                if memory.success_count[asset_name] / decision_count <= 0.5:
                    # memory.use_model[asset_index] = False
                    print(
                        f'Not trust {asset_name} model now, but still use it')

            # Do prediction: use  model to predict or not
            if memory.use_model[asset_index]:
                '''
                What should do here:
                    load data for specified asset from memory.data_save[asset_name]
                    transform data format according to diff models
                    call model predict
                    ensemble result
                    give final prediction: 1: increasing, 0: decreasing, 2: hold the line (it's no matter without 2)
                '''
                bar_x = generate_bar(memory.data_save[asset_name],
                                     barlength=BAR_LENGTH)
                x = []
                for j in range(4):
                    start = int(BAR_LENGTH * j / 4)
                    end = int(BAR_LENGTH * (j + 1) / 4)
                    x.append(bar_x.values[start:end, 0].mean())

                y1 = model_list[asset_index][0].predict(x)
                y2 = model_list[asset_index][1].predict(x)
                y3 = model_list[asset_index][2].predict(x)
                predict_price = (y1 + y2 + y3) / 3
                if predict_price > memory.last_prediction:
                    prediction = 1
                elif predict_price < memory.last_prediction:
                    prediction = 0
                else:
                    prediction = -1
                memory.last_prediction = predict_price

            else:  # NOT sure is it a better way to replacce model prediction
                # # don't use model. judge trend based on the average price of last DECISION_PERIOD & current price.
                # hist_avg_price = get_history_avg_price(memory.data_save[asset_name].drop('volume', axis=1), DECISION_PERIOD)
                # curr_avg_price = get_current_avg_price(data[asset_index,][:4])
                # # prob_pred = 1
                # prediction = 1 if hist_avg_price < curr_avg_price else 0
                position_new[asset_index] = 0
                continue

            # TODO: consider transaction fee and calculate income rate to refine deal unit
            if prediction == LONG:
                deal_type = 'long'
                if position_new[asset_index] > 0:
                    position_new[asset_index] += int(
                        deal_unit * memory.models_cof[asset_index])
                    # Assume that new open = last close or avg
                    memory.invested_balance[asset_name] += int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                elif position_new[asset_index] == 0:
                    position_new[asset_index] += int(
                        deal_unit * memory.models_cof[asset_index])
                    memory.turning_price[asset_name] = average_price
                    memory.invested_balance[asset_name] += int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                else:
                    position_new[asset_index] = 0
                    memory.invested_balance[asset_name] = 0
            elif prediction == SHORT:
                deal_type = 'short'
                if position_new[asset_index] <= 0:
                    position_new[asset_index] -= int(
                        deal_unit * memory.models_cof[asset_index])
                    memory.invested_balance[asset_name] += int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                elif position_new[asset_index] == 0:
                    position_new[asset_index] -= int(
                        deal_unit * memory.models_cof[asset_index])
                    memory.turning_price[asset_name] = average_price
                    memory.invested_balance[asset_name] += int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                else:
                    position_new[asset_index] = 0
                    memory.invested_balance[asset_name] = 0
            elif prediction == HOLD:  # HOLD
                deal_type = 'none'

            # record deal
            deal_price = memory.data_save[asset_name].iloc[-1][
                'close']  # unknown yet, for now just a assumed close price in this minute
            deal = Deal_record(amount=int(deal_unit *
                                          memory.models_cof[asset_index]))
            deal.prob_pred = memory.models_cof[asset_index]
            deal.asset_index = asset_index
            # deal.goal_price = deal_price + (1 if deal_type == 'long' else -1) * (PRIOR_WEIGHT * PRIOR + confidence) * fluctuate_volumn
            deal.deal_type = deal_type
            deal.prediction = prediction
            memory.deal_save[asset_name].append(deal)

        elif (counter != 0):  # not decision period & not the first minute
            # if current currency price can give double expect return, clean position
            return_rate = get_income_rate(position_new[asset_index],
                                          memory.invested_balance[asset_name],
                                          average_price, transaction)
            if return_rate >= EXPECT_RETURN_RATE:
                position_new[asset_index] = 0
                memory.invested_balance[asset_name] = 0

    # End of strategy
    return position_new, memory
예제 #7
0
def handle_bar(timer, data, info, init_cash, transaction, detail_last_min,
               memory):
    ''' Params: timer = int, counter of current time
        data = pandas.dataframe, data for current minute bar
        info - pandas.dataframe, information matrix
        init_cash,transaction - double, constans
        detail_last_min - list, contains cash balance, margin balance, total balance and position of last minute
        memory - class, current memory of your strategy
    '''
    # Get position of last minute
    position_new = detail_last_min[0]

    # Generate OHLC data for every 15 minutes
    if (timer == 0):
        memory.data_list = list()
        memory.bar_prev = np.array([None])
        memory.ws_check_table = np.empty((0, 2))
        memory.bc_check_table = np.empty((0, 2))
        memory.long_stop_loss = np.inf
        memory.long_profit_target = np.inf
        memory.short_stop_loss = np.inf
        memory.short_profit_target = np.inf

    if (timer % bar_length == 0 and timer != 0):
        memory.data_list.append(data)
        bar = generate_bar(memory.data_list)
        memory.data_list = list(
        )  # Clear memory.data_list after bar combination

        if memory.bar_prev.any() != None:
            ws_check = white_soider(bar, memory.bar_prev, asset_index)
            memory.ws_check_table = np.append(memory.ws_check_table,
                                              [ws_check],
                                              axis=0)
            bc_check = black_craw(bar, memory.bar_prev, asset_index)
            memory.bc_check_table = np.append(memory.bc_check_table,
                                              [bc_check],
                                              axis=0)

        bar_num = len(memory.ws_check_table)
        if bar_num > 3:
            ''' long signal 
                When there is a three white soider signal, long 10 lots of asset at next minute unless 
                the current cash balance is less than 3,000,000
            '''
            if np.sum(memory.ws_check_table[bar_num - 3:bar_num, 1]) == 3:
                if detail_last_min[1] > my_cash_balance_lower_limit:
                    position_new[asset_index] += 10.
                    memory.long_stop_loss = memory.ws_check_table[bar_num - 3,
                                                                  0]
                    memory.long_profit_target = memory.ws_check_table[
                        bar_num - 1, 0] * (1 + .05)
            ''' short signal 
                When there is a three black craw signal, short 10 lots of asset at next minute unless 
                the current cash balance is less than 3,000,000
            '''
            if np.sum(memory.bc_check_table[bar_num - 3:bar_num, 1]) == 2:
                if detail_last_min[1] > my_cash_balance_lower_limit:
                    position_new[asset_index] -= 10.
                    memory.short_stop_loss = memory.bc_check_table[bar_num - 3,
                                                                   0]
                    memory.short_profit_target = memory.bc_check_table[
                        bar_num - 1, 0] * (1 + .05)

        memory.bar_prev = bar

    # save minute data to data_list
    else:
        memory.data_list.append(data)

    # Close signal
    # When reach stop loss/target profit points, clear all long/short positions
    average_price = np.mean(data[asset_index, :4])
    if (position_new[asset_index] > 0):
        if average_price > memory.long_profit_target or average_price < memory.long_stop_loss:
            position_new[asset_index] = 0.
    else:
        if average_price > memory.short_stop_loss or average_price < memory.short_profit_target:
            position_new[asset_index] = 0.
    # End of strategy
    return position_new, memory
예제 #8
0
def handle_bar(
    counter,  # a counter for number of minute bars that have already been tested
    time,  # current time in string format such as "2018-07-30 00:30:00"
    data,  # data for current minute bar (in format 2)
    init_cash,  # your initial cash, a constant
    transaction,  # transaction ratio, a constant
    cash_balance,  # your cash balance at current minute
    crypto_balance,  # your crpyto currency balance at current minute
    total_balance,  # your total balance at current minute
    position_current,  # your position for 4 crypto currencies at this minute
    memory  # a class, containing the information you saved so far
):
    # Here you should explain the idea of your strategy briefly in the form of Python comment.
    # You can also attach facility files such as text & image & table in your team folder to illustrate your idea

    # The idea of my strategy:
    # Logistic regression with label = rising/falling signal.

    # Pattern for long signal:
    # for rising/falling prediction, long/short one unit of & according to the confidence to calculate the goal price, once it reachs sell the crypto.

    # TODO: embeded utility functions

    def get_income_rate(position, cryp_balance, current_price, transaction):
        return_balance = position * current_price
        transaction_cost = position * current_price * transaction
        if cryp_balance == 0:
            return_rate = 0
        elif cryp_balance > 0:
            return_rate = ((return_balance - cryp_balance) -
                           transaction_cost) / cryp_balance
        else:
            return_rate = ((abs(cryp_balance) - return_balance) -
                           transaction_cost) / cryp_balance
        return return_rate

    def get_confidence():
        pass

    # memory init
    if counter == 0:
        # data_save only saves data in the latest decision period (1 hour)
        memory.data_save_name = dict.fromkeys(
            ASSETS, pd.DataFrame(columns=ORIGIN_FEATURES))

        memory.deal_save = dict.fromkeys(ASSETS, [])
        memory.turning_price = dict.fromkeys(ASSETS, 0)
        memory.invested_balance = dict.fromkeys(
            ASSETS, 0)  # total money spent on the cryptos
        memory.last_prediction = dict.fromkeys(['xgb', 'lstm'], 0)

        memory.is_satisfied = False  # If True, stop to make deal
        memory.models_cof = [1 for i in range(4)]  # confidence for each model
        memory.use_model = [True for i in range(4)
                            ]  # use model or not (this is for ensembled model)

        memory.success_count = dict.fromkeys(ASSETS, 0)

        memory.data_save_index = []
        memory.data_cryp = []
        for i in range(4):
            #memory.data_save = np.zeros((DECISION_PERIOD, 5))#, dtype=np.float64)
            memory.data_save_index.append(
                pd.DataFrame(
                    columns=['close', 'high', 'low', 'open', 'volume']))
            memory.data_cryp.append(
                pd.DataFrame(
                    columns=['close', 'high', 'low', 'open', 'volume']))
        memory.hourly_rf = pd.DataFrame(columns=[
            'rate_BCH', 'dVolume_BCH', 'rate_BTC', 'dVolume_BTC', 'rate_ETH',
            'dVolume_ETH', 'rate_LTC', 'dVolume_LTC'
        ])
        memory.hourly_var = pd.DataFrame(columns=['BCH', 'BTC', 'ETH', 'LTC'])

    # data preprocess & record update
    position_new = position_current
    average_prices = np.mean(data[:, :4],
                             axis=1)  # average price for all assets

    VAR = [0.5, 0.5, 0.5, 0.5]  # Prediction for var model
    RF = [0.5, 0.5, 0.5, 0.5]  # Prediction for Random Forest
    LR = [0.5, 0.5, 0.5, 0.5]  # Prediction for Logistic regression
    XGB = []
    LSTM = []

    if total_balance >= init_cash * (1 + EXPECT_RETURN_RATE):
        memory.is_satisfied = True
    else:
        memory.is_satisfied = False

    ############# rf, var, boost classification #############

    if ((counter + 1) % DECISION_PERIOD == 0):
        bar = []
        for i in range(4):
            memory.data_save_index[i].loc[DECISION_PERIOD - 1] = data[i, ]
            line = generate_bar(memory.data_save_index[i])
            bar.append(line)
            memory.data_cryp[i] = pd.concat((memory.data_cryp[i], line),
                                            axis=0,
                                            sort=True)
            memory.data_cryp[i] = memory.data_cryp[i].reset_index(drop=True)
        price = []
        for t in range(DECISION_PERIOD):
            for i in range(4):
                time_price = memory.data_save_index[i].loc[t]
                time_price_mean = (time_price['close'] + time_price['high'] +
                                   time_price['low'] + time_price['open']) / 4
                price.append(time_price_mean)
        price = np.array(price)
        price = price.reshape(1, 240)

        LR = []
        for m in boost_models:
            LR.append(m.predict(price))

        open_ave = np.array([
            bar[0]['open_ave'].values[0], bar[1]['open_ave'].values[0],
            bar[2]['open_ave'].values[0], bar[3]['open_ave'].values[0]
        ])
        hourly_data = pd.DataFrame(data=[open_ave],
                                   columns=['BCH', 'BTC', 'ETH', 'LTC'])
        memory.hourly_var = pd.concat([memory.hourly_var, hourly_data],
                                      ignore_index=True)
        lag_order = var_model.k_ar

        if lag_order < len(memory.hourly_var.index):
            diff = np.log(memory.hourly_var).diff().dropna()
            X = diff.values[-lag_order:]
            pred = var_model.forecast(X, 2)
            baseline = 0
            for i in [0, 1, 2, 3]:
                if i == 1:
                    VAR[i] = -1
                    continue
                if (pred[0][i] > baseline and pred[1][i] > baseline):
                    VAR[i] = 1
                if (pred[0][i] < (0 - baseline) and pred[1][i] <
                    (0 - baseline)):
                    VAR[i] = 0

    else:
        for i in range(4):
            memory.data_save_index[i].loc[(counter + 1) % DECISION_PERIOD -
                                          1] = data[i, ]

    df_cryp_sp = []
    for i in range(4):
        df_cryp = memory.data_cryp[i].copy()
        if len(df_cryp) > 1:

            df_cryp['rate'] = (df_cryp['close'] -
                               df_cryp['open']) / df_cryp['open']
            volume = pd.DataFrame(df_cryp['volume'][0:len(df_cryp) - 1],
                                  columns=['volume'])
            df_cryp = df_cryp.drop(0).reset_index(drop=True)
            df_cryp['dVolume'] = abs(
                (df_cryp['volume'] - volume['volume']) / volume['volume'])
            df_cryp = df_cryp[['rate', 'dVolume']]
            rateName = 'rate_' + ASSETS_NAME[i]
            dVolumeName = 'dVolume_' + ASSETS_NAME[i]
            df_cryp.columns = [rateName, dVolumeName]
            df_cryp_sp.append(df_cryp)
            memory.data_cryp[i] = memory.data_cryp[i].drop(0).reset_index(
                drop=True)
    if df_cryp_sp:
        cryp_data = pd.DataFrame()
        for cryp in df_cryp_sp:
            cryp_data = pd.concat((cryp_data, cryp), axis=1)
        memory.hourly_rf = pd.concat((memory.hourly_rf, cryp_data),
                                     axis=0).reset_index(drop=True)

    if len(memory.hourly_rf) > 2:
        df_hourly = memory.hourly_rf.copy()
        for name in ASSETS_NAME:
            bins = [-1, -0.005, 0.01, 1]
            group_name = ['down', 'middle', 'up']
            predName = 'pred_' + name
            rateName = 'rate_' + name
            df_hourly[predName] = pd.cut(df_hourly[rateName],
                                         bins,
                                         labels=group_name)
            bins_volume = [0, 2.01, 100]
            group_volume_name = ['flat', 'sharp']
            dVolumeName = 'dVolume_' + name
            df_hourly[dVolumeName] = pd.cut(df_hourly[dVolumeName],
                                            bins_volume,
                                            labels=group_volume_name)
        df_hourly = df_hourly[[
            'pred_BCH', 'pred_BTC', 'pred_ETH', 'pred_LTC', 'dVolume_BCH',
            'dVolume_BTC', 'dVolume_ETH', 'dVolume_LTC'
        ]]
        df_cryp_t0 = pd.DataFrame(df_hourly.loc[0:len(memory.hourly_rf) - 3])
        df_cryp_t0.columns = [
            'BCH_t0', 'BTC_t0', 'ETH_t0', 'LTC_t0', 'dV_BCH_t0', 'dV_BTC_t0',
            'dV_ETH_t0', 'dV_LTC_t0'
        ]
        df_cryp_t0 = df_cryp_t0.reset_index(drop=True)
        df_cryp_t1 = pd.DataFrame(df_hourly.loc[1:len(memory.hourly_rf) - 2])
        df_cryp_t1.columns = [
            'BCH_t1', 'BTC_t1', 'ETH_t1', 'LTC_t1', 'dV_BCH_t1', 'dV_BTC_t1',
            'dV_ETH_t1', 'dV_LTC_t1'
        ]
        df_cryp_t1 = df_cryp_t1.reset_index(drop=True)
        df_hourly = df_hourly.drop([0, 1]).reset_index(drop=True)
        df_hourly = pd.concat((df_hourly, df_cryp_t0), axis=1)
        df_hourly = pd.concat((df_hourly, df_cryp_t1), axis=1)
        X_train = df_hourly.drop(
            columns=['pred_BCH', 'pred_BTC', 'pred_ETH', 'pred_LTC'])

        X_train = pd.get_dummies(X_train)
        y = []
        for m in rf_models:
            y.append(m.predict(X_train))

        for i in range(4):
            if y[i] == 'up':
                RF[i] = 1
            elif y[i] == 'down':
                RF[i] = 0
            else:
                RF[i] = -1
        memory.hourly_rf = memory.hourly_rf.drop(0).reset_index(drop=True)

    # xgboost & LSTM
    # for each asset do the predict and make deal.
    for asset_index in range(4):

        # when achieving target income, stop making deals
        # TODO: OR when is_satisfied is true & next prediction is opposite result, clean position for more income
        if memory.is_satisfied:
            position_new[asset_index] = 0
            continue

        asset_name = ASSETS[asset_index]
        # fluctuate_volumn = FLUCTUATE_VOLUMNS[asset_index]
        deal_unit = DEAL_UNITS[asset_index]
        average_price = average_prices[asset_index]

        memory.data_save_name[asset_name].loc[counter] = data[asset_index, ]

        # predict in DECISION_PERIOD
        if ((counter + 1) % DECISION_PERIOD == 0 and counter > 60):

            # Risk Ananlysis
            if check_balance_warning(cash_balance, crypto_balance,
                                     total_balance, CASH_BALANCE_LOWER_LIMIT):
                continue

            # Model Evaluation
            if len(memory.deal_save[asset_name]) > 0:
                last_deal = memory.deal_save[asset_name][-1]
            else:
                last_deal = None
            # if decision_count > 150 and (failed_count*1.0) / decision_count > 0.7 and not is_reverse:
            if last_deal and int(
                    memory.data_save_name[asset_name].iloc[-DECISION_PERIOD]
                ['open'] / memory.data_save_name[asset_name].iloc[-1]['close']
            ) == last_deal.prediction:
                memory.success_count[asset_name] += 1
            else:
                memory.models_cof[
                    asset_index] -= 0.01  # TODO better strategy needed
            if ((counter + 1) % (DECISION_PERIOD * 24 * 2) == 0):
                decision_count = int((counter + 1) / DECISION_PERIOD)
                if memory.success_count[asset_name] / decision_count <= 0.5:
                    # memory.use_model[asset_index] = False
                    print(
                        f'Not trust {asset_name} model now, but still use it')

            # Do prediction: use  model to predict or not
            if memory.use_model[asset_index]:
                '''
                What should do here:
                    load data for specified asset from memory.data_save[asset_name]
                    transform data format according to diff models
                    call model predict
                    ensemble result
                    give final prediction: 1: increasing, 0: decreasing, 2: hold the line (it's no matter without 2)
                '''
                # xgboost
                bar_x = generate_avg_bar(memory.data_save_name[asset_name],
                                         barlength=BAR_LENGTH)
                x_1 = []
                for j in range(4):
                    start = int(BAR_LENGTH * j / 4)
                    end = int(BAR_LENGTH * (j + 1) / 4)
                    x_1.append(bar_x.values[start:end, 0].mean())

                y1 = xgb_models[asset_index][0].predict(x_1)
                y2 = xgb_models[asset_index][1].predict(x_1)
                y3 = xgb_models[asset_index][2].predict(x_1)
                predict_price = (y1 + y2 + y3) / 3
                if predict_price > memory.last_prediction['xgb']:
                    XGB = 1
                elif predict_price < memory.last_prediction['xgb']:
                    XGB = 0
                else:
                    XGB = -1
                memory.last_prediction['xgb'] = predict_price

                # lstm
                bar_x = generate_avg_bar(memory.data_save_name[asset_name],
                                         barlength=BAR_LENGTH)
                bar_x = np.array([bar_x[['avg']].values[:, 0]])
                x_2 = np.reshape(bar_x, (bar_x.shape[0], 1, bar_x.shape[1]))

                predict_price = lstm_models[asset_index].predict(x_2)
                if predict_price >= memory.last_prediction['lstm']:
                    LSTM = 1
                elif predict_price < memory.last_prediction['lstm']:
                    LSTM = 0
                else:
                    LSTM = -1
                memory.last_prediction['lstm'] = predict_price

            else:  # NOT sure is it a better way to replacce model prediction
                position_new[asset_index] = 0
                continue

            price_pred = [
                LR[asset_index], VAR[asset_index], RF[asset_index], XGB, LSTM
            ]
            if price_pred.count(1) >= 2 and price_pred.count(0) <= 1:
                prediction = 1
            elif price_pred.count(0) >= 2 and price_pred.count(1) <= 1:
                prediction = 0
            else:
                prediction = -1

            # TODO: consider transaction fee and calculate income rate to refine deal unit
            if prediction == LONG:
                deal_type = 'long'
                if position_new[asset_index] > 0:
                    position_new[asset_index] += int(
                        deal_unit * memory.models_cof[asset_index])
                    # Assume that new open = last close or avg
                    memory.invested_balance[asset_name] += int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                elif position_new[asset_index] == 0:
                    position_new[asset_index] += int(
                        deal_unit * memory.models_cof[asset_index])
                    memory.turning_price[asset_name] = average_price
                    memory.invested_balance[asset_name] += int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                else:
                    position_new[asset_index] = 0
                    memory.invested_balance[asset_name] = 0
            elif prediction == SHORT:
                deal_type = 'short'
                if position_new[asset_index] < 0:
                    position_new[asset_index] -= int(
                        deal_unit * memory.models_cof[asset_index])
                    memory.invested_balance[asset_name] -= int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                elif position_new[asset_index] == 0:
                    position_new[asset_index] -= int(
                        deal_unit * memory.models_cof[asset_index])
                    memory.turning_price[asset_name] = average_price
                    memory.invested_balance[asset_name] -= int(
                        deal_unit *
                        memory.models_cof[asset_index]) * average_price
                else:
                    position_new[asset_index] = 0
                    memory.invested_balance[asset_name] = 0
            elif prediction == HOLD:  # HOLD
                deal_type = 'none'

            # record deal
            deal_price = memory.data_save_name[asset_name].iloc[-1][
                'close']  # unknown yet, for now just a assumed close price in this minute
            deal = Deal_record(amount=int(deal_unit *
                                          memory.models_cof[asset_index]))
            deal.prob_pred = memory.models_cof[asset_index]
            deal.asset_index = asset_index
            # deal.goal_price = deal_price + (1 if deal_type == 'long' else -1) * (PRIOR_WEIGHT * PRIOR + confidence) * fluctuate_volumn
            deal.deal_type = deal_type
            deal.prediction = prediction
            memory.deal_save[asset_name].append(deal)

        elif (counter != 0):  # not decision period & not the first minute
            # if current currency price can give double expect return, clean position
            return_rate = get_income_rate(position_new[asset_index],
                                          memory.invested_balance[asset_name],
                                          average_price, transaction)
            if return_rate >= EXPECT_DEAL_RETURN / 2:
                position_new[asset_index] = 0
                memory.invested_balance[asset_name] = 0

    # End of strategy
    return position_new, memory
def handle_bar(counter,  # a counter for number of minute bars that have already been tested
               time,  # current time in string format such as "2018-07-30 00:30:00"
               data,  # data for current minute bar (in format 2)
               init_cash,  # your initial cash, a constant
               transaction,  # transaction ratio, a constant
               cash_balance,  # your cash balance at current minute
               crypto_balance,  # your crpyto currency balance at current minute
               total_balance,  # your total balance at current minute
               position_current,  # your position for 4 crypto currencies at this minute
               memory  # a class, containing the information you saved so far
               ):
    # Here you should explain the idea of your strategy briefly in the form of Python comment.
    # You can also attach facility files such as text & image & table in your team folder to illustrate your idea

    # The idea of my strategy:
    # Make use of some technical patterns in candlestick plots:

    # Pattern for long signal: (unstrict) three white soldiers
    # For three sequential bars (each bar is 15 minutes long), if they have the pattern "white soldiers", i.e.
    # 1. OPEN(n) > OPEN(n-1)
    # 2. CLOSE(n) > CLOSE(n-1)
    # 3. CLOSE(n) > OPEN(n)
    # then we long 1 BTC at next bar unless the current cash balance is less than 30,000
    # stop loss point: When the price drop down to the close price of the first white soilder, clear all long position
    # target profit point: When the price go up to (1+5%) times the close price of the third white soilder, clear all long position

    # Pattern for short signal: (unstrict) three black craws
    # For three sequential bars (each bar is 15 minutes long), if they have the pattern "black craws", i.e.
    # 1. OPEN(n) < OPEN(n-1)
    # 2. CLOSE(n) < CLOSE(n-1)
    # 3. CLOSE(n) < OPEN(n)
    # then we short 1 BTC at next bar unless the current cash balance is less than 30,000
    # stop loss point: When the price go up to the close price of the first black craw, clear all short position
    # target profit point: When the price go up to (1-5%) times the close price of the third black craw, clear all long position

    # Get position of last minute
    position_new = position_current
    
    # Generate OHLC data for every 15 minutes
    if counter == 0:
        memory.data_list = list()
        memory.bar_prev = np.array([None])
        memory.ws_check_table = np.empty((0,2))
        memory.bc_check_table = np.empty((0,2))
        memory.long_stop_loss = np.inf
        memory.long_profit_target = np.inf
        memory.short_stop_loss = np.inf
        memory.short_profit_target = np.inf
    
    if (counter + 1) % bar_length == 0:
        memory.data_list.append(data)
        bar = generate_bar(memory.data_list)
        memory.data_list = list()  # Clear memory.data_list after bar combination
        
        if memory.bar_prev.any()!=None:
            ws_check = white_soider(bar, memory.bar_prev, asset_index)
            memory.ws_check_table = np.append(memory.ws_check_table, [ws_check], axis=0)
            bc_check = black_craw(bar, memory.bar_prev, asset_index)
            memory.bc_check_table = np.append(memory.bc_check_table, [bc_check], axis=0)
            
        bar_num = len(memory.ws_check_table)
        if bar_num>3:
            ''' long signal 
                When there is a three white soider signal, long 1 BTC at next minute unless 
                the current cash balance is less than my_cash_balance_lower_limit
            '''
            if np.sum(memory.ws_check_table[(bar_num-3):bar_num,1])==3:
                if cash_balance > my_cash_balance_lower_limit:
                    position_new[asset_index] += 1.
                    memory.long_stop_loss = memory.ws_check_table[bar_num-3,0]
                    memory.long_profit_target = memory.ws_check_table[bar_num-1,0]*(1+.05)
            
            ''' short signal 
                When there is a three black craw signal, short 1 BTC at next minute unless 
                the current cash balance is less than my_cash_balance_lower_limit
            '''
            if np.sum(memory.bc_check_table[(bar_num-3):bar_num,1])==3:
                if cash_balance > my_cash_balance_lower_limit:
                    position_new[asset_index] -= 1.
                    memory.short_stop_loss = memory.bc_check_table[bar_num-3,0]
                    memory.short_profit_target = memory.bc_check_table[bar_num-1,0]*(1-.05)
        
        memory.bar_prev = bar
        
    # save minute data to data_list
    else:
        memory.data_list.append(data)
    
    # Close signal
    # When reach stop loss/target profit points, clear all long/short positions
    average_price = np.mean(data[asset_index,:4])
    if(position_new[asset_index] > 0):
        if average_price > memory.long_profit_target or average_price < memory.long_stop_loss:
            position_new[asset_index] = 0.
    else:
        if average_price > memory.short_stop_loss or average_price < memory.short_profit_target:
            position_new[asset_index] = 0.
    # End of strategy
    return position_new, memory